Skip to content

Commit

Permalink
Update RustCrypto/signature crates
Browse files Browse the repository at this point in the history
Mostly to upgrade ed25519-dalek which has a vulnerability.

The impact should be minimal, but does include empty error messages when
recovered addresses don't match. This was to avoid breaking changes, and
it should be addressed after the upcoming major refactor.
  • Loading branch information
sbihel committed Sep 22, 2023
1 parent 3e18c30 commit 909c7db
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 260 deletions.
10 changes: 6 additions & 4 deletions did-key/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ secp384r1 = ["ssi-jwk/secp384r1"]

[dependencies]
ssi-dids = { path = "../ssi-dids", version = "0.1" }
ssi-jwk = { path = "../ssi-jwk", version = "0.1", default-features = false, features = ["ripemd-160"] }
ssi-crypto = { path = "../ssi-crypto", default-features = false, version = "0.1"}
ssi-jwk = { path = "../ssi-jwk", version = "0.1", default-features = false, features = [
"ripemd-160",
] }
ssi-crypto = { path = "../ssi-crypto", default-features = false, version = "0.1" }
async-trait = "0.1"
thiserror = "1.0"
multibase = "0.8"
k256 = { version = "0.11", optional = true, features = ["ecdsa"] }
p256 = { version = "0.11", optional = true, features = ["ecdsa"] }
k256 = { version = "0.13.1", optional = true, features = ["ecdsa"] }
p256 = { version = "0.13.2", optional = true, features = ["ecdsa"] }
serde_json = "1.0"
simple_asn1 = "^0.5.2"

Expand Down
8 changes: 4 additions & 4 deletions ssi-crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ documentation = "https://docs.rs/ssi-crypto/"

[features]
default = ["secp256k1", "ripemd-160"]
secp256k1 = ["k256", "k256/keccak256", "keccak"]
secp256k1 = ["k256", "keccak"]
bbs = ["dep:bbs", "pairing-plus", "rand_old", "sha2_old", "hkdf", "serde"]
ripemd-160 = ["ripemd160", "secp256k1", "bs58"]
keccak = ["keccak-hash"]
Expand All @@ -20,13 +20,13 @@ ring = ["dep:ring"]
thiserror = "1.0"
sha2 = { version = "0.10" }
ring = { version = "0.16", optional = true }
k256 = { version = "0.11", optional = true, features = ["ecdsa"] }
p256 = { version = "0.11", optional = true, features = ["ecdsa"] }
k256 = { version = "0.13.1", optional = true, features = ["ecdsa"] }
p256 = { version = "0.13.2", optional = true, features = ["ecdsa"] }
hkdf = { version = "0.8", optional = true }
rand_old = { package = "rand", version = "0.7", optional = true }
sha2_old = { package = "sha2", version = "0.8", optional = true }
keccak-hash = { version = "0.7", optional = true }
ed25519-dalek = { version = "1", optional = true }
ed25519-dalek = { version = "2.0.0", optional = true }
ripemd160 = { version = "0.9", optional = true }
bbs = { version = "=0.4.1", optional = true }
pairing-plus = { version = "=0.19.0", optional = true }
Expand Down
32 changes: 20 additions & 12 deletions ssi-jwk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,31 @@ documentation = "https://docs.rs/ssi-jwk/"
[features]
default = ["secp256k1", "secp256r1", "ed25519", "rsa", "eip", "ripemd-160"]
## enable secp256k1 keys
secp256k1 = ["k256", "rand", "k256/keccak256", "ssi-crypto/secp256k1"]
secp256k1 = ["k256", "rand", "ssi-crypto/secp256k1"]
## enable secp256r1 (p256) keys
secp256r1 = ["p256", "rand"]
## enable secp384r1 (p384) keys
secp384r1 = ["p384", "rand"]
## enable ed25519 (EdDSA) keys
ed25519 = ["ed25519-dalek", "rand_old", "getrandom"]
ed25519 = ["ed25519-dalek", "rand", "getrandom"]
## enable RSA keys
rsa = ["dep:rsa"]

