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

temp_signer.rs (5672B)


      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 #![deny(missing_docs)]
     15 
     16 //! Temporary signing instances for testing purposes.
     17 //!
     18 //! This module contains functions to create self-signed certificates
     19 //! and provision [`Signer`] instances for each of the supported signature
     20 //! formats.
     21 //!
     22 //! Private-key and signing certificate pairs are created in a directory
     23 //! provided by the caller. It is recommended to use a temporary directory
     24 //! that is deleted upon completion of the test. (We recommend using
     25 //! the [tempfile](https://crates.io/crates/tempfile) crate.)
     26 //!
     27 //! This module should be used only for testing purposes.
     28 
     29 // Since this module is intended for testing purposes, all of
     30 // its functions are allowed to panic.
     31 #![allow(clippy::panic)]
     32 #![allow(clippy::unwrap_used)]
     33 
     34 #[cfg(feature = "file_io")]
     35 use std::path::{Path, PathBuf};
     36 
     37 #[cfg(feature = "file_io")]
     38 use crate::{
     39     openssl::{EcSigner, EdSigner, RsaSigner},
     40     signer::ConfigurableSigner,
     41     SigningAlg,
     42 };
     43 
     44 /// Create an OpenSSL ES256 signer that can be used for testing purposes.
     45 ///
     46 /// # Arguments
     47 ///
     48 /// * `path` - A directory (which must already exist) to receive the temporary
     49 ///   private key / certificate pair.
     50 /// * `alg` - A format for signing. Must be one of the `SigningAlg::Es*` variants.
     51 /// * `tsa_url` - Optional URL for a timestamp authority.
     52 ///
     53 /// # Returns
     54 ///
     55 /// Returns a tuple of `(signer, sign_cert_path)` where `signer` is
     56 /// the [`Signer`] instance and `sign_cert_path` is the path to the
     57 /// signing certificate.
     58 ///
     59 /// # Panics
     60 ///
     61 /// Can panic if unable to invoke OpenSSL executable properly.
     62 #[cfg(feature = "file_io")]
     63 pub fn get_ec_signer<P: AsRef<Path>>(
     64     path: P,
     65     alg: SigningAlg,
     66     tsa_url: Option<String>,
     67 ) -> (EcSigner, PathBuf) {
     68     match alg {
     69         SigningAlg::Es256 | SigningAlg::Es384 | SigningAlg::Es512 => (),
     70         _ => {
     71             panic!("Unknown EC signer alg {alg:#?}");
     72         }
     73     }
     74 
     75     let mut sign_cert_path = path.as_ref().to_path_buf();
     76     sign_cert_path.push(alg.to_string());
     77     sign_cert_path.set_extension("pub");
     78 
     79     let mut pem_key_path = path.as_ref().to_path_buf();
     80     pem_key_path.push(alg.to_string());
     81     pem_key_path.set_extension("pem");
     82 
     83     (
     84         EcSigner::from_files(&sign_cert_path, &pem_key_path, alg, tsa_url).unwrap(),
     85         sign_cert_path,
     86     )
     87 }
     88 
     89 /// Create an OpenSSL ES256 signer that can be used for testing purposes.
     90 ///
     91 /// # Arguments
     92 ///
     93 /// * `path` - A directory (which must already exist) to look for
     94 ///   private key / certificate pair.
     95 /// * `alg` - A format for signing. Must be `ed25519`.
     96 /// * `tsa_url` - Optional URL for a timestamp authority.
     97 ///
     98 /// # Returns
     99 ///
    100 /// Returns a tuple of `(signer, sign_cert_path)` where `signer` is
    101 /// the [`Signer`] instance and `sign_cert_path` is the path to the
    102 /// signing certificate.
    103 ///
    104 /// # Panics
    105 ///
    106 /// Can panic if unable to invoke OpenSSL executable properly.
    107 #[cfg(feature = "file_io")]
    108 pub fn get_ed_signer<P: AsRef<Path>>(
    109     path: P,
    110     alg: SigningAlg,
    111     tsa_url: Option<String>,
    112 ) -> (EdSigner, PathBuf) {
    113     if alg != SigningAlg::Ed25519 {
    114         panic!("Unknown ED signer alg {alg:#?}");
    115     }
    116 
    117     let mut sign_cert_path = path.as_ref().to_path_buf();
    118     sign_cert_path.push(alg.to_string());
    119     sign_cert_path.set_extension("pub");
    120 
    121     let mut pem_key_path = path.as_ref().to_path_buf();
    122     pem_key_path.push(alg.to_string());
    123     pem_key_path.set_extension("pem");
    124 
    125     (
    126         EdSigner::from_files(&sign_cert_path, &pem_key_path, alg, tsa_url).unwrap(),
    127         sign_cert_path,
    128     )
    129 }
    130 
    131 /// Create an OpenSSL SHA+RSA signer that can be used for testing purposes.
    132 ///
    133 /// # Arguments
    134 ///
    135 /// * `path` - A directory (which must already exist) to receive the temporary
    136 ///   private key / certificate pair.
    137 /// * `alg` - A format for signing. Must be one of the `SignerAlg::Ps*` options.
    138 /// * `tsa_url` - Optional URL for a timestamp authority.
    139 ///
    140 /// # Returns
    141 ///
    142 /// Returns a tuple of `(signer, sign_cert_path)` where `signer` is
    143 /// the [`Signer`] instance and `sign_cert_path` is the path to the
    144 /// signing certificate.
    145 ///
    146 /// # Panics
    147 ///
    148 /// Can panic if unable to invoke OpenSSL executable properly.
    149 #[cfg(feature = "file_io")]
    150 pub fn get_rsa_signer<P: AsRef<Path>>(
    151     path: P,
    152     alg: SigningAlg,
    153     tsa_url: Option<String>,
    154 ) -> (RsaSigner, PathBuf) {
    155     match alg {
    156         SigningAlg::Ps256 | SigningAlg::Ps384 | SigningAlg::Ps512 => (),
    157         _ => {
    158             panic!("Unknown RSA signer alg {alg:#?}");
    159         }
    160     }
    161 
    162     let mut sign_cert_path = path.as_ref().to_path_buf();
    163     sign_cert_path.push(alg.to_string());
    164     sign_cert_path.set_extension("pub");
    165 
    166     let mut pem_key_path = path.as_ref().to_path_buf();
    167     pem_key_path.push(alg.to_string());
    168     pem_key_path.set_extension("pem");
    169 
    170     if !sign_cert_path.exists() || !pem_key_path.exists() {
    171         panic!(
    172             "path found: {}, {}",
    173             sign_cert_path.display(),
    174             pem_key_path.display()
    175         );
    176     }
    177 
    178     (
    179         RsaSigner::from_files(&sign_cert_path, &pem_key_path, alg, tsa_url).unwrap(),
    180         sign_cert_path,
    181     )
    182 }