diff --git a/Cargo.toml b/Cargo.toml index 59852451fa..2168ab12d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,7 @@ name = "sigstore" description = "An experimental crate to interact with sigstore" version = "0.6.0" edition = "2021" -authors = [ - "sigstore-rs developers", -] +authors = ["sigstore-rs developers"] license = "Apache-2.0" readme = "README.md" @@ -13,40 +11,60 @@ readme = "README.md" default = ["full-native-tls", "cached-client", "tuf"] wasm = ["getrandom/js"] -full-native-tls = ["fulcio-native-tls", "rekor-native-tls", "cosign-native-tls", "mock-client-native-tls"] -full-rustls-tls = ["fulcio-rustls-tls", "rekor-rustls-tls", "cosign-rustls-tls", "mock-client-rustls-tls"] +full-native-tls = [ + "fulcio-native-tls", + "rekor-native-tls", + "cosign-native-tls", + "mock-client-native-tls", +] +full-rustls-tls = [ + "fulcio-rustls-tls", + "rekor-rustls-tls", + "cosign-rustls-tls", + "mock-client-rustls-tls", +] # This features is used by tests that use docker to create a registry test-registry = [] -fulcio-native-tls = [ "oauth-native-tls", "reqwest/native-tls", "fulcio" ] -fulcio-rustls-tls = [ "oauth-rustls-tls", "reqwest/rustls-tls", "fulcio" ] +fulcio-native-tls = ["oauth-native-tls", "reqwest/native-tls", "fulcio"] +fulcio-rustls-tls = ["oauth-rustls-tls", "reqwest/rustls-tls", "fulcio"] fulcio = [] -oauth-native-tls = [ "openidconnect/native-tls", "oauth" ] -oauth-rustls-tls = [ "openidconnect/rustls-tls", "oauth" ] +oauth-native-tls = ["openidconnect/native-tls", "oauth"] +oauth-rustls-tls = ["openidconnect/rustls-tls", "oauth"] oauth = [] -rekor-native-tls = [ "reqwest/native-tls", "rekor"] -rekor-rustls-tls = [ "reqwest/rustls-tls", "rekor" ] +rekor-native-tls = ["reqwest/native-tls", "rekor"] +rekor-rustls-tls = ["reqwest/rustls-tls", "rekor"] rekor = ["reqwest"] -tuf = [ "tough", "regex" ] +tuf = ["tough", "regex"] -cosign-native-tls = [ "oci-distribution/native-tls", "cert", "cosign", "registry-native-tls" ] -cosign-rustls-tls = [ "oci-distribution/rustls-tls", "cert", "cosign", "registry-rustls-tls" ] +cosign-native-tls = [ + "oci-distribution/native-tls", + "cert", + "cosign", + "registry-native-tls", +] +cosign-rustls-tls = [ + "oci-distribution/rustls-tls", + "cert", + "cosign", + "registry-rustls-tls", +] cosign = [] cert = [] -registry-native-tls = [ "oci-distribution/native-tls", "registry" ] -registry-rustls-tls = [ "oci-distribution/rustls-tls", "registry" ] +registry-native-tls = ["oci-distribution/native-tls", "registry"] +registry-rustls-tls = ["oci-distribution/rustls-tls", "registry"] registry = [] -mock-client-native-tls = [ "oci-distribution/native-tls", "mock-client" ] -mock-client-rustls-tls = [ "oci-distribution/rustls-tls", "mock-client" ] +mock-client-native-tls = ["oci-distribution/native-tls", "mock-client"] +mock-client-rustls-tls = ["oci-distribution/rustls-tls", "mock-client"] mock-client = [] -cached-client = [ "cached" ] +cached-client = ["cached"] [dependencies] async-trait = "0.1.52" @@ -57,37 +75,51 @@ chrono = { version = "0.4.23" } const-oid = "0.9.1" der = "0.7.5" digest = { version = "0.10.3", default-features = false } -ecdsa = { version = "0.15", features = [ "pkcs8", "digest", "der" ] } -ed25519 = { version = "=2.1", features = [ "alloc" ] } -ed25519-dalek = { version = "2.0.0-pre.0", features = [ "pkcs8", "rand_core" ] } -elliptic-curve = { version = "0.12.2", features = [ "arithmetic", "pem" ] } +ecdsa = { version = "0.15", features = ["pkcs8", "digest", "der"] } +ed25519 = { version = "2.2.1", features = ["alloc"] } +ed25519-dalek = { version = "2.0.0-rc.2", features = ["pkcs8", "rand_core"] } +elliptic-curve = { version = "0.12.2", features = ["arithmetic", "pem"] } lazy_static = "1.4.0" oci-distribution = { version = "0.9", default-features = false, optional = true } olpc-cjson = "0.1" -openidconnect = { version = "2.3", default-features = false, features = [ "reqwest" ], optional = true} +openidconnect = { version = "2.3", default-features = false, features = [ + "reqwest", +], optional = true } p256 = "0.12" p384 = "0.12" webbrowser = "0.8.4" pem = "1.0.2" -picky = { version = "7.0.0-rc.5", default-features = false, features = [ "x509", "ec" ] } -pkcs1 = { version = "0.7.5", features = [ "std" ] } -pkcs8 = { version = "0.9.0", features = ["pem", "alloc", "pkcs5", "encryption"] } -rand = { version = "0.8.5", features = [ "getrandom", "std" ] } +picky = { version = "7.0.0-rc.5", default-features = false, features = [ + "x509", + "ec", +] } +pkcs1 = { version = "0.7.5", features = ["std"] } +pkcs8 = { version = "0.9.0", features = [ + "pem", + "alloc", + "pkcs5", + "encryption", +] } +rand = { version = "0.8.5", features = ["getrandom", "std"] } getrandom = "0.2.8" regex = { version = "1.5.5", optional = true } -reqwest = { version = "0.11", default-features = false, features = ["json", "multipart"], optional = true} +reqwest = { version = "0.11", default-features = false, features = [ + "json", + "multipart", +], optional = true } rsa = "0.8.2" scrypt = "0.10.0" serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" sha2 = { version = "0.10.6", features = ["oid"] } signature = { version = "2.0" } +spki = { version = "0.7.2", features = ["pem", "std"] } thiserror = "1.0.30" tokio = { version = "1.17.0", features = ["rt"] } -tough = { version = "0.13", features = [ "http" ], optional = true } +tough = { version = "0.13", features = ["http"], optional = true } tracing = "0.1.31" url = "2.2.2" -x509-cert = { version = "0.1.1", features = [ "pem", "std" ] } +x509-cert = { version = "0.1.1", features = ["pem", "std"] } crypto_secretbox = "0.1.1" zeroize = "1.5.7" diff --git a/src/crypto/signing_key/ed25519.rs b/src/crypto/signing_key/ed25519.rs index 1b69981f46..f2b236f5e8 100644 --- a/src/crypto/signing_key/ed25519.rs +++ b/src/crypto/signing_key/ed25519.rs @@ -60,11 +60,11 @@ //! assert!(verification_key.verify_signature(Signature::Raw(&signature),message).is_ok()); //! ``` +use ed25519::pkcs8::{DecodePrivateKey, EncodePrivateKey, EncodePublicKey}; use std::convert::TryFrom; use ed25519::KeypairBytes; use ed25519_dalek::{Signer as _, SigningKey}; -use pkcs8::{DecodePrivateKey, EncodePrivateKey, EncodePublicKey}; use crate::{ crypto::{verification_key::CosignVerificationKey, SigningScheme}, @@ -110,9 +110,10 @@ impl Ed25519Keys { match &key.tag[..] { COSIGN_PRIVATE_KEY_PEM_LABEL | SIGSTORE_PRIVATE_KEY_PEM_LABEL => { let der = kdf::decrypt(&key.contents, password)?; - let pkcs8 = pkcs8::PrivateKeyInfo::try_from(&der[..]).map_err(|e| { - SigstoreError::PKCS8Error(format!("Read PrivateKeyInfo failed: {e}")) - })?; + let pkcs8 = + ed25519_dalek::pkcs8::PrivateKeyInfo::try_from(&der[..]).map_err(|e| { + SigstoreError::PKCS8Error(format!("Read PrivateKeyInfo failed: {e}")) + })?; let key_pair_bytes = KeypairBytes::try_from(pkcs8).map_err(|e| { SigstoreError::PKCS8Error(format!( "Convert from pkcs8 pem to ed25519 private key failed: {e}" @@ -135,9 +136,10 @@ impl Ed25519Keys { match label { PRIVATE_KEY_PEM_LABEL => { - let pkcs8 = pkcs8::PrivateKeyInfo::try_from(document.as_bytes()).map_err(|e| { - SigstoreError::PKCS8Error(format!("Read PrivateKeyInfo failed: {e}")) - })?; + let pkcs8 = ed25519_dalek::pkcs8::PrivateKeyInfo::try_from(document.as_bytes()) + .map_err(|e| { + SigstoreError::PKCS8Error(format!("Read PrivateKeyInfo failed: {e}")) + })?; let key_pair_bytes = KeypairBytes::try_from(pkcs8).map_err(|e| { SigstoreError::PKCS8Error(format!( "Convert from pkcs8 pem to ed25519 private key failed: {e}" @@ -223,7 +225,9 @@ impl KeyPair for Ed25519Keys { /// Return the private key in pkcs8 PEM-encoded format. fn private_key_to_pem(&self) -> Result> { self.signing_key - .to_pkcs8_pem(pkcs8::LineEnding::LF) + .to_pkcs8_der() + .map_err(|e| SigstoreError::PKCS8SpkiError(e.to_string()))? + .to_pem(PRIVATE_KEY_PEM_LABEL, pkcs8::LineEnding::LF) .map_err(|e| SigstoreError::PKCS8SpkiError(e.to_string())) } diff --git a/src/crypto/verification_key.rs b/src/crypto/verification_key.rs index e84c7ed127..2ea8a59d7a 100644 --- a/src/crypto/verification_key.rs +++ b/src/crypto/verification_key.rs @@ -15,6 +15,7 @@ use base64::{engine::general_purpose::STANDARD as BASE64_STD_ENGINE, Engine as _}; use const_oid::db::rfc5912::{ID_EC_PUBLIC_KEY, RSA_ENCRYPTION}; +use ed25519::pkcs8::DecodePublicKey as ED25519DecodePublicKey; use pkcs8::{DecodePublicKey, SubjectPublicKeyInfo}; use rsa::{pkcs1v15, pss}; use sha2::{Digest, Sha256, Sha384}; @@ -74,18 +75,20 @@ impl<'a> TryFrom<&SubjectPublicKeyInfo<'a>> for CosignVerificationKey { match algorithm { ID_EC_PUBLIC_KEY => match public_key_der.len() { 65 => Ok(CosignVerificationKey::ECDSA_P256_SHA256_ASN1( - ecdsa::VerifyingKey::try_from(*subject_pub_key_info).map_err(|e| { - SigstoreError::PKCS8SpkiError(format!( - "Ecdsa-P256 from der bytes to public key failed: {e}" - )) - })?, + ecdsa::VerifyingKey::try_from(subject_pub_key_info.subject_public_key) + .map_err(|e| { + SigstoreError::PKCS8SpkiError(format!( + "Ecdsa-P256 from der bytes to public key failed: {e}" + )) + })?, )), 97 => Ok(CosignVerificationKey::ECDSA_P384_SHA384_ASN1( - ecdsa::VerifyingKey::try_from(*subject_pub_key_info).map_err(|e| { - SigstoreError::PKCS8SpkiError(format!( - "Ecdsa-P384 from der bytes to public key failed: {e}" - )) - })?, + ecdsa::VerifyingKey::try_from(subject_pub_key_info.subject_public_key) + .map_err(|e| { + SigstoreError::PKCS8SpkiError(format!( + "Ecdsa-P384 from der bytes to public key failed: {e}" + )) + })?, )), _ => Err(SigstoreError::PublicKeyUnsupportedAlgorithmError(format!( "EC with size {} is not supported", @@ -106,7 +109,7 @@ impl<'a> TryFrom<&SubjectPublicKeyInfo<'a>> for CosignVerificationKey { // #[cfg(feature = "cosign")] ED25519 => Ok(CosignVerificationKey::ED25519( - ed25519_dalek::VerifyingKey::try_from(*subject_pub_key_info)?, + ed25519_dalek::VerifyingKey::try_from(subject_pub_key_info.subject_public_key)?, )), _ => Err(SigstoreError::PublicKeyUnsupportedAlgorithmError(format!( "Key with algorithm OID {} is not supported", diff --git a/src/errors.rs b/src/errors.rs index d412fd7583..2f44f563ec 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -213,5 +213,5 @@ pub enum SigstoreError { PKCS1Error(#[from] pkcs1::Error), #[error(transparent)] - ED25519PKCS1Error(#[from] ed25519_dalek::pkcs8::spki::Error), + Ed25519PKCS8Error(#[from] ed25519_dalek::pkcs8::spki::Error), }