## enable aleo ecosystem keys
aleo = ["rand", "blake2", "snarkvm-dpc", "snarkvm-algorithms", "snarkvm-curves", "snarkvm-utilities", "snarkvm-parameters", "bs58"]
aleo = [
"rand",
"blake2",
"snarkvm-dpc",
"snarkvm-algorithms",
"snarkvm-curves",
"snarkvm-utilities",
"snarkvm-parameters",
"bs58",
]
## enable ripemd-160 hashing for keys, e.g. for bitcoin
ripemd-160 = ["ssi-crypto/ripemd-160", "secp256k1"]
## enable ethereum style key hashing
eip = ["ssi-crypto/keccak", "k256/keccak256", "secp256k1"]
eip = ["ssi-crypto/keccak", "secp256k1"]
## enable tezos style key hashing
tezos = ["blake2b_simd", "secp256k1", "secp256r1", "bs58"]

Expand All @@ -39,21 +48,20 @@ zeroize = { version = "1.5", features = ["zeroize_derive"] }
serde = { version = "1.0", features = ["derive"] }
base64 = "0.12"
thiserror = "1.0"
ssi-crypto = { path = "../ssi-crypto", version = "0.1"}
k256 = { version = "0.11", optional = true, features = ["ecdsa"] }
p256 = { version = "0.11", optional = true, features = ["ecdsa"] }
p384 = { version = "0.11", optional = true, features = ["ecdsa"] }
ssi-crypto = { path = "../ssi-crypto", version = "0.1" }
k256 = { version = "0.13.1", optional = true, features = ["ecdsa"] }
p256 = { version = "0.13.2", optional = true, features = ["ecdsa"] }
p384 = { version = "0.13.0", optional = true, features = ["ecdsa"] }
ring = { version = "0.16", optional = true }
rsa = { version = "0.6", optional = true }
rand = { version = "0.8", optional = true }
rand_old = { package = "rand", version = "0.7", optional = true }
ed25519-dalek = { version = "1", optional = true }
ed25519-dalek = { version = "2.0.0", optional = true, features = ["rand_core"] }
lazy_static = "1.4"
bs58 = { version = "0.4", features = ["check"], optional = true }
blake2 = { version = "0.9", optional = true }
snarkvm-dpc = { version = "0.7.9", optional = true }
snarkvm-algorithms = { version= "0.7.9", optional = true }
snarkvm-curves = { version= "0.7.9", optional = true }
snarkvm-algorithms = { version = "0.7.9", optional = true }
snarkvm-curves = { version = "0.7.9", optional = true }
snarkvm-utilities = { version = "0.7.9", optional = true }
snarkvm-parameters = { version = "0.7.9", optional = true }
blake2b_simd = { version = "0.5", optional = true }
Expand Down
66 changes: 27 additions & 39 deletions ssi-jwk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ impl Default for Algorithm {
}

