Skip to content

Commit c3ea033

Browse files
sm2: support ASN.1 DER signature format for SM2DSA (#1358)
1 parent 5f27bb4 commit c3ea033

File tree

6 files changed

+376
-18
lines changed

6 files changed

+376
-18
lines changed

sm2/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ rfc6979 = { version = "0.5.0-rc.0", optional = true }
2828
serdect = { version = "0.3", optional = true, default-features = false }
2929
signature = { version = "3.0.0-rc.1", optional = true, features = ["rand_core"] }
3030
sm3 = { version = "0.5.0-rc.0", optional = true, default-features = false }
31+
der = { version = "0.8.0-rc.7", optional = true }
3132

3233
[dev-dependencies]
3334
hex-literal = "1"
@@ -44,7 +45,7 @@ bits = ["arithmetic", "elliptic-curve/bits"]
4445
dsa = ["arithmetic", "dep:rfc6979", "dep:signature", "dep:sm3"]
4546
pke = ["arithmetic", "dep:sm3"]
4647
pem = ["elliptic-curve/pem", "pkcs8"]
47-
pkcs8 = ["elliptic-curve/pkcs8"]
48+
pkcs8 = ["elliptic-curve/pkcs8", "der"]
4849
serde = ["elliptic-curve/serde", "primeorder?/serde", "serdect"]
4950

5051
[package.metadata.docs.rs]

sm2/src/dsa.rs

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,43 @@ mod signing;
3838
#[cfg(feature = "arithmetic")]
3939
mod verifying;
4040

41+
#[cfg(feature = "der")]
42+
mod der;
43+
44+
#[cfg(feature = "der")]
45+
pub use der::Signature as DerSignature;
46+
4147
pub use signature;
4248

4349
#[cfg(feature = "arithmetic")]
4450
pub use self::{signing::SigningKey, verifying::VerifyingKey};
4551

46-
use crate::{FieldBytes, NonZeroScalar, Sm2};
47-
use core::fmt::{self, Debug};
52+
use crate::{Array, FieldBytes, FieldBytesSize, NonZeroScalar, Sm2};
53+
use core::{
54+
fmt::{self, Debug},
55+
ops::Add,
56+
};
57+
4858
use signature::{Error, Result, SignatureEncoding};
4959

5060
#[cfg(feature = "alloc")]
5161
use alloc::vec::Vec;
5262

5363
#[cfg(feature = "pkcs8")]
5464
use crate::pkcs8::{
55-
AlgorithmIdentifierRef, ObjectIdentifier, der::AnyRef, spki::AssociatedAlgorithmIdentifier,
65+
AlgorithmIdentifierRef, ObjectIdentifier,
66+
der::{self as der_core, AnyRef, asn1::BitString},
67+
spki::AssociatedAlgorithmIdentifier,
5668
};
69+
5770
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
58-
use crate::pkcs8::{der, spki::SignatureBitStringEncoding};
71+
use crate::pkcs8::spki::SignatureBitStringEncoding;
5972

60-
/// SM2DSA signature serialized as bytes.
61-
pub type SignatureBytes = [u8; Signature::BYTE_SIZE];
73+
/// SM2DSA signature size.
74+
pub type SignatureSize = <FieldBytesSize as Add>::Output;
75+
76+
/// SM2DSA signature bytes.
77+
pub type SignatureBytes = Array<u8, SignatureSize>;
6278

6379
/// Primitive scalar type (works without the `arithmetic` feature).
6480
type ScalarPrimitive = elliptic_curve::ScalarPrimitive<Sm2>;
@@ -101,9 +117,15 @@ impl Signature {
101117
Self::try_from(r.into().concat(s.into()).as_slice())
102118
}
103119

120+
/// Parse a signature from ASN.1 DER.
121+
#[cfg(feature = "der")]
122+
pub fn from_der(bytes: &[u8]) -> Result<Self> {
123+
DerSignature::try_from(bytes).and_then(Self::try_from)
124+
}
125+
104126
/// Serialize this signature as bytes.
105127
pub fn to_bytes(&self) -> SignatureBytes {
106-
let mut ret = [0; Self::BYTE_SIZE];
128+
let mut ret = SignatureBytes::default();
107129
let (r_bytes, s_bytes) = ret.split_at_mut(Self::BYTE_SIZE / 2);
108130
r_bytes.copy_from_slice(&self.r.to_bytes());
109131
s_bytes.copy_from_slice(&self.s.to_bytes());
@@ -120,6 +142,12 @@ impl Signature {
120142
self.s.to_bytes()
121143
}
122144

145+
/// Serialize this signature as ASN.1 DER.
146+
#[cfg(feature = "der")]
147+
pub fn to_der(&self) -> DerSignature {
148+
DerSignature::from_components(&self.r_bytes(), &self.s_bytes()).expect("DER encoding error")
149+
}
150+
123151
/// Convert this signature into a byte vector.
124152
#[cfg(feature = "alloc")]
125153
pub fn to_vec(&self) -> Vec<u8> {
@@ -207,8 +235,8 @@ impl TryFrom<&[u8]> for Signature {
207235

208236
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
209237
impl SignatureBitStringEncoding for Signature {
210-
fn to_bitstring(&self) -> der::Result<der::asn1::BitString> {
211-
der::asn1::BitString::new(0, self.to_vec())
238+
fn to_bitstring(&self) -> der_core::Result<BitString> {
239+
BitString::new(0, self.to_vec())
212240
}
213241
}
214242

0 commit comments

Comments
 (0)