c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

rsa_validator.rs (6296B)


      1 // Copyright 2022 Adobe. All rights reserved.
      2 // This file is licensed to you under the Apache License,
      3 // Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
      4 // or the MIT license (http://opensource.org/licenses/MIT),
      5 // at your option.
      6 
      7 // Unless required by applicable law or agreed to in writing,
      8 // this software is distributed on an "AS IS" BASIS, WITHOUT
      9 // WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
     10 // implied. See the LICENSE-MIT and LICENSE-APACHE files for the
     11 // specific language governing permissions and limitations under
     12 // each license.
     13 
     14 use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa};
     15 
     16 use crate::{validator::CoseValidator, Error, Result, SigningAlg};
     17 
     18 pub struct RsaValidator {
     19     alg: SigningAlg,
     20 }
     21 
     22 impl RsaValidator {
     23     pub const fn new(alg: SigningAlg) -> Self {
     24         RsaValidator { alg }
     25     }
     26 }
     27 
     28 impl CoseValidator for RsaValidator {
     29     fn validate(&self, sig: &[u8], data: &[u8], pkey: &[u8]) -> Result<bool> {
     30         let rsa = Rsa::public_key_from_der(pkey)?;
     31 
     32         // rebuild RSA keys to eliminate incompatible values
     33         let n = rsa.n().to_owned()?;
     34         let e = rsa.e().to_owned()?;
     35 
     36         let new_rsa = Rsa::from_public_components(n, e)?;
     37 
     38         let pkey = PKey::from_rsa(new_rsa)?;
     39 
     40         let mut verifier = match self.alg {
     41             SigningAlg::Ps256 => {
     42                 let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha256(), &pkey)?;
     43                 verifier.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; // use C2PA recommended padding
     44                 verifier.set_rsa_mgf1_md(MessageDigest::sha256())?;
     45                 verifier
     46             }
     47             SigningAlg::Ps384 => {
     48                 let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha384(), &pkey)?;
     49                 verifier.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; // use C2PA recommended padding
     50                 verifier.set_rsa_mgf1_md(MessageDigest::sha384())?;
     51                 verifier
     52             }
     53             SigningAlg::Ps512 => {
     54                 let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha512(), &pkey)?;
     55                 verifier.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?; // use C2PA recommended padding
     56                 verifier.set_rsa_mgf1_md(MessageDigest::sha512())?;
     57                 verifier
     58             }
     59             // "rs256" => openssl::sign::Verifier::new(MessageDigest::sha256(), &pkey)?,
     60             // "rs384" => openssl::sign::Verifier::new(MessageDigest::sha384(), &pkey)?,
     61             // "rs512" => openssl::sign::Verifier::new(MessageDigest::sha512(), &pkey)?,
     62             _ => return Err(Error::UnsupportedType),
     63         };
     64 
     65         verifier
     66             .verify_oneshot(sig, data)
     67             .map_err(|_err| Error::CoseSignature)
     68     }
     69 }
     70 
     71 #[allow(unused_imports)]
     72 #[allow(clippy::unwrap_used)]
     73 #[cfg(test)]
     74 mod tests {
     75 
     76     use super::*;
     77     use crate::{signer::ConfigurableSigner, Signer, SigningAlg};
     78 
     79     #[test]
     80     fn verify_rsa_signatures() {
     81         let cert_bytes = include_bytes!("../../tests/fixtures/temp_cert.data");
     82         let key_bytes = include_bytes!("../../tests/fixtures/temp_priv_key.data");
     83 
     84         let signcert = openssl::x509::X509::from_pem(cert_bytes).unwrap();
     85         let pkey = signcert.public_key().unwrap().public_key_to_der().unwrap();
     86 
     87         let data = b"some sample content to sign";
     88 
     89         // println!("Test RS256");
     90         // let mut signer = crate::openssl::RsaSigner::from_signcert_and_pkey(
     91         //     cert_bytes,
     92         //     key_bytes,
     93         //     "rs256".to_string(),
     94         //     None,
     95         // )
     96         // .unwrap();
     97 
     98         // let mut signature = signer.sign(data).unwrap();
     99         // println!("signature len = {}", signature.len());
    100         // let mut validator = RsaValidator::new("rs256");
    101         // assert!(validator.validate(&signature, data, &pkey).unwrap());
    102 
    103         // println!("Test RS384");
    104         // signer = crate::openssl::RsaSigner::from_signcert_and_pkey(
    105         //     cert_bytes,
    106         //     key_bytes,
    107         //     "rs384".to_string(),
    108         //     None,
    109         // )
    110         // .unwrap();
    111 
    112         // signature = signer.sign(data).unwrap();
    113         // println!("signature len = {}", signature.len());
    114         // validator = RsaValidator::new("rs384");
    115         // assert!(validator.validate(&signature, data, &pkey).unwrap());
    116 
    117         // println!("Test RS512");
    118         // signer = crate::openssl::RsaSigner::from_signcert_and_pkey(
    119         //     cert_bytes,
    120         //     key_bytes,
    121         //     "rs512".to_string(),
    122         //     None,
    123         // )
    124         // .unwrap();
    125 
    126         // signature = signer.sign(data).unwrap();
    127         // println!("signature len = {}", signature.len());
    128         // validator = RsaValidator::new("rs512");
    129         // assert!(validator.validate(&signature, data, &pkey).unwrap());
    130 
    131         println!("Test PS256");
    132         let mut signer = crate::openssl::RsaSigner::from_signcert_and_pkey(
    133             cert_bytes,
    134             key_bytes,
    135             SigningAlg::Ps256,
    136             None,
    137         )
    138         .unwrap();
    139 
    140         let mut signature = signer.sign(data).unwrap();
    141         println!("signature len = {}", signature.len());
    142         let mut validator = RsaValidator::new(SigningAlg::Ps256);
    143         assert!(validator.validate(&signature, data, &pkey).unwrap());
    144 
    145         println!("Test PS384");
    146         signer = crate::openssl::RsaSigner::from_signcert_and_pkey(
    147             cert_bytes,
    148             key_bytes,
    149             SigningAlg::Ps384,
    150             None,
    151         )
    152         .unwrap();
    153 
    154         signature = signer.sign(data).unwrap();
    155         println!("signature len = {}", signature.len());
    156         validator = RsaValidator::new(SigningAlg::Ps384);
    157         assert!(validator.validate(&signature, data, &pkey).unwrap());
    158 
    159         println!("Test PS512");
    160         signer = crate::openssl::RsaSigner::from_signcert_and_pkey(
    161             cert_bytes,
    162             key_bytes,
    163             SigningAlg::Ps512,
    164             None,
    165         )
    166         .unwrap();
    167 
    168         signature = signer.sign(data).unwrap();
    169         println!("signature len = {}", signature.len());
    170         validator = RsaValidator::new(SigningAlg::Ps512);
    171         assert!(validator.validate(&signature, data, &pkey).unwrap());
    172     }
    173 }