1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use generic_array::typenum::Unsigned;
use p256::{
ecdsa::signature::{RandomizedSigner, Signature},
elliptic_curve,
};
use tink_core::{utils::wrap_err, TinkError};
use tink_proto::{EcdsaSignatureEncoding, EllipticCurveType, HashType};
pub enum EcdsaPrivateKey {
NistP256(p256::ecdsa::SigningKey),
}
impl Clone for EcdsaPrivateKey {
fn clone(&self) -> Self {
match self {
EcdsaPrivateKey::NistP256(k) => {
EcdsaPrivateKey::NistP256(
p256::ecdsa::SigningKey::from_bytes(&k.to_bytes()).unwrap(),
)
}
}
}
}
#[derive(Clone)]
pub struct EcdsaSigner {
private_key: EcdsaPrivateKey,
encoding: super::SignatureEncoding,
}
impl EcdsaSigner {
pub fn new(
hash_alg: HashType,
curve: EllipticCurveType,
encoding: EcdsaSignatureEncoding,
key_value: &[u8],
) -> Result<Self, TinkError> {
let priv_key = match curve {
EllipticCurveType::NistP256 => {
if key_value.len()
!= <p256::NistP256 as elliptic_curve::Curve>::FieldSize::to_usize()
{
return Err("EcdsaSigner: invalid private key len".into());
}
EcdsaPrivateKey::NistP256(
p256::ecdsa::SigningKey::from_bytes(key_value)
.map_err(|e| wrap_err("EcdsaSigner: invalid private key", e))?,
)
}
_ => return Err(format!("EcdsaSigner: unsupported curve {:?}", curve).into()),
};
Self::new_from_private_key(hash_alg, curve, encoding, priv_key)
}
pub fn new_from_private_key(
hash_alg: HashType,
curve: EllipticCurveType,
encoding: EcdsaSignatureEncoding,
private_key: EcdsaPrivateKey,
) -> Result<Self, TinkError> {
let encoding = super::ecdsa_common::validate_ecdsa_params(hash_alg, curve, encoding)
.map_err(|e| wrap_err("EcdsaSigner", e))?;
Ok(EcdsaSigner {
private_key,
encoding,
})
}
}
impl tink_core::Signer for EcdsaSigner {
fn sign(&self, data: &[u8]) -> Result<Vec<u8>, tink_core::TinkError> {
let mut csprng = rand::rngs::OsRng {};
match &self.private_key {
EcdsaPrivateKey::NistP256(secret_key) => match self.encoding {
super::SignatureEncoding::Der => {
let signature = secret_key.sign_with_rng(&mut csprng, data).to_asn1();
Ok(signature.as_bytes().to_vec())
}
super::SignatureEncoding::IeeeP1363 => {
let signature = secret_key.sign_with_rng(&mut csprng, data);
Ok(signature.as_bytes().to_vec())
}
},
}
}
}