Loading openssl-sys/src/evp.rs +25 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,10 @@ pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; #[cfg(ossl111)] pub const EVP_PKEY_ED25519: c_int = NID_ED25519; #[cfg(ossl111)] pub const EVP_PKEY_ED448: c_int = NID_ED448; pub const EVP_PKEY_HMAC: c_int = NID_hmac; pub const EVP_PKEY_CMAC: c_int = NID_cmac; Loading Loading @@ -153,6 +157,27 @@ cfg_if! { } } } cfg_if! { if #[cfg(ossl111)] { extern "C" { pub fn EVP_DigestSign( ctx: *mut EVP_MD_CTX, sigret: *mut c_uchar, siglen: *mut size_t, tbs: *const c_uchar, tbslen: size_t ) -> c_int; pub fn EVP_DigestVerify( ctx: *mut EVP_MD_CTX, sigret: *const c_uchar, siglen: size_t, tbs: *const c_uchar, tbslen: size_t ) -> c_int; } } } cfg_if! { if #[cfg(any(ossl102, libressl280))] { extern "C" { Loading openssl-sys/src/obj_mac.rs +4 −0 Original line number Diff line number Diff line Loading @@ -912,3 +912,7 @@ pub const NID_rc4_hmac_md5: c_int = 915; pub const NID_aes_128_cbc_hmac_sha1: c_int = 916; pub const NID_aes_192_cbc_hmac_sha1: c_int = 917; pub const NID_aes_256_cbc_hmac_sha1: c_int = 918; #[cfg(ossl111)] pub const NID_ED25519: c_int = 1087; #[cfg(ossl111)] pub const NID_ED448: c_int = 1088; openssl/src/pkey.rs +39 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,11 @@ impl Id { pub const DSA: Id = Id(ffi::EVP_PKEY_DSA); pub const DH: Id = Id(ffi::EVP_PKEY_DH); pub const EC: Id = Id(ffi::EVP_PKEY_EC); #[cfg(ossl111)] pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519); #[cfg(ossl111)] pub const ED448: Id = Id(ffi::EVP_PKEY_ED448); } /// A trait indicating that a key has parameters. Loading Loading @@ -426,6 +431,40 @@ impl PKey<Private> { } } #[cfg(ossl110)] fn generate_eddsa(nid: c_int) -> Result<PKey<Private>, ErrorStack> { unsafe { let kctx = cvt_p(ffi::EVP_PKEY_CTX_new_id(nid, ptr::null_mut()))?; let ret = cvt(ffi::EVP_PKEY_keygen_init(kctx)); if let Err(e) = ret { ffi::EVP_PKEY_CTX_free(kctx); return Err(e); } let mut key = ptr::null_mut(); let ret = cvt(ffi::EVP_PKEY_keygen(kctx, &mut key)); ffi::EVP_PKEY_CTX_free(kctx); if let Err(e) = ret { return Err(e); } Ok(PKey::from_ptr(key)) } } /// Generates a new private Ed25519 key #[cfg(ossl111)] pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> { PKey::generate_eddsa(ffi::EVP_PKEY_ED25519) } /// Generates a new private Ed448 key #[cfg(ossl111)] pub fn generate_ed448() -> Result<PKey<Private>, ErrorStack> { PKey::generate_eddsa(ffi::EVP_PKEY_ED448) } private_key_from_pem! { /// Deserializes a private key from a PEM-encoded key type specific format. /// Loading openssl/src/sign.rs +135 −2 Original line number Diff line number Diff line Loading @@ -126,6 +126,9 @@ impl<'a> Drop for Signer<'a> { impl<'a> Signer<'a> { /// Creates a new `Signer`. /// /// This cannot be used with Ed25519 or Ed448 keys. Please refer to /// `new_without_digest`. /// /// OpenSSL documentation at [`EVP_DigestSignInit`]. /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html Loading @@ -138,7 +141,9 @@ impl<'a> Signer<'a> { /// Creates a new `Signer` without a digest. /// /// This can be used to create a CMAC. /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. /// It can also be used to create a CMAC. /// /// OpenSSL documentation at [`EVP_DigestSignInit`]. /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html Loading Loading @@ -249,6 +254,9 @@ impl<'a> Signer<'a> { /// Feeds more data into the `Signer`. /// /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. /// Use `sign_oneshot` instead. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. /// /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html Loading @@ -272,6 +280,11 @@ impl<'a> Signer<'a> { /// /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html pub fn len(&self) -> Result<usize, ErrorStack> { self.len_intern() } #[cfg(not(ossl111))] fn len_intern(&self) -> Result<usize, ErrorStack> { unsafe { let mut len = 0; cvt(ffi::EVP_DigestSignFinal( Loading @@ -283,6 +296,21 @@ impl<'a> Signer<'a> { } } #[cfg(ossl111)] fn len_intern(&self) -> Result<usize, ErrorStack> { unsafe { let mut len = 0; cvt(ffi::EVP_DigestSign( self.md_ctx, ptr::null_mut(), &mut len, ptr::null(), 0 ))?; Ok(len) } } /// Writes the signature into the provided buffer, returning the number of bytes written. /// /// This method will fail if the buffer is not large enough for the signature. Use the `len` Loading Loading @@ -313,6 +341,44 @@ impl<'a> Signer<'a> { buf.truncate(len); Ok(buf) } /// Signs the data in data_buf and writes the siganture into the buffer sig_buf, returning the /// number of bytes written. /// /// For PureEdDSA (Ed25519 and Ed448 keys) this is the only way to sign data. /// /// This method will fail if the buffer is not large enough for the signature. Use the `len` /// method to get an upper bound on the required size. /// /// OpenSSL documentation at [`EVP_DigestSign`]. /// /// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html #[cfg(ossl111)] pub fn sign_oneshot(&self, sig_buf: &mut [u8], data_buf: &[u8]) -> Result<usize, ErrorStack> { unsafe { let mut sig_len = sig_buf.len(); cvt(ffi::EVP_DigestSign( self.md_ctx, sig_buf.as_mut_ptr() as *mut _, &mut sig_len, data_buf.as_ptr() as *const _, data_buf.len() ))?; Ok(sig_len) } } /// Returns the signature. /// /// This is a simple convenience wrapper over `len` and `sign_oneshot`. #[cfg(ossl111)] pub fn sign_oneshot_to_vec(&self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> { let mut sig_buf = vec![0; self.len()?]; let len = self.sign_oneshot(&mut sig_buf, data_buf)?; // The advertised length is not always equal to the real length for things like DSA sig_buf.truncate(len); Ok(sig_buf) } } impl<'a> Write for Signer<'a> { Loading Loading @@ -348,10 +414,35 @@ impl<'a> Drop for Verifier<'a> { impl<'a> Verifier<'a> { /// Creates a new `Verifier`. /// /// This cannot be used with Ed25519 or Ed448 keys. Please refer to /// `new_without_digest`. /// /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. /// /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic, { Verifier::new_intern(Some(type_), pkey) } /// Creates a new `Verifier` without a digest. /// /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. /// /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. /// /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic { Verifier::new_intern(None, pkey) } fn new_intern<T>(type_: Option<MessageDigest>, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic, { Loading @@ -363,7 +454,7 @@ impl<'a> Verifier<'a> { let r = ffi::EVP_DigestVerifyInit( ctx, &mut pctx, type_.as_ptr(), type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), ptr::null_mut(), pkey.as_ptr(), ); Loading Loading @@ -448,6 +539,9 @@ impl<'a> Verifier<'a> { /// Feeds more data into the `Verifier`. /// /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. /// Use `verify_oneshot` instead. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. /// /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html Loading Loading @@ -481,6 +575,32 @@ impl<'a> Verifier<'a> { } } } /// Determines if the data given in buf matches the provided signature. /// /// OpenSSL documentation at [`EVP_DigestVerify`]. /// /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html #[cfg(ossl111)] pub fn verify_oneshot(&self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = ffi::EVP_DigestVerify( self.md_ctx, signature.as_ptr() as *const _, signature.len(), buf.as_ptr() as *const _, buf.len(), ); match r { 1 => Ok(true), 0 => { ErrorStack::get(); Ok(false) }, _ => Err(ErrorStack::get()), } } } } impl<'a> Write for Verifier<'a> { Loading Loading @@ -705,6 +825,19 @@ mod test { } #[test] #[cfg(ossl111)] fn eddsa() { let key = PKey::generate_ed25519().unwrap(); let signer = Signer::new_without_digest(&key).unwrap(); let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap(); let verifier = Verifier::new_without_digest(&key).unwrap(); assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap()); } #[test] #[cfg(ossl111)] fn rsa_sign_verify() { let key = include_bytes!("../test/rsa.pem"); let private_key = Rsa::private_key_from_pem(key).unwrap(); Loading Loading
openssl-sys/src/evp.rs +25 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,10 @@ pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; #[cfg(ossl111)] pub const EVP_PKEY_ED25519: c_int = NID_ED25519; #[cfg(ossl111)] pub const EVP_PKEY_ED448: c_int = NID_ED448; pub const EVP_PKEY_HMAC: c_int = NID_hmac; pub const EVP_PKEY_CMAC: c_int = NID_cmac; Loading Loading @@ -153,6 +157,27 @@ cfg_if! { } } } cfg_if! { if #[cfg(ossl111)] { extern "C" { pub fn EVP_DigestSign( ctx: *mut EVP_MD_CTX, sigret: *mut c_uchar, siglen: *mut size_t, tbs: *const c_uchar, tbslen: size_t ) -> c_int; pub fn EVP_DigestVerify( ctx: *mut EVP_MD_CTX, sigret: *const c_uchar, siglen: size_t, tbs: *const c_uchar, tbslen: size_t ) -> c_int; } } } cfg_if! { if #[cfg(any(ossl102, libressl280))] { extern "C" { Loading
openssl-sys/src/obj_mac.rs +4 −0 Original line number Diff line number Diff line Loading @@ -912,3 +912,7 @@ pub const NID_rc4_hmac_md5: c_int = 915; pub const NID_aes_128_cbc_hmac_sha1: c_int = 916; pub const NID_aes_192_cbc_hmac_sha1: c_int = 917; pub const NID_aes_256_cbc_hmac_sha1: c_int = 918; #[cfg(ossl111)] pub const NID_ED25519: c_int = 1087; #[cfg(ossl111)] pub const NID_ED448: c_int = 1088;
openssl/src/pkey.rs +39 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,11 @@ impl Id { pub const DSA: Id = Id(ffi::EVP_PKEY_DSA); pub const DH: Id = Id(ffi::EVP_PKEY_DH); pub const EC: Id = Id(ffi::EVP_PKEY_EC); #[cfg(ossl111)] pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519); #[cfg(ossl111)] pub const ED448: Id = Id(ffi::EVP_PKEY_ED448); } /// A trait indicating that a key has parameters. Loading Loading @@ -426,6 +431,40 @@ impl PKey<Private> { } } #[cfg(ossl110)] fn generate_eddsa(nid: c_int) -> Result<PKey<Private>, ErrorStack> { unsafe { let kctx = cvt_p(ffi::EVP_PKEY_CTX_new_id(nid, ptr::null_mut()))?; let ret = cvt(ffi::EVP_PKEY_keygen_init(kctx)); if let Err(e) = ret { ffi::EVP_PKEY_CTX_free(kctx); return Err(e); } let mut key = ptr::null_mut(); let ret = cvt(ffi::EVP_PKEY_keygen(kctx, &mut key)); ffi::EVP_PKEY_CTX_free(kctx); if let Err(e) = ret { return Err(e); } Ok(PKey::from_ptr(key)) } } /// Generates a new private Ed25519 key #[cfg(ossl111)] pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> { PKey::generate_eddsa(ffi::EVP_PKEY_ED25519) } /// Generates a new private Ed448 key #[cfg(ossl111)] pub fn generate_ed448() -> Result<PKey<Private>, ErrorStack> { PKey::generate_eddsa(ffi::EVP_PKEY_ED448) } private_key_from_pem! { /// Deserializes a private key from a PEM-encoded key type specific format. /// Loading
openssl/src/sign.rs +135 −2 Original line number Diff line number Diff line Loading @@ -126,6 +126,9 @@ impl<'a> Drop for Signer<'a> { impl<'a> Signer<'a> { /// Creates a new `Signer`. /// /// This cannot be used with Ed25519 or Ed448 keys. Please refer to /// `new_without_digest`. /// /// OpenSSL documentation at [`EVP_DigestSignInit`]. /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html Loading @@ -138,7 +141,9 @@ impl<'a> Signer<'a> { /// Creates a new `Signer` without a digest. /// /// This can be used to create a CMAC. /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. /// It can also be used to create a CMAC. /// /// OpenSSL documentation at [`EVP_DigestSignInit`]. /// /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html Loading Loading @@ -249,6 +254,9 @@ impl<'a> Signer<'a> { /// Feeds more data into the `Signer`. /// /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. /// Use `sign_oneshot` instead. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. /// /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html Loading @@ -272,6 +280,11 @@ impl<'a> Signer<'a> { /// /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html pub fn len(&self) -> Result<usize, ErrorStack> { self.len_intern() } #[cfg(not(ossl111))] fn len_intern(&self) -> Result<usize, ErrorStack> { unsafe { let mut len = 0; cvt(ffi::EVP_DigestSignFinal( Loading @@ -283,6 +296,21 @@ impl<'a> Signer<'a> { } } #[cfg(ossl111)] fn len_intern(&self) -> Result<usize, ErrorStack> { unsafe { let mut len = 0; cvt(ffi::EVP_DigestSign( self.md_ctx, ptr::null_mut(), &mut len, ptr::null(), 0 ))?; Ok(len) } } /// Writes the signature into the provided buffer, returning the number of bytes written. /// /// This method will fail if the buffer is not large enough for the signature. Use the `len` Loading Loading @@ -313,6 +341,44 @@ impl<'a> Signer<'a> { buf.truncate(len); Ok(buf) } /// Signs the data in data_buf and writes the siganture into the buffer sig_buf, returning the /// number of bytes written. /// /// For PureEdDSA (Ed25519 and Ed448 keys) this is the only way to sign data. /// /// This method will fail if the buffer is not large enough for the signature. Use the `len` /// method to get an upper bound on the required size. /// /// OpenSSL documentation at [`EVP_DigestSign`]. /// /// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html #[cfg(ossl111)] pub fn sign_oneshot(&self, sig_buf: &mut [u8], data_buf: &[u8]) -> Result<usize, ErrorStack> { unsafe { let mut sig_len = sig_buf.len(); cvt(ffi::EVP_DigestSign( self.md_ctx, sig_buf.as_mut_ptr() as *mut _, &mut sig_len, data_buf.as_ptr() as *const _, data_buf.len() ))?; Ok(sig_len) } } /// Returns the signature. /// /// This is a simple convenience wrapper over `len` and `sign_oneshot`. #[cfg(ossl111)] pub fn sign_oneshot_to_vec(&self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> { let mut sig_buf = vec![0; self.len()?]; let len = self.sign_oneshot(&mut sig_buf, data_buf)?; // The advertised length is not always equal to the real length for things like DSA sig_buf.truncate(len); Ok(sig_buf) } } impl<'a> Write for Signer<'a> { Loading Loading @@ -348,10 +414,35 @@ impl<'a> Drop for Verifier<'a> { impl<'a> Verifier<'a> { /// Creates a new `Verifier`. /// /// This cannot be used with Ed25519 or Ed448 keys. Please refer to /// `new_without_digest`. /// /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. /// /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic, { Verifier::new_intern(Some(type_), pkey) } /// Creates a new `Verifier` without a digest. /// /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. /// /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. /// /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic { Verifier::new_intern(None, pkey) } fn new_intern<T>(type_: Option<MessageDigest>, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> where T: HasPublic, { Loading @@ -363,7 +454,7 @@ impl<'a> Verifier<'a> { let r = ffi::EVP_DigestVerifyInit( ctx, &mut pctx, type_.as_ptr(), type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), ptr::null_mut(), pkey.as_ptr(), ); Loading Loading @@ -448,6 +539,9 @@ impl<'a> Verifier<'a> { /// Feeds more data into the `Verifier`. /// /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. /// Use `verify_oneshot` instead. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. /// /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html Loading Loading @@ -481,6 +575,32 @@ impl<'a> Verifier<'a> { } } } /// Determines if the data given in buf matches the provided signature. /// /// OpenSSL documentation at [`EVP_DigestVerify`]. /// /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html #[cfg(ossl111)] pub fn verify_oneshot(&self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = ffi::EVP_DigestVerify( self.md_ctx, signature.as_ptr() as *const _, signature.len(), buf.as_ptr() as *const _, buf.len(), ); match r { 1 => Ok(true), 0 => { ErrorStack::get(); Ok(false) }, _ => Err(ErrorStack::get()), } } } } impl<'a> Write for Verifier<'a> { Loading Loading @@ -705,6 +825,19 @@ mod test { } #[test] #[cfg(ossl111)] fn eddsa() { let key = PKey::generate_ed25519().unwrap(); let signer = Signer::new_without_digest(&key).unwrap(); let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap(); let verifier = Verifier::new_without_digest(&key).unwrap(); assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap()); } #[test] #[cfg(ossl111)] fn rsa_sign_verify() { let key = include_bytes!("../test/rsa.pem"); let private_key = Rsa::private_key_from_pem(key).unwrap(); Loading