Skip to content

Commit

Permalink
x509/policy: add WebPKI permitted algorithms (#9548)
Browse files Browse the repository at this point in the history
* cargo scaffolding

Signed-off-by: William Woodruff <[email protected]>

* mod: isolate failures to just RSA encodings for now

Signed-off-by: William Woodruff <[email protected]>

* policy: isolate some more

Signed-off-by: William Woodruff <[email protected]>

* policy: begin fixing things

Signed-off-by: William Woodruff <[email protected]>

* policy: fix RSASSA-PSS trailer field

* policy: make WEBPKI_PERMITTED_ALGORITHMS public

* policy: add comment with link to CA/B Forum's doc

* remove as-yet unneeded dep

Signed-off-by: William Woodruff <[email protected]>

* mod: break out each webpki algo into its own constant

Signed-off-by: William Woodruff <[email protected]>

---------

Signed-off-by: William Woodruff <[email protected]>
Co-authored-by: Facundo Tuesca <[email protected]>
  • Loading branch information
woodruffw and facutuesca authored Sep 9, 2023
1 parent ec38482 commit 69df0bd
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/rust/cryptography-x509-validation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ rust-version = "1.63.0"
[dependencies]
asn1 = { version = "0.15.5", default-features = false }
cryptography-x509 = { path = "../cryptography-x509" }
once_cell = "1"
1 change: 1 addition & 0 deletions src/rust/cryptography-x509-validation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
#![forbid(unsafe_code)]

pub mod ops;
pub mod policy;
pub mod types;
184 changes: 184 additions & 0 deletions src/rust/cryptography-x509-validation/src/policy/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// This file is dual licensed under the terms of the Apache License, Version
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use std::collections::HashSet;

use once_cell::sync::Lazy;

use cryptography_x509::common::{
AlgorithmIdentifier, AlgorithmParameters, RsaPssParameters, PSS_SHA256_HASH_ALG,
PSS_SHA256_MASK_GEN_ALG, PSS_SHA384_HASH_ALG, PSS_SHA384_MASK_GEN_ALG, PSS_SHA512_HASH_ALG,
PSS_SHA512_MASK_GEN_ALG,
};

// RSASSA‐PKCS1‐v1_5 with SHA‐256
static RSASSA_PKCS1V15_SHA256: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::RsaWithSha256(Some(())),
};

// RSASSA‐PKCS1‐v1_5 with SHA‐384
static RSASSA_PKCS1V15_SHA384: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::RsaWithSha384(Some(())),
};

// RSASSA‐PKCS1‐v1_5 with SHA‐512
static RSASSA_PKCS1V15_SHA512: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::RsaWithSha512(Some(())),
};

// RSASSA‐PSS with SHA‐256, MGF‐1 with SHA‐256, and a salt length of 32 bytes
static RSASSA_PSS_SHA256: Lazy<AlgorithmIdentifier<'_>> = Lazy::new(|| AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::RsaPss(Some(Box::new(RsaPssParameters {
hash_algorithm: PSS_SHA256_HASH_ALG,
mask_gen_algorithm: PSS_SHA256_MASK_GEN_ALG,
salt_length: 32,
_trailer_field: 1,
}))),
});

// RSASSA‐PSS with SHA‐384, MGF‐1 with SHA‐384, and a salt length of 48 bytes
static RSASSA_PSS_SHA384: Lazy<AlgorithmIdentifier<'_>> = Lazy::new(|| AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::RsaPss(Some(Box::new(RsaPssParameters {
hash_algorithm: PSS_SHA384_HASH_ALG,
mask_gen_algorithm: PSS_SHA384_MASK_GEN_ALG,
salt_length: 48,
_trailer_field: 1,
}))),
});

// RSASSA‐PSS with SHA‐512, MGF‐1 with SHA‐512, and a salt length of 64 bytes
static RSASSA_PSS_SHA512: Lazy<AlgorithmIdentifier<'_>> = Lazy::new(|| AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::RsaPss(Some(Box::new(RsaPssParameters {
hash_algorithm: PSS_SHA512_HASH_ALG,
mask_gen_algorithm: PSS_SHA512_MASK_GEN_ALG,
salt_length: 64,
_trailer_field: 1,
}))),
});

// For P-256: the signature MUST use ECDSA with SHA‐256
static ECDSA_SHA256: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::EcDsaWithSha256(None),
};

// For P-384: the signature MUST use ECDSA with SHA‐384
static ECDSA_SHA384: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::EcDsaWithSha384(None),
};

// For P-521: the signature MUST use ECDSA with SHA‐512
static ECDSA_SHA512: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::EcDsaWithSha512(None),
};

