Skip to content

Commit c2d81b6

Browse files
author
Roland Hedberg
committed
Merge pull request #48 from rebeckag/x509_rsakey
Loading certs from X.509 improved
2 parents e598597 + a54ddbf commit c2d81b6

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

src/jwkest/jwk.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,10 @@ def __init__(self, kty="RSA", alg="", use="", kid="", key=None,
340340
self.di = di
341341
self.qi = qi
342342

343-
if not self.key and self.n and self.e:
343+
has_public_key_parts = len(self.n) > 0 and len(self.e)
344+
has_x509_cert_chain = len(self.x5c) > 0
345+
346+
if not self.key and (has_public_key_parts or has_x509_cert_chain):
344347
self.deserialize()
345348
elif self.key and not (self.n and self.e):
346349
self._split()
@@ -373,11 +376,13 @@ def deserialize(self):
373376
except ValueError as err:
374377
raise DeSerializationNotPossible("%s" % err)
375378
elif self.x5c:
379+
der_cert = base64.b64decode(self.x5c[0].encode("ascii"))
380+
376381
if self.x5t: # verify the cert
377-
pass
382+
if not b64d(self.x5t.encode("ascii")) == hashlib.sha1(der_cert).digest():
383+
raise DeSerializationNotPossible("The thumbprint ('x5t') does not match the certificate.")
378384

379-
cert = "\n".join([PREFIX, str(self.x5c[0]), POSTFIX])
380-
self.key = import_rsa_key(cert)
385+
self.key = der2rsa(der_cert)
381386
self._split()
382387
if len(self.x5c) > 1: # verify chain
383388
pass

tests/test_2_jwk.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import six
99
from jwkest.ecc import P256
1010
from jwkest import long2intarr
11-
from jwkest.jwk import jwk_wrap
11+
from jwkest.jwk import jwk_wrap, DeSerializationNotPossible
1212
from jwkest.jwk import import_rsa_key_from_file
1313
from jwkest.jwk import rsa_eq
1414
from jwkest.jwk import keyrep
@@ -169,7 +169,8 @@ def test_import_rsa_key():
169169
djwk = jwk_wrap(_ckey).to_dict()
170170
print(djwk)
171171
assert _eq(djwk.keys(), ["kty", "e", "n", "p", "q", "d"])
172-
assert djwk["n"] == '5zbNbHIYIkGGJ3RGdRKkYmF4gOorv5eDuUKTVtuu3VvxrpOWvwnFV-NY0LgqkQSMMyVzodJE3SUuwQTUHPXXY5784vnkFqzPRx6bHgPxKz7XfwQjEBTafQTMmOeYI8wFIOIHY5i0RWR-gxDbh_D5TXuUqScOOqR47vSpIbUH-nc'
172+
assert djwk[
173+
"n"] == '5zbNbHIYIkGGJ3RGdRKkYmF4gOorv5eDuUKTVtuu3VvxrpOWvwnFV-NY0LgqkQSMMyVzodJE3SUuwQTUHPXXY5784vnkFqzPRx6bHgPxKz7XfwQjEBTafQTMmOeYI8wFIOIHY5i0RWR-gxDbh_D5TXuUqScOOqR47vSpIbUH-nc'
173174
assert djwk['e'] == 'AQAB'
174175

175176

@@ -310,5 +311,50 @@ def test_private_key_from_jwk():
310311
assert _eq(list(_d.keys()), kspec.keys())
311312

312313

314+
def test_rsa_pubkey_from_x509_cert_chain():
315+
cert = "MIID0jCCArqgAwIBAgIBSTANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCREUxEDAOBgNVBAgTB0JhdmF" \
316+
"yaWExEzARBgNVBAoTCkJpb0lEIEdtYkgxLzAtBgNVBAMTJkJpb0lEIENsaWVudCBDZXJ0aWZpY2F0aW9uIE" \
317+
"F1dGhvcml0eSAyMSEwHwYJKoZIhvcNAQkBFhJzZWN1cml0eUBiaW9pZC5jb20wHhcNMTUwNDE1MTQ1NjM4W" \
318+
"hcNMTYwNDE0MTQ1NjM4WjBfMQswCQYDVQQGEwJERTETMBEGA1UEChMKQmlvSUQgR21iSDE7MDkGA1UEAxMy" \
319+
"QmlvSUQgT3BlbklEIENvbm5lY3QgSWRlbnRpdHkgUHJvdmlkZXIgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb" \
320+
"3DQEBAQUAA4IBDwAwggEKAoIBAQC9aFETmU6kDfMBPKM2OfI5eedO3XP12Ci0hDC99bdzUUIhDZG34PQqcH" \
321+
"89gVWGthJv5w3kqpdSrxfPCFMsBdnyk1VCuXmLgXS8s4oBtt1c9iM0J8X6Z+5subS3Xje8fu55Csh0JXNfo" \
322+
"y29rCY/O6y0fNignegg0KS4PHv5T+agFmaG4rxCQV9/kd8tlo/HTyVPsuSPDgsXxisIVqur9aujYwdCoAZU" \
323+
"8OU+5ccMLNIhpWJn+xNjgDRr4L9nxAYKc9vy+f7EoH3LT24B71zazZsQ78vpocz98UT/7vdgS/IYXFniPuU" \
324+
"fblja7cq31bUoySDx6FYrtfCSUxNhaZSX8mppAgMBAAGjbzBtMAkGA1UdEwQCMAAwHQYDVR0OBBYEFOfg3f" \
325+
"/ewBLK5SkcBEXusD62OlzaMB8GA1UdIwQYMBaAFCQmdD+nVcVLaKt3vu73XyNgpPEpMAsGA1UdDwQEAwIDi" \
326+
"DATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQQFAAOCAQEAKQjhcL/iGhy0549hEHRQArJXs1im" \
327+
"7W244yE+TSChdMWKe2eWvEhc9wX1aVV2mNJM1ZNeYSgfoK6jjuXaHiSaIJEUcW1wVM3rDywi2a9GKzOFgrW" \
328+
"pVbpXQ05LSE7qEEWRmSpIMyKTitUalNpNA6cOML5hiuUTfZbw7OvPwbnbSYYL674gEA2sW5AhPiCr9dVnMn" \
329+
"/UK2II40802zdXUOvIxWeXpcsCxxZMjp/Ir2jIZWOEjlAXQVGr2oBfL/be/o5WXpaqWSfPRBZV8htRIf0vT" \
330+
"lGx7xR8FPWDYmcj4o/tKoNC1AchjOnCwwE/mj4hgtoAsHNmYXF0oZXk7cozqYDqKQ=="
331+
rsa_key = RSAKey(x5c=[cert])
332+
assert rsa_key.key
333+
334+
335+
def test_rsa_pubkey_verify_x509_thumbprint():
336+
cert = "MIID0jCCArqgAwIBAgIBSTANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCREUxEDAOBgNVBAgTB0JhdmF" \
337+
"yaWExEzARBgNVBAoTCkJpb0lEIEdtYkgxLzAtBgNVBAMTJkJpb0lEIENsaWVudCBDZXJ0aWZpY2F0aW9uIE" \
338+
"F1dGhvcml0eSAyMSEwHwYJKoZIhvcNAQkBFhJzZWN1cml0eUBiaW9pZC5jb20wHhcNMTUwNDE1MTQ1NjM4W" \
339+
"hcNMTYwNDE0MTQ1NjM4WjBfMQswCQYDVQQGEwJERTETMBEGA1UEChMKQmlvSUQgR21iSDE7MDkGA1UEAxMy" \
340+
"QmlvSUQgT3BlbklEIENvbm5lY3QgSWRlbnRpdHkgUHJvdmlkZXIgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb" \
341+
"3DQEBAQUAA4IBDwAwggEKAoIBAQC9aFETmU6kDfMBPKM2OfI5eedO3XP12Ci0hDC99bdzUUIhDZG34PQqcH" \
342+
"89gVWGthJv5w3kqpdSrxfPCFMsBdnyk1VCuXmLgXS8s4oBtt1c9iM0J8X6Z+5subS3Xje8fu55Csh0JXNfo" \
343+
"y29rCY/O6y0fNignegg0KS4PHv5T+agFmaG4rxCQV9/kd8tlo/HTyVPsuSPDgsXxisIVqur9aujYwdCoAZU" \
344+
"8OU+5ccMLNIhpWJn+xNjgDRr4L9nxAYKc9vy+f7EoH3LT24B71zazZsQ78vpocz98UT/7vdgS/IYXFniPuU" \
345+
"fblja7cq31bUoySDx6FYrtfCSUxNhaZSX8mppAgMBAAGjbzBtMAkGA1UdEwQCMAAwHQYDVR0OBBYEFOfg3f" \
346+
"/ewBLK5SkcBEXusD62OlzaMB8GA1UdIwQYMBaAFCQmdD+nVcVLaKt3vu73XyNgpPEpMAsGA1UdDwQEAwIDi" \
347+
"DATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQQFAAOCAQEAKQjhcL/iGhy0549hEHRQArJXs1im" \
348+
"7W244yE+TSChdMWKe2eWvEhc9wX1aVV2mNJM1ZNeYSgfoK6jjuXaHiSaIJEUcW1wVM3rDywi2a9GKzOFgrW" \
349+
"pVbpXQ05LSE7qEEWRmSpIMyKTitUalNpNA6cOML5hiuUTfZbw7OvPwbnbSYYL674gEA2sW5AhPiCr9dVnMn" \
350+
"/UK2II40802zdXUOvIxWeXpcsCxxZMjp/Ir2jIZWOEjlAXQVGr2oBfL/be/o5WXpaqWSfPRBZV8htRIf0vT" \
351+
"lGx7xR8FPWDYmcj4o/tKoNC1AchjOnCwwE/mj4hgtoAsHNmYXF0oZXk7cozqYDqKQ=="
352+
rsa_key = RSAKey(x5c=[cert], x5t="KvHXVspLmjWC6cPDIIVMHlJjN-c")
353+
assert rsa_key.key
354+
355+
with pytest.raises(DeSerializationNotPossible):
356+
RSAKey(x5c=[cert], x5t="abcdefgh") # incorrect thumbprint
357+
358+
313359
if __name__ == "__main__":
314360
test_private_key_from_jwk()

0 commit comments

Comments
 (0)