@@ -56,6 +56,7 @@ use std::ptr;
56
56
use crate :: error:: ErrorStack ;
57
57
use crate :: pkey:: { HasPrivate , HasPublic , PKeyRef } ;
58
58
use crate :: { cvt, cvt_p} ;
59
+ use openssl_macros:: corresponds;
59
60
60
61
/// A type used to derive a shared secret between two keys.
61
62
pub struct Deriver < ' a > ( * mut ffi:: EVP_PKEY_CTX , PhantomData < & ' a ( ) > ) ;
@@ -82,17 +83,37 @@ impl<'a> Deriver<'a> {
82
83
}
83
84
84
85
/// Sets the peer key used for secret derivation.
85
- ///
86
- /// This corresponds to [`EVP_PKEY_derive_set_peer`]:
87
- ///
88
- /// [`EVP_PKEY_derive_set_peer`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_derive_init.html
86
+ #[ corresponds( EVP_PKEY_derive_set_peer ) ]
89
87
pub fn set_peer < T > ( & mut self , key : & ' a PKeyRef < T > ) -> Result < ( ) , ErrorStack >
90
88
where
91
89
T : HasPublic ,
92
90
{
93
91
unsafe { cvt ( ffi:: EVP_PKEY_derive_set_peer ( self . 0 , key. as_ptr ( ) ) ) . map ( |_| ( ) ) }
94
92
}
95
93
94
+ /// Sets the peer key used for secret derivation along with optionally validating the peer public key.
95
+ ///
96
+ /// Requires OpenSSL 3.0.0 or newer.
97
+ #[ corresponds( EVP_PKEY_derive_set_peer_ex ) ]
98
+ #[ cfg( ossl300) ]
99
+ pub fn set_peer_ex < T > (
100
+ & mut self ,
101
+ key : & ' a PKeyRef < T > ,
102
+ validate_peer : bool ,
103
+ ) -> Result < ( ) , ErrorStack >
104
+ where
105
+ T : HasPublic ,
106
+ {
107
+ unsafe {
108
+ cvt ( ffi:: EVP_PKEY_derive_set_peer_ex (
109
+ self . 0 ,
110
+ key. as_ptr ( ) ,
111
+ validate_peer as i32 ,
112
+ ) )
113
+ . map ( |_| ( ) )
114
+ }
115
+ }
116
+
96
117
/// Returns the size of the shared secret.
97
118
///
98
119
/// It can be used to size the buffer passed to [`Deriver::derive`].
@@ -179,4 +200,18 @@ mod test {
179
200
let shared = deriver. derive_to_vec ( ) . unwrap ( ) ;
180
201
assert ! ( !shared. is_empty( ) ) ;
181
202
}
203
+
204
+ #[ test]
205
+ #[ cfg( ossl300) ]
206
+ fn test_ec_key_derive_ex ( ) {
207
+ let group = EcGroup :: from_curve_name ( Nid :: X9_62_PRIME256V1 ) . unwrap ( ) ;
208
+ let ec_key = EcKey :: generate ( & group) . unwrap ( ) ;
209
+ let ec_key2 = EcKey :: generate ( & group) . unwrap ( ) ;
210
+ let pkey = PKey :: from_ec_key ( ec_key) . unwrap ( ) ;
211
+ let pkey2 = PKey :: from_ec_key ( ec_key2) . unwrap ( ) ;
212
+ let mut deriver = Deriver :: new ( & pkey) . unwrap ( ) ;
213
+ deriver. set_peer_ex ( & pkey2, true ) . unwrap ( ) ;
214
+ let shared = deriver. derive_to_vec ( ) . unwrap ( ) ;
215
+ assert ! ( !shared. is_empty( ) ) ;
216
+ }
182
217
}
0 commit comments