Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/caips/src/caip10/aleo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub(crate) fn encode_aleo_address(jwk: &JWK, network_id: &str) -> Result<String,
return Err("Unexpected Aleo network id");
}
let params = match jwk.params {
Params::OKP(ref params) if params.curve == ssi_jwk::aleo::OKP_CURVE => params,
Params::OKP(ref params) if params.curve == ssi_jwk::okp::aleo::OKP_CURVE => params,
_ => return Err("Invalid public key type for Aleo"),
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,15 @@ impl VerificationAlgorithm<AleoSignature2021> for AleoSignatureAlgorithm {
return Err(ProofValidationError::InvalidKey);
}

let result = ssi_jwk::aleo::verify(
let result = ssi_jwk::okp::aleo::verify(
&prepared_claims,
&account_id.account_address,
&signature_bytes,
);

match result {
Ok(()) => Ok(Ok(())),
Err(ssi_jwk::aleo::AleoVerifyError::InvalidSignature) => {
Err(ssi_jwk::okp::aleo::AleoVerifyError::InvalidSignature) => {
Ok(Err(ssi_claims_core::InvalidProof::Signature))
}
Err(_) => Err(ProofValidationError::InvalidSignature),
Expand Down
238 changes: 14 additions & 224 deletions crates/jwk/src/der.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,70 +13,10 @@
// ISO/IEC 8825-1:2015 (E)
// https://tools.ietf.org/html/rfc8017#page-55
// https://tools.ietf.org/html/rfc8410
use num_bigint::BigInt;
use simple_asn1::{ASN1Block, ASN1Class, ASN1EncodeErr, ToASN1};

use num_bigint::{BigInt, Sign};
use simple_asn1::{
der_encode, ASN1Block, ASN1Class, ASN1DecodeErr, ASN1EncodeErr, FromASN1, ToASN1,
};

/// RSA private key for ASN.1 encoding, as specified in [RFC 8017].
///
/// [RFC 8017]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.2 "RFC 8017 PKCS #1 v2.2 - A.1.2. RSA Private Key Syntax"
#[derive(Debug, Clone)]
pub struct RSAPrivateKey {
pub modulus: Integer,
pub public_exponent: Integer,
pub private_exponent: Integer,
pub prime1: Integer,
pub prime2: Integer,
pub exponent1: Integer,
pub exponent2: Integer,
pub coefficient: Integer,
pub other_prime_infos: Option<OtherPrimeInfos>,
}

/// RSA public key for ASN.1 encoding, as specified in [RFC 8017].
///
/// [RFC 8017]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.1 "RFC 8017 PKCS #1 v2.2 - A.1.1. RSA Public Key Syntax"
#[derive(Debug, Clone)]
// https://datatracker.ietf.org/doc/html/rfc3447#appendix-A.1.1
pub struct RSAPublicKey {
pub modulus: Integer,
pub public_exponent: Integer,
}

/// Ed25519 public key for ASN.1 encoding, as specified in [RFC 8410].
///
/// [RFC 8410]: https://datatracker.ietf.org/doc/html/rfc8410#section-10.1 "RFC 8410 Safe Curves for X.509 - 10.1. Example Ed25519 Public Key"
#[derive(Debug, Clone)]
pub struct Ed25519PublicKey {
pub public_key: BitString,
}

/// Ed25519 private key for ASN.1 encoding, as specified in [RFC 8410].
///
/// [RFC 8410]: https://datatracker.ietf.org/doc/html/rfc8410#section-10.3 "RFC 8410 Safe Curves for X.509 - 10.3. Examples of Ed25519 Private Key"
#[derive(Debug, Clone)]
pub struct Ed25519PrivateKey {
pub public_key: BitString,
pub private_key: OctetString,
}

/// Additional primes in a [RSA private key][RSAPrivateKey], as specified in [RFC 8017].
///
/// [RFC 8017]: https://datatracker.ietf.org/doc/html/rfc8017#page-56 "RFC 8017 PKCS #1 v2.2 - Page 56"
#[derive(Debug, Clone)]
pub struct OtherPrimeInfos(pub Vec<OtherPrimeInfo>);

/// Additional prime in a [RSA private key][RSAPrivateKey], as specified in [RFC 8017].
///
/// [RFC 8017]: https://datatracker.ietf.org/doc/html/rfc8017#page-56 "RFC 8017 PKCS #1 v2.2 - Page 56"
#[derive(Debug, Clone)]
pub struct OtherPrimeInfo {
pub prime: Integer,
pub exponent: Integer,
pub coefficient: Integer,
}
use crate::{Error, Params, JWK};

#[derive(Debug, Clone)]
/// An integer value, for encoding in [ASN.1][ITU X.690]
Expand All @@ -99,116 +39,6 @@ pub struct OctetString(pub Vec<u8>);
/// [ITU X.690]: https://www.itu.int/rec/T-REC-X.690-202102-I/en
pub struct BitString(pub Vec<u8>);

impl ToASN1 for RSAPrivateKey {
type Error = ASN1EncodeErr;
fn to_asn1_class(&self, class: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error> {
let multiprime = self.other_prime_infos.is_some();
let version = Integer(BigInt::new(Sign::Plus, vec![u32::from(multiprime)]));
Ok(vec![ASN1Block::Sequence(
0,
[
version.to_asn1_class(class)?,
self.modulus.to_asn1_class(class)?,
self.public_exponent.to_asn1_class(class)?,
self.private_exponent.to_asn1_class(class)?,
self.prime1.to_asn1_class(class)?,
self.prime2.to_asn1_class(class)?,
self.exponent1.to_asn1_class(class)?,
self.exponent2.to_asn1_class(class)?,
self.coefficient.to_asn1_class(class)?,
match self.other_prime_infos {
Some(ref infos) => infos.to_asn1_class(class)?,
None => Vec::new(),
},
]
.concat(),
)])
}
}

impl ToASN1 for RSAPublicKey {
type Error = ASN1EncodeErr;
fn to_asn1_class(&self, class: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error> {
Ok(vec![ASN1Block::Sequence(
0,
[
self.modulus.to_asn1_class(class)?,
self.public_exponent.to_asn1_class(class)?,
]
.concat(),
)])
}
}

#[derive(thiserror::Error, Debug)]
pub enum RSAPublicKeyFromASN1Error {
#[error("Expected single sequence")]
ExpectedSingleSequence,
#[error("Expected two integers")]
ExpectedTwoIntegers,
#[error("ASN1 decoding error: {0:?}")]
ASN1Decode(#[from] ASN1DecodeErr),
}

impl FromASN1 for RSAPublicKey {
type Error = RSAPublicKeyFromASN1Error;
fn from_asn1(v: &[ASN1Block]) -> Result<(Self, &[ASN1Block]), Self::Error> {
let vec = match v {
[ASN1Block::Sequence(_, vec)] => vec,
_ => return Err(RSAPublicKeyFromASN1Error::ExpectedSingleSequence),
};
let (n, e) = match vec.as_slice() {
[ASN1Block::Integer(_, n), ASN1Block::Integer(_, e)] => (n, e),
_ => return Err(RSAPublicKeyFromASN1Error::ExpectedTwoIntegers),
};
let pk = Self {
modulus: Integer(n.clone()),
public_exponent: Integer(e.clone()),
};
Ok((pk, &[]))
}
}

impl Ed25519PrivateKey {
fn oid() -> ASN1Block {
use simple_asn1::BigUint;
// id-Ed25519 1.3.101.112
let oid = simple_asn1::OID::new(vec![
BigUint::new(vec![1]),
BigUint::new(vec![3]),
BigUint::new(vec![101]),
BigUint::new(vec![112]),
]);
ASN1Block::Sequence(0, vec![ASN1Block::ObjectIdentifier(0, oid)])
}
}

impl ToASN1 for Ed25519PrivateKey {
type Error = ASN1EncodeErr;
fn to_asn1_class(&self, _class: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error> {
let version = 0;
// TODO: include public key
Ok(vec![ASN1Block::Sequence(
0,
vec![
ASN1Block::Integer(0, BigInt::new(Sign::NoSign, vec![version])),
Ed25519PrivateKey::oid(),
ASN1Block::OctetString(0, der_encode(&self.private_key)?),
],
)])
}
}

impl ToASN1 for Ed25519PublicKey {
type Error = ASN1EncodeErr;
fn to_asn1_class(&self, class: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error> {
Ok(vec![ASN1Block::Sequence(
0,
self.public_key.to_asn1_class(class)?,
)])
}
}

impl ToASN1 for Integer {
type Error = ASN1EncodeErr;
fn to_asn1_class(&self, _: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error> {
Expand All @@ -230,49 +60,27 @@ impl ToASN1 for BitString {
}
}

impl ToASN1 for OtherPrimeInfos {
type Error = ASN1EncodeErr;
fn to_asn1_class(&self, class: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error> {
Ok(vec![ASN1Block::Sequence(
0,
self.0
.iter()
.map(|x| x.to_asn1_class(class))
.collect::<Result<Vec<Vec<ASN1Block>>, ASN1EncodeErr>>()?
.concat(),
)])
}
}
impl ToASN1 for JWK {
type Error = Error;

impl ToASN1 for OtherPrimeInfo {
type Error = ASN1EncodeErr;
fn to_asn1_class(&self, class: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error> {
Ok(vec![ASN1Block::Sequence(
0,
[
self.prime.to_asn1_class(class)?,
self.exponent.to_asn1_class(class)?,
self.coefficient.to_asn1_class(class)?,
]
.concat(),
)])
match &self.params {
// EC(params) => params.to_asn1_class(class),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks new, why is EC comented out?

Params::RSA(params) => params.to_asn1_class(class),
// Symmetric(params) => params.to_asn1_class(class),
Params::OKP(params) => params.to_asn1_class(class),
_ => Err(Error::KeyTypeNotImplemented(Box::new(self.to_public()))),
}
}
}

#[cfg(test)]
mod tests {
use base64::Engine;
use num_bigint::Sign;
use simple_asn1::der_encode;

use super::*;

#[test]
fn encode_oid() {
let expected = vec![0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70];
let asn1 = Ed25519PrivateKey::oid();
let der = simple_asn1::to_der(&asn1).unwrap();
assert_eq!(der, expected);
}

#[test]
fn encode_integer() {
let integer = Integer(BigInt::new(Sign::Plus, vec![5]));
Expand All @@ -283,22 +91,4 @@ mod tests {
let der = der_encode(&integer).unwrap();
assert_eq!(der, expected);
}

#[test]
fn encode_ed25519_private_key() {
let key = Ed25519PrivateKey {
public_key: BitString(vec![]),
private_key: OctetString(vec![
0xD4, 0xEE, 0x72, 0xDB, 0xF9, 0x13, 0x58, 0x4A, 0xD5, 0xB6, 0xD8, 0xF1, 0xF7, 0x69,
0xF8, 0xAD, 0x3A, 0xFE, 0x7C, 0x28, 0xCB, 0xF1, 0xD4, 0xFB, 0xE0, 0x97, 0xA8, 0x8F,
0x44, 0x75, 0x58, 0x42,
]),
};
let expected_b64 = "MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC";
let expected_key = base64::prelude::BASE64_STANDARD
.decode(expected_b64)
.unwrap();
let key_der = der_encode(&key).unwrap();
assert_eq!(key_der, expected_key);
}
}
2 changes: 1 addition & 1 deletion crates/jwk/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Error types for `ssi-jwk` crate
#[cfg(feature = "aleo")]
use crate::aleo::AleoGeneratePrivateKeyError;
use crate::okp::aleo::AleoGeneratePrivateKeyError;
use crate::JWK;
use base64::DecodeError as Base64Error;
#[cfg(feature = "ring")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ pub fn hash_public_key(jwk: &JWK) -> Result<String, Error> {
let curve = params.curve.as_ref().ok_or(Error::MissingCurve)?;
match &curve[..] {
"secp256k1" => {
bytes = crate::serialize_secp256k1(params)?;
bytes = crate::ec::k256::serialize_secp256k1(params)?;
(&TZ2_HASH, &bytes)
}
"P-256" => {
bytes = crate::serialize_p256(params)?;
bytes = crate::ec::p256::serialize_p256(params)?;
(&TZ3_HASH, &bytes)
}
_ => return Err(Error::CurveNotImplemented(curve.to_string())),
Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions crates/jwk/src/hash/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[cfg(feature = "ripemd-160")]
pub mod ripemd160;

#[cfg(feature = "eip")]
pub mod eip155;

#[cfg(feature = "tezos")]
pub mod blakesig;
File renamed without changes.
Loading