crypto docstrings.

This commit is contained in:
William Grant
2011-03-12 15:37:25 +11:00
parent 7dec2e4697
commit 7fa823748d
+54 -19
View File
@@ -68,11 +68,16 @@ ASN1_RSAPrivateKey = [
]
class DigestTooLarge(Exception):
pass
def parse_public_key(data):
"""Parse an RSA public key.
@param data: A DER-encoded X.509 subjectPublicKeyInfo
@param data: DER-encoded X.509 subjectPublicKeyInfo
containing an RFC3447 RSAPublicKey.
@return: RSA public key
"""
x = asn1_parse(ASN1_Object, data)
# 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):
"""Parse an RSA private key.
@param data: DER-encoded RFC3447 RSAPrivateKey.
@return: RSA private key
"""
pka = asn1_parse(ASN1_RSAPrivateKey, data)
pk = {
'version': pka[0][0],
@@ -100,14 +110,13 @@ def parse_private_key(data):
return pk
def EMSA_PKCS1_v1_5_encode(digest, modlen, hashid):
"""Encode a digest with EMSA-PKCS1-v1_5.
def EMSA_PKCS1_v1_5_encode(digest, mlen, hashid):
"""Encode a digest with RFC3447 EMSA-PKCS1-v1_5.
Defined in RFC3447 section 9.2.
@param digest: A digest value to encode.
@param modlen: The desired message length.
@param hashid: The ID of the hash used to generate the digest.
@param digest: digest byte string to encode
@param mlen: desired message length
@param hashid: ID of the hash used to generate the digest
@return: encoded digest byte string
"""
dinfo = asn1_build(
(SEQUENCE, [
@@ -117,15 +126,16 @@ def EMSA_PKCS1_v1_5_encode(digest, modlen, hashid):
]),
(OCTET_STRING, digest),
]))
if len(dinfo)+3 > modlen:
if len(dinfo)+3 > mlen:
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):
"""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
for c in s:
@@ -134,13 +144,13 @@ def str2int(s):
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 length: Minimum length, or -1 to return the smallest number of
bytes that represent the integer.
@param n: positive integer to convert
@param length: minimum length
@return: converted bytestring, of at least the minimum length if it was
specified
"""
assert n >= 0
r = []
while length < 0 or len(r) < length:
@@ -153,11 +163,27 @@ def int2str(n, length = -1):
return ''.join(r)
def perform_rsa(input, exponent, modulus, modlen):
return int2str(pow(str2int(input), exponent, modulus), modlen)
def perform_rsa(message, exponent, modulus, mlen):
"""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):
"""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))
encoded_digest = EMSA_PKCS1_v1_5_encode(digest, modlen, hashid)
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,
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))
encoded_digest = EMSA_PKCS1_v1_5_encode(digest, modlen, hashid)
signed_digest = perform_rsa(signature, public_exponent, modulus, modlen)