From bfff3c10f7ef583cd8c3d6d1564bb7c99ea353a0 Mon Sep 17 00:00:00 2001 From: Hsiaoming Yang Date: Mon, 20 Jan 2025 23:23:06 +0900 Subject: [PATCH] feat: support import key from a certificate pem file --- src/joserfc/rfc7517/pem.py | 5 +++++ tests/jwk/test_rsa_key.py | 6 ++++++ tests/keys/firebase-cert.pem | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tests/keys/firebase-cert.pem diff --git a/src/joserfc/rfc7517/pem.py b/src/joserfc/rfc7517/pem.py index 778a2f2..9e014a5 100644 --- a/src/joserfc/rfc7517/pem.py +++ b/src/joserfc/rfc7517/pem.py @@ -1,6 +1,7 @@ from __future__ import annotations from typing import Any, Literal, cast from abc import ABCMeta, abstractmethod +from cryptography.x509 import load_pem_x509_certificate from cryptography.hazmat.primitives.serialization import ( load_pem_private_key, load_pem_public_key, @@ -38,6 +39,10 @@ def load_pem_key( elif b"PRIVATE" in raw: key = load_pem_private_key(raw, password=password, backend=default_backend()) + elif b"CERTIFICATE" in raw: + cert = load_pem_x509_certificate(raw, backend=default_backend()) + return cert.public_key() + else: try: key = load_der_private_key(raw, password=password, backend=default_backend()) diff --git a/tests/jwk/test_rsa_key.py b/tests/jwk/test_rsa_key.py index 9cf6cae..04516a6 100644 --- a/tests/jwk/test_rsa_key.py +++ b/tests/jwk/test_rsa_key.py @@ -133,6 +133,12 @@ def test_import_from_der_bytes(self): key1 = RSAKey.import_key(value1) self.assertEqual(value1, key1.as_der()) + def test_import_from_certificate(self): + firebase_cert = read_key("firebase-cert.pem") + key: RSAKey = RSAKey.import_key(firebase_cert) + data = key.as_dict() + self.assertEqual(data['kty'], 'RSA') + def test_output_with_password(self): private_pem = read_key("rsa-openssl-private.pem") key: RSAKey = RSAKey.import_key(private_pem) diff --git a/tests/keys/firebase-cert.pem b/tests/keys/firebase-cert.pem new file mode 100644 index 0000000..cc64c14 --- /dev/null +++ b/tests/keys/firebase-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHTCCAgWgAwIBAgIJANuivDoSiT/NMA0GCSqGSIb3DQEBBQUAMDExLzAtBgNV +BAMMJnNlY3VyZXRva2VuLnN5c3RlbS5nc2VydmljZWFjY291bnQuY29tMB4XDTI0 +MTIxMDA3MzI0OVoXDTI0MTIyNjE5NDc0OVowMTEvMC0GA1UEAwwmc2VjdXJldG9r +ZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDhywhKx2L+GZJLjmGcOVMCc+x09hrYpCVk3K/LxgJtZZ34 +vHeFUjGexazZiSc9LHd03fNmATFcdtqpVW4Qz+xsP5mQXEqbwPQu2qWZhb5VY8Z6 +Oh02uFFxRCdegupuzggdqEhc/QlkrKb2Y/undxcIyRcXKWcDaEn+5dqQA2NhjMp5 +ir1YsKRanZIJ69wR65Ok8e0YlHHGsP+7uJaW0b1yr0RyilyluEsb7DmpMV/7j7pr +cnNnOnL7jhpLW2gjbVzjB1FR5ScNy5gKp72htFkxdGxS58/AQoT06kBu80OI2VMb +mijU6JD4b3tIYtHZp9FOiCNhiQS1e/GTDyGT1ZT1AgMBAAGjODA2MAwGA1UdEwEB +/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMCMA0G +CSqGSIb3DQEBBQUAA4IBAQDOf4MfPzEesqqm50J0gVW1geCiukD6MrH1nPGuUhm8 +FUYy/4W6Rx69XnKKRxb1rEQwrqmi8WNiELRrpXugY5ieowuRwlcrPk450bB1IwK5 +Jxcqgf4fxwbvqeoADzl0Z0+JxoiYDpH2FMG1HRpdl/YCzB7W0ftv3q1uUqTDLQ+r +K6Cm1rHyznsOio9oJknkQ8mPbvE7qSRdCYir806gGurzyhO1RacbR97B8M/vujyc +sNxCxxSphHCgCBW1mz4XqgOF4Sd/XYPrO8/2qhoSjqaqta+gmg644afx82NqsW+Z +NJrR9cZxaLNEfwzv+fX9s70xT1nSa9U4avINE58o3Dsk +-----END CERTIFICATE-----