From 58489462e06d8978022b6f0183ae836b63cec168 Mon Sep 17 00:00:00 2001 From: Zhang Jingqiang Date: Fri, 13 Oct 2023 14:44:09 +0800 Subject: [PATCH] g3-tls-cert: update keyUsage for tls end-entity cert --- doc/standards.md | 2 + g3fcgen/src/backend/mod.rs | 2 +- g3mkcert/src/main.rs | 16 +++-- lib/g3-tls-cert/Cargo.toml | 2 +- lib/g3-tls-cert/src/builder/client.rs | 45 ++++++++++++-- lib/g3-tls-cert/src/builder/intermediate.rs | 2 - lib/g3-tls-cert/src/builder/root.rs | 2 - lib/g3-tls-cert/src/builder/server.rs | 68 +++++++++++++++++++-- 8 files changed, 119 insertions(+), 20 deletions(-) diff --git a/doc/standards.md b/doc/standards.md index 3c382f1a..4e35cef3 100644 --- a/doc/standards.md +++ b/doc/standards.md @@ -79,6 +79,8 @@ The code should comply to these, but should be more compliant to existing popula : Internet X.509 Public Key Infrastructure: Additional Algorithms and Identifiers for DSA and ECDSA - [rfc4055](https://datatracker.ietf.org/doc/html/rfc4055/) : Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile + - [rfc9295](https://datatracker.ietf.org/doc/html/rfc9295/) + : Clarifications for Ed25519, Ed448, X25519, and X448 Algorithm Identifiers ## Cryptography diff --git a/g3fcgen/src/backend/mod.rs b/g3fcgen/src/backend/mod.rs index 166d4ed7..72e60c0c 100644 --- a/g3fcgen/src/backend/mod.rs +++ b/g3fcgen/src/backend/mod.rs @@ -41,7 +41,7 @@ impl OpensslBackend { pub(crate) fn refresh(&mut self) -> anyhow::Result<()> { self.builder.refresh_datetime()?; - self.builder.refresh_pkey()?; + self.builder.refresh_ec256()?; self.builder.refresh_serial()?; Ok(()) } diff --git a/g3mkcert/src/main.rs b/g3mkcert/src/main.rs index 22b2ecb4..de28b3e5 100644 --- a/g3mkcert/src/main.rs +++ b/g3mkcert/src/main.rs @@ -478,9 +478,13 @@ fn generate_root(args: ArgMatches) -> anyhow::Result<()> { let mut builder = if let Some(bits) = args.get_one::(ARG_RSA) { RootCertBuilder::new_rsa(*bits)? } else if args.get_flag(ARG_X448) { - RootCertBuilder::new_x448()? + return Err(anyhow!( + "x448 can not be used in certification authority certificate" + )); } else if args.get_flag(ARG_X25519) { - RootCertBuilder::new_x25519()? + return Err(anyhow!( + "x25519 can not be used in certification authority certificate" + )); } else if args.get_flag(ARG_ED448) { RootCertBuilder::new_ed448()? } else if args.get_flag(ARG_ED25519) { @@ -518,9 +522,13 @@ fn generate_intermediate(args: ArgMatches) -> anyhow::Result<()> { let mut builder = if let Some(bits) = args.get_one::(ARG_RSA) { IntermediateCertBuilder::new_rsa(*bits)? } else if args.get_flag(ARG_X448) { - IntermediateCertBuilder::new_x448()? + return Err(anyhow!( + "x448 can not be used in certification authority certificate" + )); } else if args.get_flag(ARG_X25519) { - IntermediateCertBuilder::new_x25519()? + return Err(anyhow!( + "x25519 can not be used in certification authority certificate" + )); } else if args.get_flag(ARG_ED448) { IntermediateCertBuilder::new_ed448()? } else if args.get_flag(ARG_ED25519) { diff --git a/lib/g3-tls-cert/Cargo.toml b/lib/g3-tls-cert/Cargo.toml index 27f5ceb3..39ac9d6d 100644 --- a/lib/g3-tls-cert/Cargo.toml +++ b/lib/g3-tls-cert/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "g3-tls-cert" -version = "0.2.0" +version = "0.3.0" license.workspace = true edition.workspace = true diff --git a/lib/g3-tls-cert/src/builder/client.rs b/lib/g3-tls-cert/src/builder/client.rs index ebbd3edf..3504eb58 100644 --- a/lib/g3-tls-cert/src/builder/client.rs +++ b/lib/g3-tls-cert/src/builder/client.rs @@ -57,10 +57,46 @@ impl TlsClientCertBuilder { tls_impl_new!(new_ec384); tls_impl_new!(new_ec521); tls_impl_new!(new_sm2); - tls_impl_new!(new_ed25519); - tls_impl_new!(new_ed448); - tls_impl_new!(new_x25519); - tls_impl_new!(new_x448); + + pub fn new_ed25519() -> anyhow::Result { + let pkey = super::pkey::new_ed25519()?; + let key_usage = KeyUsage::new() + .critical() + .digital_signature() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ClientCertBuilder::new(pkey, key_usage) + } + + pub fn new_ed448() -> anyhow::Result { + let pkey = super::pkey::new_ed448()?; + let key_usage = KeyUsage::new() + .critical() + .digital_signature() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ClientCertBuilder::new(pkey, key_usage) + } + + pub fn new_x25519() -> anyhow::Result { + let pkey = super::pkey::new_x25519()?; + let key_usage = KeyUsage::new() + .critical() + .key_agreement() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ClientCertBuilder::new(pkey, key_usage) + } + + pub fn new_x448() -> anyhow::Result { + let pkey = super::pkey::new_x448()?; + let key_usage = KeyUsage::new() + .critical() + .key_agreement() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ClientCertBuilder::new(pkey, key_usage) + } pub fn new_rsa(bits: u32) -> anyhow::Result { let pkey = super::pkey::new_rsa(bits)?; @@ -70,6 +106,7 @@ impl TlsClientCertBuilder { fn with_pkey(pkey: PKey) -> anyhow::Result { let key_usage = KeyUsage::new() .critical() + .key_agreement() .digital_signature() .key_encipherment() .build() diff --git a/lib/g3-tls-cert/src/builder/intermediate.rs b/lib/g3-tls-cert/src/builder/intermediate.rs index b60f077a..83032ece 100644 --- a/lib/g3-tls-cert/src/builder/intermediate.rs +++ b/lib/g3-tls-cert/src/builder/intermediate.rs @@ -53,8 +53,6 @@ impl IntermediateCertBuilder { impl_new!(new_sm2); impl_new!(new_ed25519); impl_new!(new_ed448); - impl_new!(new_x25519); - impl_new!(new_x448); pub fn new_rsa(bits: u32) -> anyhow::Result { let pkey = super::pkey::new_rsa(bits)?; diff --git a/lib/g3-tls-cert/src/builder/root.rs b/lib/g3-tls-cert/src/builder/root.rs index 78f33388..e1f93b9a 100644 --- a/lib/g3-tls-cert/src/builder/root.rs +++ b/lib/g3-tls-cert/src/builder/root.rs @@ -52,8 +52,6 @@ impl RootCertBuilder { impl_new!(new_sm2); impl_new!(new_ed25519); impl_new!(new_ed448); - impl_new!(new_x25519); - impl_new!(new_x448); pub fn new_rsa(bits: u32) -> anyhow::Result { let pkey = super::pkey::new_rsa(bits)?; diff --git a/lib/g3-tls-cert/src/builder/server.rs b/lib/g3-tls-cert/src/builder/server.rs index 5e9919bd..f2df5509 100644 --- a/lib/g3-tls-cert/src/builder/server.rs +++ b/lib/g3-tls-cert/src/builder/server.rs @@ -57,10 +57,46 @@ impl TlsServerCertBuilder { tls_impl_new!(new_ec384); tls_impl_new!(new_ec521); tls_impl_new!(new_sm2); - tls_impl_new!(new_ed25519); - tls_impl_new!(new_ed448); - tls_impl_new!(new_x25519); - tls_impl_new!(new_x448); + + pub fn new_ed25519() -> anyhow::Result { + let pkey = super::pkey::new_ed25519()?; + let key_usage = KeyUsage::new() + .critical() + .digital_signature() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ServerCertBuilder::new(pkey, key_usage) + } + + pub fn new_ed448() -> anyhow::Result { + let pkey = super::pkey::new_ed448()?; + let key_usage = KeyUsage::new() + .critical() + .digital_signature() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ServerCertBuilder::new(pkey, key_usage) + } + + pub fn new_x25519() -> anyhow::Result { + let pkey = super::pkey::new_x25519()?; + let key_usage = KeyUsage::new() + .critical() + .key_agreement() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ServerCertBuilder::new(pkey, key_usage) + } + + pub fn new_x448() -> anyhow::Result { + let pkey = super::pkey::new_x448()?; + let key_usage = KeyUsage::new() + .critical() + .key_agreement() + .build() + .map_err(|e| anyhow!("failed to build KeyUsage extension: {e}"))?; + ServerCertBuilder::new(pkey, key_usage) + } pub fn new_rsa(bits: u32) -> anyhow::Result { let pkey = super::pkey::new_rsa(bits)?; @@ -70,6 +106,7 @@ impl TlsServerCertBuilder { fn with_pkey(pkey: PKey) -> anyhow::Result { let key_usage = KeyUsage::new() .critical() + .key_agreement() .digital_signature() .key_encipherment() .build() @@ -136,6 +173,15 @@ impl TlcpServerEncCertBuilder { } } +macro_rules! impl_refresh_pkey { + ($refresh:ident, $new:ident) => { + pub fn $refresh(&mut self) -> anyhow::Result<()> { + self.pkey = super::pkey::$new()?; + Ok(()) + } + }; +} + impl ServerCertBuilder { pub fn new(pkey: PKey, key_usage: X509Extension) -> anyhow::Result { let serial = super::serial::random_16()?; @@ -187,8 +233,18 @@ impl ServerCertBuilder { self.pkey = pkey; } - pub fn refresh_pkey(&mut self) -> anyhow::Result<()> { - self.pkey = super::pkey::new_ec256()?; + impl_refresh_pkey!(refresh_ec224, new_ec224); + impl_refresh_pkey!(refresh_ec256, new_ec256); + impl_refresh_pkey!(refresh_ec384, new_ec384); + impl_refresh_pkey!(refresh_ec521, new_ec521); + impl_refresh_pkey!(refresh_sm2, new_sm2); + impl_refresh_pkey!(refresh_ed25519, new_ed25519); + impl_refresh_pkey!(refresh_ed448, new_ed448); + impl_refresh_pkey!(refresh_x25519, new_x25519); + impl_refresh_pkey!(refresh_x448, new_x448); + + pub fn refresh_rsa(&mut self, bits: u32) -> anyhow::Result<()> { + self.pkey = super::pkey::new_rsa(bits)?; Ok(()) }