1use crate::bio::{MemBio, MemBioBuf};
14use crate::error::ErrorStack;
15use native_ossl_sys as sys;
16use std::marker::PhantomData;
17use std::sync::Arc;
18
19pub struct Public;
23pub struct Private;
25pub struct Params;
27
28mod sealed {
29 pub trait HasParams {}
31 impl HasParams for super::Public {}
32 impl HasParams for super::Private {}
33 impl HasParams for super::Params {}
34
35 pub trait HasPublic: HasParams {}
37 impl HasPublic for super::Public {}
38 impl HasPublic for super::Private {}
39
40 pub trait HasPrivate: HasPublic {}
42 impl HasPrivate for super::Private {}
43}
44
45pub trait HasParams: sealed::HasParams {}
47impl<T: sealed::HasParams> HasParams for T {}
48
49pub trait HasPublic: sealed::HasPublic {}
51impl<T: sealed::HasPublic> HasPublic for T {}
52
53pub trait HasPrivate: sealed::HasPrivate {}
55impl<T: sealed::HasPrivate> HasPrivate for T {}
56
57pub struct Pkey<T> {
63 ptr: *mut sys::EVP_PKEY,
64 _role: PhantomData<T>,
65}
66
67unsafe impl<T> Send for Pkey<T> {}
69unsafe impl<T> Sync for Pkey<T> {}
70
71impl<T> Clone for Pkey<T> {
72 fn clone(&self) -> Self {
73 unsafe { sys::EVP_PKEY_up_ref(self.ptr) };
74 Pkey {
75 ptr: self.ptr,
76 _role: PhantomData,
77 }
78 }
79}
80
81impl<T> Drop for Pkey<T> {
82 fn drop(&mut self) {
83 unsafe { sys::EVP_PKEY_free(self.ptr) };
84 }
85}
86
87impl<T: HasParams> Pkey<T> {
88 #[must_use]
94 pub unsafe fn from_ptr(ptr: *mut sys::EVP_PKEY) -> Self {
95 Pkey {
96 ptr,
97 _role: PhantomData,
98 }
99 }
100
101 #[must_use]
103 pub fn as_ptr(&self) -> *mut sys::EVP_PKEY {
104 self.ptr
105 }
106
107 #[must_use]
109 pub fn bits(&self) -> u32 {
110 u32::try_from(unsafe { sys::EVP_PKEY_get_bits(self.ptr) }).unwrap_or(0)
111 }
112
113 #[must_use]
115 pub fn security_bits(&self) -> u32 {
116 u32::try_from(unsafe { sys::EVP_PKEY_get_security_bits(self.ptr) }).unwrap_or(0)
117 }
118
119 #[must_use]
121 pub fn is_a(&self, name: &std::ffi::CStr) -> bool {
122 unsafe { sys::EVP_PKEY_is_a(self.ptr, name.as_ptr()) == 1 }
123 }
124
125 #[must_use]
130 pub fn public_eq<U: HasPublic>(&self, other: &Pkey<U>) -> bool
131 where
132 T: HasPublic,
133 {
134 unsafe { sys::EVP_PKEY_eq(self.ptr, other.ptr) == 1 }
135 }
136
137 pub fn get_params(&self, params: &mut crate::params::Params<'_>) -> Result<(), ErrorStack> {
144 crate::ossl_call!(sys::EVP_PKEY_get_params(self.ptr, params.as_mut_ptr()))
145 }
146
147 pub fn public_key_to_der(&self) -> Result<Vec<u8>, ErrorStack>
156 where
157 T: HasPublic,
158 {
159 let len = unsafe { sys::i2d_PUBKEY(self.ptr, std::ptr::null_mut()) };
161 if len < 0 {
162 return Err(ErrorStack::drain());
163 }
164 let mut buf = vec![0u8; usize::try_from(len).unwrap_or(0)];
167 let mut out_ptr = buf.as_mut_ptr();
168 let written = unsafe { sys::i2d_PUBKEY(self.ptr, std::ptr::addr_of_mut!(out_ptr)) };
169 if written < 0 {
170 return Err(ErrorStack::drain());
171 }
172 buf.truncate(usize::try_from(written).unwrap_or(0));
173 Ok(buf)
174 }
175}
176
177impl Pkey<Private> {
180 #[cfg(feature = "fips-provider")]
197 pub unsafe fn keydata(&self) -> *mut std::ffi::c_void {
198 self.ptr
202 .cast::<u8>()
203 .add(native_ossl_sys::fips_internal::EVP_PKEY_KEYDATA_OFFSET)
204 .cast::<*mut std::ffi::c_void>()
205 .read()
206 }
207
208 pub fn from_pem(pem: &[u8]) -> Result<Self, ErrorStack> {
214 let bio = MemBioBuf::new(pem)?;
215 let ptr = unsafe {
216 sys::PEM_read_bio_PrivateKey(
217 bio.as_ptr(),
218 std::ptr::null_mut(),
219 None,
220 std::ptr::null_mut(),
221 )
222 };
223 if ptr.is_null() {
224 return Err(ErrorStack::drain());
225 }
226 Ok(unsafe { Pkey::from_ptr(ptr) })
227 }
228
229 pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
233 let mut bio = MemBio::new()?;
234 let rc = unsafe {
235 sys::PEM_write_bio_PrivateKey(
236 bio.as_ptr(),
237 self.ptr,
238 std::ptr::null(),
239 std::ptr::null_mut(),
240 0,
241 None,
242 std::ptr::null_mut(),
243 )
244 };
245 if rc != 1 {
246 return Err(ErrorStack::drain());
247 }
248 Ok(bio.into_vec())
249 }
250
251 pub fn from_pem_in(ctx: &Arc<crate::lib_ctx::LibCtx>, pem: &[u8]) -> Result<Self, ErrorStack> {
259 let bio = MemBioBuf::new(pem)?;
260 let ptr = unsafe {
261 sys::PEM_read_bio_PrivateKey_ex(
262 bio.as_ptr(),
263 std::ptr::null_mut(),
264 None,
265 std::ptr::null_mut(),
266 ctx.as_ptr(),
267 std::ptr::null(),
268 )
269 };
270 if ptr.is_null() {
271 return Err(ErrorStack::drain());
272 }
273 Ok(unsafe { Pkey::from_ptr(ptr) })
274 }
275
276 pub fn from_der(der: &[u8]) -> Result<Self, ErrorStack> {
282 let bio = MemBioBuf::new(der)?;
283 let ptr = unsafe { sys::d2i_PrivateKey_bio(bio.as_ptr(), std::ptr::null_mut()) };
284 if ptr.is_null() {
285 return Err(ErrorStack::drain());
286 }
287 Ok(unsafe { Pkey::from_ptr(ptr) })
288 }
289
290 pub fn from_pem_passphrase(pem: &[u8], passphrase: &[u8]) -> Result<Self, ErrorStack> {
298 extern "C" fn passwd_cb(
299 buf: *mut std::ffi::c_char,
300 size: std::ffi::c_int,
301 _rwflag: std::ffi::c_int,
302 u: *mut std::ffi::c_void,
303 ) -> std::ffi::c_int {
304 let pw: &[u8] = unsafe { *(u as *const &[u8]) };
306 let max_len = usize::try_from(size).unwrap_or(0);
308 let n = pw.len().min(max_len);
309 unsafe { std::ptr::copy_nonoverlapping(pw.as_ptr(), buf.cast::<u8>(), n) };
310 i32::try_from(n).unwrap()
312 }
313 let bio = MemBioBuf::new(pem)?;
314 let pw: &[u8] = passphrase;
315 let ptr = unsafe {
316 sys::PEM_read_bio_PrivateKey(
317 bio.as_ptr(),
318 std::ptr::null_mut(),
319 Some(passwd_cb),
320 std::ptr::addr_of!(pw).cast::<std::ffi::c_void>().cast_mut(),
321 )
322 };
323 if ptr.is_null() {
324 return Err(ErrorStack::drain());
325 }
326 Ok(unsafe { Pkey::from_ptr(ptr) })
327 }
328
329 pub fn to_pem_encrypted(
342 &self,
343 cipher: &crate::cipher::CipherAlg,
344 passphrase: &[u8],
345 ) -> Result<Vec<u8>, ErrorStack> {
346 let mut bio = MemBio::new()?;
347 let rc = unsafe {
348 sys::PEM_write_bio_PKCS8PrivateKey(
349 bio.as_ptr(),
350 self.ptr,
351 cipher.as_ptr(),
352 passphrase.as_ptr().cast(),
353 i32::try_from(passphrase.len()).expect("passphrase too long"),
354 None,
355 std::ptr::null_mut(),
356 )
357 };
358 if rc != 1 {
359 return Err(ErrorStack::drain());
360 }
361 Ok(bio.into_vec())
362 }
363
364 pub fn to_pkcs8_der(&self) -> Result<Vec<u8>, ErrorStack> {
373 let mut bio = MemBio::new()?;
374 let rc = unsafe { sys::i2d_PKCS8PrivateKeyInfo_bio(bio.as_ptr(), self.ptr) };
375 if rc != 1 {
376 return Err(ErrorStack::drain());
377 }
378 Ok(bio.into_vec())
379 }
380}
381
382impl Pkey<Public> {
385 pub fn from_pem(pem: &[u8]) -> Result<Self, ErrorStack> {
389 let bio = MemBioBuf::new(pem)?;
390 let ptr = unsafe {
391 sys::PEM_read_bio_PUBKEY(
392 bio.as_ptr(),
393 std::ptr::null_mut(),
394 None,
395 std::ptr::null_mut(),
396 )
397 };
398 if ptr.is_null() {
399 return Err(ErrorStack::drain());
400 }
401 Ok(unsafe { Pkey::from_ptr(ptr) })
402 }
403
404 pub fn from_pem_in(ctx: &Arc<crate::lib_ctx::LibCtx>, pem: &[u8]) -> Result<Self, ErrorStack> {
412 let bio = MemBioBuf::new(pem)?;
413 let ptr = unsafe {
414 sys::PEM_read_bio_PUBKEY_ex(
415 bio.as_ptr(),
416 std::ptr::null_mut(),
417 None,
418 std::ptr::null_mut(),
419 ctx.as_ptr(),
420 std::ptr::null(),
421 )
422 };
423 if ptr.is_null() {
424 return Err(ErrorStack::drain());
425 }
426 Ok(unsafe { Pkey::from_ptr(ptr) })
427 }
428
429 pub fn from_der(der: &[u8]) -> Result<Self, ErrorStack> {
433 let bio = MemBioBuf::new(der)?;
434 let ptr = unsafe { sys::d2i_PUBKEY_bio(bio.as_ptr(), std::ptr::null_mut()) };
435 if ptr.is_null() {
436 return Err(ErrorStack::drain());
437 }
438 Ok(unsafe { Pkey::from_ptr(ptr) })
439 }
440
441 pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
445 let mut bio = MemBio::new()?;
446 let rc = unsafe { sys::PEM_write_bio_PUBKEY(bio.as_ptr(), self.ptr) };
447 if rc != 1 {
448 return Err(ErrorStack::drain());
449 }
450 Ok(bio.into_vec())
451 }
452}
453
454impl From<Pkey<Private>> for Pkey<Public> {
456 fn from(k: Pkey<Private>) -> Self {
457 unsafe { sys::EVP_PKEY_up_ref(k.ptr) };
458 Pkey {
459 ptr: k.ptr,
460 _role: PhantomData,
461 }
462 }
463}
464
465const PKEY_PUBLIC_KEY: i32 = 0x86;
476const PKEY_KEYPAIR: i32 = 0x87;
477
478fn pkey_fromdata(
480 ctx: Option<&Arc<crate::lib_ctx::LibCtx>>,
481 pkey_type: &std::ffi::CStr,
482 params: &crate::params::Params<'_>,
483 selection: i32,
484) -> Result<*mut sys::EVP_PKEY, ErrorStack> {
485 let libctx = ctx.map_or(std::ptr::null_mut(), |c| c.as_ptr());
486 let pctx =
487 unsafe { sys::EVP_PKEY_CTX_new_from_name(libctx, pkey_type.as_ptr(), std::ptr::null()) };
488 if pctx.is_null() {
489 return Err(ErrorStack::drain());
490 }
491 let rc = unsafe { sys::EVP_PKEY_fromdata_init(pctx) };
492 if rc != 1 {
493 unsafe { sys::EVP_PKEY_CTX_free(pctx) };
494 return Err(ErrorStack::drain());
495 }
496 let mut pkey: *mut sys::EVP_PKEY = std::ptr::null_mut();
497 let rc = unsafe {
498 sys::EVP_PKEY_fromdata(
499 pctx,
500 std::ptr::addr_of_mut!(pkey),
501 selection,
502 params.as_ptr().cast_mut(),
504 )
505 };
506 unsafe { sys::EVP_PKEY_CTX_free(pctx) };
507 if rc != 1 || pkey.is_null() {
508 return Err(ErrorStack::drain());
509 }
510 Ok(pkey)
511}
512
513fn pkey_todata(
515 ptr: *mut sys::EVP_PKEY,
516 selection: i32,
517) -> Result<crate::params::Params<'static>, ErrorStack> {
518 let mut out: *mut sys::OSSL_PARAM = std::ptr::null_mut();
519 let rc = unsafe { sys::EVP_PKEY_todata(ptr, selection, std::ptr::addr_of_mut!(out)) };
520 if rc != 1 || out.is_null() {
521 return Err(ErrorStack::drain());
522 }
523 Ok(unsafe { crate::params::Params::from_owned_ptr(out) })
526}
527
528impl Pkey<Private> {
529 pub fn from_params(
536 ctx: Option<&Arc<crate::lib_ctx::LibCtx>>,
537 pkey_type: &std::ffi::CStr,
538 params: &crate::params::Params<'_>,
539 ) -> Result<Self, ErrorStack> {
540 pkey_fromdata(ctx, pkey_type, params, PKEY_KEYPAIR)
541 .map(|ptr| unsafe { Pkey::from_ptr(ptr) })
542 }
543
544 pub fn export(&self) -> Result<crate::params::Params<'static>, ErrorStack> {
551 pkey_todata(self.ptr, PKEY_KEYPAIR)
552 }
553}
554
555impl Pkey<Public> {
556 pub fn from_params(
563 ctx: Option<&Arc<crate::lib_ctx::LibCtx>>,
564 pkey_type: &std::ffi::CStr,
565 params: &crate::params::Params<'_>,
566 ) -> Result<Self, ErrorStack> {
567 pkey_fromdata(ctx, pkey_type, params, PKEY_PUBLIC_KEY)
568 .map(|ptr| unsafe { Pkey::from_ptr(ptr) })
569 }
570
571 pub fn export(&self) -> Result<crate::params::Params<'static>, ErrorStack> {
577 pkey_todata(self.ptr, PKEY_PUBLIC_KEY)
578 }
579}
580
581pub struct KeygenCtx {
585 ptr: *mut sys::EVP_PKEY_CTX,
586}
587
588impl KeygenCtx {
589 pub fn new(name: &std::ffi::CStr) -> Result<Self, ErrorStack> {
595 let ptr = unsafe {
596 sys::EVP_PKEY_CTX_new_from_name(std::ptr::null_mut(), name.as_ptr(), std::ptr::null())
597 };
598 if ptr.is_null() {
599 return Err(ErrorStack::drain());
600 }
601 let rc = unsafe { sys::EVP_PKEY_keygen_init(ptr) };
602 if rc != 1 {
603 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
604 return Err(ErrorStack::drain());
605 }
606 Ok(KeygenCtx { ptr })
607 }
608
609 pub fn set_params(&mut self, params: &crate::params::Params<'_>) -> Result<(), ErrorStack> {
613 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(self.ptr, params.as_ptr()))
614 }
615
616 pub fn generate(&mut self) -> Result<Pkey<Private>, ErrorStack> {
620 let mut key: *mut sys::EVP_PKEY = std::ptr::null_mut();
621 crate::ossl_call!(sys::EVP_PKEY_keygen(self.ptr, std::ptr::addr_of_mut!(key)))?;
622 if key.is_null() {
623 return Err(ErrorStack::drain());
624 }
625 Ok(unsafe { Pkey::from_ptr(key) })
626 }
627}
628
629impl Drop for KeygenCtx {
630 fn drop(&mut self) {
631 unsafe { sys::EVP_PKEY_CTX_free(self.ptr) };
632 }
633}
634
635#[derive(Default)]
639pub struct SignInit<'a> {
640 pub digest: Option<&'a crate::digest::DigestAlg>,
642 pub params: Option<&'a crate::params::Params<'a>>,
644}
645
646pub struct Signer {
650 ctx: crate::digest::DigestCtx,
651 _key: Pkey<Private>,
653}
654
655impl Signer {
656 pub fn new(key: &Pkey<Private>, init: &SignInit<'_>) -> Result<Self, ErrorStack> {
660 let ctx = alloc_digest_ctx()?;
661 let md_name_ptr = if let Some(d) = init.digest {
663 let p = unsafe { sys::OBJ_nid2sn(d.nid()) };
664 if p.is_null() {
665 return Err(ErrorStack::drain());
666 }
667 p
668 } else {
669 std::ptr::null()
670 };
671 let params_ptr = init
672 .params
673 .map_or(crate::params::null_params(), crate::params::Params::as_ptr);
674 let rc = unsafe {
675 sys::EVP_DigestSignInit_ex(
676 ctx.as_ptr(),
677 std::ptr::null_mut(),
678 md_name_ptr,
679 std::ptr::null_mut(),
680 std::ptr::null(),
681 key.ptr,
682 params_ptr,
683 )
684 };
685 if rc != 1 {
686 return Err(ErrorStack::drain());
687 }
688 Ok(Signer {
689 ctx,
690 _key: key.clone(),
691 })
692 }
693
694 pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> {
698 crate::ossl_call!(sys::EVP_DigestSignUpdate(
699 self.ctx.as_ptr(),
700 data.as_ptr().cast(),
701 data.len()
702 ))
703 }
704
705 pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> {
712 let mut siglen: usize = 0;
714 let rc = unsafe {
715 sys::EVP_DigestSignFinal(
716 self.ctx.as_ptr(),
717 std::ptr::null_mut(),
718 std::ptr::addr_of_mut!(siglen),
719 )
720 };
721 if rc != 1 {
722 return Err(ErrorStack::drain());
723 }
724 let mut sig = vec![0u8; siglen];
725 let rc = unsafe {
726 sys::EVP_DigestSignFinal(
727 self.ctx.as_ptr(),
728 sig.as_mut_ptr(),
729 std::ptr::addr_of_mut!(siglen),
730 )
731 };
732 if rc != 1 {
733 return Err(ErrorStack::drain());
734 }
735 sig.truncate(siglen);
736 Ok(sig)
737 }
738
739 pub fn sign_oneshot(&mut self, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
746 let mut siglen: usize = 0;
748 let rc = unsafe {
749 sys::EVP_DigestSign(
750 self.ctx.as_ptr(),
751 std::ptr::null_mut(),
752 std::ptr::addr_of_mut!(siglen),
753 data.as_ptr(),
754 data.len(),
755 )
756 };
757 if rc != 1 {
758 return Err(ErrorStack::drain());
759 }
760 let mut sig = vec![0u8; siglen];
761 let rc = unsafe {
762 sys::EVP_DigestSign(
763 self.ctx.as_ptr(),
764 sig.as_mut_ptr(),
765 std::ptr::addr_of_mut!(siglen),
766 data.as_ptr(),
767 data.len(),
768 )
769 };
770 if rc != 1 {
771 return Err(ErrorStack::drain());
772 }
773 sig.truncate(siglen);
774 Ok(sig)
775 }
776
777 pub fn sign_into(&mut self, data: &[u8], sig: &mut [u8]) -> Result<usize, ErrorStack> {
789 let mut siglen = sig.len();
790 let rc = unsafe {
791 sys::EVP_DigestSign(
792 self.ctx.as_ptr(),
793 sig.as_mut_ptr(),
794 std::ptr::addr_of_mut!(siglen),
795 data.as_ptr(),
796 data.len(),
797 )
798 };
799 if rc != 1 {
800 return Err(ErrorStack::drain());
801 }
802 Ok(siglen)
803 }
804}
805
806pub struct Verifier {
810 ctx: crate::digest::DigestCtx,
811 _key: Pkey<Public>,
812}
813
814impl Verifier {
815 pub fn new(key: &Pkey<Public>, init: &SignInit<'_>) -> Result<Self, ErrorStack> {
819 let ctx = alloc_digest_ctx()?;
820 let md_name_ptr = if let Some(d) = init.digest {
822 let p = unsafe { sys::OBJ_nid2sn(d.nid()) };
823 if p.is_null() {
824 return Err(ErrorStack::drain());
825 }
826 p
827 } else {
828 std::ptr::null()
829 };
830 let params_ptr = init
831 .params
832 .map_or(crate::params::null_params(), crate::params::Params::as_ptr);
833 let rc = unsafe {
834 sys::EVP_DigestVerifyInit_ex(
835 ctx.as_ptr(),
836 std::ptr::null_mut(),
837 md_name_ptr,
838 std::ptr::null_mut(),
839 std::ptr::null(),
840 key.ptr,
841 params_ptr,
842 )
843 };
844 if rc != 1 {
845 return Err(ErrorStack::drain());
846 }
847 Ok(Verifier {
848 ctx,
849 _key: key.clone(),
850 })
851 }
852
853 pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> {
857 crate::ossl_call!(sys::EVP_DigestVerifyUpdate(
858 self.ctx.as_ptr(),
859 data.as_ptr().cast(),
860 data.len()
861 ))
862 }
863
864 pub fn verify(&mut self, signature: &[u8]) -> Result<bool, ErrorStack> {
874 let rc = unsafe {
875 sys::EVP_DigestVerifyFinal(self.ctx.as_ptr(), signature.as_ptr(), signature.len())
876 };
877 match rc {
878 1 => Ok(true),
879 0 => Ok(false),
880 _ => Err(ErrorStack::drain()),
881 }
882 }
883
884 pub fn verify_oneshot(&mut self, data: &[u8], signature: &[u8]) -> Result<bool, ErrorStack> {
890 let rc = unsafe {
891 sys::EVP_DigestVerify(
892 self.ctx.as_ptr(),
893 signature.as_ptr(),
894 signature.len(),
895 data.as_ptr(),
896 data.len(),
897 )
898 };
899 match rc {
900 1 => Ok(true),
901 0 => Ok(false),
902 _ => Err(ErrorStack::drain()),
903 }
904 }
905}
906
907fn alloc_digest_ctx() -> Result<crate::digest::DigestCtx, ErrorStack> {
912 let ctx_ptr = unsafe { sys::EVP_MD_CTX_new() };
913 if ctx_ptr.is_null() {
914 return Err(ErrorStack::drain());
915 }
916 Ok(unsafe { crate::digest::DigestCtx::from_ptr(ctx_ptr) })
918}
919
920pub struct DeriveCtx {
924 ptr: *mut sys::EVP_PKEY_CTX,
925}
926
927impl DeriveCtx {
928 pub fn new(key: &Pkey<Private>) -> Result<Self, ErrorStack> {
932 let ptr = unsafe {
933 sys::EVP_PKEY_CTX_new_from_pkey(std::ptr::null_mut(), key.ptr, std::ptr::null())
934 };
935 if ptr.is_null() {
936 return Err(ErrorStack::drain());
937 }
938 crate::ossl_call!(sys::EVP_PKEY_derive_init(ptr)).map_err(|e| {
939 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
940 e
941 })?;
942 Ok(DeriveCtx { ptr })
943 }
944
945 pub fn set_peer(&mut self, peer: &Pkey<Public>) -> Result<(), ErrorStack> {
949 crate::ossl_call!(sys::EVP_PKEY_derive_set_peer(self.ptr, peer.ptr))
950 }
951
952 pub fn derive(&mut self, out: &mut [u8]) -> Result<usize, ErrorStack> {
958 let mut len = out.len();
959 crate::ossl_call!(sys::EVP_PKEY_derive(
960 self.ptr,
961 out.as_mut_ptr(),
962 std::ptr::addr_of_mut!(len)
963 ))?;
964 Ok(len)
965 }
966
967 pub fn derive_len(&mut self) -> Result<usize, ErrorStack> {
971 let mut len: usize = 0;
972 crate::ossl_call!(sys::EVP_PKEY_derive(
973 self.ptr,
974 std::ptr::null_mut(),
975 std::ptr::addr_of_mut!(len)
976 ))?;
977 Ok(len)
978 }
979}
980
981impl Drop for DeriveCtx {
982 fn drop(&mut self) {
983 unsafe { sys::EVP_PKEY_CTX_free(self.ptr) };
984 }
985}
986
987pub struct PkeyEncryptCtx {
991 ptr: *mut sys::EVP_PKEY_CTX,
992}
993
994impl PkeyEncryptCtx {
995 pub fn new(
1005 key: &Pkey<Public>,
1006 params: Option<&crate::params::Params<'_>>,
1007 ) -> Result<Self, ErrorStack> {
1008 let ptr = unsafe {
1009 sys::EVP_PKEY_CTX_new_from_pkey(std::ptr::null_mut(), key.ptr, std::ptr::null())
1010 };
1011 if ptr.is_null() {
1012 return Err(ErrorStack::drain());
1013 }
1014 crate::ossl_call!(sys::EVP_PKEY_encrypt_init(ptr)).map_err(|e| {
1015 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1016 e
1017 })?;
1018 let ctx = PkeyEncryptCtx { ptr };
1019 if let Some(p) = params {
1020 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(ctx.ptr, p.as_ptr())).map_err(|e| {
1021 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1022 e
1023 })?;
1024 }
1025 Ok(ctx)
1026 }
1027
1028 pub fn set_params(&mut self, params: &crate::params::Params<'_>) -> Result<(), ErrorStack> {
1032 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(self.ptr, params.as_ptr()))
1033 }
1034
1035 pub fn encrypt(
1041 &mut self,
1042 plaintext: &[u8],
1043 ciphertext: &mut [u8],
1044 ) -> Result<usize, ErrorStack> {
1045 let mut outlen = ciphertext.len();
1046 crate::ossl_call!(sys::EVP_PKEY_encrypt(
1047 self.ptr,
1048 ciphertext.as_mut_ptr(),
1049 std::ptr::addr_of_mut!(outlen),
1050 plaintext.as_ptr(),
1051 plaintext.len()
1052 ))?;
1053 Ok(outlen)
1054 }
1055
1056 pub fn encrypt_len(&mut self, plaintext_len: usize) -> Result<usize, ErrorStack> {
1060 let mut outlen: usize = 0;
1061 crate::ossl_call!(sys::EVP_PKEY_encrypt(
1062 self.ptr,
1063 std::ptr::null_mut(),
1064 std::ptr::addr_of_mut!(outlen),
1065 std::ptr::null(),
1066 plaintext_len
1067 ))?;
1068 Ok(outlen)
1069 }
1070}
1071
1072impl Drop for PkeyEncryptCtx {
1073 fn drop(&mut self) {
1074 unsafe { sys::EVP_PKEY_CTX_free(self.ptr) };
1075 }
1076}
1077
1078pub struct PkeyDecryptCtx {
1080 ptr: *mut sys::EVP_PKEY_CTX,
1081}
1082
1083impl PkeyDecryptCtx {
1084 pub fn new(
1090 key: &Pkey<Private>,
1091 params: Option<&crate::params::Params<'_>>,
1092 ) -> Result<Self, ErrorStack> {
1093 let ptr = unsafe {
1094 sys::EVP_PKEY_CTX_new_from_pkey(std::ptr::null_mut(), key.ptr, std::ptr::null())
1095 };
1096 if ptr.is_null() {
1097 return Err(ErrorStack::drain());
1098 }
1099 crate::ossl_call!(sys::EVP_PKEY_decrypt_init(ptr)).map_err(|e| {
1100 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1101 e
1102 })?;
1103 let ctx = PkeyDecryptCtx { ptr };
1104 if let Some(p) = params {
1105 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(ctx.ptr, p.as_ptr())).map_err(|e| {
1106 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1107 e
1108 })?;
1109 }
1110 Ok(ctx)
1111 }
1112
1113 pub fn set_params(&mut self, params: &crate::params::Params<'_>) -> Result<(), ErrorStack> {
1117 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(self.ptr, params.as_ptr()))
1118 }
1119
1120 pub fn decrypt(
1126 &mut self,
1127 ciphertext: &[u8],
1128 plaintext: &mut [u8],
1129 ) -> Result<usize, ErrorStack> {
1130 let mut outlen = plaintext.len();
1131 crate::ossl_call!(sys::EVP_PKEY_decrypt(
1132 self.ptr,
1133 plaintext.as_mut_ptr(),
1134 std::ptr::addr_of_mut!(outlen),
1135 ciphertext.as_ptr(),
1136 ciphertext.len()
1137 ))?;
1138 Ok(outlen)
1139 }
1140}
1141
1142impl Drop for PkeyDecryptCtx {
1143 fn drop(&mut self) {
1144 unsafe { sys::EVP_PKEY_CTX_free(self.ptr) };
1145 }
1146}
1147
1148#[cfg(ossl320)]
1152pub struct EncapResult {
1153 pub wrapped_key: Vec<u8>,
1155 pub shared_secret: Vec<u8>,
1157}
1158
1159#[cfg(ossl320)]
1161pub struct EncapCtx {
1162 ptr: *mut sys::EVP_PKEY_CTX,
1163}
1164
1165#[cfg(ossl320)]
1166impl EncapCtx {
1167 pub fn new(key: &Pkey<Public>) -> Result<Self, ErrorStack> {
1171 let ptr = unsafe {
1172 sys::EVP_PKEY_CTX_new_from_pkey(std::ptr::null_mut(), key.ptr, std::ptr::null())
1173 };
1174 if ptr.is_null() {
1175 return Err(ErrorStack::drain());
1176 }
1177 crate::ossl_call!(sys::EVP_PKEY_encapsulate_init(ptr, std::ptr::null())).map_err(|e| {
1178 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1179 e
1180 })?;
1181 Ok(EncapCtx { ptr })
1182 }
1183
1184 pub fn encapsulate(&mut self) -> Result<EncapResult, ErrorStack> {
1188 let mut wkeylen: usize = 0;
1189 let mut sslen: usize = 0;
1190 let rc = unsafe {
1192 sys::EVP_PKEY_encapsulate(
1193 self.ptr,
1194 std::ptr::null_mut(),
1195 std::ptr::addr_of_mut!(wkeylen),
1196 std::ptr::null_mut(),
1197 std::ptr::addr_of_mut!(sslen),
1198 )
1199 };
1200 if rc != 1 {
1201 return Err(ErrorStack::drain());
1202 }
1203 let mut wrapped_key = vec![0u8; wkeylen];
1204 let mut shared_secret = vec![0u8; sslen];
1205 crate::ossl_call!(sys::EVP_PKEY_encapsulate(
1206 self.ptr,
1207 wrapped_key.as_mut_ptr(),
1208 std::ptr::addr_of_mut!(wkeylen),
1209 shared_secret.as_mut_ptr(),
1210 std::ptr::addr_of_mut!(sslen)
1211 ))?;
1212 wrapped_key.truncate(wkeylen);
1213 shared_secret.truncate(sslen);
1214 Ok(EncapResult {
1215 wrapped_key,
1216 shared_secret,
1217 })
1218 }
1219}
1220
1221#[cfg(ossl320)]
1222impl Drop for EncapCtx {
1223 fn drop(&mut self) {
1224 unsafe { sys::EVP_PKEY_CTX_free(self.ptr) };
1225 }
1226}
1227
1228#[cfg(ossl320)]
1230pub struct DecapCtx {
1231 ptr: *mut sys::EVP_PKEY_CTX,
1232}
1233
1234#[cfg(ossl320)]
1235impl DecapCtx {
1236 pub fn new(key: &Pkey<Private>) -> Result<Self, ErrorStack> {
1240 let ptr = unsafe {
1241 sys::EVP_PKEY_CTX_new_from_pkey(std::ptr::null_mut(), key.ptr, std::ptr::null())
1242 };
1243 if ptr.is_null() {
1244 return Err(ErrorStack::drain());
1245 }
1246 crate::ossl_call!(sys::EVP_PKEY_decapsulate_init(ptr, std::ptr::null())).map_err(|e| {
1247 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1248 e
1249 })?;
1250 Ok(DecapCtx { ptr })
1251 }
1252
1253 pub fn decapsulate(&mut self, wrapped_key: &[u8]) -> Result<Vec<u8>, ErrorStack> {
1257 let mut sslen: usize = 0;
1258 let rc = unsafe {
1260 sys::EVP_PKEY_decapsulate(
1261 self.ptr,
1262 std::ptr::null_mut(),
1263 std::ptr::addr_of_mut!(sslen),
1264 wrapped_key.as_ptr(),
1265 wrapped_key.len(),
1266 )
1267 };
1268 if rc != 1 {
1269 return Err(ErrorStack::drain());
1270 }
1271 let mut ss = vec![0u8; sslen];
1272 crate::ossl_call!(sys::EVP_PKEY_decapsulate(
1273 self.ptr,
1274 ss.as_mut_ptr(),
1275 std::ptr::addr_of_mut!(sslen),
1276 wrapped_key.as_ptr(),
1277 wrapped_key.len()
1278 ))?;
1279 ss.truncate(sslen);
1280 Ok(ss)
1281 }
1282}
1283
1284#[cfg(ossl320)]
1285impl Drop for DecapCtx {
1286 fn drop(&mut self) {
1287 unsafe { sys::EVP_PKEY_CTX_free(self.ptr) };
1288 }
1289}
1290
1291pub struct RawSigner {
1303 ctx: *mut sys::EVP_PKEY_CTX,
1304}
1305
1306unsafe impl Send for RawSigner {}
1309
1310impl RawSigner {
1311 pub fn new(
1319 key: &Pkey<Private>,
1320 libctx: Option<&Arc<crate::lib_ctx::LibCtx>>,
1321 ) -> Result<Self, ErrorStack> {
1322 let lctx = libctx.map_or(std::ptr::null_mut(), |c| c.as_ptr());
1323 let ptr = unsafe { sys::EVP_PKEY_CTX_new_from_pkey(lctx, key.ptr, std::ptr::null()) };
1324 if ptr.is_null() {
1325 return Err(ErrorStack::drain());
1326 }
1327 crate::ossl_call!(sys::EVP_PKEY_sign_init(ptr)).map_err(|e| {
1328 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1329 e
1330 })?;
1331 Ok(RawSigner { ctx: ptr })
1332 }
1333
1334 pub fn set_params(&mut self, params: &crate::params::Params<'_>) -> Result<(), ErrorStack> {
1338 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(self.ctx, params.as_ptr()))
1339 }
1340
1341 pub fn sign_len(&mut self, tbs_len: usize) -> Result<usize, ErrorStack> {
1348 let mut siglen: usize = 0;
1349 crate::ossl_call!(sys::EVP_PKEY_sign(
1350 self.ctx,
1351 std::ptr::null_mut(),
1352 std::ptr::addr_of_mut!(siglen),
1353 std::ptr::null(),
1354 tbs_len,
1355 ))?;
1356 Ok(siglen)
1357 }
1358
1359 pub fn sign(&mut self, tbs: &[u8], sig: &mut [u8]) -> Result<usize, ErrorStack> {
1365 let mut siglen = sig.len();
1366 crate::ossl_call!(sys::EVP_PKEY_sign(
1367 self.ctx,
1368 sig.as_mut_ptr(),
1369 std::ptr::addr_of_mut!(siglen),
1370 tbs.as_ptr(),
1371 tbs.len(),
1372 ))?;
1373 Ok(siglen)
1374 }
1375
1376 pub fn sign_alloc(&mut self, tbs: &[u8]) -> Result<Vec<u8>, ErrorStack> {
1382 let siglen = self.sign_len(tbs.len())?;
1383 let mut sig = vec![0u8; siglen];
1384 let written = self.sign(tbs, &mut sig)?;
1385 sig.truncate(written);
1386 Ok(sig)
1387 }
1388}
1389
1390impl Drop for RawSigner {
1391 fn drop(&mut self) {
1392 unsafe { sys::EVP_PKEY_CTX_free(self.ctx) };
1393 }
1394}
1395
1396pub struct RawVerifier {
1403 ctx: *mut sys::EVP_PKEY_CTX,
1404}
1405
1406unsafe impl Send for RawVerifier {}
1407
1408impl RawVerifier {
1409 pub fn new<T: HasPublic>(
1413 key: &Pkey<T>,
1414 libctx: Option<&Arc<crate::lib_ctx::LibCtx>>,
1415 ) -> Result<Self, ErrorStack> {
1416 let lctx = libctx.map_or(std::ptr::null_mut(), |c| c.as_ptr());
1417 let ptr = unsafe { sys::EVP_PKEY_CTX_new_from_pkey(lctx, key.ptr, std::ptr::null()) };
1418 if ptr.is_null() {
1419 return Err(ErrorStack::drain());
1420 }
1421 crate::ossl_call!(sys::EVP_PKEY_verify_init(ptr)).map_err(|e| {
1422 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1423 e
1424 })?;
1425 Ok(RawVerifier { ctx: ptr })
1426 }
1427
1428 pub fn set_params(&mut self, params: &crate::params::Params<'_>) -> Result<(), ErrorStack> {
1432 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(self.ctx, params.as_ptr()))
1433 }
1434
1435 pub fn verify(&mut self, tbs: &[u8], sig: &[u8]) -> Result<(), ErrorStack> {
1441 crate::ossl_call!(sys::EVP_PKEY_verify(
1442 self.ctx,
1443 sig.as_ptr(),
1444 sig.len(),
1445 tbs.as_ptr(),
1446 tbs.len(),
1447 ))
1448 }
1449}
1450
1451impl Drop for RawVerifier {
1452 fn drop(&mut self) {
1453 unsafe { sys::EVP_PKEY_CTX_free(self.ctx) };
1454 }
1455}
1456
1457#[cfg(ossl320)]
1465pub struct SigAlg {
1466 ptr: *mut sys::EVP_SIGNATURE,
1467}
1468
1469#[cfg(ossl320)]
1471unsafe impl Send for SigAlg {}
1472#[cfg(ossl320)]
1473unsafe impl Sync for SigAlg {}
1474
1475#[cfg(ossl320)]
1476impl SigAlg {
1477 pub fn fetch(
1483 name: &std::ffi::CStr,
1484 props: Option<&std::ffi::CStr>,
1485 ) -> Result<Self, ErrorStack> {
1486 let props_ptr = props.map_or(std::ptr::null(), std::ffi::CStr::as_ptr);
1487 let ptr =
1488 unsafe { sys::EVP_SIGNATURE_fetch(std::ptr::null_mut(), name.as_ptr(), props_ptr) };
1489 if ptr.is_null() {
1490 return Err(ErrorStack::drain());
1491 }
1492 Ok(SigAlg { ptr })
1493 }
1494
1495 pub fn fetch_in(
1499 ctx: &Arc<crate::lib_ctx::LibCtx>,
1500 name: &std::ffi::CStr,
1501 props: Option<&std::ffi::CStr>,
1502 ) -> Result<Self, ErrorStack> {
1503 let props_ptr = props.map_or(std::ptr::null(), std::ffi::CStr::as_ptr);
1504 let ptr = unsafe { sys::EVP_SIGNATURE_fetch(ctx.as_ptr(), name.as_ptr(), props_ptr) };
1505 if ptr.is_null() {
1506 return Err(ErrorStack::drain());
1507 }
1508 Ok(SigAlg { ptr })
1509 }
1510}
1511
1512#[cfg(ossl320)]
1513impl Clone for SigAlg {
1514 fn clone(&self) -> Self {
1515 unsafe { sys::EVP_SIGNATURE_up_ref(self.ptr) };
1516 SigAlg { ptr: self.ptr }
1517 }
1518}
1519
1520#[cfg(ossl320)]
1521impl Drop for SigAlg {
1522 fn drop(&mut self) {
1523 unsafe { sys::EVP_SIGNATURE_free(self.ptr) };
1524 }
1525}
1526
1527#[cfg(ossl320)]
1540pub struct MessageSigner {
1541 ctx: *mut sys::EVP_PKEY_CTX,
1542}
1543
1544#[cfg(ossl320)]
1545unsafe impl Send for MessageSigner {}
1546
1547#[cfg(ossl320)]
1548impl MessageSigner {
1549 pub fn new(
1556 key: &Pkey<Private>,
1557 alg: &mut SigAlg,
1558 params: Option<&crate::params::Params<'_>>,
1559 ) -> Result<Self, ErrorStack> {
1560 let ptr = unsafe {
1561 sys::EVP_PKEY_CTX_new_from_pkey(std::ptr::null_mut(), key.ptr, std::ptr::null())
1562 };
1563 if ptr.is_null() {
1564 return Err(ErrorStack::drain());
1565 }
1566 let params_ptr = params.map_or(crate::params::null_params(), crate::params::Params::as_ptr);
1567 crate::ossl_call!(sys::EVP_PKEY_sign_message_init(ptr, alg.ptr, params_ptr)).map_err(
1568 |e| {
1569 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1570 e
1571 },
1572 )?;
1573 Ok(MessageSigner { ctx: ptr })
1574 }
1575
1576 pub fn supports_streaming(&mut self) -> bool {
1584 unsafe { sys::ERR_set_mark() };
1587 let probe: [u8; 0] = [];
1588 let rc = unsafe { sys::EVP_PKEY_sign_message_update(self.ctx, probe.as_ptr(), 0) };
1589 unsafe { sys::ERR_pop_to_mark() };
1590 rc == 1
1591 }
1592
1593 pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> {
1600 crate::ossl_call!(sys::EVP_PKEY_sign_message_update(
1601 self.ctx,
1602 data.as_ptr(),
1603 data.len(),
1604 ))
1605 }
1606
1607 pub fn sig_len(&mut self) -> Result<usize, ErrorStack> {
1614 let mut siglen: usize = 0;
1615 crate::ossl_call!(sys::EVP_PKEY_sign_message_final(
1616 self.ctx,
1617 std::ptr::null_mut(),
1618 std::ptr::addr_of_mut!(siglen),
1619 ))?;
1620 Ok(siglen)
1621 }
1622
1623 pub fn finish(self, sig: &mut [u8]) -> Result<usize, ErrorStack> {
1631 let mut siglen = sig.len();
1632 let rc = unsafe {
1633 sys::EVP_PKEY_sign_message_final(
1634 self.ctx,
1635 sig.as_mut_ptr(),
1636 std::ptr::addr_of_mut!(siglen),
1637 )
1638 };
1639 if rc != 1 {
1641 return Err(ErrorStack::drain());
1642 }
1643 Ok(siglen)
1644 }
1645
1646 pub fn sign_oneshot(self, data: &[u8], sig: &mut [u8]) -> Result<usize, ErrorStack> {
1653 let rc_upd =
1655 unsafe { sys::EVP_PKEY_sign_message_update(self.ctx, data.as_ptr(), data.len()) };
1656 if rc_upd != 1 {
1657 return Err(ErrorStack::drain());
1659 }
1660 let mut siglen = sig.len();
1661 let rc_fin = unsafe {
1662 sys::EVP_PKEY_sign_message_final(
1663 self.ctx,
1664 sig.as_mut_ptr(),
1665 std::ptr::addr_of_mut!(siglen),
1666 )
1667 };
1668 if rc_fin != 1 {
1670 return Err(ErrorStack::drain());
1671 }
1672 Ok(siglen)
1673 }
1674
1675 pub fn sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result<usize, ErrorStack> {
1696 let (sig_ptr, mut siglen) = match sig {
1697 Some(buf) => (buf.as_mut_ptr(), buf.len()),
1698 None => (std::ptr::null_mut(), 0usize),
1699 };
1700 crate::ossl_call!(sys::EVP_PKEY_sign(
1701 self.ctx,
1702 sig_ptr,
1703 std::ptr::addr_of_mut!(siglen),
1704 data.as_ptr(),
1705 data.len(),
1706 ))?;
1707 Ok(siglen)
1708 }
1709}
1710
1711#[cfg(ossl320)]
1712impl Drop for MessageSigner {
1713 fn drop(&mut self) {
1714 unsafe { sys::EVP_PKEY_CTX_free(self.ctx) };
1715 }
1716}
1717
1718#[cfg(ossl320)]
1728pub struct MessageVerifier {
1729 ctx: *mut sys::EVP_PKEY_CTX,
1730}
1731
1732#[cfg(ossl320)]
1733unsafe impl Send for MessageVerifier {}
1734
1735#[cfg(ossl320)]
1736impl MessageVerifier {
1737 pub fn new<T: HasPublic>(
1741 key: &Pkey<T>,
1742 alg: &mut SigAlg,
1743 params: Option<&crate::params::Params<'_>>,
1744 ) -> Result<Self, ErrorStack> {
1745 let ptr = unsafe {
1746 sys::EVP_PKEY_CTX_new_from_pkey(std::ptr::null_mut(), key.ptr, std::ptr::null())
1747 };
1748 if ptr.is_null() {
1749 return Err(ErrorStack::drain());
1750 }
1751 let params_ptr = params.map_or(crate::params::null_params(), crate::params::Params::as_ptr);
1752 crate::ossl_call!(sys::EVP_PKEY_verify_message_init(ptr, alg.ptr, params_ptr)).map_err(
1753 |e| {
1754 unsafe { sys::EVP_PKEY_CTX_free(ptr) };
1755 e
1756 },
1757 )?;
1758 Ok(MessageVerifier { ctx: ptr })
1759 }
1760
1761 pub fn set_params(&mut self, params: &crate::params::Params<'_>) -> Result<(), ErrorStack> {
1765 crate::ossl_call!(sys::EVP_PKEY_CTX_set_params(self.ctx, params.as_ptr()))
1766 }
1767
1768 pub fn set_signature(&mut self, sig: &[u8]) -> Result<(), ErrorStack> {
1775 crate::ossl_call!(sys::EVP_PKEY_CTX_set_signature(
1776 self.ctx,
1777 sig.as_ptr(),
1778 sig.len()
1779 ))
1780 }
1781
1782 pub fn supports_streaming(&mut self) -> bool {
1787 unsafe { sys::ERR_set_mark() };
1788 let probe: [u8; 0] = [];
1789 let rc = unsafe { sys::EVP_PKEY_verify_message_update(self.ctx, probe.as_ptr(), 0) };
1790 unsafe { sys::ERR_pop_to_mark() };
1791 rc == 1
1792 }
1793
1794 pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> {
1798 crate::ossl_call!(sys::EVP_PKEY_verify_message_update(
1799 self.ctx,
1800 data.as_ptr(),
1801 data.len(),
1802 ))
1803 }
1804
1805 pub fn finish(self) -> Result<(), ErrorStack> {
1812 let rc = unsafe { sys::EVP_PKEY_verify_message_final(self.ctx) };
1813 if rc != 1 {
1815 return Err(ErrorStack::drain());
1816 }
1817 Ok(())
1818 }
1819
1820 pub fn verify_oneshot(self, data: &[u8], sig: &[u8]) -> Result<(), ErrorStack> {
1826 let rc_set = unsafe { sys::EVP_PKEY_CTX_set_signature(self.ctx, sig.as_ptr(), sig.len()) };
1827 if rc_set != 1 {
1828 return Err(ErrorStack::drain());
1829 }
1830 let rc_upd =
1831 unsafe { sys::EVP_PKEY_verify_message_update(self.ctx, data.as_ptr(), data.len()) };
1832 if rc_upd != 1 {
1833 return Err(ErrorStack::drain());
1834 }
1835 let rc_fin = unsafe { sys::EVP_PKEY_verify_message_final(self.ctx) };
1836 if rc_fin != 1 {
1838 return Err(ErrorStack::drain());
1839 }
1840 Ok(())
1841 }
1842
1843 pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
1860 let rc = unsafe {
1861 sys::EVP_PKEY_verify(self.ctx, sig.as_ptr(), sig.len(), data.as_ptr(), data.len())
1862 };
1863 match rc {
1864 1 => Ok(true),
1865 0 => Ok(false),
1866 _ => Err(ErrorStack::drain()),
1867 }
1868 }
1869}
1870
1871#[cfg(ossl320)]
1872impl Drop for MessageVerifier {
1873 fn drop(&mut self) {
1874 unsafe { sys::EVP_PKEY_CTX_free(self.ctx) };
1875 }
1876}
1877
1878#[cfg(test)]
1881mod tests {
1882 use super::*;
1883
1884 #[test]
1888 fn ed25519_sign_verify() {
1889 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
1890 let priv_key = kgen.generate().unwrap();
1891 let pub_key = Pkey::<Public>::from(priv_key.clone());
1892
1893 let msg = b"hello world";
1894 let init = SignInit::default();
1895
1896 let mut signer = Signer::new(&priv_key, &init).unwrap();
1897 let sig = signer.sign_oneshot(msg).unwrap();
1898 assert!(!sig.is_empty());
1899
1900 let mut verifier = Verifier::new(&pub_key, &init).unwrap();
1901 assert!(verifier.verify_oneshot(msg, &sig).unwrap());
1902 }
1903
1904 #[test]
1906 fn ed25519_verify_wrong_msg_fails() {
1907 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
1908 let priv_key = kgen.generate().unwrap();
1909 let pub_key = Pkey::<Public>::from(priv_key.clone());
1910
1911 let mut signer = Signer::new(&priv_key, &SignInit::default()).unwrap();
1912 let sig = signer.sign_oneshot(b"correct").unwrap();
1913
1914 let mut verifier = Verifier::new(&pub_key, &SignInit::default()).unwrap();
1915 assert!(!verifier.verify_oneshot(b"tampered", &sig).unwrap());
1916 }
1917
1918 #[test]
1920 fn x25519_derive() {
1921 let mut kgen_a = KeygenCtx::new(c"X25519").unwrap();
1922 let priv_a = kgen_a.generate().unwrap();
1923
1924 let mut kgen_b = KeygenCtx::new(c"X25519").unwrap();
1925 let priv_b = kgen_b.generate().unwrap();
1926 let pub_b = Pkey::<Public>::from(priv_b);
1927
1928 let mut derive = DeriveCtx::new(&priv_a).unwrap();
1929 derive.set_peer(&pub_b).unwrap();
1930 let len = derive.derive_len().unwrap();
1931 assert_eq!(len, 32); let mut ss = vec![0u8; len];
1934 let n = derive.derive(&mut ss).unwrap();
1935 assert_eq!(n, 32);
1936 assert_ne!(ss, [0u8; 32]);
1937 }
1938
1939 #[test]
1941 fn pem_round_trip() {
1942 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
1943 let priv_key = kgen.generate().unwrap();
1944
1945 let pem = priv_key.to_pem().unwrap();
1946 assert!(!pem.is_empty());
1947 assert!(pem.starts_with(b"-----BEGIN"));
1948
1949 let priv_key2 = Pkey::<Private>::from_pem(&pem).unwrap();
1950 assert_eq!(priv_key.bits(), priv_key2.bits());
1951 assert!(priv_key.is_a(c"ED25519"));
1952 }
1953
1954 #[test]
1956 fn ed25519_metadata() {
1957 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
1958 let key = kgen.generate().unwrap();
1959 assert_eq!(key.bits(), 256);
1960 assert_eq!(key.security_bits(), 128);
1961 assert!(key.is_a(c"ED25519"));
1962 }
1963
1964 #[cfg(ossl320)]
1966 #[test]
1967 fn ml_dsa_44_sign_verify() {
1968 let mut kgen = KeygenCtx::new(c"ML-DSA-44").unwrap();
1969 let priv_key = kgen.generate().unwrap();
1970 let pub_key = Pkey::<Public>::from(priv_key.clone());
1971
1972 let msg = b"hello ML-DSA-44";
1973
1974 let mut alg = SigAlg::fetch(c"ML-DSA-44", None).unwrap();
1975 let mut signer = MessageSigner::new(&priv_key, &mut alg, None).unwrap();
1976 let sig_len = signer.sign(msg, None).unwrap();
1978 assert_eq!(sig_len, 2420);
1979 let mut sig = vec![0u8; sig_len];
1980 let written = signer.sign(msg, Some(&mut sig)).unwrap();
1981 assert_eq!(written, 2420);
1982
1983 let mut alg2 = SigAlg::fetch(c"ML-DSA-44", None).unwrap();
1984 let mut ver = MessageVerifier::new(&pub_key, &mut alg2, None).unwrap();
1985 assert!(ver.verify(msg, &sig).unwrap());
1986
1987 let mut bad = sig.clone();
1989 bad[0] ^= 0xff;
1990 assert!(!ver.verify(msg, &bad).unwrap());
1991 }
1992
1993 #[cfg(ossl320)]
1995 #[test]
1996 fn ml_dsa_44_sign_with_context() {
1997 let mut kgen = KeygenCtx::new(c"ML-DSA-44").unwrap();
1998 let priv_key = kgen.generate().unwrap();
1999 let pub_key = Pkey::<Public>::from(priv_key.clone());
2000
2001 let msg = b"signed with context";
2002 let ctx_bytes = b"my-app-domain";
2003
2004 let ctx_params = crate::params::ParamBuilder::new()
2005 .unwrap()
2006 .push_octet_slice(c"context-string", ctx_bytes)
2007 .unwrap()
2008 .build()
2009 .unwrap();
2010
2011 let mut alg = SigAlg::fetch(c"ML-DSA-44", None).unwrap();
2012 let mut signer = MessageSigner::new(&priv_key, &mut alg, Some(&ctx_params)).unwrap();
2013 let sig_len = signer.sign(msg, None).unwrap();
2014 let mut sig = vec![0u8; sig_len];
2015 signer.sign(msg, Some(&mut sig)).unwrap();
2016
2017 let mut alg2 = SigAlg::fetch(c"ML-DSA-44", None).unwrap();
2019 let mut ver = MessageVerifier::new(&pub_key, &mut alg2, Some(&ctx_params)).unwrap();
2020 assert!(ver.verify(msg, &sig).unwrap());
2021
2022 let other_params = crate::params::ParamBuilder::new()
2024 .unwrap()
2025 .push_octet_slice(c"context-string", b"other-domain")
2026 .unwrap()
2027 .build()
2028 .unwrap();
2029 let mut alg3 = SigAlg::fetch(c"ML-DSA-44", None).unwrap();
2030 let mut ver_bad = MessageVerifier::new(&pub_key, &mut alg3, Some(&other_params)).unwrap();
2031 assert!(!ver_bad.verify(msg, &sig).unwrap());
2032 }
2033
2034 #[test]
2036 fn ecdsa_p256_raw_sign_verify() {
2037 let mut kgen = KeygenCtx::new(c"EC").unwrap();
2039 let params = crate::params::ParamBuilder::new()
2040 .unwrap()
2041 .push_utf8_string(c"group", c"P-256")
2042 .unwrap()
2043 .build()
2044 .unwrap();
2045 kgen.set_params(¶ms).unwrap();
2046 let priv_key = kgen.generate().unwrap();
2047 let pub_key = Pkey::<Public>::from(priv_key.clone());
2048
2049 let tbs: [u8; 32] = *b"0123456789abcdef0123456789abcdef";
2051
2052 let mut signer = RawSigner::new(&priv_key, None).unwrap();
2053 let sig = signer.sign_alloc(&tbs).unwrap();
2054 assert!(!sig.is_empty());
2055
2056 let mut verifier = RawVerifier::new(&pub_key, None).unwrap();
2057 verifier.verify(&tbs, &sig).unwrap();
2058 }
2059
2060 #[test]
2062 fn ecdsa_p256_raw_verify_tampered_fails() {
2063 let mut kgen = KeygenCtx::new(c"EC").unwrap();
2064 let params = crate::params::ParamBuilder::new()
2065 .unwrap()
2066 .push_utf8_string(c"group", c"P-256")
2067 .unwrap()
2068 .build()
2069 .unwrap();
2070 kgen.set_params(¶ms).unwrap();
2071 let priv_key = kgen.generate().unwrap();
2072 let pub_key = Pkey::<Public>::from(priv_key.clone());
2073
2074 let tbs: [u8; 32] = *b"0123456789abcdef0123456789abcdef";
2075 let mut signer = RawSigner::new(&priv_key, None).unwrap();
2076 let mut sig = signer.sign_alloc(&tbs).unwrap();
2077 if let Some(b) = sig.last_mut() {
2079 *b ^= 0xff;
2080 }
2081
2082 let mut verifier = RawVerifier::new(&pub_key, None).unwrap();
2083 assert!(verifier.verify(&tbs, &sig).is_err());
2084 }
2085
2086 #[cfg(ossl320)]
2093 #[test]
2094 fn sig_alg_fetch_clone_drop() {
2095 let alg = SigAlg::fetch(c"ML-DSA-44", None).unwrap();
2096 let alg2 = alg.clone();
2097 drop(alg);
2098 drop(alg2); }
2100
2101 #[cfg(ossl320)]
2106 #[test]
2107 fn message_signer_construction_and_streaming_probe() {
2108 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
2109 let priv_key = kgen.generate().unwrap();
2110
2111 let mut alg = SigAlg::fetch(c"ED25519", None).unwrap();
2112 let mut signer = MessageSigner::new(&priv_key, &mut alg, None).unwrap();
2113
2114 let _streaming = signer.supports_streaming();
2116 assert_eq!(crate::error::ErrorStack::drain().errors().count(), 0);
2118 }
2119
2120 #[cfg(ossl320)]
2122 #[test]
2123 fn message_verifier_construction() {
2124 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
2125 let priv_key = kgen.generate().unwrap();
2126 let pub_key = Pkey::<Public>::from(priv_key.clone());
2127
2128 let mut alg = SigAlg::fetch(c"ED25519", None).unwrap();
2129 let _verifier = MessageVerifier::new(&pub_key, &mut alg, None).unwrap();
2130 }
2131
2132 #[test]
2134 fn encrypted_pem_round_trip() {
2135 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
2136 let key = kgen.generate().unwrap();
2137
2138 let cipher = crate::cipher::CipherAlg::fetch(c"AES-256-CBC", None).unwrap();
2139 let pem = key.to_pem_encrypted(&cipher, b"s3cret").unwrap();
2140 assert!(pem.starts_with(b"-----BEGIN ENCRYPTED PRIVATE KEY-----"));
2141
2142 let key2 = Pkey::<Private>::from_pem_passphrase(&pem, b"s3cret").unwrap();
2143 assert!(key.public_eq(&key2));
2144 }
2145
2146 #[test]
2148 fn encrypted_pem_wrong_passphrase_fails() {
2149 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
2150 let key = kgen.generate().unwrap();
2151
2152 let cipher = crate::cipher::CipherAlg::fetch(c"AES-256-CBC", None).unwrap();
2153 let pem = key.to_pem_encrypted(&cipher, b"correct").unwrap();
2154 assert!(Pkey::<Private>::from_pem_passphrase(&pem, b"wrong").is_err());
2155 }
2156
2157 #[test]
2159 fn pkcs8_der_round_trip() {
2160 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
2161 let key = kgen.generate().unwrap();
2162
2163 let der = key.to_pkcs8_der().unwrap();
2164 assert!(!der.is_empty());
2165
2166 let key2 = Pkey::<Private>::from_der(&der).unwrap();
2167 assert!(key.public_eq(&key2));
2168 }
2169
2170 #[test]
2172 fn pubkey_from_pem_in_roundtrip() {
2173 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
2175 let priv_key = kgen.generate().unwrap();
2176 let pub_pem = Pkey::<Public>::from(priv_key).to_pem().unwrap();
2177
2178 let lib_ctx = Arc::new(crate::lib_ctx::LibCtx::new().unwrap());
2180 let pub_key = Pkey::<Public>::from_pem_in(&lib_ctx, &pub_pem).unwrap();
2181
2182 assert!(!pub_key.to_pem().unwrap().is_empty());
2184 }
2185}