diff --git a/Cargo.lock b/Cargo.lock index a4a3d881..7b422dc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -834,7 +834,6 @@ dependencies = [ "diesel-async", "diesel_migrations", "dotenv", - "elliptic-curve", "email_address", "futures", "futures-util", @@ -854,7 +853,6 @@ dependencies = [ "mime_guess", "oauth2", "openidconnect", - "p256", "pbjson-types", "pbkdf2", "pem", @@ -878,6 +876,7 @@ dependencies = [ "rustls-native-certs 0.8.1", "rustls-pemfile", "scoped-futures", + "sec1", "serde", "serde_json", "serde_urlencoded", diff --git a/chirpstack/Cargo.toml b/chirpstack/Cargo.toml index 0caff742..2543e5d4 100644 --- a/chirpstack/Cargo.toml +++ b/chirpstack/Cargo.toml @@ -118,8 +118,7 @@ pem = "3.0" x509-parser = "0.16" rsa = "0.9" - elliptic-curve = { version = "0.13", features = ["pem"] } - p256 = "0.13" + sec1 = { version = "0.7.3", features = ["alloc", "pem", "pkcs8"] } rcgen = { version = "0.13.1", features = ["x509-parser"] } oauth2 = "5.0.0-alpha.4" openidconnect = { version = "4.0.0-alpha.2", features = [ diff --git a/chirpstack/src/helpers/tls.rs b/chirpstack/src/helpers/tls.rs index c9a3e2e1..61b7cf29 100644 --- a/chirpstack/src/helpers/tls.rs +++ b/chirpstack/src/helpers/tls.rs @@ -68,17 +68,34 @@ pub fn private_key_to_pkcs8(pem: &str) -> Result { let pkcs8_pem = pkey.to_pkcs8_pem(LineEnding::default())?; Ok(pkcs8_pem.as_str().to_owned()) } else if pem.contains("EC PRIVATE KEY") { - use elliptic_curve::{ - pkcs8::{EncodePrivateKey, LineEnding}, - SecretKey, + use sec1::{ + der::{Decode, Encode, EncodePem}, + pkcs8::{AlgorithmIdentifierRef, PrivateKeyInfo}, + EcPrivateKey, LineEnding, }; - // We assume it is a P256 based secret-key, which is the most popular curve. - // Attempting to decode it as P256 is still better than just failing to read it. - let pkey: SecretKey = - SecretKey::from_sec1_pem(pem).context("Read EC SEC1")?; - let pkcs8_pem = pkey.to_pkcs8_pem(LineEnding::default())?; - Ok(pkcs8_pem.as_str().to_owned()) + // Get a SEC1 ECPrivateKey from the PEM string input + let pem = pem::parse(pem).context("Parse PEM string")?; + let pkey = + EcPrivateKey::from_der(pem.contents()).context("Decode PEM into SEC1 ECPrivateKey")?; + + // Retrieve the curve name from the decoded private key's parameters + let params_oid = pkey.parameters.and_then(|params| params.named_curve()); + + // Get the proper types to construct a PKCS#8 PrivateKeyInfo + let private_key = &pkey.to_der()?; + let algorithm = AlgorithmIdentifierRef { + oid: sec1::ALGORITHM_OID, + parameters: params_oid.as_ref().map(Into::into), + }; + + let pkcs8 = PrivateKeyInfo { + algorithm, + private_key, + public_key: None, + }; + + Ok(pkcs8.to_pem(LineEnding::default())?) } else { Ok(pem.to_string()) } diff --git a/chirpstack/src/helpers/tls22.rs b/chirpstack/src/helpers/tls22.rs index 184ab673..de392f4c 100644 --- a/chirpstack/src/helpers/tls22.rs +++ b/chirpstack/src/helpers/tls22.rs @@ -71,17 +71,34 @@ pub fn private_key_to_pkcs8(pem: &str) -> Result { let pkcs8_pem = pkey.to_pkcs8_pem(LineEnding::default())?; Ok(pkcs8_pem.as_str().to_owned()) } else if pem.contains("EC PRIVATE KEY") { - use elliptic_curve::{ - pkcs8::{EncodePrivateKey, LineEnding}, - SecretKey, + use sec1::{ + der::{Decode, Encode, EncodePem}, + pkcs8::{AlgorithmIdentifierRef, PrivateKeyInfo}, + EcPrivateKey, LineEnding, }; - // We assume it is a P256 based secret-key, which is the most popular curve. - // Attempting to decode it as P256 is still better than just failing to read it. - let pkey: SecretKey = - SecretKey::from_sec1_pem(pem).context("Read EC SEC1")?; - let pkcs8_pem = pkey.to_pkcs8_pem(LineEnding::default())?; - Ok(pkcs8_pem.as_str().to_owned()) + // Get a SEC1 ECPrivateKey from the PEM string input + let pem = pem::parse(pem).context("Parse PEM string")?; + let pkey = + EcPrivateKey::from_der(pem.contents()).context("Decode PEM into SEC1 ECPrivateKey")?; + + // Retrieve the curve name from the decoded private key's parameters + let params_oid = pkey.parameters.and_then(|params| params.named_curve()); + + // Get the proper types to construct a PKCS#8 PrivateKeyInfo + let private_key = &pkey.to_der()?; + let algorithm = AlgorithmIdentifierRef { + oid: sec1::ALGORITHM_OID, + parameters: params_oid.as_ref().map(Into::into), + }; + + let pkcs8 = PrivateKeyInfo { + algorithm, + private_key, + public_key: None, + }; + + Ok(pkcs8.to_pem(LineEnding::default())?) } else { Ok(pem.to_string()) }