Skip to content

Commit b7b51cd

Browse files
definitelynobodynpmccallum
authored andcommitted
feat(chore): add EcdsaPubKey and EcdsaP256Sig types
Signed-off-by: Nicholas Farshidmehr <[email protected]>
1 parent ee2f062 commit b7b51cd

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ rcrypto = ["rand", "rsa", "sha2", "num-integer", "num-traits"]
2828
x86_64 = { version = "^0.14.6", default-features = false }
2929
xsave = { version = "^2.0.0", default-features = false }
3030
openssl = { version = "^0.10.36", optional = true }
31+
der = { version = "0.6.0-pre.3", features = ["derive"], optional = false }
3132
bitflags = "^1.3.2"
3233

3334
# Used by the rcrypto feature (see above).

src/crypto/mod.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub mod openssl;
1111
#[cfg(feature = "rcrypto")]
1212
pub mod rcrypto;
1313

14+
use der::{asn1::UIntBytes, Encodable, Sequence};
15+
1416
/// A fixed-size hash
1517
pub trait Digest: Sized {
1618
type Output: AsRef<[u8]>;
@@ -45,6 +47,58 @@ pub struct SigData {
4547
pub q2: [u8; 384],
4648
}
4749

50+
/// EC KT-I Public Key, the x-coordinate followed by
51+
/// the y-coordinate (on the RFC 6090P-256 curve),
52+
/// 2 x 32 bytes.
53+
/// A.4, Table 7
54+
#[derive(Clone, Debug)]
55+
#[repr(C)]
56+
pub struct EcdsaPubKey {
57+
pub x: [u8; 32],
58+
pub y: [u8; 32],
59+
}
60+
61+
/// ECDSA signature, the r component followed by the
62+
/// s component, 2 x 32 bytes.
63+
/// A.4, Table 6
64+
#[derive(Clone, Debug)]
65+
#[repr(C)]
66+
pub struct EcdsaP256Sig {
67+
pub r: [u8; 32],
68+
pub s: [u8; 32],
69+
}
70+
71+
impl EcdsaP256Sig {
72+
// The size of the buffer the DER encoded signature will occupy.
73+
const DER_ENCODED_LEN: usize = 72;
74+
75+
/// Converts the concatenated signature to a DER signature.
76+
///
77+
/// Returns the buffer containing the DER and its length.
78+
pub fn to_der(&self) -> Result<([u8; Self::DER_ENCODED_LEN], usize), der::Error> {
79+
/// ECDSA-Sig-Value ::= SEQUENCE {
80+
/// r INTEGER,
81+
/// s INTEGER
82+
/// }
83+
#[derive(Clone, Debug, Sequence)]
84+
struct EcdsaSig<'a> {
85+
r: UIntBytes<'a>,
86+
s: UIntBytes<'a>,
87+
}
88+
89+
let es = EcdsaSig {
90+
r: UIntBytes::new(&self.r)?,
91+
s: UIntBytes::new(&self.s)?,
92+
};
93+
94+
let mut buffer = [0; Self::DER_ENCODED_LEN];
95+
let mut encoder = der::Encoder::new(&mut buffer);
96+
es.encode(&mut encoder)?;
97+
let len = encoder.finish()?.len();
98+
Ok((buffer, len))
99+
}
100+
}
101+
48102
#[cfg(test)]
49103
#[allow(dead_code)]
50104
fn selftest<K: PrivateKey, D: Digest<Output = [u8; 32]>>() {

0 commit comments

Comments
 (0)