1 /* 2 * PKCS #8 3 * (C) 1999-2007 Jack Lloyd 4 * 5 * Botan is released under the Simplified BSD License (see license.txt) 6 */ 7 8 #ifndef BOTAN_PKCS8_H_ 9 #define BOTAN_PKCS8_H_ 10 11 #include <botan/pk_keys.h> 12 #include <botan/exceptn.h> 13 #include <botan/secmem.h> 14 #include <functional> 15 #include <chrono> 16 #include <memory> 17 18 namespace Botan { 19 20 class DataSource; 21 class RandomNumberGenerator; 22 23 /** 24 * PKCS #8 General Exception 25 */ 26 class BOTAN_PUBLIC_API(2,0) PKCS8_Exception final : public Decoding_Error 27 { 28 public: PKCS8_Exception(const std::string & error)29 explicit PKCS8_Exception(const std::string& error) : 30 Decoding_Error("PKCS #8: " + error) {} 31 }; 32 33 /** 34 * This namespace contains functions for handling PKCS #8 private keys 35 */ 36 namespace PKCS8 { 37 38 /** 39 * BER encode a private key 40 * @param key the private key to encode 41 * @return BER encoded key 42 */ 43 BOTAN_PUBLIC_API(2,0) secure_vector<uint8_t> BER_encode(const Private_Key& key); 44 45 /** 46 * Get a string containing a PEM encoded private key. 47 * @param key the key to encode 48 * @return encoded key 49 */ 50 BOTAN_PUBLIC_API(2,0) std::string PEM_encode(const Private_Key& key); 51 52 /** 53 * Encrypt a key using PKCS #8 encryption 54 * @param key the key to encode 55 * @param rng the rng to use 56 * @param pass the password to use for encryption 57 * @param msec number of milliseconds to run the password derivation 58 * @param pbe_algo the name of the desired password-based encryption 59 * algorithm; if empty ("") a reasonable (portable/secure) 60 * default will be chosen. 61 * @return encrypted key in binary BER form 62 */ 63 BOTAN_PUBLIC_API(2,0) std::vector<uint8_t> 64 BER_encode(const Private_Key& key, 65 RandomNumberGenerator& rng, 66 const std::string& pass, 67 std::chrono::milliseconds msec = std::chrono::milliseconds(300), 68 const std::string& pbe_algo = ""); 69 70 /** 71 * Get a string containing a PEM encoded private key, encrypting it with a 72 * password. 73 * @param key the key to encode 74 * @param rng the rng to use 75 * @param pass the password to use for encryption 76 * @param msec number of milliseconds to run the password derivation 77 * @param pbe_algo the name of the desired password-based encryption 78 * algorithm; if empty ("") a reasonable (portable/secure) 79 * default will be chosen. 80 * @return encrypted key in PEM form 81 */ 82 BOTAN_PUBLIC_API(2,0) std::string 83 PEM_encode(const Private_Key& key, 84 RandomNumberGenerator& rng, 85 const std::string& pass, 86 std::chrono::milliseconds msec = std::chrono::milliseconds(300), 87 const std::string& pbe_algo = ""); 88 89 /** 90 * Encrypt a key using PKCS #8 encryption and a fixed iteration count 91 * @param key the key to encode 92 * @param rng the rng to use 93 * @param pass the password to use for encryption 94 * @param pbkdf_iter number of interations to run PBKDF2 95 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes 96 * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". 97 * If empty a suitable default is chosen. 98 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. 99 * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. 100 * @return encrypted key in binary BER form 101 */ 102 BOTAN_PUBLIC_API(2,1) std::vector<uint8_t> 103 BER_encode_encrypted_pbkdf_iter(const Private_Key& key, 104 RandomNumberGenerator& rng, 105 const std::string& pass, 106 size_t pbkdf_iter, 107 const std::string& cipher = "", 108 const std::string& pbkdf_hash = ""); 109 110 /** 111 * Get a string containing a PEM encoded private key, encrypting it with a 112 * password. 113 * @param key the key to encode 114 * @param rng the rng to use 115 * @param pass the password to use for encryption 116 * @param pbkdf_iter number of iterations to run PBKDF 117 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes 118 * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". 119 * If empty a suitable default is chosen. 120 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. 121 * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. 122 * @return encrypted key in PEM form 123 */ 124 BOTAN_PUBLIC_API(2,1) std::string 125 PEM_encode_encrypted_pbkdf_iter(const Private_Key& key, 126 RandomNumberGenerator& rng, 127 const std::string& pass, 128 size_t pbkdf_iter, 129 const std::string& cipher = "", 130 const std::string& pbkdf_hash = ""); 131 132 /** 133 * Encrypt a key using PKCS #8 encryption and a variable iteration count 134 * @param key the key to encode 135 * @param rng the rng to use 136 * @param pass the password to use for encryption 137 * @param pbkdf_msec how long to run PBKDF2 138 * @param pbkdf_iterations if non-null, set to the number of iterations used 139 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes 140 * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". 141 * If empty a suitable default is chosen. 142 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. 143 * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. 144 * @return encrypted key in binary BER form 145 */ 146 BOTAN_PUBLIC_API(2,1) std::vector<uint8_t> 147 BER_encode_encrypted_pbkdf_msec(const Private_Key& key, 148 RandomNumberGenerator& rng, 149 const std::string& pass, 150 std::chrono::milliseconds pbkdf_msec, 151 size_t* pbkdf_iterations, 152 const std::string& cipher = "", 153 const std::string& pbkdf_hash = ""); 154 155 /** 156 * Get a string containing a PEM encoded private key, encrypting it with a 157 * password. 158 * @param key the key to encode 159 * @param rng the rng to use 160 * @param pass the password to use for encryption 161 * @param pbkdf_msec how long in milliseconds to run PBKDF2 162 * @param pbkdf_iterations (output argument) number of iterations of PBKDF 163 * that ended up being used 164 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes 165 * are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". 166 * If empty a suitable default is chosen. 167 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. 168 * For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. 169 * @return encrypted key in PEM form 170 */ 171 BOTAN_PUBLIC_API(2,1) std::string 172 PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, 173 RandomNumberGenerator& rng, 174 const std::string& pass, 175 std::chrono::milliseconds pbkdf_msec, 176 size_t* pbkdf_iterations, 177 const std::string& cipher = "", 178 const std::string& pbkdf_hash = ""); 179 180 /** 181 * Load an encrypted key from a data source. 182 * @param source the data source providing the encoded key 183 * @param rng ignored for compatibility 184 * @param get_passphrase a function that returns passphrases 185 * @return loaded private key object 186 */ 187 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, 188 RandomNumberGenerator& rng, 189 std::function<std::string ()> get_passphrase); 190 191 /** Load an encrypted key from a data source. 192 * @param source the data source providing the encoded key 193 * @param rng ignored for compatibility 194 * @param pass the passphrase to decrypt the key 195 * @return loaded private key object 196 */ 197 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, 198 RandomNumberGenerator& rng, 199 const std::string& pass); 200 201 /** Load an unencrypted key from a data source. 202 * @param source the data source providing the encoded key 203 * @param rng ignored for compatibility 204 * @return loaded private key object 205 */ 206 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, 207 RandomNumberGenerator& rng); 208 209 #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) 210 /** 211 * Load an encrypted key from a file. 212 * @param filename the path to the file containing the encoded key 213 * @param rng ignored for compatibility 214 * @param get_passphrase a function that returns passphrases 215 * @return loaded private key object 216 */ 217 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, 218 RandomNumberGenerator& rng, 219 std::function<std::string ()> get_passphrase); 220 221 /** Load an encrypted key from a file. 222 * @param filename the path to the file containing the encoded key 223 * @param rng ignored for compatibility 224 * @param pass the passphrase to decrypt the key 225 * @return loaded private key object 226 */ 227 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, 228 RandomNumberGenerator& rng, 229 const std::string& pass); 230 231 /** Load an unencrypted key from a file. 232 * @param filename the path to the file containing the encoded key 233 * @param rng ignored for compatibility 234 * @return loaded private key object 235 */ 236 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, 237 RandomNumberGenerator& rng); 238 #endif 239 240 /** 241 * Copy an existing encoded key object. 242 * @param key the key to copy 243 * @param rng ignored for compatibility 244 * @return new copy of the key 245 */ 246 BOTAN_PUBLIC_API(2,0) Private_Key* copy_key(const Private_Key& key, 247 RandomNumberGenerator& rng); 248 249 250 /** 251 * Load an encrypted key from a data source. 252 * @param source the data source providing the encoded key 253 * @param get_passphrase a function that returns passphrases 254 * @return loaded private key object 255 */ 256 BOTAN_PUBLIC_API(2,3) 257 std::unique_ptr<Private_Key> load_key(DataSource& source, 258 std::function<std::string ()> get_passphrase); 259 260 /** Load an encrypted key from a data source. 261 * @param source the data source providing the encoded key 262 * @param pass the passphrase to decrypt the key 263 * @return loaded private key object 264 */ 265 BOTAN_PUBLIC_API(2,3) 266 std::unique_ptr<Private_Key> load_key(DataSource& source, 267 const std::string& pass); 268 269 /** Load an unencrypted key from a data source. 270 * @param source the data source providing the encoded key 271 * @return loaded private key object 272 */ 273 BOTAN_PUBLIC_API(2,3) 274 std::unique_ptr<Private_Key> load_key(DataSource& source); 275 276 /** 277 * Copy an existing encoded key object. 278 * @param key the key to copy 279 * @return new copy of the key 280 */ 281 BOTAN_PUBLIC_API(2,3) 282 std::unique_ptr<Private_Key> copy_key(const Private_Key& key); 283 284 } 285 286 } 287 288 #endif 289