Unverified Commit d1724d49 authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #786 from sfackler/sign-tweaks

Sign tweaks
parents 13a13727 531ca4a0
Loading
Loading
Loading
Loading
+172 −488
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@
//! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap();
//! verifier.update(data).unwrap();
//! verifier.update(data2).unwrap();
//! assert!(verifier.finish(&signature).unwrap());
//! assert!(verifier.verify(&signature).unwrap());
//! ```
//!
//! Compute an HMAC:
@@ -53,7 +53,7 @@
//! let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
//! signer.update(data).unwrap();
//! signer.update(data2).unwrap();
//! let hmac = signer.finish().unwrap();
//! let hmac = signer.sign_to_vec().unwrap();
//!
//! // `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead
//! //
@@ -69,14 +69,15 @@ use std::ptr;

use {cvt, cvt_p};
use hash::MessageDigest;
use pkey::{PKeyRef, PKeyCtxRef};
use pkey::{PKeyCtxRef, PKeyRef};
use error::ErrorStack;

#[cfg(ossl110)]
use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
#[cfg(any(ossl101, ossl102))]
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};

/// A type which computes cryptographic signatures of data.
pub struct Signer<'a> {
    md_ctx: *mut ffi::EVP_MD_CTX,
    pkey_ctx: *mut ffi::EVP_PKEY_CTX,
@@ -93,6 +94,11 @@ impl<'a> Drop for Signer<'a> {
}

impl<'a> Signer<'a> {
    /// Creates a new `Signer`.
    ///
    /// OpenSSL documentation at [`EVP_DigestSignInit`].
    ///
    /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html
    pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Signer<'a>, ErrorStack> {
        unsafe {
            ffi::init();
@@ -121,14 +127,21 @@ impl<'a> Signer<'a> {
        }
    }

    /// Returns a shared reference to the `PKeyCtx` associated with the `Signer`.
    pub fn pkey_ctx(&self) -> &PKeyCtxRef {
        unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
    }

