From 18dfc9b6b2509be30a5905b42b6477b9eaf054e2 Mon Sep 17 00:00:00 2001 From: Mike Belopuhov Date: Fri, 28 Sep 2018 14:43:33 +0200 Subject: [PATCH] Add support for encoding and decoding ECDSA signatures --- openssl-sys/src/ec.rs | 8 ++++++++ openssl/src/ecdsa.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/openssl-sys/src/ec.rs b/openssl-sys/src/ec.rs index a33d4d46..d422997a 100644 --- a/openssl-sys/src/ec.rs +++ b/openssl-sys/src/ec.rs @@ -200,4 +200,12 @@ extern "C" { sig: *const ECDSA_SIG, eckey: *mut EC_KEY, ) -> c_int; + + pub fn d2i_ECDSA_SIG( + sig: *mut *mut ECDSA_SIG, + inp: *mut *const c_uchar, + length: c_long, + ) -> *mut ECDSA_SIG; + + pub fn i2d_ECDSA_SIG(sig: *const ECDSA_SIG, out: *mut *mut c_uchar) -> c_int; } diff --git a/openssl/src/ecdsa.rs b/openssl/src/ecdsa.rs index 86b42677..ac65c06c 100644 --- a/openssl/src/ecdsa.rs +++ b/openssl/src/ecdsa.rs @@ -102,6 +102,25 @@ impl EcdsaSig { BigNumRef::from_ptr(s as *mut _) } } + + from_der! { + /// Decodes a DER-encoded ECDSA signature. + /// + /// This corresponds to [`d2i_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_ECDSA_SIG.html + from_der, + EcdsaSig, + ffi::d2i_ECDSA_SIG + } +} + +impl EcdsaSigRef { + to_der! { + /// Serializes the ECDSA signature into a DER-encoded ECDSASignature structure. + /// + /// This corresponds to [`i2d_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_ECDSA_SIG.html + to_der, + ffi::i2d_ECDSA_SIG + } } cfg_if! { @@ -194,4 +213,21 @@ mod test { let verification2 = res2.verify(data.as_bytes(), &public_key).unwrap(); assert!(verification2); } + + #[test] + #[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)] + fn serialize_deserialize() { + let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap(); + let private_key = EcKey::generate(&group).unwrap(); + let public_key = get_public_key(&group, &private_key).unwrap(); + + let data = String::from("hello"); + let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap(); + + let der = res.to_der().unwrap(); + let sig = EcdsaSig::from_der(&der).unwrap(); + + let verification = sig.verify(data.as_bytes(), &public_key).unwrap(); + assert!(verification); + } }