Skip to content

Commit 5254651

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

File tree

5 files changed

+109
-9
lines changed

5 files changed

+109
-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,
@@ -104,6 +104,7 @@ impl_sign_algorithm!(p256::NistP256);
104104
impl_sign_algorithm!(p384::NistP384);
105105
impl_sign_algorithm!(k256::Secp256k1);
106106

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

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

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

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+
}

0 commit comments

Comments
 (0)