Detect truncated ASN data as UnparsableKeyError

This commit is contained in:
Stuart D. Gathman
2013-03-13 23:41:01 -04:00
parent d7d0979a7e
commit 188515ddf7
3 changed files with 47 additions and 39 deletions
+40 -38
View File
@@ -53,44 +53,46 @@ def asn1_parse(template, data):
data = bytearray(data)
r = []
i = 0
for t in template:
tag = data[i]
i += 1
if tag == t[0]:
length = data[i]
i += 1
if length & 0x80:
n = length & 0x7f
length = 0
for j in range(n):
length = (length << 8) | data[i]
i += 1
if tag == INTEGER:
n = 0
for j in range(length):
n = (n << 8) | data[i]
i += 1
r.append(n)
elif tag == BIT_STRING:
r.append(data[i:i+length])
i += length
elif tag == NULL:
assert length == 0
r.append(None)
elif tag == OBJECT_IDENTIFIER:
r.append(data[i:i+length])
i += length
elif tag == SEQUENCE:
r.append(asn1_parse(t[1], data[i:i+length]))
i += length
else:
raise ASN1FormatError(
"Unexpected tag in template: %02x" % tag)
else:
raise ASN1FormatError(
"Unexpected tag (got %02x, expecting %02x)" % (tag, t[0]))
return r
try:
for t in template:
tag = data[i]
i += 1
if tag == t[0]:
length = data[i]
i += 1
if length & 0x80:
n = length & 0x7f
length = 0
for j in range(n):
length = (length << 8) | data[i]
i += 1
if tag == INTEGER:
n = 0
for j in range(length):
n = (n << 8) | data[i]
i += 1
r.append(n)
elif tag == BIT_STRING:
r.append(data[i:i+length])
i += length
elif tag == NULL:
assert length == 0
r.append(None)
elif tag == OBJECT_IDENTIFIER:
r.append(data[i:i+length])
i += length
elif tag == SEQUENCE:
r.append(asn1_parse(t[1], data[i:i+length]))
i += length
else:
raise ASN1FormatError(
"Unexpected tag in template: %02x" % tag)
else:
raise ASN1FormatError(
"Unexpected tag (got %02x, expecting %02x)" % (tag, t[0]))
return r
except IndexError:
raise ASN1FormatError("Data truncated at byte %d"%i)
def asn1_length(n):
"""Return a string representing a field length in ASN.1 format.
+1
View File
@@ -0,0 +1 @@
v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkHlOQoBTzWRiGs5V6NpP3idY6Wk08a5qhdR6wy5bdOKb2jLQiY/J16JYi0Qvx/byYzCNb3W91y3FutACDfzwQ/BC/e/8uBsCR+yz1Lxj+PL6lHvqMKrM3rG4hstT5QjvHO9PzoxZyVYLzBfO2EeC3Ip3G+2kryOTIKT+l/K4w3QIDAQA=
+6 -1
View File
@@ -23,6 +23,7 @@ import unittest
from dkim.crypto import (
DigestTooLargeError,
UnparsableKeyError,
EMSA_PKCS1_v1_5_encode,
int2str,
parse_pem_private_key,
@@ -108,7 +109,11 @@ class TestParseKeys(unittest.TestCase):
key = parse_public_key(base64.b64decode(parse_tag_value(data)[b'p']))
self.assertEqual(key['modulus'], TEST_KEY_MODULUS)
self.assertEqual(key['publicExponent'], TEST_KEY_PUBLIC_EXPONENT)
try:
data = read_test_data('test_bad.txt')
key = parse_public_key(base64.b64decode(parse_tag_value(data)[b'p']))
except UnparsableKeyError: return
self.fail("failed to reject invalid public key")
class TestEMSA_PKCS1_v1_5(unittest.TestCase):