    /// Returns a mutable reference to the `PKeyCtx` associated with the `Signer`.
    pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
        unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
    }

    /// Feeds more data into the `Signer`.
    ///
    /// OpenSSL documentation at [`EVP_DigestUpdate`].
    ///
    /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
    pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
        unsafe {
            cvt(ffi::EVP_DigestUpdate(
@@ -140,7 +153,14 @@ impl<'a> Signer<'a> {
    }

    /// Computes an upper bound on the signature length.
    pub fn finish_len(&self) -> Result<usize, ErrorStack> {
    ///
    /// The actual signature may be shorter than this value. Check the return value of
    /// `sign` to get the exact length.
    ///
    /// OpenSSL documentation at [`EVP_DigestSignFinal`].
    ///
    /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html
    pub fn len(&self) -> Result<usize, ErrorStack> {
        unsafe {
            let mut len = 0;
            cvt(ffi::EVP_DigestSignFinal(
@@ -152,13 +172,15 @@ impl<'a> Signer<'a> {
        }
    }

    /// Outputs the signature into the provided buffer, returning the
    /// length of that buffer.
    /// 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, one can use `finish_len` to get an upper bound
    /// on the required size.
    pub fn finish_into(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
    /// 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_DigestSignFinal`].
    ///
    /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestSignFinal.html
    pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> {
        unsafe {
            let mut len = buf.len();
            cvt(ffi::EVP_DigestSignFinal(
@@ -170,16 +192,21 @@ impl<'a> Signer<'a> {
        }
    }

    /// Combines `self.finish_len()` and `self.finish_into()`,
    /// allocating a vector of the correct size for the signature.
    pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
        let mut buf = vec![0; self.finish_len()?];
        let len = self.finish_into(&mut buf)?;
        // The advertised length is not always equal to the real
        // length for things like DSA
    /// Returns the signature.
    ///
    /// This is a simple convenience wrapper over `len` and `sign`.
    pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> {
        let mut buf = vec![0; self.len()?];
        let len = self.sign(&mut buf)?;
        // The advertised length is not always equal to the real length for things like DSA
        buf.truncate(len);
        Ok(buf)
    }

    #[deprecated(since = "0.9.23", note = "renamed to sign_to_vec")]
    pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
        self.sign_to_vec()
    }
}

impl<'a> Write for Signer<'a> {
@@ -208,7 +235,13 @@ impl<'a> Drop for Verifier<'a> {
    }
}

/// A type which verifies cryptographic signatures of data.
impl<'a> Verifier<'a> {
    /// Creates a new `Verifier`.
    ///
    /// OpenSSL documentation at [`EVP_DigestVerifyInit`].
    ///
    /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html
    pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Verifier<'a>, ErrorStack> {
        unsafe {
            ffi::init();
@@ -237,14 +270,21 @@ impl<'a> Verifier<'a> {
        }
    }

    /// Returns a shared reference to the `PKeyCtx` associated with the `Verifier`.
    pub fn pkey_ctx(&self) -> &PKeyCtxRef {
        unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
    }

    /// Returns a mutable reference to the `PKeyCtx` associated with the `Verifier`.
    pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
        unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
    }

    /// Feeds more data into the `Verifier`.
    ///
    /// OpenSSL documentation at [`EVP_DigestUpdate`].
    ///
    /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html
    pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
        unsafe {
            cvt(ffi::EVP_DigestUpdate(
@@ -255,7 +295,12 @@ impl<'a> Verifier<'a> {
        }
    }

    pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
    /// Determines if the data fed into the `Verifier` matches the provided signature.
    ///
    /// OpenSSL documentation at [`EVP_DigestVerifyFinal`].
    ///
    /// [`EVP_DigestVerifyFinal`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyFinal.html
    pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
        unsafe {
            let r =
                EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
@@ -269,6 +314,11 @@ impl<'a> Verifier<'a> {
            }
        }
    }

    #[deprecated(since = "0.9.23", note = "renamed to `verify`")]
    pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
        self.verify(signature)
    }
}

impl<'a> Write for Verifier<'a> {
@@ -297,393 +347,29 @@ unsafe fn EVP_DigestVerifyFinal(

#[cfg(test)]
mod test {
    use hex::FromHex;
    use hex::{FromHex, ToHex};
    use std::iter;

    use hash::MessageDigest;
    use sign::{Signer, Verifier};
    use ec::{EcGroup, EcKey};
    use nid;
    use rsa::{Rsa, PKCS1_PADDING};
    use rsa::{PKCS1_PADDING, Rsa};
    use dsa::Dsa;
    use pkey::PKey;

    static INPUT: &'static [u8] = &[
        101,
        121,
        74,
        104,
        98,
        71,
        99,
        105,
        79,
        105,
        74,
        83,
        85,
        122,
        73,
        49,
        78,
        105,
        74,
        57,
        46,
        101,
        121,
        74,
        112,
        99,
        51,
        77,
        105,
        79,
        105,
        74,
        113,
        98,
        50,
        85,
        105,
        76,
        65,
        48,
        75,
        73,
        67,
        74,
        108,
        101,
        72,
        65,
        105,
        79,
        106,
        69,
        122,
        77,
        68,
        65,
        52,
        77,
        84,
        107,
        122,
        79,
        68,
        65,
        115,
        68,
        81,
        111,
        103,
        73,
        109,
        104,
        48,
        100,
        72,
        65,
        54,
        76,
        121,
        57,
        108,
        101,
        71,
        70,
        116,
        99,
        71,
        120,
        108,
        76,
        109,
        78,
        118,
        98,
        83,
        57,
        112,
        99,
        49,
        57,
        121,
        98,
        50,
        57,
        48,
        73,
        106,
        112,
        48,
        99,
        110,
        86,
        108,
        102,
        81,
    ];
    const INPUT: &'static str =
        "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
         654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\
         6d4e76625339706331397962323930496a7030636e566c6651";

    static SIGNATURE: &'static [u8] = &[
        112,
        46,
        33,
        137,
        67,
        232,
        143,
        209,
        30,
        181,
        216,
        45,
        191,
        120,
        69,
        243,
        65,
        6,
        174,
        27,
        129,
        255,
        247,
        115,
        17,
        22,
        173,
        209,
        113,
        125,
        131,
        101,
        109,
        66,
        10,
        253,
        60,
        150,
        238,
        221,
        115,
        162,
        102,
        62,
        81,
        102,
        104,
        123,
        0,
        11,
        135,
        34,
        110,
        1,
        135,
        237,
        16,
        115,
        249,
        69,
        229,
        130,
        173,
        252,
        239,
        22,
        216,
        90,
        121,
        142,
        232,
        198,
        109,
        219,
        61,
        184,
        151,
        91,
        23,
        208,
        148,
        2,
        190,
        237,
        213,
        217,
        217,
        112,
        7,
        16,
        141,
        178,
        129,
        96,
        213,
        248,
        4,
        12,
        167,
        68,
        87,
        98,
        184,
        31,
        190,
        127,
        249,
        217,
        46,
        10,
        231,
        111,
        36,
        242,
        91,
        51,
        187,
        230,
        244,
        74,
        230,
        30,
        177,
        4,
        10,
        203,
        32,
        4,
        77,
        62,
        249,
        18,
        142,
        212,
        1,
        48,
        121,
        91,
        212,
        189,
        59,
        65,
        238,
        202,
        208,
        102,
        171,
        101,
        25,
        129,
        253,
        228,
        141,
        247,
        127,
        55,
        45,
        195,
        139,
        159,
        175,
        221,
        59,
        239,
        177,
        139,
        93,
        163,
        204,
        60,
        46,
        176,
        47,
        158,
        58,
        65,
        214,
        18,
        202,
        173,
        21,
        145,
        18,
        115,
        160,
        95,
        35,
        185,
        232,
        56,
        250,
        175,
        132,
        157,
        105,
        132,
        41,
        239,
        90,
        30,
        136,
        121,
        130,
        54,
        195,
        212,
        14,
        96,
        69,
        34,
        165,
        68,
        200,
        242,
        122,
        122,
        45,
        184,
        6,
        99,
        209,
        108,
        247,
        202,
        234,
        86,
        222,
        64,
        92,
        178,
        33,
        90,
        69,
        178,
        194,
        85,
        102,
        181,
        90,
        193,
        167,
        72,
        160,
        112,
        223,
        200,
        163,
        42,
        70,
        149,
        67,
        208,
        25,
        238,
        251,
        71,
    ];
    const SIGNATURE: &'static str =
        "702e218943e88fd11eb5d82dbf7845f34106ae1b81fff7731116add1717d83656d420afd3c96eedd73a2663e51\
         66687b000b87226e0187ed1073f945e582adfcef16d85a798ee8c66ddb3db8975b17d09402beedd5d9d9700710\
         8db28160d5f8040ca7445762b81fbe7ff9d92e0ae76f24f25b33bbe6f44ae61eb1040acb20044d3ef9128ed401\
         30795bd4bd3b41eecad066ab651981fde48df77f372dc38b9fafdd3befb18b5da3cc3c2eb02f9e3a41d612caad\
         15911273a05f23b9e838faaf849d698429ef5a1e88798236c3d40e604522a544c8f27a7a2db80663d16cf7caea\
         56de405cb2215a45b2c25566b55ac1a748a070dfc8a32a469543d019eefb47";

    #[test]
    fn rsa_sign() {
@@ -697,10 +383,10 @@ mod test {
            .pkey_ctx_mut()
            .set_rsa_padding(PKCS1_PADDING)
            .unwrap();
        signer.update(INPUT).unwrap();
        let result = signer.finish().unwrap();
        signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
        let result = signer.sign_to_vec().unwrap();

        assert_eq!(result, SIGNATURE);
        assert_eq!(result.to_hex(), SIGNATURE);
    }

    #[test]
@@ -714,8 +400,8 @@ mod test {
            verifier.pkey_ctx_mut().rsa_padding().unwrap(),
            PKCS1_PADDING
        );
        verifier.update(INPUT).unwrap();
        assert!(verifier.finish(SIGNATURE).unwrap());
        verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
        assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
    }

    #[test]
@@ -725,9 +411,9 @@ mod test {
        let pkey = PKey::from_rsa(private_key).unwrap();

        let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
        verifier.update(INPUT).unwrap();
        verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap();
        verifier.update(b"foobar").unwrap();
        assert!(!verifier.finish(SIGNATURE).unwrap());
        assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap());
    }

    #[test]
@@ -746,11 +432,11 @@ mod test {

        let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
        signer.update(&input).unwrap();
        let sig = signer.finish().unwrap();
        let sig = signer.sign_to_vec().unwrap();

        let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
        verifier.update(&input).unwrap();
        assert!(verifier.finish(&sig).unwrap());
        assert!(verifier.verify(&sig).unwrap());
    }

    #[test]
@@ -769,12 +455,12 @@ mod test {

        let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
        signer.update(&input).unwrap();
        let mut sig = signer.finish().unwrap();
        let mut sig = signer.sign_to_vec().unwrap();
        sig[0] -= 1;

        let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
        verifier.update(&input).unwrap();
        match verifier.finish(&sig) {
        match verifier.verify(&sig) {
            Ok(true) => panic!("unexpected success"),
            Ok(false) | Err(_) => {}
        }
@@ -785,15 +471,14 @@ mod test {
            let pkey = PKey::hmac(key).unwrap();
            let mut signer = Signer::new(ty, &pkey).unwrap();
            signer.update(data).unwrap();
            assert_eq!(signer.finish().unwrap(), *res);
            assert_eq!(signer.sign_to_vec().unwrap(), *res);
        }
    }

    #[test]
    fn hmac_md5() {
        // test vectors from RFC 2202
        let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] =
            [
        let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [
            (
                iter::repeat(0x0b_u8).take(16).collect(),
                b"Hi There".to_vec(),
@@ -839,8 +524,7 @@ mod test {
    #[test]
    fn hmac_sha1() {
        // test vectors from RFC 2202
        let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] =
            [
        let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [
            (
                iter::repeat(0x0b_u8).take(20).collect(),
                b"Hi There".to_vec(),
@@ -895,6 +579,6 @@ mod test {

        let mut verifier = Verifier::new(MessageDigest::sha256(), &key).unwrap();
        verifier.update(b"hello world").unwrap();
        assert!(verifier.finish(&signature).unwrap());
        assert!(verifier.verify(&signature).unwrap());
    }
}