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 }