crypto docstrings.
This commit is contained in:
+55
-20
@@ -68,11 +68,16 @@ ASN1_RSAPrivateKey = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class DigestTooLarge(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def parse_public_key(data):
|
def parse_public_key(data):
|
||||||
"""Parse an RSA public key.
|
"""Parse an RSA public key.
|
||||||
|
|
||||||
@param data: A DER-encoded X.509 subjectPublicKeyInfo
|
@param data: DER-encoded X.509 subjectPublicKeyInfo
|
||||||
containing an RFC3447 RSAPublicKey.
|
containing an RFC3447 RSAPublicKey.
|
||||||
|
@return: RSA public key
|
||||||
"""
|
"""
|
||||||
x = asn1_parse(ASN1_Object, data)
|
x = asn1_parse(ASN1_Object, data)
|
||||||
# Not sure why the [1:] is necessary to skip a byte.
|
# Not sure why the [1:] is necessary to skip a byte.
|
||||||
@@ -85,6 +90,11 @@ def parse_public_key(data):
|
|||||||
|
|
||||||
|
|
||||||
def parse_private_key(data):
|
def parse_private_key(data):
|
||||||
|
"""Parse an RSA private key.
|
||||||
|
|
||||||
|
@param data: DER-encoded RFC3447 RSAPrivateKey.
|
||||||
|
@return: RSA private key
|
||||||
|
"""
|
||||||
pka = asn1_parse(ASN1_RSAPrivateKey, data)
|
pka = asn1_parse(ASN1_RSAPrivateKey, data)
|
||||||
pk = {
|
pk = {
|
||||||
'version': pka[0][0],
|
'version': pka[0][0],
|
||||||
@@ -100,14 +110,13 @@ def parse_private_key(data):
|
|||||||
return pk
|
return pk
|
||||||
|
|
||||||
|
|
||||||
def EMSA_PKCS1_v1_5_encode(digest, modlen, hashid):
|
def EMSA_PKCS1_v1_5_encode(digest, mlen, hashid):
|
||||||
"""Encode a digest with EMSA-PKCS1-v1_5.
|
"""Encode a digest with RFC3447 EMSA-PKCS1-v1_5.
|
||||||
|
|
||||||
Defined in RFC3447 section 9.2.
|
@param digest: digest byte string to encode
|
||||||
|
@param mlen: desired message length
|
||||||
@param digest: A digest value to encode.
|
@param hashid: ID of the hash used to generate the digest
|
||||||
@param modlen: The desired message length.
|
@return: encoded digest byte string
|
||||||
@param hashid: The ID of the hash used to generate the digest.
|
|
||||||
"""
|
"""
|
||||||
dinfo = asn1_build(
|
dinfo = asn1_build(
|
||||||
(SEQUENCE, [
|
(SEQUENCE, [
|
||||||
@@ -117,15 +126,16 @@ def EMSA_PKCS1_v1_5_encode(digest, modlen, hashid):
|
|||||||
]),
|
]),
|
||||||
(OCTET_STRING, digest),
|
(OCTET_STRING, digest),
|
||||||
]))
|
]))
|
||||||
if len(dinfo)+3 > modlen:
|
if len(dinfo)+3 > mlen:
|
||||||
raise Exception("Hash too large for modulus") # XXX: DKIMException
|
raise Exception("Hash too large for modulus") # XXX: DKIMException
|
||||||
return "\x00\x01"+"\xff"*(modlen-len(dinfo)-3)+"\x00"+dinfo
|
return "\x00\x01"+"\xff"*(mlen-len(dinfo)-3)+"\x00"+dinfo
|
||||||
|
|
||||||
|
|
||||||
def str2int(s):
|
def str2int(s):
|
||||||
"""Convert an octet string to an integer.
|
"""Convert a byte string to an integer.
|
||||||
|
|
||||||
Octet string assumed to represent a positive integer.
|
@param s: byte string representing a positive integer to convert
|
||||||
|
@return: converted integer
|
||||||
"""
|
"""
|
||||||
r = 0
|
r = 0
|
||||||
for c in s:
|
for c in s:
|
||||||
@@ -133,14 +143,14 @@ def str2int(s):
|
|||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
def int2str(n, length = -1):
|
def int2str(n, length=-1):
|
||||||
"""Convert an integer to an octet string. Number must be positive.
|
"""Convert an integer to a byte string.
|
||||||
|
|
||||||
@param n: Number to convert.
|
@param n: positive integer to convert
|
||||||
@param length: Minimum length, or -1 to return the smallest number of
|
@param length: minimum length
|
||||||
bytes that represent the integer.
|
@return: converted bytestring, of at least the minimum length if it was
|
||||||
|
specified
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert n >= 0
|
assert n >= 0
|
||||||
r = []
|
r = []
|
||||||
while length < 0 or len(r) < length:
|
while length < 0 or len(r) < length:
|
||||||
@@ -153,11 +163,27 @@ def int2str(n, length = -1):
|
|||||||
return ''.join(r)
|
return ''.join(r)
|
||||||
|
|
||||||
|
|
||||||
def perform_rsa(input, exponent, modulus, modlen):
|
def perform_rsa(message, exponent, modulus, mlen):
|
||||||
return int2str(pow(str2int(input), exponent, modulus), modlen)
|
"""Perform RSA signing or verification.
|
||||||
|
|
||||||
|
@param message: byte string to operate on
|
||||||
|
@param exponent: public or private key exponent
|
||||||
|
@param modulus: key modulus
|
||||||
|
@param mlen: desired output length
|
||||||
|
@return: byte string result of the operation
|
||||||
|
"""
|
||||||
|
return int2str(pow(str2int(message), exponent, modulus), mlen)
|
||||||
|
|
||||||
|
|
||||||
def RSASSA_PKCS1_v1_5_sign(digest, hashid, private_exponent, modulus):
|
def RSASSA_PKCS1_v1_5_sign(digest, hashid, private_exponent, modulus):
|
||||||
|
"""Sign a digest with RFC3447 RSASSA-PKCS1-v1_5.
|
||||||
|
|
||||||
|
@param digest: digest byte string to sign
|
||||||
|
@param hashid: ID of the hash used to generate the digest
|
||||||
|
@param private_exponent: private key exponent
|
||||||
|
@param modulus: key modulus
|
||||||
|
@return: signed digest byte string
|
||||||
|
"""
|
||||||
modlen = len(int2str(modulus))
|
modlen = len(int2str(modulus))
|
||||||
encoded_digest = EMSA_PKCS1_v1_5_encode(digest, modlen, hashid)
|
encoded_digest = EMSA_PKCS1_v1_5_encode(digest, modlen, hashid)
|
||||||
return perform_rsa(encoded_digest, private_exponent, modulus, modlen)
|
return perform_rsa(encoded_digest, private_exponent, modulus, modlen)
|
||||||
@@ -165,6 +191,15 @@ def RSASSA_PKCS1_v1_5_sign(digest, hashid, private_exponent, modulus):
|
|||||||
|
|
||||||
def RSASSA_PKCS1_v1_5_verify(digest, hashid, signature, public_exponent,
|
def RSASSA_PKCS1_v1_5_verify(digest, hashid, signature, public_exponent,
|
||||||
modulus):
|
modulus):
|
||||||
|
"""Verify a digest signed with RFC3447 RSASSA-PKCS1-v1_5.
|
||||||
|
|
||||||
|
@param digest: digest byte string to check
|
||||||
|
@param hashid: ID of the hash used to generate the digest
|
||||||
|
@param signature: signed digest byte string
|
||||||
|
@param public_exponent: public key exponent
|
||||||
|
@param modulus: key modulus
|
||||||
|
@return: True if the signature is valid, False otherwise
|
||||||
|
"""
|
||||||
modlen = len(int2str(modulus))
|
modlen = len(int2str(modulus))
|
||||||
encoded_digest = EMSA_PKCS1_v1_5_encode(digest, modlen, hashid)
|
encoded_digest = EMSA_PKCS1_v1_5_encode(digest, modlen, hashid)
|
||||||
signed_digest = perform_rsa(signature, public_exponent, modulus, modlen)
|
signed_digest = perform_rsa(signature, public_exponent, modulus, modlen)
|
||||||
|
|||||||
Reference in New Issue
Block a user