refacor of PKCS8 parsing, added pkcs8 test

This commit is contained in:
Spitap
2022-08-01 00:49:39 +02:00
parent 20d9ca1e1c
commit 8e78ce7e13
4 changed files with 50 additions and 12 deletions
+9 -9
View File
@@ -145,8 +145,14 @@ def parse_private_key(data):
""" """
try: try:
pka = asn1_parse(ASN1_RSAPrivateKey, data) pka = asn1_parse(ASN1_RSAPrivateKey, data)
except ASN1FormatError as e: except ASN1FormatError:
raise UnparsableKeyError('Unparsable private key: ' + str(e)) try:
#If it fails it might be because of PKCS#8 (key generated with openSSL 3.X)
pkt = asn1_parse(ASN1_PKCS8_PrivateKey, data)
pka = asn1_parse(ASN1_RSAPrivateKey, pkt[0][2])
except ASN1FormatError as e:
raise UnparsableKeyError("Unparsable private key (are your sure it is encoded in PKCS#1 or PKCS#8 standard ?):\n" + str(e))
pk = { pk = {
'version': pka[0][0], 'version': pka[0][0],
'modulus': pka[0][1], 'modulus': pka[0][1],
@@ -174,13 +180,7 @@ def parse_pem_private_key(data):
pkdata = base64.b64decode(m.group(1)) pkdata = base64.b64decode(m.group(1))
except TypeError as e: except TypeError as e:
raise UnparsableKeyError(str(e)) raise UnparsableKeyError(str(e))
try: return parse_private_key(pkdata)
pk = parse_private_key(pkdata)
except UnparsableKeyError:
#If it fails it might be because of PKCS#8 (key generated with openSSL 3.X)
pka = asn1_parse(ASN1_PKCS8_PrivateKey, pkdata)
pk = parse_private_key(pka[0][2])
return pk
def EMSA_PKCS1_v1_5_encode(hash, mlen): def EMSA_PKCS1_v1_5_encode(hash, mlen):
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDYMGhEok34XiUg
szO7cuYph/dw0lliI18+wwX0ybUNwjkmc89jfRNZ6OEF5BfuyMYAoHB96D9EhIAI
qXzjmvFtjZIrYTyzb2X/4Cml7uxGLiekSFjrANL1mybg36FKeMAV59s078++IrcQ
Trr1E6e7q127/YRwCGy+KZQ0Sl2CrL+IdPuCK5WAJtYT1zQ/h3PQ/xUcHLnUtem5
BOirg7sweoxdfZWsXu7WeGDYiFOOV5pMmdueFfun5CJe8MfdEJ4YsXqxCxa2yqrN
klkX4RSphEfwreU/sv0DsWj/eaWmFDhagvd2AwixId/lFYGsY2X7G6bs/SqThoBk
9GftRGihAgMBAAECggEAYiHjCpiUBPQTLVs61dEridmWp8dL3IDK6K3VA88VmMe7
cmlqT7JEOPE9R5PIi1Lmkf1B4t0r7tmoVoY80wIPqhdzrK5IQ/kCl1n0/cXMyXSE
+Q0AE7h9ihAh3zyTtb7HDop+1fIvXhLa/xOFyN5hqo34j+9dkQ858T3lcLD67mfO
1/lpBhwEeF/7+wg2MiwM/4Rd217ReUgdgXTKZ8DYtLr+TFagv/8E8zAgHVqnklHf
yEGR5+O94WYpqbanagfivxmogHsW6Eu5Ub/RJuWj06AvhRQSkPgVV5pl1zv0EP2w
vhAl2YVzorRJDEzclmP+PyTzp+sPbrIqywof+K89WwKBgQDddD6eqISrWC4Vo2CZ
WvBetiC48KKKjWwcFGERHGYqrmZMTDVYKqSUO7PvcgHIVyElYnlcqJWqyyQDBhy/
ShOZjQ0oy9SblZMoVjLYONS0iFDoz2of8/kvY+kuzh+3iU9Qg6BI+lfRSd8KjGBB
xsLOoUhzQceXqmx5SmOGIn6EmwKBgQD56efYqmYj/GGLz/gyfyElsQFUWG0tyNjm
ujufTxjhEDWw3pnS3vUVG/gleGJH7f9vzCfEI4WlBuZUidrwM64cnF4QXQwuhT7p
5U+nKNVfJpMeglehgVl6vSi/L1ovilCNo5A4aQJxyS73KTcU1UAZ4/VZnrvYrV/f
ysxWTrx1cwKBgDAAyKofoVJ69NJf7cqQOdZt6D3ue21JJowXpsrMuyC5WRdk1ZNc
+vvezSw0LEq/CEJQTDpXmMnC6vV017pnVkRMnPOg618mVxXBSZgxCXpwqgktHLX8
bqFlKOCqcZmZPAYZ4h6vlWWae6yPrTXU3dlogInrUlZ/7K+F/njO9VnNAoGBAOvp
QsPDruGfd9GMQ2YfngG/glrFkmKa6y16dZfgCcNDEvvgVeK6Ny5zFZ8Bcf0mjG9T
j+JWCe2LgtggvfzrPBuj/COEQmCTxZzzq2pHYIwOlOhC8Ef0G6yCbbl0ELU54uqh
kR2++uDAokYMsQNIftcx2kR8VCSpHQzbmmKKttpDAoGBAIGVTOJtRi3nvmz1q3Zy
vad1gTrkyy/gtjuE+8KNKhWwnC+MYXsSOykh+x6GQQ1gHRjk6GMsQxwl3xbHvzdG
yp7Fc3aWkJbARSINOcAblH8JWdCMGBY/FlSogl0ptROVFxkyM2DnchM1bSsJ9wvf
xB4hqm1VSknnOCCK+NekIC48
-----END PRIVATE KEY-----
@@ -0,0 +1 @@
v=DKIM1; g=*; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2DBoRKJN+F4lILMzu3LmKYf3cNJZYiNfPsMF9Mm1DcI5JnPPY30TWejhBeQX7sjGAKBwfeg/RISACKl845rxbY2SK2E8s29l/+Appe7sRi4npEhY6wDS9Zsm4N+hSnjAFefbNO/PviK3EE669ROnu6tdu/2EcAhsvimUNEpdgqy/iHT7giuVgCbWE9c0P4dz0P8VHBy51LXpuQToq4O7MHqMXX2VrF7u1nhg2IhTjleaTJnbnhX7p+QiXvDH3RCeGLF6sQsWtsqqzZJZF+EUqYRH8K3lP7L9A7Fo/3mlphQ4WoL3dgMIsSHf5RWBrGNl+xum7P0qk4aAZPRn7URooQIDAQAB
+12 -3
View File
@@ -41,6 +41,7 @@ class TestSignAndVerify(unittest.TestCase):
self.message = read_test_data("test.message") self.message = read_test_data("test.message")
self.key1024 = read_test_data("1024_testkey.key") self.key1024 = read_test_data("1024_testkey.key")
self.key2048 = read_test_data("2048_testkey.key") self.key2048 = read_test_data("2048_testkey.key")
self.key2048PKCS8 = read_test_data("2048_testkey_PKCS8.key")
def dnsfunc(self, domain, timeout=5): def dnsfunc(self, domain, timeout=5):
_dns_responses = { _dns_responses = {
@@ -48,6 +49,7 @@ class TestSignAndVerify(unittest.TestCase):
'test2._domainkey.example.com.': read_test_data("1024_testkey_wo_markers.pub.rsa.txt"), 'test2._domainkey.example.com.': read_test_data("1024_testkey_wo_markers.pub.rsa.txt"),
'test3._domainkey.example.com.': read_test_data("2048_testkey_wo_markers.pub.txt"), 'test3._domainkey.example.com.': read_test_data("2048_testkey_wo_markers.pub.txt"),
'test4._domainkey.example.com.': read_test_data("2048_testkey_wo_markers.pub.rsa.txt"), 'test4._domainkey.example.com.': read_test_data("2048_testkey_wo_markers.pub.rsa.txt"),
'test5._domainkey.example.com.': read_test_data("2048_testkey_PKCS8.key.pub.txt")
} }
try: try:
domain = domain.decode('ascii') domain = domain.decode('ascii')
@@ -56,7 +58,6 @@ class TestSignAndVerify(unittest.TestCase):
self.assertTrue(domain in _dns_responses,domain) self.assertTrue(domain in _dns_responses,domain)
return _dns_responses[domain] return _dns_responses[domain]
def test_verifies_SubjectPublicKeyInfo1024(self): def test_verifies_SubjectPublicKeyInfo1024(self):
# A message verifies after being signed. # A message verifies after being signed.
for header_algo in (b"simple", b"relaxed"): for header_algo in (b"simple", b"relaxed"):
@@ -67,8 +68,6 @@ class TestSignAndVerify(unittest.TestCase):
res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc) res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc)
self.assertTrue(res) self.assertTrue(res)
def test_verifies_RSAPublicKey1024(self): def test_verifies_RSAPublicKey1024(self):
# A message verifies after being signed. # A message verifies after being signed.
for header_algo in (b"simple", b"relaxed"): for header_algo in (b"simple", b"relaxed"):
@@ -102,6 +101,16 @@ class TestSignAndVerify(unittest.TestCase):
self.assertTrue(res) self.assertTrue(res)
def test_verifies_RSAPublicKey2048PKCS8(self):
#A message verifies after being signed (with PKCS8 private key)
for header_algo in (b"simple", b"relaxed"):
for body_algo in (b"simple", b"relaxed"):
sig = dkim.sign(
self.message, b"test5", b"example.com", self.key2048PKCS8,
canonicalize=(header_algo, body_algo))
res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc)
self.assertTrue(res)
def test_suite(): def test_suite():
from unittest import TestLoader from unittest import TestLoader
return TestLoader().loadTestsFromName(__name__) return TestLoader().loadTestsFromName(__name__)