1use foreign_types::{ForeignType, ForeignTypeRef};
4use libc::c_int;
5use std::fmt;
6use std::mem;
7use std::ptr;
8
9use crate::bn::{BigNum, BigNumRef};
10use crate::ec::EcKeyRef;
11use crate::error::ErrorStack;
12use crate::pkey::{HasPrivate, HasPublic};
13use crate::util::ForeignTypeRefExt;
14use crate::{cvt_n, cvt_p, LenType};
15use openssl_macros::corresponds;
16
17foreign_type_and_impl_send_sync! {
18 type CType = ffi::ECDSA_SIG;
19 fn drop = ffi::ECDSA_SIG_free;
20
21 pub struct EcdsaSig;
23 pub struct EcdsaSigRef;
25}
26
27impl EcdsaSig {
28 #[corresponds(ECDSA_do_sign)]
30 pub fn sign<T>(data: &[u8], eckey: &EcKeyRef<T>) -> Result<EcdsaSig, ErrorStack>
31 where
32 T: HasPrivate,
33 {
34 unsafe {
35 assert!(data.len() <= c_int::MAX as usize);
36 let sig = cvt_p(ffi::ECDSA_do_sign(
37 data.as_ptr(),
38 data.len() as LenType,
39 eckey.as_ptr(),
40 ))?;
41 Ok(EcdsaSig::from_ptr(sig))
42 }
43 }
44
45 #[corresponds(ECDSA_SIG_set0)]
47 pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> {
48 unsafe {
49 let sig = cvt_p(ffi::ECDSA_SIG_new())?;
50 ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
51 mem::forget((r, s));
52 Ok(EcdsaSig::from_ptr(sig))
53 }
54 }
55
56 from_der! {
57 #[corresponds(d2i_ECDSA_SIG)]
59 from_der,
60 EcdsaSig,
61 ffi::d2i_ECDSA_SIG
62 }
63}
64
65impl fmt::Debug for EcdsaSig {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_struct("EcdsaSig")
68 .field("r", &self.r())
69 .field("s", &self.s())
70 .finish()
71 }
72}
73
74impl EcdsaSigRef {
75 to_der! {
76 #[corresponds(i2d_ECDSA_SIG)]
78 to_der,
79 ffi::i2d_ECDSA_SIG
80 }
81
82 #[corresponds(ECDSA_do_verify)]
84 pub fn verify<T>(&self, data: &[u8], eckey: &EcKeyRef<T>) -> Result<bool, ErrorStack>
85 where
86 T: HasPublic,
87 {
88 unsafe {
89 assert!(data.len() <= c_int::MAX as usize);
90 cvt_n(ffi::ECDSA_do_verify(
91 data.as_ptr(),
92 data.len() as LenType,
93 self.as_ptr(),
94 eckey.as_ptr(),
95 ))
96 .map(|x| x == 1)
97 }
98 }
99
100 #[corresponds(ECDSA_SIG_get0)]
102 pub fn r(&self) -> &BigNumRef {
103 unsafe {
104 let mut r = ptr::null();
105 ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
106 BigNumRef::from_const_ptr(r)
107 }
108 }
109
110 #[corresponds(ECDSA_SIG_get0)]
112 pub fn s(&self) -> &BigNumRef {
113 unsafe {
114 let mut s = ptr::null();
115 ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
116 BigNumRef::from_const_ptr(s)
117 }
118 }
119}
120
121impl fmt::Debug for EcdsaSigRef {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 f.debug_struct("EcdsaSig")
124 .field("r", &self.r())
125 .field("s", &self.s())
126 .finish()
127 }
128}
129
130use ffi::{ECDSA_SIG_get0, ECDSA_SIG_set0};
131
132#[cfg(test)]
133mod test {
134 use super::*;
135 use crate::ec::EcGroup;
136 use crate::ec::EcKey;
137 use crate::nid::Nid;
138 use crate::pkey::{Private, Public};
139
140 fn get_public_key(group: &EcGroup, x: &EcKey<Private>) -> Result<EcKey<Public>, ErrorStack> {
141 EcKey::from_public_key(group, x.public_key())
142 }
143
144 #[test]
145 #[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)]
146 fn sign_and_verify() {
147 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
148 let private_key = EcKey::generate(&group).unwrap();
149 let public_key = get_public_key(&group, &private_key).unwrap();
150
151 let private_key2 = EcKey::generate(&group).unwrap();
152 let public_key2 = get_public_key(&group, &private_key2).unwrap();
153
154 let data = String::from("hello");
155 let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
156
157 let verification = res.verify(data.as_bytes(), &public_key).unwrap();
159 assert!(verification);
160
161 let verification2 = res
163 .verify(String::from("hello2").as_bytes(), &public_key)
164 .unwrap();
165 assert!(!verification2);
166
167 let verification3 = res.verify(data.as_bytes(), &public_key2).unwrap();
169 assert!(!verification3);
170 }
171
172 #[test]
173 #[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)]
174 fn check_private_components() {
175 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
176 let private_key = EcKey::generate(&group).unwrap();
177 let public_key = get_public_key(&group, &private_key).unwrap();
178 let data = String::from("hello");
179 let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
180
181 let verification = res.verify(data.as_bytes(), &public_key).unwrap();
182 assert!(verification);
183
184 let r = res.r().to_owned().unwrap();
185 let s = res.s().to_owned().unwrap();
186
187 let res2 = EcdsaSig::from_private_components(r, s).unwrap();
188 let verification2 = res2.verify(data.as_bytes(), &public_key).unwrap();
189 assert!(verification2);
190 }
191
192 #[test]
193 #[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)]
194 fn serialize_deserialize() {
195 let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
196 let private_key = EcKey::generate(&group).unwrap();
197 let public_key = get_public_key(&group, &private_key).unwrap();
198
199 let data = String::from("hello");
200 let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap();
201
202 let der = res.to_der().unwrap();
203 let sig = EcdsaSig::from_der(&der).unwrap();
204
205 let verification = sig.verify(data.as_bytes(), &public_key).unwrap();
206 assert!(verification);
207 }
208}