/// Permitted algorithms, from CA/B Forum's Baseline Requirements, section 7.1.3.2 (pages 96-98)
/// https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-v2.0.0.pdf
pub static WEBPKI_PERMITTED_ALGORITHMS: Lazy<HashSet<&AlgorithmIdentifier<'_>>> = Lazy::new(|| {
HashSet::from([
&RSASSA_PKCS1V15_SHA256,
&RSASSA_PKCS1V15_SHA384,
&RSASSA_PKCS1V15_SHA512,
&RSASSA_PSS_SHA256,
&RSASSA_PSS_SHA384,
&RSASSA_PSS_SHA512,
&ECDSA_SHA256,
&ECDSA_SHA384,
&ECDSA_SHA512,
])
});

#[cfg(test)]
mod tests {
use std::ops::Deref;

use super::{
ECDSA_SHA256, ECDSA_SHA384, ECDSA_SHA512, RSASSA_PKCS1V15_SHA256, RSASSA_PKCS1V15_SHA384,
RSASSA_PKCS1V15_SHA512, RSASSA_PSS_SHA256, RSASSA_PSS_SHA384, RSASSA_PSS_SHA512,
WEBPKI_PERMITTED_ALGORITHMS,
};

#[test]
fn test_webpki_permitted_algorithms_canonical_encodings() {
{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&RSASSA_PKCS1V15_SHA256));
let exp_encoding = b"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00";
assert_eq!(
asn1::write_single(&RSASSA_PKCS1V15_SHA256).unwrap(),
exp_encoding
);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&RSASSA_PKCS1V15_SHA384));
let exp_encoding = b"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0c\x05\x00";
assert_eq!(
asn1::write_single(&RSASSA_PKCS1V15_SHA384).unwrap(),
exp_encoding
);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&RSASSA_PKCS1V15_SHA512));
let exp_encoding = b"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\r\x05\x00";
assert_eq!(
asn1::write_single(&RSASSA_PKCS1V15_SHA512).unwrap(),
exp_encoding
);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&RSASSA_PSS_SHA256.deref()));
let exp_encoding = b"0A\x06\t*\x86H\x86\xf7\r\x01\x01\n04\xa0\x0f0\r\x06\t`\x86H\x01e\x03\x04\x02\x01\x05\x00\xa1\x1c0\x1a\x06\t*\x86H\x86\xf7\r\x01\x01\x080\r\x06\t`\x86H\x01e\x03\x04\x02\x01\x05\x00\xa2\x03\x02\x01 ";
assert_eq!(
asn1::write_single(&RSASSA_PSS_SHA256.deref()).unwrap(),
exp_encoding
);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&RSASSA_PSS_SHA384.deref()));
let exp_encoding = b"0A\x06\t*\x86H\x86\xf7\r\x01\x01\n04\xa0\x0f0\r\x06\t`\x86H\x01e\x03\x04\x02\x02\x05\x00\xa1\x1c0\x1a\x06\t*\x86H\x86\xf7\r\x01\x01\x080\r\x06\t`\x86H\x01e\x03\x04\x02\x02\x05\x00\xa2\x03\x02\x010";
assert_eq!(
asn1::write_single(&RSASSA_PSS_SHA384.deref()).unwrap(),
exp_encoding
);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&RSASSA_PSS_SHA512.deref()));
let exp_encoding = b"0A\x06\t*\x86H\x86\xf7\r\x01\x01\n04\xa0\x0f0\r\x06\t`\x86H\x01e\x03\x04\x02\x03\x05\x00\xa1\x1c0\x1a\x06\t*\x86H\x86\xf7\r\x01\x01\x080\r\x06\t`\x86H\x01e\x03\x04\x02\x03\x05\x00\xa2\x03\x02\x01@";
assert_eq!(
asn1::write_single(&RSASSA_PSS_SHA512.deref()).unwrap(),
exp_encoding
);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&ECDSA_SHA256));
let exp_encoding = b"0\n\x06\x08*\x86H\xce=\x04\x03\x02";
assert_eq!(asn1::write_single(&ECDSA_SHA256).unwrap(), exp_encoding);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&ECDSA_SHA384));
let exp_encoding = b"0\n\x06\x08*\x86H\xce=\x04\x03\x03";
assert_eq!(asn1::write_single(&ECDSA_SHA384).unwrap(), exp_encoding);
}

{
assert!(WEBPKI_PERMITTED_ALGORITHMS.contains(&ECDSA_SHA512));
let exp_encoding = b"0\n\x06\x08*\x86H\xce=\x04\x03\x04";
assert_eq!(asn1::write_single(&ECDSA_SHA512).unwrap(), exp_encoding);
}
}
}

0 comments on commit 69df0bd

Please sign in to comment.