Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow SPKI RSA keys to be parsed even if they have an incorrect delimiter (#10248) #10251

Merged
merged 1 commit into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/development/test-vectors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,18 @@ Custom asymmetric vectors
* ``asymmetric/PEM_Serialization/ec_public_key.pem`` and
``asymmetric/DER_Serialization/ec_public_key.der``- Contains the public key
corresponding to ``ec_private_key.pem``, generated using OpenSSL.
* ``asymmetric/PEM_Serialization/ec_public_key_rsa_delimiter.pem`` - Contains
the public key corresponding to ``ec_private_key.pem``, but with the wrong PEM
delimiter (``RSA PUBLIC KEY`` when it should be ``PUBLIC KEY``).
* ``asymmetric/PEM_Serialization/rsa_private_key.pem`` - Contains an RSA 2048
bit key generated using OpenSSL, protected by the secret "123456" with DES3
encryption.
* ``asymmetric/PEM_Serialization/rsa_public_key.pem`` and
``asymmetric/DER_Serialization/rsa_public_key.der``- Contains an RSA 2048
bit public generated using OpenSSL from ``rsa_private_key.pem``.
* ``asymmetric/PEM_Serialization/rsa_wrong_delimiter_public_key.pem`` - Contains
an RSA 2048 bit public key generated from ``rsa_private_key.pem``, but with
the wrong PEM delimiter (``RSA PUBLIC KEY`` when it should be ``PUBLIC KEY``).
* ``asymmetric/PEM_Serialization/dsa_4096.pem`` - Contains a 4096-bit DSA
private key generated using OpenSSL.
* ``asymmetric/PEM_Serialization/dsaparam.pem`` - Contains 2048-bit DSA
Expand Down
21 changes: 20 additions & 1 deletion src/rust/src/backend/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,26 @@ fn load_pem_public_key(
let _ = backend;
let p = pem::parse(data.as_bytes())?;
let pkey = match p.tag() {
"RSA PUBLIC KEY" => cryptography_key_parsing::rsa::parse_pkcs1_public_key(p.contents())?,
"RSA PUBLIC KEY" => {
// We try to parse it as a PKCS1 first since that's the PEM delimiter, and if
// that fails we try to parse it as an SPKI. This is to match the permissiveness
// of OpenSSL, which doesn't care about the delimiter.
match cryptography_key_parsing::rsa::parse_pkcs1_public_key(p.contents()) {
Ok(pkey) => pkey,
Err(err) => {
let pkey = cryptography_key_parsing::spki::parse_public_key(p.contents())
.map_err(|_| err)?;
if pkey.id() != openssl::pkey::Id::RSA {
return Err(CryptographyError::from(
pyo3::exceptions::PyValueError::new_err(
"Incorrect PEM delimiter for key type.",
),
));
}
pkey
}
}
}
"PUBLIC KEY" => cryptography_key_parsing::spki::parse_public_key(p.contents())?,
_ => return Err(CryptographyError::from(pem::PemError::MalformedFraming)),
};
Expand Down
16 changes: 16 additions & 0 deletions tests/hazmat/primitives/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,11 @@ def test_load_pem_ec_private_key(self, key_path, password, backend):
"asymmetric", "PEM_Serialization", "rsa_public_key.pem"
),
os.path.join("asymmetric", "public", "PKCS1", "rsa.pub.pem"),
os.path.join(
"asymmetric",
"PEM_Serialization",
"rsa_wrong_delimiter_public_key.pem",
),
],
)
def test_load_pem_rsa_public_key(self, key_file, backend):
Expand All @@ -520,6 +525,17 @@ def test_load_pem_rsa_public_key(self, key_file, backend):
numbers = key.public_numbers()
assert numbers.e == 65537

def test_load_pem_public_fails_with_ec_key_with_rsa_delimiter(self):
with pytest.raises(ValueError):
load_vectors_from_file(
os.path.join(
"asymmetric",
"PEM_Serialization",
"ec_public_key_rsa_delimiter.pem",
),
lambda pemfile: load_pem_public_key(pemfile.read().encode()),
)

def test_load_priv_key_with_public_key_api_fails(
self, rsa_key_2048, backend
):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN RSA PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJLzzbuz2tRnLFlOL+6bTX6giVavA
sc6NDFFT0IMCd2ibTTNUDDkFGsgq0cH5JYPg/6xUlMBFKrWYe3yQ4has9w==
-----END RSA PUBLIC KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnR4AZ+tgWYql+S3MaTQ6
zeIO1fKzFIoau9Q0zGuv/1oCAewXwxeDSSxw+/Z3GL1NpuuS9CpbR5EQ3d71bD0v
0G+Sf+mShSl0oljG7YqnNSPzKl+EQ3/KE+eEButcwas6KGof2BA4bFNCw/fPbuhk
u/d8sIIEgdzBMiGRMdW33uci3rsdOenMZQA7uWsM/q/pu85YLAVOxq6wlUCzP4FM
Tw/RKzayrPkn3Jfbqcy1aM2HDlFVx24vaN+RRbPSnVoQbo5EQYkUMXE8WmadSyHl
pXGRnWsJSV9AdGyDrbU+6tcFwcIwnW22jb/OJy8swHdqKGkuR1kQ0XqokK1yGKFZ
8wIDAQAB
-----END RSA PUBLIC KEY-----
Loading