Skip to content

Commit

Permalink
Add support for P384 public key algorithm (awslabs#251)
Browse files Browse the repository at this point in the history
* Add support for P384 public key algorithm

I found that I could not use root certificates which use a P384 public
key algorithm. More specifically, passing in a certificate with

```
$ openssl x509 -noout -text -in root.der
…
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    …
                ASN1 OID: secp384r1
                NIST CURVE: P-384
…
```

gives me

```
EcX509Error(UnsupportedPublicKeyAlgorithm("ObjectIdentifier(1.2.840.10045.2.1)"))
```

back. The changes here seem to fix this, but I’ll admit that they were
made very mechanically based on the existing code.

This would be a continuation of the work in awslabs#190.

* Add P384 certificate test

The test certificate was generated using certificatetools.com, which I
believe is where the others were generated as well.
  • Loading branch information
mgeisler authored Feb 4, 2025
1 parent f7a8f87 commit 7087fc8
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 3 deletions.
2 changes: 1 addition & 1 deletion mls-rs-crypto-rustcrypto/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mls-rs-crypto-rustcrypto"
version = "0.13.0"
version = "0.13.1"
edition = "2021"
description = "RustCrypto based CryptoProvider for mls-rs"
homepage = "https://github.com/awslabs/mls-rs"
Expand Down
2 changes: 2 additions & 0 deletions mls-rs-crypto-rustcrypto/src/ec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ pub enum EcPrivateKey {
pub enum EcError {
#[cfg_attr(feature = "std", error("p256 error: {0:?}"))]
P256Error(p256::elliptic_curve::Error),
#[cfg_attr(feature = "std", error("p384 error: {0:?}"))]
P384Error(p384::elliptic_curve::Error),
#[cfg_attr(feature = "std", error("unsupported curve type"))]
UnsupportedCurve,
#[cfg_attr(feature = "std", error("invalid public key data"))]
Expand Down
8 changes: 7 additions & 1 deletion mls-rs-crypto-rustcrypto/src/ec_for_x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::{
pub const X25519_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.101.110");
pub const ED25519_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.101.112");
pub const P256_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
pub const P384_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.132.0.34");

#[derive(Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
Expand Down Expand Up @@ -68,6 +69,8 @@ pub fn curve_from_algorithm(algorithm: &AlgorithmIdentifier<Any>) -> Result<Curv
Ok(Curve::X25519)
} else if borrowed.parameters_oid() == Ok(P256_OID) {
Ok(Curve::P256)
} else if borrowed.parameters_oid() == Ok(P384_OID) {
Ok(Curve::P384)
} else {
Err(EcX509Error::UnsupportedPublicKeyAlgorithm(format!(
"{:?}",
Expand All @@ -82,7 +85,7 @@ pub fn signer_from_algorithm(
let curve = curve_from_algorithm(algorithm)?;

match curve {
Curve::Ed25519 | Curve::P256 => Ok(EcSigner::new_from_curve(curve)),
Curve::Ed25519 | Curve::P256 | Curve::P384 => Ok(EcSigner::new_from_curve(curve)),
_ => Err(EcX509Error::UnsupportedPublicKeyAlgorithm(format!(
"{:?}",
algorithm.oid
Expand Down Expand Up @@ -120,6 +123,9 @@ pub fn pub_key_from_spki(
Curve::P256 => p256::PublicKey::from_sec1_bytes(spki.subject_public_key.raw_bytes())
.map_err(|e| EcX509Error::from(EcError::P256Error(e)))
.map(EcPublicKey::P256),
Curve::P384 => p384::PublicKey::from_sec1_bytes(spki.subject_public_key.raw_bytes())
.map_err(|e| EcX509Error::from(EcError::P384Error(e)))
.map(EcPublicKey::P384),
_ => Err(EcError::UnsupportedCurve.into()),
}
}
Expand Down
4 changes: 4 additions & 0 deletions mls-rs-crypto-rustcrypto/src/x509/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ pub(crate) mod test_utils {
DerCertificate::from(include_bytes!("../../test_data/x509/ca.der").to_vec())
}

pub fn load_test_p384_ca() -> DerCertificate {
DerCertificate::from(include_bytes!("../../test_data/x509/p384_ca.der").to_vec())
}

pub fn load_test_cert_chain() -> CertificateChain {
let entry0 = include_bytes!("../../test_data/x509/leaf.der").to_vec();
let entry1 = include_bytes!("../../test_data/x509/intermediate.der").to_vec();
Expand Down
12 changes: 11 additions & 1 deletion mls-rs-crypto-rustcrypto/src/x509/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ mod tests {
x509::{
util::test_utils::{
load_another_ca, load_test_ca, load_test_cert_chain, load_test_invalid_ca_chain,
load_test_invalid_chain,
load_test_invalid_chain, load_test_p384_ca,
},
X509Error,
},
Expand Down Expand Up @@ -280,6 +280,16 @@ mod tests {
X509CredentialValidator::validate_chain(&validator, &chain, Some(MlsTime::now())).unwrap();
}

#[test]
fn can_validate_p384_cert() {
let mut validator = X509Validator::new(vec![]).unwrap();
validator.allow_self_signed(true);

let chain = vec![load_test_p384_ca()].into();

X509CredentialValidator::validate_chain(&validator, &chain, Some(MlsTime::now())).unwrap();
}

#[test]
fn fails_on_too_long_self_signed() {
let mut validator = X509Validator::new(vec![]).unwrap();
Expand Down
Binary file added mls-rs-crypto-rustcrypto/test_data/x509/p384_ca.der
Binary file not shown.
Binary file not shown.
15 changes: 15 additions & 0 deletions mls-rs-crypto-rustcrypto/test_data/x509/root_ca_p384/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICQjCCAcmgAwIBAgIUT4DMt5h05A+ykGMRVbfdrUHl7AswCgYIKoZIzj0EAwMw
TzEeMBwGA1UEAwwVUDM4NCBSb290IENlcnRpZmljYXRlMQswCQYDVQQGEwJDSDEP
MA0GA1UECAwGWnVyaWNoMQ8wDQYDVQQHDAZadXJpY2gwHhcNMjUwMjAzMTMwODM4
WhcNMjkwMjAyMTMwODM4WjBPMR4wHAYDVQQDDBVQMzg0IFJvb3QgQ2VydGlmaWNh
dGUxCzAJBgNVBAYTAkNIMQ8wDQYDVQQIDAZadXJpY2gxDzANBgNVBAcMBlp1cmlj
aDB2MBAGByqGSM49AgEGBSuBBAAiA2IABG+BvLAs4Au1tGJv264lwur+hg8aWChz
FZjNFsb5cOWaW6Jz9U8Ol1WCmePEhQq58L1HIEM+J0LTMyUSUScF09eLtRHHyBGw
1waFRbTtkKTGcRlXhs+6L3uVrPTAxgF0CqNmMGQwHQYDVR0OBBYEFFLcd/9H9lJs
sRQjLtdgBwD7kCpIMB8GA1UdIwQYMBaAFFLcd/9H9lJssRQjLtdgBwD7kCpIMA4G
A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMAoGCCqGSM49BAMDA2cA
MGQCMDE6A9SpFq96xvo/IKLG2VWyRwS+7zTzkyyL/Rcb8NLG9sz6hAISMYdYXFJF
bF90DQIweOBNWH8754M9bBB7VQAB3gp5T2HTMGaKz8xRxYasyVSDffpP+sgBcWrP
A0qSCQ6T
-----END CERTIFICATE-----
11 changes: 11 additions & 0 deletions mls-rs-crypto-rustcrypto/test_data/x509/root_ca_p384/csr.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBfTCCAQMCAQAwTzEeMBwGA1UEAwwVUDM4NCBSb290IENlcnRpZmljYXRlMQsw
CQYDVQQGEwJDSDEPMA0GA1UECAwGWnVyaWNoMQ8wDQYDVQQHDAZadXJpY2gwdjAQ
BgcqhkjOPQIBBgUrgQQAIgNiAARvgbywLOALtbRib9uuJcLq/oYPGlgocxWYzRbG
+XDlmluic/VPDpdVgpnjxIUKufC9RyBDPidC0zMlElEnBdPXi7URx8gRsNcGhUW0
7ZCkxnEZV4bPui97laz0wMYBdAqgNTAzBgkqhkiG9w0BCQ4xJjAkMA4GA1UdDwEB
/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMAoGCCqGSM49BAMDA2gAMGUCMQCg
dRLyj0qX3jkt0m10833Wf/6wcqBgnURYQkw8ZJFtyswnYhPC9/Vs+LcIiuvrTIMC
MBEWvCnOjtJ+83fqSsmJqydc4bvuj+APHIL7XFY/lRtGsy5tJKZRI8LfMmzjkCTv
Ew==
-----END CERTIFICATE REQUEST-----
6 changes: 6 additions & 0 deletions mls-rs-crypto-rustcrypto/test_data/x509/root_ca_p384/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-----BEGIN PRIVATE KEY-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC1NU0+NlWxfTuZ7WmT
mGxfyCI5e6/LCTjyWP9nTYNK8WzTLQ9b+6K/IZf0FRog+1+hZANiAARvgbywLOAL
tbRib9uuJcLq/oYPGlgocxWYzRbG+XDlmluic/VPDpdVgpnjxIUKufC9RyBDPidC
0zMlElEnBdPXi7URx8gRsNcGhUW07ZCkxnEZV4bPui97laz0wMYBdAo=
-----END PRIVATE KEY-----

0 comments on commit 7087fc8

Please sign in to comment.