Skip to content

Commit

Permalink
fixup ecdsa signer implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Gautier <[email protected]>
  • Loading branch information
baloo committed Jan 2, 2024
1 parent 2972f78 commit f6998fc
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 9 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cryptoki-rustcrypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ p256 = { version = "0.13.2", features = ["pkcs8"] }
p384 = { version = "0.13.0", features = ["pkcs8"] }
k256 = { version = "0.13.2", features = ["pkcs8"] }
rsa = "0.9.6"
signature = { version = "2.2.0", features = ["digest"] }
signature = { version = "2.2.0", features = ["derive", "digest"] }
sha1 = { version = "0.10", features = ["oid"] }
sha2 = { version = "0.10", features = ["oid"] }
spki = "0.7.3"
Expand Down
24 changes: 20 additions & 4 deletions cryptoki-rustcrypto/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use ecdsa::{
hazmat::DigestPrimitive,
PrimeCurve, Signature, VerifyingKey,
};
use signature::digest::Digest;
use signature::{digest::Digest, DigestSigner};
use spki::{
AlgorithmIdentifier, AlgorithmIdentifierRef, AssociatedAlgorithmIdentifier,
SignatureAlgorithmIdentifier,
Expand Down Expand Up @@ -103,6 +103,7 @@ impl_sign_algorithm!(p256::NistP256);
impl_sign_algorithm!(p384::NistP384);
impl_sign_algorithm!(k256::Secp256k1);

#[derive(signature::Signer)]
pub struct Signer<C: SignAlgorithm, S: SessionLike> {
session: S,
private_key: ObjectHandle,
Expand Down Expand Up @@ -177,12 +178,12 @@ impl<C: SignAlgorithm, S: SessionLike> signature::Keypair for Signer<C, S> {
}
}

impl<C: SignAlgorithm, S: SessionLike> signature::Signer<Signature<C>> for Signer<C, S>
impl<C: SignAlgorithm, S: SessionLike> DigestSigner<C::Digest, Signature<C>> for Signer<C, S>
where
<<C as ecdsa::elliptic_curve::Curve>::FieldBytesSize as Add>::Output: ArrayLength<u8>,
{
fn try_sign(&self, msg: &[u8]) -> Result<Signature<C>, signature::Error> {
let msg = C::Digest::digest(msg);
fn try_sign_digest(&self, digest: C::Digest) -> Result<Signature<C>, signature::Error> {
let msg = digest.finalize();

let bytes = self
.session
Expand All @@ -208,3 +209,18 @@ where
const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> =
Signature::<C>::ALGORITHM_IDENTIFIER;
}

impl<C: SignAlgorithm, S: SessionLike> DigestSigner<C::Digest, ecdsa::der::Signature<C>>
for Signer<C, S>
where
ecdsa::der::MaxSize<C>: ArrayLength<u8>,
<FieldBytesSize<C> as Add>::Output: Add<ecdsa::der::MaxOverhead> + ArrayLength<u8>,
Self: DigestSigner<C::Digest, Signature<C>>,
{
fn try_sign_digest(
&self,
digest: C::Digest,
) -> Result<ecdsa::der::Signature<C>, signature::Error> {
DigestSigner::<C::Digest, Signature<C>>::try_sign_digest(self, digest).map(Into::into)
}
}
2 changes: 1 addition & 1 deletion cryptoki-rustcrypto/tests/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn sign_verify() -> TestResult {
let signer =
ecdsa::Signer::<p256::NistP256, _>::new(&session, label).expect("Lookup keys from HSM");

let signature = signer.sign(&data);
let signature: p256::ecdsa::Signature = signer.sign(&data);

let verifying_key = signer.verifying_key();
verifying_key.verify(&data, &signature)?;
Expand Down
78 changes: 75 additions & 3 deletions cryptoki-rustcrypto/tests/x509-ca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ mod common;

use crate::common::USER_PIN;
use common::init_pins;
use cryptoki::{mechanism::Mechanism, object::Attribute, session::UserType, types::AuthPin};
use cryptoki_rustcrypto::rsa::pss;
use der::{pem::LineEnding, EncodePem};
use cryptoki::{
mechanism::Mechanism,
object::{Attribute, KeyType},
session::UserType,
types::AuthPin,
};
use cryptoki_rustcrypto::{ecdsa, rsa::pss};
use der::{pem::LineEnding, Encode, EncodePem};
use p256::pkcs8::AssociatedOid;
use serial_test::serial;
use signature::Keypair;
use spki::SubjectPublicKeyInfoOwned;
Expand Down Expand Up @@ -80,3 +86,69 @@ fn pss_create_ca() -> TestResult {

Ok(())
}

#[test]
#[serial]
fn ecdsa_create_ca() -> TestResult {
let (pkcs11, slot) = init_pins();

// open a session
let session = pkcs11.open_rw_session(slot)?;

// log in the session
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;

// get mechanism
let mechanism = Mechanism::EccKeyPairGen;

let secp256r1_oid: Vec<u8> = p256::NistP256::OID.to_der().unwrap();

let label = b"demo-signer";

// pub key template
let pub_key_template = vec![
Attribute::Token(true),
Attribute::Private(false),
Attribute::KeyType(KeyType::EC),
Attribute::Verify(true),
Attribute::EcParams(secp256r1_oid.clone()),
Attribute::Label(label.to_vec()),
];

// priv key template
let priv_key_template = vec![
Attribute::Token(true),
Attribute::Private(true),
Attribute::Sign(true),
Attribute::Label(label.to_vec()),
];

// generate a key pair
let (public, private) =
session.generate_key_pair(&mechanism, &pub_key_template, &priv_key_template)?;

let signer =
ecdsa::Signer::<p256::NistP256, _>::new(&session, label).expect("Lookup keys from HSM");

let serial_number = SerialNumber::from(42u32);
let validity = Validity::from_now(Duration::new(5, 0)).unwrap();
let profile = Profile::Root;
let subject =
Name::from_str("CN=World domination corporation,O=World domination Inc,C=US").unwrap();
let pub_key = SubjectPublicKeyInfoOwned::from_key(signer.verifying_key()).unwrap();

let builder =
CertificateBuilder::new(profile, serial_number, validity, subject, pub_key, &signer)
.expect("Create certificate");

let certificate = builder.build::<p256::ecdsa::DerSignature>().unwrap();

let pem = certificate.to_pem(LineEnding::LF).expect("generate pem");
println!("{}", pem);

// delete keys
session.destroy_object(public)?;
session.destroy_object(private)?;

Ok(())
}
1 change: 1 addition & 0 deletions cryptoki/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ fn aes_key_attributes_test() -> TestResult {
Attribute::Class(ObjectClass::SECRET_KEY),
Attribute::Token(true),
Attribute::Sensitive(true),
Attribute::Value(vec![0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]),
Attribute::ValueLen(16.into()),
Attribute::KeyType(KeyType::AES),
Attribute::Label(b"testAES".to_vec()),
Expand Down

0 comments on commit f6998fc

Please sign in to comment.