1 //! Message signatures.
3 //! The `Signer` allows for the computation of cryptographic signatures of
4 //! data given a private key. The `Verifier` can then be used with the
5 //! corresponding public key to verify the integrity and authenticity of that
6 //! data given the signature.
10 //! Sign and verify data given an RSA keypair:
13 //! use openssl::sign::{Signer, Verifier};
14 //! use openssl::rsa::Rsa;
15 //! use openssl::pkey::PKey;
16 //! use openssl::hash::MessageDigest;
18 //! // Generate a keypair
19 //! let keypair = Rsa::generate(2048).unwrap();
20 //! let keypair = PKey::from_rsa(keypair).unwrap();
22 //! let data = b"hello, world!";
23 //! let data2 = b"hola, mundo!";
26 //! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap();
27 //! signer.update(data).unwrap();
28 //! signer.update(data2).unwrap();
29 //! let signature = signer.finish().unwrap();
31 //! // Verify the data
32 //! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap();
33 //! verifier.update(data).unwrap();
34 //! verifier.update(data2).unwrap();
35 //! assert!(verifier.finish(&signature).unwrap());
41 //! use openssl::hash::MessageDigest;
42 //! use openssl::memcmp;
43 //! use openssl::pkey::PKey;
44 //! use openssl::sign::Signer;
47 //! let key = PKey::hmac(b"my secret").unwrap();
49 //! let data = b"hello, world!";
50 //! let data2 = b"hola, mundo!";
52 //! // Compute the HMAC
53 //! let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
54 //! signer.update(data).unwrap();
55 //! signer.update(data2).unwrap();
56 //! let hmac = signer.finish().unwrap();
58 //! // `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead
60 //! // Do not simply check for equality with `==`!
61 //! # let target = hmac.clone();
62 //! assert!(memcmp::eq(&hmac, &target));
65 use foreign_types
::ForeignTypeRef
;
66 use std
::io
::{self, Write}
;
67 use std
::marker
::PhantomData
;
71 use hash
::MessageDigest
;
72 use pkey
::{PKeyRef, PKeyCtxRef}
;
73 use error
::ErrorStack
;
76 use ffi
::{EVP_MD_CTX_new, EVP_MD_CTX_free}
;
77 #[cfg(any(ossl101, ossl102))]
78 use ffi
::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}
;
80 pub struct Signer
<'a
> {
81 md_ctx
: *mut ffi
::EVP_MD_CTX
,
82 pkey_ctx
: *mut ffi
::EVP_PKEY_CTX
,
83 pkey_pd
: PhantomData
<&'a PKeyRef
>,
86 impl<'a
> Drop
for Signer
<'a
> {
88 // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
90 EVP_MD_CTX_free(self.md_ctx
);
96 pub fn new(type_
: MessageDigest
, pkey
: &'a PKeyRef
) -> Result
<Signer
<'a
>, ErrorStack
> {
100 let ctx
= try
!(cvt_p(EVP_MD_CTX_new()));
101 let mut pctx
: *mut ffi
::EVP_PKEY_CTX
= ptr
::null_mut();
102 let r
= ffi
::EVP_DigestSignInit(
110 EVP_MD_CTX_free(ctx
);
111 return Err(ErrorStack
::get());
114 assert
!(!pctx
.is_null());
119 pkey_pd
: PhantomData
,
124 pub fn pkey_ctx(&self) -> &PKeyCtxRef
{
125 unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
128 pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef
{
129 unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
132 pub fn update(&mut self, buf
: &[u8]) -> Result
<(), ErrorStack
> {
134 cvt(ffi
::EVP_DigestUpdate(
136 buf
.as_ptr() as *const _
,
142 pub fn finish(&self) -> Result
<Vec
<u8>, ErrorStack
> {
145 try
!(cvt(ffi
::EVP_DigestSignFinal(
150 let mut buf
= vec
![0; len
];
151 try
!(cvt(ffi
::EVP_DigestSignFinal(
153 buf
.as_mut_ptr() as *mut _
,
156 // The advertised length is not always equal to the real length for things like DSA
163 impl<'a
> Write
for Signer
<'a
> {
164 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
165 try
!(self.update(buf
));
169 fn flush(&mut self) -> io
::Result
<()> {
174 pub struct Verifier
<'a
> {
175 md_ctx
: *mut ffi
::EVP_MD_CTX
,
176 pkey_ctx
: *mut ffi
::EVP_PKEY_CTX
,
177 pkey_pd
: PhantomData
<&'a PKeyRef
>,
180 impl<'a
> Drop
for Verifier
<'a
> {
182 // pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
184 EVP_MD_CTX_free(self.md_ctx
);
189 impl<'a
> Verifier
<'a
> {
190 pub fn new(type_
: MessageDigest
, pkey
: &'a PKeyRef
) -> Result
<Verifier
<'a
>, ErrorStack
> {
194 let ctx
= try
!(cvt_p(EVP_MD_CTX_new()));
195 let mut pctx
: *mut ffi
::EVP_PKEY_CTX
= ptr
::null_mut();
196 let r
= ffi
::EVP_DigestVerifyInit(
204 EVP_MD_CTX_free(ctx
);
205 return Err(ErrorStack
::get());
208 assert
!(!pctx
.is_null());
213 pkey_pd
: PhantomData
,
218 pub fn pkey_ctx(&self) -> &PKeyCtxRef
{
219 unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
222 pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef
{
223 unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
226 pub fn update(&mut self, buf
: &[u8]) -> Result
<(), ErrorStack
> {
228 cvt(ffi
::EVP_DigestUpdate(
230 buf
.as_ptr() as *const _
,
236 pub fn finish(&self, signature
: &[u8]) -> Result
<bool
, ErrorStack
> {
239 EVP_DigestVerifyFinal(self.md_ctx
, signature
.as_ptr() as *const _
, signature
.len());
243 ErrorStack
::get(); // discard error stack
246 _
=> Err(ErrorStack
::get()),
252 impl<'a
> Write
for Verifier
<'a
> {
253 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
254 try
!(self.update(buf
));
258 fn flush(&mut self) -> io
::Result
<()> {
264 use ffi
::EVP_DigestVerifyFinal
;
268 unsafe fn EVP_DigestVerifyFinal(
269 ctx
: *mut ffi
::EVP_MD_CTX
,
270 sigret
: *const ::libc
::c_uchar
,
271 siglen
: ::libc
::size_t
,
273 ffi
::EVP_DigestVerifyFinal(ctx
, sigret
as *mut _
, siglen
)
281 use hash
::MessageDigest
;
282 use sign
::{Signer, Verifier}
;
283 use ec
::{EcGroup, EcKey}
;
285 use rsa
::{Rsa, PKCS1_PADDING}
;
289 static INPUT
: &'
static [u8] = &[
407 static SIGNATURE
: &'
static [u8] = &[
668 let key
= include_bytes
!("../test/rsa.pem");
669 let private_key
= Rsa
::private_key_from_pem(key
).unwrap();
670 let pkey
= PKey
::from_rsa(private_key
).unwrap();
672 let mut signer
= Signer
::new(MessageDigest
::sha256(), &pkey
).unwrap();
673 assert_eq
!(signer
.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING
);
676 .set_rsa_padding(PKCS1_PADDING
)
678 signer
.update(INPUT
).unwrap();
679 let result
= signer
.finish().unwrap();
681 assert_eq
!(result
, SIGNATURE
);
686 let key
= include_bytes
!("../test/rsa.pem");
687 let private_key
= Rsa
::private_key_from_pem(key
).unwrap();
688 let pkey
= PKey
::from_rsa(private_key
).unwrap();
690 let mut verifier
= Verifier
::new(MessageDigest
::sha256(), &pkey
).unwrap();
692 verifier
.pkey_ctx_mut().rsa_padding().unwrap(),
695 verifier
.update(INPUT
).unwrap();
696 assert
!(verifier
.finish(SIGNATURE
).unwrap());
700 fn rsa_verify_invalid() {
701 let key
= include_bytes
!("../test/rsa.pem");
702 let private_key
= Rsa
::private_key_from_pem(key
).unwrap();
703 let pkey
= PKey
::from_rsa(private_key
).unwrap();
705 let mut verifier
= Verifier
::new(MessageDigest
::sha256(), &pkey
).unwrap();
706 verifier
.update(INPUT
).unwrap();
707 verifier
.update(b
"foobar").unwrap();
708 assert
!(!verifier
.finish(SIGNATURE
).unwrap());
712 pub fn dsa_sign_verify() {
713 let input
: Vec
<u8> = (0..25).cycle().take(1024).collect();
716 let key
= include_bytes
!("../test/dsa.pem");
717 PKey
::from_dsa(Dsa
::private_key_from_pem(key
).unwrap()).unwrap()
721 let key
= include_bytes
!("../test/dsa.pem.pub");
722 PKey
::from_dsa(Dsa
::public_key_from_pem(key
).unwrap()).unwrap()
725 let mut signer
= Signer
::new(MessageDigest
::sha1(), &private_key
).unwrap();
726 signer
.update(&input
).unwrap();
727 let sig
= signer
.finish().unwrap();
729 let mut verifier
= Verifier
::new(MessageDigest
::sha1(), &public_key
).unwrap();
730 verifier
.update(&input
).unwrap();
731 assert
!(verifier
.finish(&sig
).unwrap());
735 pub fn dsa_sign_verify_fail() {
736 let input
: Vec
<u8> = (0..25).cycle().take(1024).collect();
739 let key
= include_bytes
!("../test/dsa.pem");
740 PKey
::from_dsa(Dsa
::private_key_from_pem(key
).unwrap()).unwrap()
744 let key
= include_bytes
!("../test/dsa.pem.pub");
745 PKey
::from_dsa(Dsa
::public_key_from_pem(key
).unwrap()).unwrap()
748 let mut signer
= Signer
::new(MessageDigest
::sha1(), &private_key
).unwrap();
749 signer
.update(&input
).unwrap();
750 let mut sig
= signer
.finish().unwrap();
753 let mut verifier
= Verifier
::new(MessageDigest
::sha1(), &public_key
).unwrap();
754 verifier
.update(&input
).unwrap();
755 match verifier
.finish(&sig
) {
756 Ok(true) => panic
!("unexpected success"),
757 Ok(false) | Err(_
) => {}
761 fn test_hmac(ty
: MessageDigest
, tests
: &[(Vec
<u8>, Vec
<u8>, Vec
<u8>)]) {
762 for &(ref key
, ref data
, ref res
) in tests
.iter() {
763 let pkey
= PKey
::hmac(key
).unwrap();
764 let mut signer
= Signer
::new(ty
, &pkey
).unwrap();
765 signer
.update(data
).unwrap();
766 assert_eq
!(signer
.finish().unwrap(), *res
);
772 // test vectors from RFC 2202
773 let tests
: [(Vec
<u8>, Vec
<u8>, Vec
<u8>); 7] =
776 iter
::repeat(0x0b_u8).take(16).collect(),
777 b
"Hi There".to_vec(),
778 Vec
::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(),
782 b
"what do ya want for nothing?".to_vec(),
783 Vec
::from_hex("750c783e6ab0b503eaa86e310a5db738").unwrap(),
786 iter
::repeat(0xaa_u8).take(16).collect(),
787 iter
::repeat(0xdd_u8).take(50).collect(),
788 Vec
::from_hex("56be34521d144c88dbb8c733f0e8b3f6").unwrap(),
791 Vec
::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
792 iter
::repeat(0xcd_u8).take(50).collect(),
793 Vec
::from_hex("697eaf0aca3a3aea3a75164746ffaa79").unwrap(),
796 iter
::repeat(0x0c_u8).take(16).collect(),
797 b
"Test With Truncation".to_vec(),
798 Vec
::from_hex("56461ef2342edc00f9bab995690efd4c").unwrap(),
801 iter
::repeat(0xaa_u8).take(80).collect(),
802 b
"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
803 Vec
::from_hex("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd").unwrap(),
806 iter
::repeat(0xaa_u8).take(80).collect(),
807 b
"Test Using Larger Than Block-Size Key \
808 and Larger Than One Block-Size Data"
810 Vec
::from_hex("6f630fad67cda0ee1fb1f562db3aa53e").unwrap(),
814 test_hmac(MessageDigest
::md5(), &tests
);
819 // test vectors from RFC 2202
820 let tests
: [(Vec
<u8>, Vec
<u8>, Vec
<u8>); 7] =
823 iter
::repeat(0x0b_u8).take(20).collect(),
824 b
"Hi There".to_vec(),
825 Vec
::from_hex("b617318655057264e28bc0b6fb378c8ef146be00").unwrap(),
829 b
"what do ya want for nothing?".to_vec(),
830 Vec
::from_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79").unwrap(),
833 iter
::repeat(0xaa_u8).take(20).collect(),
834 iter
::repeat(0xdd_u8).take(50).collect(),
835 Vec
::from_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3").unwrap(),
838 Vec
::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(),
839 iter
::repeat(0xcd_u8).take(50).collect(),
840 Vec
::from_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da").unwrap(),
843 iter
::repeat(0x0c_u8).take(20).collect(),
844 b
"Test With Truncation".to_vec(),
845 Vec
::from_hex("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04").unwrap(),
848 iter
::repeat(0xaa_u8).take(80).collect(),
849 b
"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
850 Vec
::from_hex("aa4ae5e15272d00e95705637ce8a3b55ed402112").unwrap(),
853 iter
::repeat(0xaa_u8).take(80).collect(),
854 b
"Test Using Larger Than Block-Size Key \
855 and Larger Than One Block-Size Data"
857 Vec
::from_hex("e8e99d0f45237d786d6bbaa7965c7808bbff1a91").unwrap(),
861 test_hmac(MessageDigest
::sha1(), &tests
);
866 let group
= EcGroup
::from_curve_name(nid
::X9_62_PRIME256V1
).unwrap();
867 let key
= EcKey
::generate(&group
).unwrap();
868 let key
= PKey
::from_ec_key(key
).unwrap();
870 let mut signer
= Signer
::new(MessageDigest
::sha256(), &key
).unwrap();
871 signer
.update(b
"hello world").unwrap();
872 let signature
= signer
.finish().unwrap();
874 let mut verifier
= Verifier
::new(MessageDigest
::sha256(), &key
).unwrap();
875 verifier
.update(b
"hello world").unwrap();
876 assert
!(verifier
.finish(&signature
).unwrap());