Skip to content

Commit 56255de

Browse files
authored
allow SPKI RSA keys to be parsed even if they have an incorrect delimiter (#10248) (#10251)
* allow SPKI RSA keys to be parsed even if they have an incorrect delimiter This allows RSA SPKI keys (typically delimited with PUBLIC KEY) to be parsed even if they are using the RSA PUBLIC KEY delimiter. * formatting * use original error if nothing parses, don't let it parse non-RSA
1 parent 12f038b commit 56255de

File tree

5 files changed

+55
-1
lines changed

5 files changed

+55
-1
lines changed

docs/development/test-vectors.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,18 @@ Custom asymmetric vectors
7272
* ``asymmetric/PEM_Serialization/ec_public_key.pem`` and
7373
``asymmetric/DER_Serialization/ec_public_key.der``- Contains the public key
7474
corresponding to ``ec_private_key.pem``, generated using OpenSSL.
75+
* ``asymmetric/PEM_Serialization/ec_public_key_rsa_delimiter.pem`` - Contains
76+
the public key corresponding to ``ec_private_key.pem``, but with the wrong PEM
77+
delimiter (``RSA PUBLIC KEY`` when it should be ``PUBLIC KEY``).
7578
* ``asymmetric/PEM_Serialization/rsa_private_key.pem`` - Contains an RSA 2048
7679
bit key generated using OpenSSL, protected by the secret "123456" with DES3
7780
encryption.
7881
* ``asymmetric/PEM_Serialization/rsa_public_key.pem`` and
7982
``asymmetric/DER_Serialization/rsa_public_key.der``- Contains an RSA 2048
8083
bit public generated using OpenSSL from ``rsa_private_key.pem``.
84+
* ``asymmetric/PEM_Serialization/rsa_wrong_delimiter_public_key.pem`` - Contains
85+
an RSA 2048 bit public key generated from ``rsa_private_key.pem``, but with
86+
the wrong PEM delimiter (``RSA PUBLIC KEY`` when it should be ``PUBLIC KEY``).
8187
* ``asymmetric/PEM_Serialization/dsa_4096.pem`` - Contains a 4096-bit DSA
8288
private key generated using OpenSSL.
8389
* ``asymmetric/PEM_Serialization/dsaparam.pem`` - Contains 2048-bit DSA

src/rust/src/backend/keys.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,26 @@ fn load_pem_public_key(
165165
let _ = backend;
166166
let p = pem::parse(data.as_bytes())?;
167167
let pkey = match p.tag() {
168-
"RSA PUBLIC KEY" => cryptography_key_parsing::rsa::parse_pkcs1_public_key(p.contents())?,
168+
"RSA PUBLIC KEY" => {
169+
// We try to parse it as a PKCS1 first since that's the PEM delimiter, and if
170+
// that fails we try to parse it as an SPKI. This is to match the permissiveness
171+
// of OpenSSL, which doesn't care about the delimiter.
172+
match cryptography_key_parsing::rsa::parse_pkcs1_public_key(p.contents()) {
173+
Ok(pkey) => pkey,
174+
Err(err) => {
175+
let pkey = cryptography_key_parsing::spki::parse_public_key(p.contents())
176+
.map_err(|_| err)?;
177+
if pkey.id() != openssl::pkey::Id::RSA {
178+
return Err(CryptographyError::from(
179+
pyo3::exceptions::PyValueError::new_err(
180+
"Incorrect PEM delimiter for key type.",
181+
),
182+
));
183+
}
184+
pkey
185+
}
186+
}
187+
}
169188
"PUBLIC KEY" => cryptography_key_parsing::spki::parse_public_key(p.contents())?,
170189
_ => return Err(CryptographyError::from(pem::PemError::MalformedFraming)),
171190
};

tests/hazmat/primitives/test_serialization.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,11 @@ def test_load_pem_ec_private_key(self, key_path, password, backend):
506506
"asymmetric", "PEM_Serialization", "rsa_public_key.pem"
507507
),
508508
os.path.join("asymmetric", "public", "PKCS1", "rsa.pub.pem"),
509+
os.path.join(
510+
"asymmetric",
511+
"PEM_Serialization",
512+
"rsa_wrong_delimiter_public_key.pem",
513+
),
509514
],
510515
)
511516
def test_load_pem_rsa_public_key(self, key_file, backend):
@@ -520,6 +525,17 @@ def test_load_pem_rsa_public_key(self, key_file, backend):
520525
numbers = key.public_numbers()
521526
assert numbers.e == 65537
522527

528+
def test_load_pem_public_fails_with_ec_key_with_rsa_delimiter(self):
529+
with pytest.raises(ValueError):
530+
load_vectors_from_file(
531+
os.path.join(
532+
"asymmetric",
533+
"PEM_Serialization",
534+
"ec_public_key_rsa_delimiter.pem",
535+
),
536+
lambda pemfile: load_pem_public_key(pemfile.read().encode()),
537+
)
538+
523539
def test_load_priv_key_with_public_key_api_fails(
524540
self, rsa_key_2048, backend
525541
):
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-----BEGIN RSA PUBLIC KEY-----
2+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJLzzbuz2tRnLFlOL+6bTX6giVavA
3+
sc6NDFFT0IMCd2ibTTNUDDkFGsgq0cH5JYPg/6xUlMBFKrWYe3yQ4has9w==
4+
-----END RSA PUBLIC KEY-----
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN RSA PUBLIC KEY-----
2+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnR4AZ+tgWYql+S3MaTQ6
3+
zeIO1fKzFIoau9Q0zGuv/1oCAewXwxeDSSxw+/Z3GL1NpuuS9CpbR5EQ3d71bD0v
4+
0G+Sf+mShSl0oljG7YqnNSPzKl+EQ3/KE+eEButcwas6KGof2BA4bFNCw/fPbuhk
5+
u/d8sIIEgdzBMiGRMdW33uci3rsdOenMZQA7uWsM/q/pu85YLAVOxq6wlUCzP4FM
6+
Tw/RKzayrPkn3Jfbqcy1aM2HDlFVx24vaN+RRbPSnVoQbo5EQYkUMXE8WmadSyHl
7+
pXGRnWsJSV9AdGyDrbU+6tcFwcIwnW22jb/OJy8swHdqKGkuR1kQ0XqokK1yGKFZ
8+
8wIDAQAB
9+
-----END RSA PUBLIC KEY-----

0 commit comments

Comments
 (0)