Skip to content

Commit f6998fc

Browse files
committed
fixup ecdsa signer implementation
Signed-off-by: Arthur Gautier <[email protected]>
1 parent 2972f78 commit f6998fc

File tree

6 files changed

+110
-9
lines changed

6 files changed

+110
-9
lines changed

Cargo.lock

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cryptoki-rustcrypto/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ p256 = { version = "0.13.2", features = ["pkcs8"] }
1919
p384 = { version = "0.13.0", features = ["pkcs8"] }
2020
k256 = { version = "0.13.2", features = ["pkcs8"] }
2121
rsa = "0.9.6"
22-
signature = { version = "2.2.0", features = ["digest"] }
22+
signature = { version = "2.2.0", features = ["derive", "digest"] }
2323
sha1 = { version = "0.10", features = ["oid"] }
2424
sha2 = { version = "0.10", features = ["oid"] }
2525
spki = "0.7.3"

cryptoki-rustcrypto/src/ecdsa.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ecdsa::{
1919
hazmat::DigestPrimitive,
2020
PrimeCurve, Signature, VerifyingKey,
2121
};
22-
use signature::digest::Digest;
22+
use signature::{digest::Digest, DigestSigner};
2323
use spki::{
2424
AlgorithmIdentifier, AlgorithmIdentifierRef, AssociatedAlgorithmIdentifier,
2525
SignatureAlgorithmIdentifier,
@@ -103,6 +103,7 @@ impl_sign_algorithm!(p256::NistP256);
103103
impl_sign_algorithm!(p384::NistP384);
104104
impl_sign_algorithm!(k256::Secp256k1);
105105

106+
#[derive(signature::Signer)]
106107
pub struct Signer<C: SignAlgorithm, S: SessionLike> {
107108
session: S,
108109
private_key: ObjectHandle,
@@ -177,12 +178,12 @@ impl<C: SignAlgorithm, S: SessionLike> signature::Keypair for Signer<C, S> {
177178
}
178179
}
179180

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

187188
let bytes = self
188189
.session
@@ -208,3 +209,18 @@ where
208209
const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> =
209210
Signature::<C>::ALGORITHM_IDENTIFIER;
210211
}
212+
213+
impl<C: SignAlgorithm, S: SessionLike> DigestSigner<C::Digest, ecdsa::der::Signature<C>>
214+
for Signer<C, S>
215+
where
216+
ecdsa::der::MaxSize<C>: ArrayLength<u8>,
217+
<FieldBytesSize<C> as Add>::Output: Add<ecdsa::der::MaxOverhead> + ArrayLength<u8>,
218+
Self: DigestSigner<C::Digest, Signature<C>>,
219+
{
220+
fn try_sign_digest(
221+
&self,
222+
digest: C::Digest,
223+
) -> Result<ecdsa::der::Signature<C>, signature::Error> {
224+
DigestSigner::<C::Digest, Signature<C>>::try_sign_digest(self, digest).map(Into::into)
225+
}
226+
}

cryptoki-rustcrypto/tests/ecdsa.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fn sign_verify() -> TestResult {
6565
let signer =
6666
ecdsa::Signer::<p256::NistP256, _>::new(&session, label).expect("Lookup keys from HSM");
6767

68-
let signature = signer.sign(&data);
68+
let signature: p256::ecdsa::Signature = signer.sign(&data);
6969

7070
let verifying_key = signer.verifying_key();
7171
verifying_key.verify(&data, &signature)?;

cryptoki-rustcrypto/tests/x509-ca.rs

+75-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ mod common;
55

66
use crate::common::USER_PIN;
77
use common::init_pins;
8-
use cryptoki::{mechanism::Mechanism, object::Attribute, session::UserType, types::AuthPin};
9-
use cryptoki_rustcrypto::rsa::pss;
10-
use der::{pem::LineEnding, EncodePem};
8+
use cryptoki::{
9+
mechanism::Mechanism,
10+
object::{Attribute, KeyType},
11+
session::UserType,
12+
types::AuthPin,
13+
};
14+
use cryptoki_rustcrypto::{ecdsa, rsa::pss};
15+
use der::{pem::LineEnding, Encode, EncodePem};
16+
use p256::pkcs8::AssociatedOid;
1117
use serial_test::serial;
1218
use signature::Keypair;
1319
use spki::SubjectPublicKeyInfoOwned;
@@ -80,3 +86,69 @@ fn pss_create_ca() -> TestResult {
8086

8187
Ok(())
8288
}
89+
90+
#[test]
91+
#[serial]
92+
fn ecdsa_create_ca() -> TestResult {
93+
let (pkcs11, slot) = init_pins();
94+
95+
// open a session
96+
let session = pkcs11.open_rw_session(slot)?;
97+
98+
// log in the session
99+
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;
100+
101+
// get mechanism
102+
let mechanism = Mechanism::EccKeyPairGen;
103+
104+
let secp256r1_oid: Vec<u8> = p256::NistP256::OID.to_der().unwrap();
105+
106+
let label = b"demo-signer";
107+
108+
// pub key template
109+
let pub_key_template = vec![
110+
Attribute::Token(true),
111+
Attribute::Private(false),
112+
Attribute::KeyType(KeyType::EC),
113+
Attribute::Verify(true),
114+
Attribute::EcParams(secp256r1_oid.clone()),
115+
Attribute::Label(label.to_vec()),
116+
];
117+
118+
// priv key template
119+
let priv_key_template = vec![
120+
Attribute::Token(true),
121+
Attribute::Private(true),
122+
Attribute::Sign(true),
123+
Attribute::Label(label.to_vec()),
124+
];
125+
126+
// generate a key pair
127+
let (public, private) =
128+
session.generate_key_pair(&mechanism, &pub_key_template, &priv_key_template)?;
129+
130+
let signer =
131+
ecdsa::Signer::<p256::NistP256, _>::new(&session, label).expect("Lookup keys from HSM");
132+
133+
let serial_number = SerialNumber::from(42u32);
134+
let validity = Validity::from_now(Duration::new(5, 0)).unwrap();
135+
let profile = Profile::Root;
136+
let subject =
137+
Name::from_str("CN=World domination corporation,O=World domination Inc,C=US").unwrap();
138+
let pub_key = SubjectPublicKeyInfoOwned::from_key(signer.verifying_key()).unwrap();
139+
140+
let builder =
141+
CertificateBuilder::new(profile, serial_number, validity, subject, pub_key, &signer)
142+
.expect("Create certificate");
143+
144+
let certificate = builder.build::<p256::ecdsa::DerSignature>().unwrap();
145+
146+
let pem = certificate.to_pem(LineEnding::LF).expect("generate pem");
147+
println!("{}", pem);
148+
149+
// delete keys
150+
session.destroy_object(public)?;
151+
session.destroy_object(private)?;
152+
153+
Ok(())
154+
}

cryptoki/tests/basic.rs

+1
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@ fn aes_key_attributes_test() -> TestResult {
752752
Attribute::Class(ObjectClass::SECRET_KEY),
753753
Attribute::Token(true),
754754
Attribute::Sensitive(true),
755+
Attribute::Value(vec![0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f]),
755756
Attribute::ValueLen(16.into()),
756757
Attribute::KeyType(KeyType::AES),
757758
Attribute::Label(b"testAES".to_vec()),

0 commit comments

Comments
 (0)