impl JWK {
#[cfg(any(feature = "ed25519"))]
#[cfg(feature = "ed25519")]
pub fn generate_ed25519() -> Result<JWK, Error> {
#[cfg(feature = "ring")]
{
Expand All @@ -289,12 +289,13 @@ impl JWK {
}
#[cfg(not(feature = "ring"))]
{
let mut csprng = rand_old::rngs::OsRng {};
let keypair = ed25519_dalek::Keypair::generate(&mut csprng);
let mut csprng = rand::rngs::OsRng {};
let secret = ed25519_dalek::SigningKey::generate(&mut csprng);
let public = secret.verifying_key();
Ok(JWK::from(Params::OKP(OctetParams {
curve: "Ed25519".to_string(),
public_key: Base64urlUInt(keypair.public.as_ref().to_vec()),
private_key: Some(Base64urlUInt(keypair.secret.as_ref().to_vec())),
public_key: Base64urlUInt(public.as_ref().to_vec()),
private_key: Some(Base64urlUInt(secret.to_bytes().to_vec())),
})))
}
}
Expand All @@ -303,7 +304,7 @@ impl JWK {
pub fn generate_secp256k1() -> Result<JWK, Error> {
let mut rng = rand::rngs::OsRng {};
let secret_key = k256::SecretKey::random(&mut rng);
let sk_bytes = zeroize::Zeroizing::new(secret_key.to_be_bytes().to_vec());
let sk_bytes = zeroize::Zeroizing::new(secret_key.to_bytes().to_vec());
let public_key = secret_key.public_key();
let mut ec_params = ECParams::try_from(&public_key)?;
ec_params.ecc_private_key = Some(Base64urlUInt(sk_bytes.to_vec()));
Expand All @@ -314,7 +315,7 @@ impl JWK {
pub fn generate_p256() -> Result<JWK, Error> {
let mut rng = rand::rngs::OsRng {};
let secret_key = p256::SecretKey::random(&mut rng);
let sk_bytes = zeroize::Zeroizing::new(secret_key.to_be_bytes().to_vec());
let sk_bytes = zeroize::Zeroizing::new(secret_key.to_bytes().to_vec());
let public_key: p256::PublicKey = secret_key.public_key();
let mut ec_params = ECParams::try_from(&public_key)?;
ec_params.ecc_private_key = Some(Base64urlUInt(sk_bytes.to_vec()));
Expand All @@ -325,7 +326,7 @@ impl JWK {
pub fn generate_p384() -> Result<JWK, Error> {
let mut rng = rand::rngs::OsRng {};
let secret_key = p384::SecretKey::random(&mut rng);
let sk_bytes = zeroize::Zeroizing::new(secret_key.to_be_bytes().to_vec());
let sk_bytes = zeroize::Zeroizing::new(secret_key.to_bytes().to_vec());
let public_key: p384::PublicKey = secret_key.public_key();
let mut ec_params = ECParams::try_from(&public_key)?;
ec_params.ecc_private_key = Some(Base64urlUInt(sk_bytes.to_vec()));
Expand Down Expand Up @@ -492,7 +493,7 @@ impl JWK {
}
"Multikey" => match multicodec::decode(&pk_bytes) {
Ok((codec, pk)) => match codec {
#[cfg(any(feature = "ed25519"))]
#[cfg(feature = "ed25519")]
multicodec::Codec::Ed25519Pub => ed25519_parse(&pk),
#[cfg(feature = "secp256k1")]
multicodec::Codec::Secp256k1Pub => secp256k1_parse(&pk),
Expand All @@ -512,9 +513,9 @@ impl JWK {
let bytes = multibase::decode(multicodec)?.1;
match multicodec::decode(&bytes) {
Ok((codec, k)) => match codec {
#[cfg(any(feature = "ed25519"))]
#[cfg(feature = "ed25519")]
multicodec::Codec::Ed25519Pub => ed25519_parse(&k),
#[cfg(any(feature = "ed25519"))]
#[cfg(feature = "ed25519")]
multicodec::Codec::Ed25519Priv => ed25519_parse_private(&k),
#[cfg(feature = "secp256k1")]
multicodec::Codec::Secp256k1Pub => secp256k1_parse(&k),
Expand Down Expand Up @@ -793,18 +794,18 @@ impl TryFrom<&RSAParams> for ring::signature::RsaKeyPair {
}

#[cfg(feature = "ed25519")]
impl TryFrom<&OctetParams> for ed25519_dalek::PublicKey {
impl TryFrom<&OctetParams> for ed25519_dalek::VerifyingKey {
type Error = Error;
fn try_from(params: &OctetParams) -> Result<Self, Self::Error> {
if params.curve != *"Ed25519" {
return Err(Error::CurveNotImplemented(params.curve.to_string()));
}
Ok(Self::from_bytes(&params.public_key.0)?)
Ok(params.public_key.0.as_slice().as_ref().try_into()?)
}
}

#[cfg(feature = "ed25519")]
impl TryFrom<&OctetParams> for ed25519_dalek::SecretKey {
impl TryFrom<&OctetParams> for ed25519_dalek::SigningKey {
type Error = Error;
fn try_from(params: &OctetParams) -> Result<Self, Self::Error> {
if params.curve != *"Ed25519" {
Expand All @@ -814,20 +815,7 @@ impl TryFrom<&OctetParams> for ed25519_dalek::SecretKey {
.private_key
.as_ref()
.ok_or(Error::MissingPrivateKey)?;
Ok(Self::from_bytes(&private_key.0)?)
}
}

#[cfg(feature = "ed25519")]
impl TryFrom<&OctetParams> for ed25519_dalek::Keypair {
type Error = Error;
fn try_from(params: &OctetParams) -> Result<Self, Self::Error> {
if params.curve != *"Ed25519" {
return Err(Error::CurveNotImplemented(params.curve.to_string()));
}
let public = ed25519_dalek::PublicKey::try_from(params)?;
let secret = ed25519_dalek::SecretKey::try_from(params)?;
Ok(ed25519_dalek::Keypair { secret, public })
Ok(private_key.0.as_slice().as_ref().try_into()?)
}
}

Expand Down Expand Up @@ -861,7 +849,7 @@ impl TryFrom<&OctetParams> for ring::signature::Ed25519KeyPair {

#[cfg(feature = "ed25519")]
pub fn ed25519_parse(data: &[u8]) -> Result<JWK, Error> {
let _ = ed25519_dalek::PublicKey::from_bytes(data)?;
let _: ed25519_dalek::VerifyingKey = data.try_into()?;
Ok(JWK::from(Params::OKP(OctetParams {
curve: "Ed25519".to_string(),
public_key: Base64urlUInt(data.to_owned()),
Expand All @@ -871,10 +859,10 @@ pub fn ed25519_parse(data: &[u8]) -> Result<JWK, Error> {

#[cfg(feature = "ed25519")]
fn ed25519_parse_private(data: &[u8]) -> Result<JWK, Error> {
let key = ed25519_dalek::SecretKey::from_bytes(data)?;
let key: ed25519_dalek::SigningKey = data.try_into()?;
Ok(JWK::from(Params::OKP(OctetParams {
curve: "Ed25519".to_string(),
public_key: Base64urlUInt(ed25519_dalek::PublicKey::from(&key).as_bytes().to_vec()),
public_key: Base64urlUInt(ed25519_dalek::VerifyingKey::from(&key).as_bytes().to_vec()),
private_key: Some(Base64urlUInt(data.to_owned())),
})))
}
Expand Down Expand Up @@ -932,7 +920,7 @@ pub fn p256_parse(pk_bytes: &[u8]) -> Result<JWK, Error> {

#[cfg(feature = "secp256r1")]
fn p256_parse_private(data: &[u8]) -> Result<JWK, Error> {
let k = p256::SecretKey::from_be_bytes(data)?;
let k = p256::SecretKey::from_bytes(data.into())?;
let jwk = JWK {
params: Params::EC(ECParams::try_from(&k)?),
public_key_use: None,
Expand Down Expand Up @@ -966,7 +954,7 @@ pub fn p384_parse(pk_bytes: &[u8]) -> Result<JWK, Error> {

#[cfg(feature = "secp384r1")]
fn p384_parse_private(data: &[u8]) -> Result<JWK, Error> {
let k = p384::SecretKey::from_be_bytes(data)?;
let k = p384::SecretKey::from_bytes(data.into())?;
let jwk = JWK {
params: Params::EC(ECParams::try_from(&k)?),
public_key_use: None,
Expand Down Expand Up @@ -1082,7 +1070,7 @@ impl TryFrom<&ECParams> for k256::SecretKey {
.ecc_private_key
.as_ref()
.ok_or(Error::MissingPrivateKey)?;
let secret_key = k256::SecretKey::from_be_bytes(&private_key.0)?;
let secret_key = k256::SecretKey::from_bytes(private_key.0.as_slice().into())?;
Ok(secret_key)
}
}
Expand All @@ -1099,7 +1087,7 @@ impl TryFrom<&ECParams> for p256::SecretKey {
.ecc_private_key
.as_ref()
.ok_or(Error::MissingPrivateKey)?;
let secret_key = p256::SecretKey::from_be_bytes(&private_key.0)?;
let secret_key = p256::SecretKey::from_bytes(private_key.0.as_slice().into())?;
Ok(secret_key)
}
}
Expand All @@ -1116,7 +1104,7 @@ impl TryFrom<&ECParams> for p384::SecretKey {
.ecc_private_key
.as_ref()
.ok_or(Error::MissingPrivateKey)?;
let secret_key = p384::SecretKey::from_be_bytes(&private_key.0)?;
let secret_key = p384::SecretKey::from_bytes(private_key.0.as_slice().into())?;
Ok(secret_key)
}
}
Expand Down Expand Up @@ -1204,7 +1192,7 @@ impl TryFrom<&k256::SecretKey> for ECParams {
curve: Some("secp256k1".to_string()),
x_coordinate: Some(Base64urlUInt(x.to_vec())),
y_coordinate: Some(Base64urlUInt(y.to_vec())),
ecc_private_key: Some(Base64urlUInt(k.to_be_bytes().to_vec())),
ecc_private_key: Some(Base64urlUInt(k.to_bytes().to_vec())),
})
}
}
Expand Down Expand Up @@ -1239,7 +1227,7 @@ impl TryFrom<&p256::SecretKey> for ECParams {
curve: Some("P-256".to_string()),
x_coordinate: Some(Base64urlUInt(x.to_vec())),
y_coordinate: Some(Base64urlUInt(y.to_vec())),
ecc_private_key: Some(Base64urlUInt(k.to_be_bytes().to_vec())),
ecc_private_key: Some(Base64urlUInt(k.to_bytes().to_vec())),
})
}
}
Expand Down Expand Up @@ -1274,7 +1262,7 @@ impl TryFrom<&p384::SecretKey> for ECParams {
curve: Some("P-384".to_string()),
x_coordinate: Some(Base64urlUInt(x.to_vec())),
y_coordinate: Some(Base64urlUInt(y.to_vec())),
ecc_private_key: Some(Base64urlUInt(k.to_be_bytes().to_vec())),
ecc_private_key: Some(Base64urlUInt(k.to_bytes().to_vec())),
})
}
}
Expand Down
33 changes: 24 additions & 9 deletions ssi-jws/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,23 @@ repository = "https://github.com/spruceid/ssi/"
documentation = "https://docs.rs/ssi-jws/"

[features]
default = ["secp256k1", "secp256r1", "ed25519", "rsa", "eip", "ssi-jwk/ripemd-160"]
default = [
"secp256k1",
"secp256r1",
"ed25519",
"rsa",
"eip",
"ssi-jwk/ripemd-160",
]
## enable secp256k1 signatures
secp256k1 = ["ssi-jwk/secp256k1", "k256/keccak256", "ssi-crypto/secp256k1", "blake2", "dep:sha2"]
secp256k1 = [
"ssi-jwk/secp256k1",
"k256",
"ssi-crypto/secp256k1",
"blake2",
"dep:sha2",
"dep:sha3",
]
## enable secp256r1 (p256) signatures
secp256r1 = ["ssi-jwk/secp256r1", "p256", "blake2"]
## enable secp384r1 (p384) signatures
Expand All @@ -24,7 +38,7 @@ rsa = ["ssi-jwk/rsa", "dep:rsa", "dep:sha2", "rand"]
## enable aleo ecosystem signatures
aleo = ["ssi-jwk/aleo"]
## enable ethereum style signatures
eip = ["ssi-jwk/eip", "ssi-crypto/keccak", "k256/keccak256", "secp256k1"]
eip = ["ssi-jwk/eip", "ssi-crypto/keccak", "secp256k1"]
## enable tezos style signatures
tezos = ["ssi-jwk/tezos", "secp256k1", "secp256r1", "ed25519"]

Expand All @@ -36,18 +50,19 @@ thiserror = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
base64 = "0.12"
k256 = { version = "0.11", optional = true, features = ["ecdsa"] }
p256 = { version = "0.11", optional = true, features = ["ecdsa"] }
p384 = { version = "0.11", optional = true, features = ["ecdsa"] }
k256 = { version = "0.13.1", optional = true, features = ["ecdsa"] }
p256 = { version = "0.13.2", optional = true, features = ["ecdsa"] }
p384 = { version = "0.13.0", optional = true, features = ["ecdsa"] }
# blake2b_simd = { version = "0.5", optional = true }
blake2 = { version = "0.10", optional = true }
ed25519-dalek = { version = "1", optional = true }
ed25519-dalek = { version = "2.0.0", optional = true }
sha2 = { version = "0.10", optional = true }
sha3 = { version = "0.10.8", optional = true }
rsa = { version = "0.6", optional = true }
rand = { version = "0.8", optional = true }
ring = { version = "0.16", optional = true }
ssi-crypto = { path = "../ssi-crypto", version = "0.1"}
ssi-jwk = { path = "../ssi-jwk", version = "0.1"}
ssi-crypto = { path = "../ssi-crypto", version = "0.1" }
ssi-jwk = { path = "../ssi-jwk", version = "0.1" }


[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand Down
Loading

0 comments on commit 909c7db

Please sign in to comment.