From 6fd01228840942ad122d1adabb3f7971a4e3b244 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 15 Jul 2009 15:12:20 +0000 Subject: Move the contents of pubkey/pubkey (which was kind of a catch-all to just toplevel pubkey). This was a convention I realized made sense sometime on when I was first doing the modularization changes. Move pkcs8.* and x509_key.* to pk_codecs --- src/pubkey/dh/info.txt | 1 - src/pubkey/dlies/info.txt | 1 - src/pubkey/dsa/info.txt | 1 - src/pubkey/ecc_key/info.txt | 1 - src/pubkey/ecdsa/info.txt | 1 - src/pubkey/eckaeg/info.txt | 1 - src/pubkey/elgamal/info.txt | 1 - src/pubkey/info.txt | 31 +++ src/pubkey/keypair/info.txt | 2 +- src/pubkey/nr/info.txt | 1 - src/pubkey/pk_algs.cpp | 112 +++++++++++ src/pubkey/pk_algs.h | 31 +++ src/pubkey/pk_codecs/pkcs8.cpp | 313 +++++++++++++++++++++++++++++ src/pubkey/pk_codecs/pkcs8.h | 182 +++++++++++++++++ src/pubkey/pk_codecs/x509_key.cpp | 176 +++++++++++++++++ src/pubkey/pk_codecs/x509_key.h | 110 +++++++++++ src/pubkey/pk_filts.cpp | 115 +++++++++++ src/pubkey/pk_filts.h | 91 +++++++++ src/pubkey/pk_keys.cpp | 54 +++++ src/pubkey/pk_keys.h | 180 +++++++++++++++++ src/pubkey/pubkey.cpp | 396 +++++++++++++++++++++++++++++++++++++ src/pubkey/pubkey.h | 392 ++++++++++++++++++++++++++++++++++++ src/pubkey/pubkey/info.txt | 32 --- src/pubkey/pubkey/pk_algs.cpp | 112 ----------- src/pubkey/pubkey/pk_algs.h | 32 --- src/pubkey/pubkey/pk_filts.cpp | 115 ----------- src/pubkey/pubkey/pk_filts.h | 91 --------- src/pubkey/pubkey/pk_keys.cpp | 54 ----- src/pubkey/pubkey/pk_keys.h | 180 ----------------- src/pubkey/pubkey/pkcs8.cpp | 313 ----------------------------- src/pubkey/pubkey/pkcs8.h | 182 ----------------- src/pubkey/pubkey/pubkey.cpp | 396 ------------------------------------- src/pubkey/pubkey/pubkey.h | 392 ------------------------------------ src/pubkey/pubkey/pubkey_enums.cpp | 42 ---- src/pubkey/pubkey/pubkey_enums.h | 77 -------- src/pubkey/pubkey/x509_key.cpp | 176 ----------------- src/pubkey/pubkey/x509_key.h | 110 ----------- src/pubkey/pubkey_enums.cpp | 42 ++++ src/pubkey/pubkey_enums.h | 77 ++++++++ src/pubkey/rsa/info.txt | 1 - src/pubkey/rw/info.txt | 1 - 41 files changed, 2303 insertions(+), 2315 deletions(-) create mode 100644 src/pubkey/info.txt create mode 100644 src/pubkey/pk_algs.cpp create mode 100644 src/pubkey/pk_algs.h create mode 100644 src/pubkey/pk_codecs/pkcs8.cpp create mode 100644 src/pubkey/pk_codecs/pkcs8.h create mode 100644 src/pubkey/pk_codecs/x509_key.cpp create mode 100644 src/pubkey/pk_codecs/x509_key.h create mode 100644 src/pubkey/pk_filts.cpp create mode 100644 src/pubkey/pk_filts.h create mode 100644 src/pubkey/pk_keys.cpp create mode 100644 src/pubkey/pk_keys.h create mode 100644 src/pubkey/pubkey.cpp create mode 100644 src/pubkey/pubkey.h delete mode 100644 src/pubkey/pubkey/info.txt delete mode 100644 src/pubkey/pubkey/pk_algs.cpp delete mode 100644 src/pubkey/pubkey/pk_algs.h delete mode 100644 src/pubkey/pubkey/pk_filts.cpp delete mode 100644 src/pubkey/pubkey/pk_filts.h delete mode 100644 src/pubkey/pubkey/pk_keys.cpp delete mode 100644 src/pubkey/pubkey/pk_keys.h delete mode 100644 src/pubkey/pubkey/pkcs8.cpp delete mode 100644 src/pubkey/pubkey/pkcs8.h delete mode 100644 src/pubkey/pubkey/pubkey.cpp delete mode 100644 src/pubkey/pubkey/pubkey.h delete mode 100644 src/pubkey/pubkey/pubkey_enums.cpp delete mode 100644 src/pubkey/pubkey/pubkey_enums.h delete mode 100644 src/pubkey/pubkey/x509_key.cpp delete mode 100644 src/pubkey/pubkey/x509_key.h create mode 100644 src/pubkey/pubkey_enums.cpp create mode 100644 src/pubkey/pubkey_enums.h (limited to 'src/pubkey') diff --git a/src/pubkey/dh/info.txt b/src/pubkey/dh/info.txt index 5d3396216..9e4ceb65b 100644 --- a/src/pubkey/dh/info.txt +++ b/src/pubkey/dh/info.txt @@ -17,5 +17,4 @@ asn1 bigint dl_algo numbertheory -pubkey diff --git a/src/pubkey/dlies/info.txt b/src/pubkey/dlies/info.txt index 1a09dcbc5..9e32aeb2a 100644 --- a/src/pubkey/dlies/info.txt +++ b/src/pubkey/dlies/info.txt @@ -12,5 +12,4 @@ dlies.h dh kdf2 -pubkey diff --git a/src/pubkey/dsa/info.txt b/src/pubkey/dsa/info.txt index f1b505800..2d6287fbd 100644 --- a/src/pubkey/dsa/info.txt +++ b/src/pubkey/dsa/info.txt @@ -10,7 +10,6 @@ bigint dl_algo keypair numbertheory -pubkey diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt index c5213aef4..a57de3d0c 100644 --- a/src/pubkey/ecc_key/info.txt +++ b/src/pubkey/ecc_key/info.txt @@ -10,7 +10,6 @@ bigint ec_dompar numbertheory gfpmath -pubkey diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt index 48e88bda9..c67122348 100644 --- a/src/pubkey/ecdsa/info.txt +++ b/src/pubkey/ecdsa/info.txt @@ -11,7 +11,6 @@ ec_dompar ecc_key numbertheory gfpmath -pubkey diff --git a/src/pubkey/eckaeg/info.txt b/src/pubkey/eckaeg/info.txt index bac47f861..cdac09220 100644 --- a/src/pubkey/eckaeg/info.txt +++ b/src/pubkey/eckaeg/info.txt @@ -11,7 +11,6 @@ ec_dompar ecc_key numbertheory gfpmath -pubkey diff --git a/src/pubkey/elgamal/info.txt b/src/pubkey/elgamal/info.txt index c457e1529..53a039585 100644 --- a/src/pubkey/elgamal/info.txt +++ b/src/pubkey/elgamal/info.txt @@ -11,7 +11,6 @@ bigint dl_algo keypair numbertheory -pubkey diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt new file mode 100644 index 000000000..74698503a --- /dev/null +++ b/src/pubkey/info.txt @@ -0,0 +1,31 @@ +realname "Public Key Base" + +define PUBLIC_KEY_CRYPTO + +load_on auto + + +asn1 +bigint +numbertheory +oid_lookup +pbe +pk_codecs +pk_pad +rng + + + +pk_algs.cpp +pk_algs.h +pk_filts.cpp +pk_filts.h +pk_keys.cpp +pk_keys.h +pubkey.cpp +pubkey.h +pubkey_enums.cpp +pubkey_enums.h +x509_key.cpp +x509_key.h + diff --git a/src/pubkey/keypair/info.txt b/src/pubkey/keypair/info.txt index c6fa4af5d..9e758643f 100644 --- a/src/pubkey/keypair/info.txt +++ b/src/pubkey/keypair/info.txt @@ -10,5 +10,5 @@ keypair.h -pubkey +libstate diff --git a/src/pubkey/nr/info.txt b/src/pubkey/nr/info.txt index 6434d4385..a02be064d 100644 --- a/src/pubkey/nr/info.txt +++ b/src/pubkey/nr/info.txt @@ -19,5 +19,4 @@ bigint dl_algo keypair numbertheory -pubkey diff --git a/src/pubkey/pk_algs.cpp b/src/pubkey/pk_algs.cpp new file mode 100644 index 000000000..99d7294f0 --- /dev/null +++ b/src/pubkey/pk_algs.cpp @@ -0,0 +1,112 @@ +/* +* PK Key +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include + +#if defined(BOTAN_HAS_RSA) + #include +#endif + +#if defined(BOTAN_HAS_DSA) + #include +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + #include +#endif + +#if defined(BOTAN_HAS_ECDSA) + #include +#endif + +#if defined(BOTAN_HAS_NYBERG_RUEPPEL) + #include +#endif + +#if defined(BOTAN_HAS_RW) + #include +#endif + +#if defined(BOTAN_HAS_ELGAMAL) + #include +#endif + +namespace Botan { + +/* +* Get an PK public key object +*/ +Public_Key* get_public_key(const std::string& alg_name) + { +#if defined(BOTAN_HAS_RSA) + if(alg_name == "RSA") return new RSA_PublicKey; +#endif + +#if defined(BOTAN_HAS_DSA) + if(alg_name == "DSA") return new DSA_PublicKey; +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + if(alg_name == "DH") return new DH_PublicKey; +#endif + +#if defined(BOTAN_HAS_NYBERG_RUEPPEL) + if(alg_name == "NR") return new NR_PublicKey; +#endif + +#if defined(BOTAN_HAS_RW) + if(alg_name == "RW") return new RW_PublicKey; +#endif + +#if defined(BOTAN_HAS_ELG) + if(alg_name == "ELG") return new ElGamal_PublicKey; +#endif + +#if defined(BOTAN_HAS_ECDSA) + if(alg_name == "ECDSA") return new ECDSA_PublicKey; +#endif + + return 0; + } + +/* +* Get an PK private key object +*/ +Private_Key* get_private_key(const std::string& alg_name) + { +#if defined(BOTAN_HAS_RSA) + if(alg_name == "RSA") return new RSA_PrivateKey; +#endif + +#if defined(BOTAN_HAS_DSA) + if(alg_name == "DSA") return new DSA_PrivateKey; +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + if(alg_name == "DH") return new DH_PrivateKey; +#endif + +#if defined(BOTAN_HAS_NYBERG_RUEPPEL) + if(alg_name == "NR") return new NR_PrivateKey; +#endif + +#if defined(BOTAN_HAS_RW) + if(alg_name == "RW") return new RW_PrivateKey; +#endif + +#if defined(BOTAN_HAS_ELG) + if(alg_name == "ELG") return new ElGamal_PrivateKey; +#endif + +#if defined(BOTAN_HAS_ECDSA) + if(alg_name == "ECDSA") return new ECDSA_PrivateKey; +#endif + + return 0; + } + +} diff --git a/src/pubkey/pk_algs.h b/src/pubkey/pk_algs.h new file mode 100644 index 000000000..c41bf1a63 --- /dev/null +++ b/src/pubkey/pk_algs.h @@ -0,0 +1,31 @@ +/* +* PK Key Factory +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PK_KEY_FACTORY_H__ +#define BOTAN_PK_KEY_FACTORY_H__ + +#include + +namespace Botan { + +/** +* Get an empty public key object. +* @param name the name of the desired public key algorithm +* @return the public key object +*/ +BOTAN_DLL Public_Key* get_public_key(const std::string&); + +/** +* Get an empty private key object. +* @param name the name of the desired public key algorithm +* @return the private key object +*/ +BOTAN_DLL Private_Key* get_private_key(const std::string&); + +} + +#endif diff --git a/src/pubkey/pk_codecs/pkcs8.cpp b/src/pubkey/pk_codecs/pkcs8.cpp new file mode 100644 index 000000000..8a464ecfe --- /dev/null +++ b/src/pubkey/pk_codecs/pkcs8.cpp @@ -0,0 +1,313 @@ +/* +* PKCS #8 +* (C) 1999-2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace PKCS8 { + +namespace { + +/* +* Get info from an EncryptedPrivateKeyInfo +*/ +SecureVector PKCS8_extract(DataSource& source, + AlgorithmIdentifier& pbe_alg_id) + { + SecureVector key_data; + + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(pbe_alg_id) + .decode(key_data, OCTET_STRING) + .verify_end(); + + return key_data; + } + +/* +* PEM decode and/or decrypt a private key +*/ +SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, + AlgorithmIdentifier& pk_alg_id) + { + AlgorithmIdentifier pbe_alg_id; + SecureVector key_data, key; + bool is_encrypted = true; + + try { + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + key_data = PKCS8_extract(source, pbe_alg_id); + else + { + std::string label; + key_data = PEM_Code::decode(source, label); + if(label == "PRIVATE KEY") + is_encrypted = false; + else if(label == "ENCRYPTED PRIVATE KEY") + { + DataSource_Memory key_source(key_data); + key_data = PKCS8_extract(key_source, pbe_alg_id); + } + else + throw PKCS8_Exception("Unknown PEM label " + label); + } + + if(key_data.is_empty()) + throw PKCS8_Exception("No key data found"); + } + catch(Decoding_Error) + { + throw Decoding_Error("PKCS #8 private key decoding failed"); + } + + if(!is_encrypted) + key = key_data; + + const u32bit MAX_TRIES = 3; + + u32bit tries = 0; + while(true) + { + try { + if(MAX_TRIES && tries >= MAX_TRIES) + break; + + if(is_encrypted) + { + DataSource_Memory params(pbe_alg_id.parameters); + std::auto_ptr pbe(get_pbe(pbe_alg_id.oid, params)); + + User_Interface::UI_Result result = User_Interface::OK; + const std::string passphrase = + ui.get_passphrase("PKCS #8 private key", source.id(), result); + + if(result == User_Interface::CANCEL_ACTION) + break; + + pbe->set_key(passphrase); + Pipe decryptor(pbe.release()); + + decryptor.process_msg(key_data, key_data.size()); + key = decryptor.read_all(); + } + + u32bit version; + + BER_Decoder(key) + .start_cons(SEQUENCE) + .decode(version) + .decode(pk_alg_id) + .decode(key, OCTET_STRING) + .discard_remaining() + .end_cons(); + + if(version != 0) + throw Decoding_Error("PKCS #8: Unknown version number"); + + break; + } + catch(Decoding_Error) + { + ++tries; + } + } + + if(key.is_empty()) + throw Decoding_Error("PKCS #8 private key decoding failed"); + return key; + } + +} + +/* +* DER or PEM encode a PKCS #8 private key +*/ +void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding) + { + std::auto_ptr encoder(key.pkcs8_encoder()); + if(!encoder.get()) + throw Encoding_Error("PKCS8::encode: Key does not support encoding"); + + const u32bit PKCS8_VERSION = 0; + + SecureVector contents = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(PKCS8_VERSION) + .encode(encoder->alg_id()) + .encode(encoder->key_bits(), OCTET_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(contents, "PRIVATE KEY")); + else + pipe.write(contents); + } + +/* +* Encode and encrypt a PKCS #8 private key +*/ +void encrypt_key(const Private_Key& key, + Pipe& pipe, + RandomNumberGenerator& rng, + const std::string& pass, const std::string& pbe_algo, + X509_Encoding encoding) + { + const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"; + + Pipe raw_key; + raw_key.start_msg(); + encode(key, raw_key, RAW_BER); + raw_key.end_msg(); + + std::auto_ptr pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); + + pbe->new_params(rng); + pbe->set_key(pass); + + AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); + + Pipe key_encrytor(pbe.release()); + key_encrytor.process_msg(raw_key); + + SecureVector enc_key = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(pbe_algid) + .encode(key_encrytor.read_all(), OCTET_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(enc_key, "ENCRYPTED PRIVATE KEY")); + else + pipe.write(enc_key); + } + +/* +* PEM encode a PKCS #8 private key +*/ +std::string PEM_encode(const Private_Key& key) + { + Pipe pem; + pem.start_msg(); + encode(key, pem, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Encrypt and PEM encode a PKCS #8 private key +*/ +std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo) + { + if(pass == "") + return PEM_encode(key); + + Pipe pem; + pem.start_msg(); + encrypt_key(key, pem, rng, pass, pbe_algo, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const User_Interface& ui) + { + AlgorithmIdentifier alg_id; + SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); + + const std::string alg_name = OIDS::lookup(alg_id.oid); + if(alg_name == "" || alg_name == alg_id.oid.as_string()) + throw PKCS8_Exception("Unknown algorithm OID: " + + alg_id.oid.as_string()); + + std::auto_ptr key(get_private_key(alg_name)); + + if(!key.get()) + throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " + + alg_id.oid.as_string()); + + std::auto_ptr decoder(key->pkcs8_decoder(rng)); + + if(!decoder.get()) + throw Decoding_Error("Key does not support PKCS #8 decoding"); + + decoder->alg_id(alg_id); + decoder->key_bits(pkcs8_key); + + return key.release(); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + const User_Interface& ui) + { + DataSource_Stream source(fsname, true); + return PKCS8::load_key(source, rng, ui); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass) + { + return PKCS8::load_key(source, rng, User_Interface(pass)); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + const std::string& pass) + { + return PKCS8::load_key(fsname, rng, User_Interface(pass)); + } + +/* +* Make a copy of this private key +*/ +Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng) + { + Pipe bits; + + bits.start_msg(); + PKCS8::encode(key, bits); + bits.end_msg(); + + DataSource_Memory source(bits.read_all()); + return PKCS8::load_key(source, rng); + } + +} + +} diff --git a/src/pubkey/pk_codecs/pkcs8.h b/src/pubkey/pk_codecs/pkcs8.h new file mode 100644 index 000000000..87f8ba326 --- /dev/null +++ b/src/pubkey/pk_codecs/pkcs8.h @@ -0,0 +1,182 @@ +/* +* PKCS #8 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PKCS8_H__ +#define BOTAN_PKCS8_H__ + +#include +#include + +namespace Botan { + +/** +* PKCS #8 Private Key Encoder. +*/ +class BOTAN_DLL PKCS8_Encoder + { + public: + /** + * Get the algorithm identifier associated with the scheme + * this encoders key is part of. + * @return the algorithm identifier + */ + virtual AlgorithmIdentifier alg_id() const = 0; + + /** + * Get the DER encoded key. + * @return the DER encoded key + */ + // XXX: Why not SecureVector? + virtual MemoryVector key_bits() const = 0; + virtual ~PKCS8_Encoder() {} + }; + +/* +* PKCS #8 Private Key Decoder +*/ +class BOTAN_DLL PKCS8_Decoder + { + public: + /** + * Set the algorithm identifier associated with the scheme + * this decoders key is part of. + * @param alg_id the algorithm identifier + */ + virtual void alg_id(const AlgorithmIdentifier&) = 0; + + /** + * Set the DER encoded key. + * @param key the DER encoded key + */ + virtual void key_bits(const MemoryRegion&) = 0; + virtual ~PKCS8_Decoder() {} + }; + +/** +* PKCS #8 General Exception +*/ +struct BOTAN_DLL PKCS8_Exception : public Decoding_Error + { + PKCS8_Exception(const std::string& error) : + Decoding_Error("PKCS #8: " + error) {} + }; + +namespace PKCS8 { + +/** +* Encode a private key into a pipe. +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param enc the encoding type to use +*/ +BOTAN_DLL void encode(const Private_Key& key, Pipe& pipe, + X509_Encoding enc = PEM); + +/** +* Encode and encrypt a private key into a pipe. +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param pass the password to use for encryption +* @param rng the rng to use +* @param pbe_algo the name of the desired password-based encryption algorithm. +* Provide an empty string to use the default PBE defined in the configuration +* under base/default_pbe. +* @param enc the encoding type to use +*/ +BOTAN_DLL void encrypt_key(const Private_Key& key, + Pipe& pipe, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = "", + X509_Encoding enc = PEM); + + +/** +* Get a string containing a PEM encoded private key. +* @param key the key to encode +* @return the encoded key +*/ +BOTAN_DLL std::string PEM_encode(const Private_Key& key); + +/** +* Get a string containing a PEM encoded private key, encrypting it with a +* password. +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbe_algo the name of the desired password-based encryption algorithm. +* Provide an empty string to use the default PBE defined in the configuration +* under base/default_pbe. +*/ +BOTAN_DLL std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = ""); + +BOTAN_DLL std::string PEM_encode(const Private_Key&, + const std::string&, + const std::string& = ""); + + +/** +* Load a key from a data source. +* @param source the data source providing the encoded key +* @param rng the rng to use +* @param ui the user interface to be used for passphrase dialog +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const User_Interface& ui); + +/** Load a key from a data source. +* @param source the data source providing the encoded key +* @param rng the rng to use +* @param pass the passphrase to decrypt the key. Provide an empty +* string if the key is not encoded. +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass = ""); + +/** +* Load a key from a file. +* @param filename the path to the file containing the encoded key +* @param rng the rng to use +* @param ui the user interface to be used for passphrase dialog +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const User_Interface& ui); + +/** Load a key from a file. +* @param filename the path to the file containing the encoded key +* @param rng the rng to use +* @param pass the passphrase to decrypt the key. Provide an empty +* string if the key is not encoded. +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const std::string& pass = ""); + +/** +* Copy an existing encoded key object. +* @param key the key to copy +* @param rng the rng to use +* @return the new copy of the key +*/ +BOTAN_DLL Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng); + +} + +} + +#endif diff --git a/src/pubkey/pk_codecs/x509_key.cpp b/src/pubkey/pk_codecs/x509_key.cpp new file mode 100644 index 000000000..455e627f3 --- /dev/null +++ b/src/pubkey/pk_codecs/x509_key.cpp @@ -0,0 +1,176 @@ +/* +* X.509 Public Key +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace X509 { + +/* +* DER or PEM encode a X.509 public key +*/ +void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) + { + std::auto_ptr encoder(key.x509_encoder()); + if(!encoder.get()) + throw Encoding_Error("X509::encode: Key does not support encoding"); + + MemoryVector der = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(encoder->alg_id()) + .encode(encoder->key_bits(), BIT_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(der, "PUBLIC KEY")); + else + pipe.write(der); + } + +/* +* PEM encode a X.509 public key +*/ +std::string PEM_encode(const Public_Key& key) + { + Pipe pem; + pem.start_msg(); + encode(key, pem, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(DataSource& source) + { + try { + AlgorithmIdentifier alg_id; + MemoryVector key_bits; + + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + { + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .verify_end() + .end_cons(); + } + else + { + DataSource_Memory ber( + PEM_Code::decode_check_label(source, "PUBLIC KEY") + ); + + BER_Decoder(ber) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .verify_end() + .end_cons(); + } + + if(key_bits.is_empty()) + throw Decoding_Error("X.509 public key decoding failed"); + + const std::string alg_name = OIDS::lookup(alg_id.oid); + if(alg_name == "") + throw Decoding_Error("Unknown algorithm OID: " + + alg_id.oid.as_string()); + + std::auto_ptr key_obj(get_public_key(alg_name)); + if(!key_obj.get()) + throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " + + alg_id.oid.as_string()); + + std::auto_ptr decoder(key_obj->x509_decoder()); + + if(!decoder.get()) + throw Decoding_Error("Key does not support X.509 decoding"); + + decoder->alg_id(alg_id); + decoder->key_bits(key_bits); + + return key_obj.release(); + } + catch(Decoding_Error) + { + throw Decoding_Error("X.509 public key decoding failed"); + } + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const std::string& fsname) + { + DataSource_Stream source(fsname, true); + return X509::load_key(source); + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const MemoryRegion& mem) + { + DataSource_Memory source(mem); + return X509::load_key(source); + } + +/* +* Make a copy of this public key +*/ +Public_Key* copy_key(const Public_Key& key) + { + Pipe bits; + bits.start_msg(); + X509::encode(key, bits, RAW_BER); + bits.end_msg(); + DataSource_Memory source(bits.read_all()); + return X509::load_key(source); + } + +/* +* Find the allowable key constraints +*/ +Key_Constraints find_constraints(const Public_Key& pub_key, + Key_Constraints limits) + { + const Public_Key* key = &pub_key; + u32bit constraints = 0; + + if(dynamic_cast(key)) + constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; + + if(dynamic_cast(key)) + constraints |= KEY_AGREEMENT; + + if(dynamic_cast(key) || + dynamic_cast(key)) + constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION; + + if(limits) + constraints &= limits; + + return Key_Constraints(constraints); + } + +} + +} diff --git a/src/pubkey/pk_codecs/x509_key.h b/src/pubkey/pk_codecs/x509_key.h new file mode 100644 index 000000000..9404b7ecc --- /dev/null +++ b/src/pubkey/pk_codecs/x509_key.h @@ -0,0 +1,110 @@ +/* +* X.509 Public Key +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_X509_PUBLIC_KEY_H__ +#define BOTAN_X509_PUBLIC_KEY_H__ + +#include +#include +#include +#include + +namespace Botan { + +/** +* This class represents abstract X.509 public key encoders. +*/ +class BOTAN_DLL X509_Encoder + { + public: + virtual AlgorithmIdentifier alg_id() const = 0; + virtual MemoryVector key_bits() const = 0; + virtual ~X509_Encoder() {} + }; + +/** +* This class represents abstract X.509 public key decoders. +*/ +class BOTAN_DLL X509_Decoder + { + public: + virtual void alg_id(const AlgorithmIdentifier&) = 0; + virtual void key_bits(const MemoryRegion&) = 0; + virtual ~X509_Decoder() {} + }; + +/** +* This namespace contains functions for handling X509 objects. +*/ +namespace X509 { + +/* +* X.509 Public Key Encoding/Decoding +*/ + +/** +* Encode a key into a pipe. +* @param key the public key to encode +* @param pipe the pipe to feed the encoded key into +* @param enc the encoding type to use +*/ +BOTAN_DLL void encode(const Public_Key& key, Pipe& pipe, + X509_Encoding enc = PEM); + +/** +* PEM encode a public key into a string. +* @param key the key to encode +* @return the PEM encoded key +*/ +BOTAN_DLL std::string PEM_encode(const Public_Key& key); + +/** +* Create a public key from a data source. +* @param source the source providing the DER or PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(DataSource& source); + +/** +* Create a public key from a string. +* @param enc the string containing the PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(const std::string& enc); + +/** +* Create a public key from a memory region. +* @param enc the memory region containing the DER or PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(const MemoryRegion& enc); + +/** +* Copy a key. +* @param key the public key to copy +* @return the new public key object +*/ +BOTAN_DLL Public_Key* copy_key(const Public_Key& key); + +/** +* Create the key constraints for a specific public key. +* @param pub_key the public key from which the basic set of +* constraints to be placed in the return value is derived +* @param limits additional limits that will be incorporated into the +* return value +* @return the combination of key type specific constraints and +* additional limits +*/ + +BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, + Key_Constraints limits); + +} + +} + +#endif diff --git a/src/pubkey/pk_filts.cpp b/src/pubkey/pk_filts.cpp new file mode 100644 index 000000000..18da9c10b --- /dev/null +++ b/src/pubkey/pk_filts.cpp @@ -0,0 +1,115 @@ +/* +* PK Filters +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include + +namespace Botan { + +/* +* Append to the buffer +*/ +void PK_Encryptor_Filter::write(const byte input[], u32bit length) + { + buffer.append(input, length); + } + +/* +* Encrypt the message +*/ +void PK_Encryptor_Filter::end_msg() + { + send(cipher->encrypt(buffer, buffer.size(), rng)); + buffer.destroy(); + } + +/* +* Append to the buffer +*/ +void PK_Decryptor_Filter::write(const byte input[], u32bit length) + { + buffer.append(input, length); + } + +/* +* Decrypt the message +*/ +void PK_Decryptor_Filter::end_msg() + { + send(cipher->decrypt(buffer, buffer.size())); + buffer.destroy(); + } + +/* +* Add more data +*/ +void PK_Signer_Filter::write(const byte input[], u32bit length) + { + signer->update(input, length); + } + +/* +* Sign the message +*/ +void PK_Signer_Filter::end_msg() + { + send(signer->signature(rng)); + } + +/* +* Add more data +*/ +void PK_Verifier_Filter::write(const byte input[], u32bit length) + { + verifier->update(input, length); + } + +/* +* Verify the message +*/ +void PK_Verifier_Filter::end_msg() + { + if(signature.is_empty()) + throw Exception("PK_Verifier_Filter: No signature to check against"); + bool is_valid = verifier->check_signature(signature, signature.size()); + send((is_valid ? 1 : 0)); + } + +/* +* Set the signature to check +*/ +void PK_Verifier_Filter::set_signature(const byte sig[], u32bit length) + { + signature.set(sig, length); + } + +/* +* Set the signature to check +*/ +void PK_Verifier_Filter::set_signature(const MemoryRegion& sig) + { + signature = sig; + } + +/* +* PK_Verifier_Filter Constructor +*/ +PK_Verifier_Filter::PK_Verifier_Filter(PK_Verifier* v, const byte sig[], + u32bit length) : + verifier(v), signature(sig, length) + { + } + +/* +* PK_Verifier_Filter Constructor +*/ +PK_Verifier_Filter::PK_Verifier_Filter(PK_Verifier* v, + const MemoryRegion& sig) : + verifier(v), signature(sig) + { + } + +} diff --git a/src/pubkey/pk_filts.h b/src/pubkey/pk_filts.h new file mode 100644 index 000000000..8bf3fc238 --- /dev/null +++ b/src/pubkey/pk_filts.h @@ -0,0 +1,91 @@ +/* +* PK Filters +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PK_FILTERS_H__ +#define BOTAN_PK_FILTERS_H__ + +#include +#include + +namespace Botan { + +/* +* PK_Encryptor Filter +*/ +class BOTAN_DLL PK_Encryptor_Filter : public Filter + { + public: + void write(const byte[], u32bit); + void end_msg(); + PK_Encryptor_Filter(PK_Encryptor* c, + RandomNumberGenerator& rng_ref) : + cipher(c), rng(rng_ref) {} + ~PK_Encryptor_Filter() { delete cipher; } + private: + PK_Encryptor* cipher; + RandomNumberGenerator& rng; + SecureVector buffer; + }; + +/* +* PK_Decryptor Filter +*/ +class BOTAN_DLL PK_Decryptor_Filter : public Filter + { + public: + void write(const byte[], u32bit); + void end_msg(); + PK_Decryptor_Filter(PK_Decryptor* c) : cipher(c) {} + ~PK_Decryptor_Filter() { delete cipher; } + private: + PK_Decryptor* cipher; + SecureVector buffer; + }; + +/* +* PK_Signer Filter +*/ +class BOTAN_DLL PK_Signer_Filter : public Filter + { + public: + void write(const byte[], u32bit); + void end_msg(); + + PK_Signer_Filter(PK_Signer* s, + RandomNumberGenerator& rng_ref) : + signer(s), rng(rng_ref) {} + + ~PK_Signer_Filter() { delete signer; } + private: + PK_Signer* signer; + RandomNumberGenerator& rng; + }; + +/* +* PK_Verifier Filter +*/ +class BOTAN_DLL PK_Verifier_Filter : public Filter + { + public: + void write(const byte[], u32bit); + void end_msg(); + + void set_signature(const byte[], u32bit); + void set_signature(const MemoryRegion&); + + PK_Verifier_Filter(PK_Verifier* v) : verifier(v) {} + PK_Verifier_Filter(PK_Verifier*, const byte[], u32bit); + PK_Verifier_Filter(PK_Verifier*, const MemoryRegion&); + ~PK_Verifier_Filter() { delete verifier; } + private: + PK_Verifier* verifier; + SecureVector signature; + }; + +} + +#endif diff --git a/src/pubkey/pk_keys.cpp b/src/pubkey/pk_keys.cpp new file mode 100644 index 000000000..b93158558 --- /dev/null +++ b/src/pubkey/pk_keys.cpp @@ -0,0 +1,54 @@ +/* +* PK Key Types +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +namespace Botan { + +/* +* Default OID access +*/ +OID Public_Key::get_oid() const + { + try { + return OIDS::lookup(algo_name()); + } + catch(Lookup_Error) + { + throw Lookup_Error("PK algo " + algo_name() + " has no defined OIDs"); + } + } + +/* +* Run checks on a loaded public key +*/ +void Public_Key::load_check(RandomNumberGenerator& rng) const + { + if(!check_key(rng, BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD)) + throw Invalid_Argument(algo_name() + ": Invalid public key"); + } + +/* +* Run checks on a loaded private key +*/ +void Private_Key::load_check(RandomNumberGenerator& rng) const + { + if(!check_key(rng, BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD)) + throw Invalid_Argument(algo_name() + ": Invalid private key"); + } + +/* +* Run checks on a generated private key +*/ +void Private_Key::gen_check(RandomNumberGenerator& rng) const + { + if(!check_key(rng, BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_GENERATE)) + throw Self_Test_Failure(algo_name() + " private key generation failed"); + } + +} diff --git a/src/pubkey/pk_keys.h b/src/pubkey/pk_keys.h new file mode 100644 index 000000000..5b612577d --- /dev/null +++ b/src/pubkey/pk_keys.h @@ -0,0 +1,180 @@ +/* +* PK Key Types +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PK_KEYS_H__ +#define BOTAN_PK_KEYS_H__ + +#include +#include +#include + +namespace Botan { + +/** +* Public Key Base Class. +*/ +class BOTAN_DLL Public_Key + { + public: + /** + * Get the name of the underlying public key scheme. + * @return the name of the public key scheme + */ + virtual std::string algo_name() const = 0; + + /** + * Get the OID of the underlying public key scheme. + * @return the OID of the public key scheme + */ + virtual OID get_oid() const; + + /** + * Test the key values for consistency. + * @param rng rng to use + * @param strong whether to perform strong and lengthy version + * of the test + * @return true if the test is passed + */ + virtual bool check_key(RandomNumberGenerator&, bool) const + { return true; } + + /** + * Find out the number of message parts supported by this scheme. + * @return the number of message parts + */ + virtual u32bit message_parts() const { return 1; } + + /** + * Find out the message part size supported by this scheme/key. + * @return the size of the message parts + */ + virtual u32bit message_part_size() const { return 0; } + + /** + * Get the maximum message size in bits supported by this public key. + * @return the maximum message in bits + */ + virtual u32bit max_input_bits() const = 0; + + /** + * Get an X509 encoder that can be used to encode this key in X509 format. + * @return an X509 encoder for this key + */ + virtual class X509_Encoder* x509_encoder() const = 0; + + /** + * Get an X509 decoder that can be used to set the values of this + * key based on an X509 encoded key object. + * @return an X509 decoder for this key + */ + virtual class X509_Decoder* x509_decoder() = 0; + + virtual ~Public_Key() {} + protected: + virtual void load_check(RandomNumberGenerator&) const; + }; + +/** +* Private Key Base Class +*/ +class BOTAN_DLL Private_Key : public virtual Public_Key + { + public: + /** + * Get a PKCS#8 encoder that can be used to encode this key in + * PKCS#8 format. + * @return an PKCS#8 encoder for this key + */ + virtual class PKCS8_Encoder* pkcs8_encoder() const + { return 0; } + + /** + * Get an PKCS#8 decoder that can be used to set the values of this key + * based on an PKCS#8 encoded key object. + * @return an PKCS#8 decoder for this key + */ + virtual class PKCS8_Decoder* pkcs8_decoder(RandomNumberGenerator&) + { return 0; } + protected: + void load_check(RandomNumberGenerator&) const; + void gen_check(RandomNumberGenerator&) const; + }; + +/** +* PK Encrypting Key. +*/ +class BOTAN_DLL PK_Encrypting_Key : public virtual Public_Key + { + public: + virtual SecureVector encrypt(const byte[], u32bit, + RandomNumberGenerator&) const = 0; + virtual ~PK_Encrypting_Key() {} + }; + +/** +* PK Decrypting Key +*/ +class BOTAN_DLL PK_Decrypting_Key : public virtual Private_Key + { + public: + virtual SecureVector decrypt(const byte[], u32bit) const = 0; + virtual ~PK_Decrypting_Key() {} + }; + +/** +* PK Signing Key +*/ +class BOTAN_DLL PK_Signing_Key : public virtual Private_Key + { + public: + virtual SecureVector sign(const byte[], u32bit, + RandomNumberGenerator& rng) const = 0; + virtual ~PK_Signing_Key() {} + }; + +/** +* PK Verifying Key, Message Recovery Version +*/ +class BOTAN_DLL PK_Verifying_with_MR_Key : public virtual Public_Key + { + public: + virtual SecureVector verify(const byte[], u32bit) const = 0; + virtual ~PK_Verifying_with_MR_Key() {} + }; + +/** +* PK Verifying Key, No Message Recovery Version +*/ +class BOTAN_DLL PK_Verifying_wo_MR_Key : public virtual Public_Key + { + public: + virtual bool verify(const byte[], u32bit, + const byte[], u32bit) const = 0; + virtual ~PK_Verifying_wo_MR_Key() {} + }; + +/** +* PK Secret Value Derivation Key +*/ +class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key + { + public: + virtual SecureVector derive_key(const byte[], u32bit) const = 0; + virtual MemoryVector public_value() const = 0; + virtual ~PK_Key_Agreement_Key() {} + }; + +/* +* Typedefs +*/ +typedef PK_Key_Agreement_Key PK_KA_Key; +typedef Public_Key X509_PublicKey; +typedef Private_Key PKCS8_PrivateKey; + +} + +#endif diff --git a/src/pubkey/pubkey.cpp b/src/pubkey/pubkey.cpp new file mode 100644 index 000000000..4ddaa6fb6 --- /dev/null +++ b/src/pubkey/pubkey.cpp @@ -0,0 +1,396 @@ +/* +* Public Key Base +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* Encrypt a message +*/ +SecureVector PK_Encryptor::encrypt(const byte in[], u32bit len, + RandomNumberGenerator& rng) const + { + return enc(in, len, rng); + } + +/* +* Encrypt a message +*/ +SecureVector PK_Encryptor::encrypt(const MemoryRegion& in, + RandomNumberGenerator& rng) const + { + return enc(in.begin(), in.size(), rng); + } + +/* +* Decrypt a message +*/ +SecureVector PK_Decryptor::decrypt(const byte in[], u32bit len) const + { + return dec(in, len); + } + +/* +* Decrypt a message +*/ +SecureVector PK_Decryptor::decrypt(const MemoryRegion& in) const + { + return dec(in.begin(), in.size()); + } + +/* +* PK_Encryptor_MR_with_EME Constructor +*/ +PK_Encryptor_MR_with_EME::PK_Encryptor_MR_with_EME(const PK_Encrypting_Key& k, + EME* eme_obj) : + key(k), encoder(eme_obj) + { + } + +/* +* Encrypt a message +*/ +SecureVector +PK_Encryptor_MR_with_EME::enc(const byte msg[], + u32bit length, + RandomNumberGenerator& rng) const + { + SecureVector message; + if(encoder) + message = encoder->encode(msg, length, key.max_input_bits(), rng); + else + message.set(msg, length); + + if(8*(message.size() - 1) + high_bit(message[0]) > key.max_input_bits()) + throw Exception("PK_Encryptor_MR_with_EME: Input is too large"); + + return key.encrypt(message, message.size(), rng); + } + +/* +* Return the max size, in bytes, of a message +*/ +u32bit PK_Encryptor_MR_with_EME::maximum_input_size() const + { + if(!encoder) + return (key.max_input_bits() / 8); + else + return encoder->maximum_input_size(key.max_input_bits()); + } + +/* +* PK_Decryptor_MR_with_EME Constructor +*/ +PK_Decryptor_MR_with_EME::PK_Decryptor_MR_with_EME(const PK_Decrypting_Key& k, + EME* eme_obj) : + key(k), encoder(eme_obj) + { + } + +/* +* Decrypt a message +*/ +SecureVector PK_Decryptor_MR_with_EME::dec(const byte msg[], + u32bit length) const + { + try { + SecureVector decrypted = key.decrypt(msg, length); + if(encoder) + return encoder->decode(decrypted, key.max_input_bits()); + else + return decrypted; + } + catch(Invalid_Argument) + { + throw Exception("PK_Decryptor_MR_with_EME: Input is invalid"); + } + catch(Decoding_Error) + { + throw Exception("PK_Decryptor_MR_with_EME: Input is invalid"); + } + } + +/* +* PK_Signer Constructor +*/ +PK_Signer::PK_Signer(const PK_Signing_Key& k, EMSA* emsa_obj) : + key(k), emsa(emsa_obj) + { + sig_format = IEEE_1363; + } + +/* +* Set the signature format +*/ +void PK_Signer::set_output_format(Signature_Format format) + { + if(key.message_parts() == 1 && format != IEEE_1363) + throw Invalid_State("PK_Signer: Cannot set the output format for " + + key.algo_name() + " keys"); + sig_format = format; + } + +/* +* Sign a message +*/ +SecureVector PK_Signer::sign_message(const byte msg[], u32bit length, + RandomNumberGenerator& rng) + { + update(msg, length); + return signature(rng); + } + +/* +* Sign a message +*/ +SecureVector PK_Signer::sign_message(const MemoryRegion& msg, + RandomNumberGenerator& rng) + { + return sign_message(msg, msg.size(), rng); + } + +/* +* Add more to the message to be signed +*/ +void PK_Signer::update(const byte in[], u32bit length) + { + emsa->update(in, length); + } + +/* +* Add more to the message to be signed +*/ +void PK_Signer::update(byte in) + { + update(&in, 1); + } + +/* +* Add more to the message to be signed +*/ +void PK_Signer::update(const MemoryRegion& in) + { + update(in, in.size()); + } + +/* +* Create a signature +*/ +SecureVector PK_Signer::signature(RandomNumberGenerator& rng) + { + SecureVector encoded = emsa->encoding_of(emsa->raw_data(), + key.max_input_bits(), + rng); + + SecureVector plain_sig = key.sign(encoded, encoded.size(), rng); + + if(key.message_parts() == 1 || sig_format == IEEE_1363) + return plain_sig; + + if(sig_format == DER_SEQUENCE) + { + if(plain_sig.size() % key.message_parts()) + throw Encoding_Error("PK_Signer: strange signature size found"); + const u32bit SIZE_OF_PART = plain_sig.size() / key.message_parts(); + + std::vector sig_parts(key.message_parts()); + for(u32bit j = 0; j != sig_parts.size(); ++j) + sig_parts[j].binary_decode(plain_sig + SIZE_OF_PART*j, SIZE_OF_PART); + + return DER_Encoder() + .start_cons(SEQUENCE) + .encode_list(sig_parts) + .end_cons() + .get_contents(); + } + else + throw Encoding_Error("PK_Signer: Unknown signature format " + + to_string(sig_format)); + } + +/* +* PK_Verifier Constructor +*/ +PK_Verifier::PK_Verifier(EMSA* emsa_obj) + { + emsa = emsa_obj; + sig_format = IEEE_1363; + } + +/* +* PK_Verifier Destructor +*/ +PK_Verifier::~PK_Verifier() + { + delete emsa; + } + +/* +* Set the signature format +*/ +void PK_Verifier::set_input_format(Signature_Format format) + { + if(key_message_parts() == 1 && format != IEEE_1363) + throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363"); + sig_format = format; + } + +/* +* Verify a message +*/ +bool PK_Verifier::verify_message(const MemoryRegion& msg, + const MemoryRegion& sig) + { + return verify_message(msg, msg.size(), sig, sig.size()); + } + +/* +* Verify a message +*/ +bool PK_Verifier::verify_message(const byte msg[], u32bit msg_length, + const byte sig[], u32bit sig_length) + { + update(msg, msg_length); + return check_signature(sig, sig_length); + } + +/* +* Append to the message +*/ +void PK_Verifier::update(const byte in[], u32bit length) + { + emsa->update(in, length); + } + +/* +* Append to the message +*/ +void PK_Verifier::update(byte in) + { + update(&in, 1); + } + +/* +* Append to the message +*/ +void PK_Verifier::update(const MemoryRegion& in) + { + update(in, in.size()); + } + +/* +* Check a signature +*/ +bool PK_Verifier::check_signature(const MemoryRegion& sig) + { + return check_signature(sig, sig.size()); + } + +/* +* Check a signature +*/ +bool PK_Verifier::check_signature(const byte sig[], u32bit length) + { + try { + if(sig_format == IEEE_1363) + return validate_signature(emsa->raw_data(), sig, length); + else if(sig_format == DER_SEQUENCE) + { + BER_Decoder decoder(sig, length); + BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); + + u32bit count = 0; + SecureVector real_sig; + while(ber_sig.more_items()) + { + BigInt sig_part; + ber_sig.decode(sig_part); + real_sig.append(BigInt::encode_1363(sig_part, + key_message_part_size())); + ++count; + } + if(count != key_message_parts()) + throw Decoding_Error("PK_Verifier: signature size invalid"); + + return validate_signature(emsa->raw_data(), + real_sig, real_sig.size()); + } + else + throw Decoding_Error("PK_Verifier: Unknown signature format " + + to_string(sig_format)); + } + catch(Invalid_Argument) { return false; } + catch(Decoding_Error) { return false; } + } + +/* +* Verify a signature +*/ +bool PK_Verifier_with_MR::validate_signature(const MemoryRegion& msg, + const byte sig[], u32bit sig_len) + { + SecureVector output_of_key = key.verify(sig, sig_len); + return emsa->verify(output_of_key, msg, key.max_input_bits()); + } + +/* +* Verify a signature +*/ +bool PK_Verifier_wo_MR::validate_signature(const MemoryRegion& msg, + const byte sig[], u32bit sig_len) + { + Null_RNG rng; + + SecureVector encoded = + emsa->encoding_of(msg, key.max_input_bits(), rng); + + return key.verify(encoded, encoded.size(), sig, sig_len); + } + +/* +* PK_Key_Agreement Constructor +*/ +PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& k, + KDF* kdf_obj) : + key(k), kdf(kdf_obj) + { + } + +/* +* Perform Key Agreement Operation +*/ +SymmetricKey PK_Key_Agreement::derive_key(u32bit key_len, + const byte in[], u32bit in_len, + const std::string& params) const + { + return derive_key(key_len, in, in_len, + reinterpret_cast(params.data()), + params.length()); + } + +/* +* Perform Key Agreement Operation +*/ +SymmetricKey PK_Key_Agreement::derive_key(u32bit key_len, const byte in[], + u32bit in_len, const byte params[], + u32bit params_len) const + { + OctetString z = key.derive_key(in, in_len); + if(!kdf) + return z; + + return kdf->derive_key(key_len, z.bits_of(), params, params_len); + } + +} diff --git a/src/pubkey/pubkey.h b/src/pubkey/pubkey.h new file mode 100644 index 000000000..815550edd --- /dev/null +++ b/src/pubkey/pubkey.h @@ -0,0 +1,392 @@ +/* +* Public Key Interface +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PUBKEY_H__ +#define BOTAN_PUBKEY_H__ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/** +* The two types of signature format supported by Botan. +*/ +enum Signature_Format { IEEE_1363, DER_SEQUENCE }; + +/** +* Public Key Encryptor +*/ +class BOTAN_DLL PK_Encryptor + { + public: + + /** + * Encrypt a message. + * @param in the message as a byte array + * @param length the length of the above byte array + * @param rng the random number source to use + * @return the encrypted message + */ + SecureVector encrypt(const byte in[], u32bit length, + RandomNumberGenerator& rng) const; + + /** + * Encrypt a message. + * @param in the message + * @param rng the random number source to use + * @return the encrypted message + */ + SecureVector encrypt(const MemoryRegion& in, + RandomNumberGenerator& rng) const; + + /** + * Return the maximum allowed message size in bytes. + * @return the maximum message size in bytes + */ + virtual u32bit maximum_input_size() const = 0; + + virtual ~PK_Encryptor() {} + private: + virtual SecureVector enc(const byte[], u32bit, + RandomNumberGenerator&) const = 0; + }; + +/** +* Public Key Decryptor +*/ +class BOTAN_DLL PK_Decryptor + { + public: + /** + * Decrypt a ciphertext. + * @param in the ciphertext as a byte array + * @param length the length of the above byte array + * @return the decrypted message + */ + SecureVector decrypt(const byte in[], u32bit length) const; + + /** + * Decrypt a ciphertext. + * @param in the ciphertext + * @return the decrypted message + */ + SecureVector decrypt(const MemoryRegion& in) const; + + virtual ~PK_Decryptor() {} + private: + virtual SecureVector dec(const byte[], u32bit) const = 0; + }; + +/** +* Public Key Signer. Use the sign_message() functions for small +* messages. Use multiple calls update() to process large messages and +* generate the signature by finally calling signature(). +*/ +class BOTAN_DLL PK_Signer + { + public: + /** + * Sign a message. + * @param in the message to sign as a byte array + * @param length the length of the above byte array + * @param rng the rng to use + * @return the signature + */ + SecureVector sign_message(const byte in[], u32bit length, + RandomNumberGenerator& rng); + + /** + * Sign a message. + * @param in the message to sign + * @param rng the rng to use + * @return the signature + */ + SecureVector sign_message(const MemoryRegion& in, + RandomNumberGenerator& rng); + + /** + * Add a message part (single byte). + * @param the byte to add + */ + void update(byte in); + + /** + * Add a message part. + * @param in the message part to add as a byte array + * @param length the length of the above byte array + */ + void update(const byte in[], u32bit length); + + /** + * Add a message part. + * @param in the message part to add + */ + void update(const MemoryRegion& in); + + /** + * Get the signature of the so far processed message (provided by the + * calls to update()). + * @param rng the rng to use + * @return the signature of the total message + */ + SecureVector signature(RandomNumberGenerator& rng); + + /** + * Set the output format of the signature. + * @param format the signature format to use + */ + void set_output_format(Signature_Format format); + + /** + * Construct a PK Signer. + * @param key the key to use inside this signer + * @param emsa the EMSA to use + * An example would be "EMSA1(SHA-224)". + */ + PK_Signer(const PK_Signing_Key& key, EMSA* emsa); + + ~PK_Signer() { delete emsa; } + private: + PK_Signer(const PK_Signer&); + PK_Signer& operator=(const PK_Signer&); + + const PK_Signing_Key& key; + Signature_Format sig_format; + EMSA* emsa; + }; + +/** +* Public Key Verifier. Use the verify_message() functions for small +* messages. Use multiple calls update() to process large messages and +* verify the signature by finally calling check_signature(). +*/ +class BOTAN_DLL PK_Verifier + { + public: + /** + * Verify a signature. + * @param msg the message that the signature belongs to, as a byte array + * @param msg_length the length of the above byte array msg + * @param sig the signature as a byte array + * @param sig_length the length of the above byte array sig + * @return true if the signature is valid + */ + bool verify_message(const byte msg[], u32bit msg_length, + const byte sig[], u32bit sig_length); + /** + * Verify a signature. + * @param msg the message that the signature belongs to + * @param sig the signature + * @return true if the signature is valid + */ + bool verify_message(const MemoryRegion& msg, + const MemoryRegion& sig); + + /** + * Add a message part (single byte) of the message corresponding to the + * signature to be verified. + * @param msg_part the byte to add + */ + void update(byte msg_part); + + /** + * Add a message part of the message corresponding to the + * signature to be verified. + * @param msg_part the new message part as a byte array + * @param length the length of the above byte array + */ + void update(const byte msg_part[], u32bit length); + + /** + * Add a message part of the message corresponding to the + * signature to be verified. + * @param msg_part the new message part + */ + void update(const MemoryRegion& msg_part); + + /** + * Check the signature of the buffered message, i.e. the one build + * by successive calls to update. + * @param sig the signature to be verified as a byte array + * @param length the length of the above byte array + * @return true if the signature is valid, false otherwise + */ + bool check_signature(const byte sig[], u32bit length); + + /** + * Check the signature of the buffered message, i.e. the one build + * by successive calls to update. + * @param sig the signature to be verified + * @return true if the signature is valid, false otherwise + */ + bool check_signature(const MemoryRegion& sig); + + /** + * Set the format of the signatures fed to this verifier. + * @param format the signature format to use + */ + void set_input_format(Signature_Format format); + + /** + * Construct a PK Verifier. + * @param emsa the EMSA to use + * An example would be new EMSA1(new SHA_224) + */ + PK_Verifier(EMSA* emsa); + + virtual ~PK_Verifier(); + protected: + virtual bool validate_signature(const MemoryRegion&, + const byte[], u32bit) = 0; + virtual u32bit key_message_parts() const = 0; + virtual u32bit key_message_part_size() const = 0; + + Signature_Format sig_format; + EMSA* emsa; + private: + PK_Verifier(const PK_Verifier&); + PK_Verifier& operator=(const PK_Verifier&); + }; + +/* +* Key Agreement +*/ +class BOTAN_DLL PK_Key_Agreement + { + public: + SymmetricKey derive_key(u32bit, const byte[], u32bit, + const std::string& = "") const; + SymmetricKey derive_key(u32bit, const byte[], u32bit, + const byte[], u32bit) const; + + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param kdf the KDF to use + */ + PK_Key_Agreement(const PK_Key_Agreement_Key& key, KDF* kdf); + + ~PK_Key_Agreement() { delete kdf; } + private: + PK_Key_Agreement(const PK_Key_Agreement_Key&); + PK_Key_Agreement& operator=(const PK_Key_Agreement&); + + const PK_Key_Agreement_Key& key; + KDF* kdf; + }; + +/** +* Encryption with an MR algorithm and an EME. +*/ +class BOTAN_DLL PK_Encryptor_MR_with_EME : public PK_Encryptor + { + public: + u32bit maximum_input_size() const; + + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param eme the EME to use + */ + PK_Encryptor_MR_with_EME(const PK_Encrypting_Key& key, + EME* eme); + + ~PK_Encryptor_MR_with_EME() { delete encoder; } + private: + PK_Encryptor_MR_with_EME(const PK_Encryptor_MR_with_EME&); + PK_Encryptor_MR_with_EME& operator=(const PK_Encryptor_MR_with_EME&); + + SecureVector enc(const byte[], u32bit, + RandomNumberGenerator& rng) const; + + const PK_Encrypting_Key& key; + const EME* encoder; + }; + +/** +* Decryption with an MR algorithm and an EME. +*/ +class BOTAN_DLL PK_Decryptor_MR_with_EME : public PK_Decryptor + { + public: + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param eme the EME to use + */ + PK_Decryptor_MR_with_EME(const PK_Decrypting_Key& key, + EME* eme); + + ~PK_Decryptor_MR_with_EME() { delete encoder; } + private: + PK_Decryptor_MR_with_EME(const PK_Decryptor_MR_with_EME&); + PK_Decryptor_MR_with_EME& operator=(const PK_Decryptor_MR_with_EME&); + + SecureVector dec(const byte[], u32bit) const; + + const PK_Decrypting_Key& key; + const EME* encoder; + }; + +/** +* Public Key Verifier with Message Recovery. +*/ +class BOTAN_DLL PK_Verifier_with_MR : public PK_Verifier + { + public: + /** + * Construct an instance. + * @param key the key to use inside the verifier + * @param emsa_name the name of the EMSA to use + */ + PK_Verifier_with_MR(const PK_Verifying_with_MR_Key& k, + EMSA* emsa_obj) : PK_Verifier(emsa_obj), key(k) {} + + private: + PK_Verifier_with_MR(const PK_Verifying_with_MR_Key&); + PK_Verifier_with_MR& operator=(const PK_Verifier_with_MR&); + + bool validate_signature(const MemoryRegion&, const byte[], u32bit); + u32bit key_message_parts() const { return key.message_parts(); } + u32bit key_message_part_size() const { return key.message_part_size(); } + + const PK_Verifying_with_MR_Key& key; + }; + +/** +* Public Key Verifier without Message Recovery +*/ +class BOTAN_DLL PK_Verifier_wo_MR : public PK_Verifier + { + public: + /** + * Construct an instance. + * @param key the key to use inside the verifier + * @param emsa_name the name of the EMSA to use + */ + PK_Verifier_wo_MR(const PK_Verifying_wo_MR_Key& k, + EMSA* emsa_obj) : PK_Verifier(emsa_obj), key(k) {} + + private: + PK_Verifier_wo_MR(const PK_Verifying_wo_MR_Key&); + PK_Verifier_wo_MR& operator=(const PK_Verifier_wo_MR&); + + bool validate_signature(const MemoryRegion&, const byte[], u32bit); + u32bit key_message_parts() const { return key.message_parts(); } + u32bit key_message_part_size() const { return key.message_part_size(); } + + const PK_Verifying_wo_MR_Key& key; + }; + +} + +#endif diff --git a/src/pubkey/pubkey/info.txt b/src/pubkey/pubkey/info.txt deleted file mode 100644 index 83b2c80cc..000000000 --- a/src/pubkey/pubkey/info.txt +++ /dev/null @@ -1,32 +0,0 @@ -realname "Public Key Base" - -define PUBLIC_KEY_CRYPTO - -load_on auto - - -asn1 -bigint -numbertheory -pbe -oid_lookup -pk_pad -rng - - - -pk_algs.cpp -pk_algs.h -pk_filts.cpp -pk_filts.h -pk_keys.cpp -pk_keys.h -pkcs8.cpp -pkcs8.h -pubkey.cpp -pubkey.h -pubkey_enums.cpp -pubkey_enums.h -x509_key.cpp -x509_key.h - diff --git a/src/pubkey/pubkey/pk_algs.cpp b/src/pubkey/pubkey/pk_algs.cpp deleted file mode 100644 index 99d7294f0..000000000 --- a/src/pubkey/pubkey/pk_algs.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* -* PK Key -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -#if defined(BOTAN_HAS_RSA) - #include -#endif - -#if defined(BOTAN_HAS_DSA) - #include -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include -#endif - -#if defined(BOTAN_HAS_ECDSA) - #include -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - #include -#endif - -#if defined(BOTAN_HAS_RW) - #include -#endif - -#if defined(BOTAN_HAS_ELGAMAL) - #include -#endif - -namespace Botan { - -/* -* Get an PK public key object -*/ -Public_Key* get_public_key(const std::string& alg_name) - { -#if defined(BOTAN_HAS_RSA) - if(alg_name == "RSA") return new RSA_PublicKey; -#endif - -#if defined(BOTAN_HAS_DSA) - if(alg_name == "DSA") return new DSA_PublicKey; -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(alg_name == "DH") return new DH_PublicKey; -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - if(alg_name == "NR") return new NR_PublicKey; -#endif - -#if defined(BOTAN_HAS_RW) - if(alg_name == "RW") return new RW_PublicKey; -#endif - -#if defined(BOTAN_HAS_ELG) - if(alg_name == "ELG") return new ElGamal_PublicKey; -#endif - -#if defined(BOTAN_HAS_ECDSA) - if(alg_name == "ECDSA") return new ECDSA_PublicKey; -#endif - - return 0; - } - -/* -* Get an PK private key object -*/ -Private_Key* get_private_key(const std::string& alg_name) - { -#if defined(BOTAN_HAS_RSA) - if(alg_name == "RSA") return new RSA_PrivateKey; -#endif - -#if defined(BOTAN_HAS_DSA) - if(alg_name == "DSA") return new DSA_PrivateKey; -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(alg_name == "DH") return new DH_PrivateKey; -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - if(alg_name == "NR") return new NR_PrivateKey; -#endif - -#if defined(BOTAN_HAS_RW) - if(alg_name == "RW") return new RW_PrivateKey; -#endif - -#if defined(BOTAN_HAS_ELG) - if(alg_name == "ELG") return new ElGamal_PrivateKey; -#endif - -#if defined(BOTAN_HAS_ECDSA) - if(alg_name == "ECDSA") return new ECDSA_PrivateKey; -#endif - - return 0; - } - -} diff --git a/src/pubkey/pubkey/pk_algs.h b/src/pubkey/pubkey/pk_algs.h deleted file mode 100644 index d32c9365b..000000000 --- a/src/pubkey/pubkey/pk_algs.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* PK Key Factory -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_PK_KEY_FACTORY_H__ -#define BOTAN_PK_KEY_FACTORY_H__ - -#include -#include - -namespace Botan { - -/** -* Get an empty public key object. -* @param name the name of the desired public key algorithm -* @return the public key object -*/ -BOTAN_DLL Public_Key* get_public_key(const std::string&); - -/** -* Get an empty private key object. -* @param name the name of the desired public key algorithm -* @return the private key object -*/ -BOTAN_DLL Private_Key* get_private_key(const std::string&); - -} - -#endif diff --git a/src/pubkey/pubkey/pk_filts.cpp b/src/pubkey/pubkey/pk_filts.cpp deleted file mode 100644 index 18da9c10b..000000000 --- a/src/pubkey/pubkey/pk_filts.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* -* PK Filters -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Append to the buffer -*/ -void PK_Encryptor_Filter::write(const byte input[], u32bit length) - { - buffer.append(input, length); - } - -/* -* Encrypt the message -*/ -void PK_Encryptor_Filter::end_msg() - { - send(cipher->encrypt(buffer, buffer.size(), rng)); - buffer.destroy(); - } - -/* -* Append to the buffer -*/ -void PK_Decryptor_Filter::write(const byte input[], u32bit length) - { - buffer.append(input, length); - } - -/* -* Decrypt the message -*/ -void PK_Decryptor_Filter::end_msg() - { - send(cipher->decrypt(buffer, buffer.size())); - buffer.destroy(); - } - -/* -* Add more data -*/ -void PK_Signer_Filter::write(const byte input[], u32bit length) - { - signer->update(input, length); - } - -/* -* Sign the message -*/ -void PK_Signer_Filter::end_msg() - { - send(signer->signature(rng)); - } - -/* -* Add more data -*/ -void PK_Verifier_Filter::write(const byte input[], u32bit length) - { - verifier->update(input, length); - } - -/* -* Verify the message -*/ -void PK_Verifier_Filter::end_msg() - { - if(signature.is_empty()) - throw Exception("PK_Verifier_Filter: No signature to check against"); - bool is_valid = verifier->check_signature(signature, signature.size()); - send((is_valid ? 1 : 0)); - } - -/* -* Set the signature to check -*/ -void PK_Verifier_Filter::set_signature(const byte sig[], u32bit length) - { - signature.set(sig, length); - } - -/* -* Set the signature to check -*/ -void PK_Verifier_Filter::set_signature(const MemoryRegion& sig) - { - signature = sig; - } - -/* -* PK_Verifier_Filter Constructor -*/ -PK_Verifier_Filter::PK_Verifier_Filter(PK_Verifier* v, const byte sig[], - u32bit length) : - verifier(v), signature(sig, length) - { - } - -/* -* PK_Verifier_Filter Constructor -*/ -PK_Verifier_Filter::PK_Verifier_Filter(PK_Verifier* v, - const MemoryRegion& sig) : - verifier(v), signature(sig) - { - } - -} diff --git a/src/pubkey/pubkey/pk_filts.h b/src/pubkey/pubkey/pk_filts.h deleted file mode 100644 index 8bf3fc238..000000000 --- a/src/pubkey/pubkey/pk_filts.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -* PK Filters -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_PK_FILTERS_H__ -#define BOTAN_PK_FILTERS_H__ - -#include -#include - -namespace Botan { - -/* -* PK_Encryptor Filter -*/ -class BOTAN_DLL PK_Encryptor_Filter : public Filter - { - public: - void write(const byte[], u32bit); - void end_msg(); - PK_Encryptor_Filter(PK_Encryptor* c, - RandomNumberGenerator& rng_ref) : - cipher(c), rng(rng_ref) {} - ~PK_Encryptor_Filter() { delete cipher; } - private: - PK_Encryptor* cipher; - RandomNumberGenerator& rng; - SecureVector buffer; - }; - -/* -* PK_Decryptor Filter -*/ -class BOTAN_DLL PK_Decryptor_Filter : public Filter - { - public: - void write(const byte[], u32bit); - void end_msg(); - PK_Decryptor_Filter(PK_Decryptor* c) : cipher(c) {} - ~PK_Decryptor_Filter() { delete cipher; } - private: - PK_Decryptor* cipher; - SecureVector buffer; - }; - -/* -* PK_Signer Filter -*/ -class BOTAN_DLL PK_Signer_Filter : public Filter - { - public: - void write(const byte[], u32bit); - void end_msg(); - - PK_Signer_Filter(PK_Signer* s, - RandomNumberGenerator& rng_ref) : - signer(s), rng(rng_ref) {} - - ~PK_Signer_Filter() { delete signer; } - private: - PK_Signer* signer; - RandomNumberGenerator& rng; - }; - -/* -* PK_Verifier Filter -*/ -class BOTAN_DLL PK_Verifier_Filter : public Filter - { - public: - void write(const byte[], u32bit); - void end_msg(); - - void set_signature(const byte[], u32bit); - void set_signature(const MemoryRegion&); - - PK_Verifier_Filter(PK_Verifier* v) : verifier(v) {} - PK_Verifier_Filter(PK_Verifier*, const byte[], u32bit); - PK_Verifier_Filter(PK_Verifier*, const MemoryRegion&); - ~PK_Verifier_Filter() { delete verifier; } - private: - PK_Verifier* verifier; - SecureVector signature; - }; - -} - -#endif diff --git a/src/pubkey/pubkey/pk_keys.cpp b/src/pubkey/pubkey/pk_keys.cpp deleted file mode 100644 index b93158558..000000000 --- a/src/pubkey/pubkey/pk_keys.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* -* PK Key Types -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/* -* Default OID access -*/ -OID Public_Key::get_oid() const - { - try { - return OIDS::lookup(algo_name()); - } - catch(Lookup_Error) - { - throw Lookup_Error("PK algo " + algo_name() + " has no defined OIDs"); - } - } - -/* -* Run checks on a loaded public key -*/ -void Public_Key::load_check(RandomNumberGenerator& rng) const - { - if(!check_key(rng, BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD)) - throw Invalid_Argument(algo_name() + ": Invalid public key"); - } - -/* -* Run checks on a loaded private key -*/ -void Private_Key::load_check(RandomNumberGenerator& rng) const - { - if(!check_key(rng, BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD)) - throw Invalid_Argument(algo_name() + ": Invalid private key"); - } - -/* -* Run checks on a generated private key -*/ -void Private_Key::gen_check(RandomNumberGenerator& rng) const - { - if(!check_key(rng, BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_GENERATE)) - throw Self_Test_Failure(algo_name() + " private key generation failed"); - } - -} diff --git a/src/pubkey/pubkey/pk_keys.h b/src/pubkey/pubkey/pk_keys.h deleted file mode 100644 index 5b612577d..000000000 --- a/src/pubkey/pubkey/pk_keys.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -* PK Key Types -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_PK_KEYS_H__ -#define BOTAN_PK_KEYS_H__ - -#include -#include -#include - -namespace Botan { - -/** -* Public Key Base Class. -*/ -class BOTAN_DLL Public_Key - { - public: - /** - * Get the name of the underlying public key scheme. - * @return the name of the public key scheme - */ - virtual std::string algo_name() const = 0; - - /** - * Get the OID of the underlying public key scheme. - * @return the OID of the public key scheme - */ - virtual OID get_oid() const; - - /** - * Test the key values for consistency. - * @param rng rng to use - * @param strong whether to perform strong and lengthy version - * of the test - * @return true if the test is passed - */ - virtual bool check_key(RandomNumberGenerator&, bool) const - { return true; } - - /** - * Find out the number of message parts supported by this scheme. - * @return the number of message parts - */ - virtual u32bit message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return the size of the message parts - */ - virtual u32bit message_part_size() const { return 0; } - - /** - * Get the maximum message size in bits supported by this public key. - * @return the maximum message in bits - */ - virtual u32bit max_input_bits() const = 0; - - /** - * Get an X509 encoder that can be used to encode this key in X509 format. - * @return an X509 encoder for this key - */ - virtual class X509_Encoder* x509_encoder() const = 0; - - /** - * Get an X509 decoder that can be used to set the values of this - * key based on an X509 encoded key object. - * @return an X509 decoder for this key - */ - virtual class X509_Decoder* x509_decoder() = 0; - - virtual ~Public_Key() {} - protected: - virtual void load_check(RandomNumberGenerator&) const; - }; - -/** -* Private Key Base Class -*/ -class BOTAN_DLL Private_Key : public virtual Public_Key - { - public: - /** - * Get a PKCS#8 encoder that can be used to encode this key in - * PKCS#8 format. - * @return an PKCS#8 encoder for this key - */ - virtual class PKCS8_Encoder* pkcs8_encoder() const - { return 0; } - - /** - * Get an PKCS#8 decoder that can be used to set the values of this key - * based on an PKCS#8 encoded key object. - * @return an PKCS#8 decoder for this key - */ - virtual class PKCS8_Decoder* pkcs8_decoder(RandomNumberGenerator&) - { return 0; } - protected: - void load_check(RandomNumberGenerator&) const; - void gen_check(RandomNumberGenerator&) const; - }; - -/** -* PK Encrypting Key. -*/ -class BOTAN_DLL PK_Encrypting_Key : public virtual Public_Key - { - public: - virtual SecureVector encrypt(const byte[], u32bit, - RandomNumberGenerator&) const = 0; - virtual ~PK_Encrypting_Key() {} - }; - -/** -* PK Decrypting Key -*/ -class BOTAN_DLL PK_Decrypting_Key : public virtual Private_Key - { - public: - virtual SecureVector decrypt(const byte[], u32bit) const = 0; - virtual ~PK_Decrypting_Key() {} - }; - -/** -* PK Signing Key -*/ -class BOTAN_DLL PK_Signing_Key : public virtual Private_Key - { - public: - virtual SecureVector sign(const byte[], u32bit, - RandomNumberGenerator& rng) const = 0; - virtual ~PK_Signing_Key() {} - }; - -/** -* PK Verifying Key, Message Recovery Version -*/ -class BOTAN_DLL PK_Verifying_with_MR_Key : public virtual Public_Key - { - public: - virtual SecureVector verify(const byte[], u32bit) const = 0; - virtual ~PK_Verifying_with_MR_Key() {} - }; - -/** -* PK Verifying Key, No Message Recovery Version -*/ -class BOTAN_DLL PK_Verifying_wo_MR_Key : public virtual Public_Key - { - public: - virtual bool verify(const byte[], u32bit, - const byte[], u32bit) const = 0; - virtual ~PK_Verifying_wo_MR_Key() {} - }; - -/** -* PK Secret Value Derivation Key -*/ -class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key - { - public: - virtual SecureVector derive_key(const byte[], u32bit) const = 0; - virtual MemoryVector public_value() const = 0; - virtual ~PK_Key_Agreement_Key() {} - }; - -/* -* Typedefs -*/ -typedef PK_Key_Agreement_Key PK_KA_Key; -typedef Public_Key X509_PublicKey; -typedef Private_Key PKCS8_PrivateKey; - -} - -#endif diff --git a/src/pubkey/pubkey/pkcs8.cpp b/src/pubkey/pubkey/pkcs8.cpp deleted file mode 100644 index 8a464ecfe..000000000 --- a/src/pubkey/pubkey/pkcs8.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* -* PKCS #8 -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -namespace PKCS8 { - -namespace { - -/* -* Get info from an EncryptedPrivateKeyInfo -*/ -SecureVector PKCS8_extract(DataSource& source, - AlgorithmIdentifier& pbe_alg_id) - { - SecureVector key_data; - - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(pbe_alg_id) - .decode(key_data, OCTET_STRING) - .verify_end(); - - return key_data; - } - -/* -* PEM decode and/or decrypt a private key -*/ -SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, - AlgorithmIdentifier& pk_alg_id) - { - AlgorithmIdentifier pbe_alg_id; - SecureVector key_data, key; - bool is_encrypted = true; - - try { - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - key_data = PKCS8_extract(source, pbe_alg_id); - else - { - std::string label; - key_data = PEM_Code::decode(source, label); - if(label == "PRIVATE KEY") - is_encrypted = false; - else if(label == "ENCRYPTED PRIVATE KEY") - { - DataSource_Memory key_source(key_data); - key_data = PKCS8_extract(key_source, pbe_alg_id); - } - else - throw PKCS8_Exception("Unknown PEM label " + label); - } - - if(key_data.is_empty()) - throw PKCS8_Exception("No key data found"); - } - catch(Decoding_Error) - { - throw Decoding_Error("PKCS #8 private key decoding failed"); - } - - if(!is_encrypted) - key = key_data; - - const u32bit MAX_TRIES = 3; - - u32bit tries = 0; - while(true) - { - try { - if(MAX_TRIES && tries >= MAX_TRIES) - break; - - if(is_encrypted) - { - DataSource_Memory params(pbe_alg_id.parameters); - std::auto_ptr pbe(get_pbe(pbe_alg_id.oid, params)); - - User_Interface::UI_Result result = User_Interface::OK; - const std::string passphrase = - ui.get_passphrase("PKCS #8 private key", source.id(), result); - - if(result == User_Interface::CANCEL_ACTION) - break; - - pbe->set_key(passphrase); - Pipe decryptor(pbe.release()); - - decryptor.process_msg(key_data, key_data.size()); - key = decryptor.read_all(); - } - - u32bit version; - - BER_Decoder(key) - .start_cons(SEQUENCE) - .decode(version) - .decode(pk_alg_id) - .decode(key, OCTET_STRING) - .discard_remaining() - .end_cons(); - - if(version != 0) - throw Decoding_Error("PKCS #8: Unknown version number"); - - break; - } - catch(Decoding_Error) - { - ++tries; - } - } - - if(key.is_empty()) - throw Decoding_Error("PKCS #8 private key decoding failed"); - return key; - } - -} - -/* -* DER or PEM encode a PKCS #8 private key -*/ -void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding) - { - std::auto_ptr encoder(key.pkcs8_encoder()); - if(!encoder.get()) - throw Encoding_Error("PKCS8::encode: Key does not support encoding"); - - const u32bit PKCS8_VERSION = 0; - - SecureVector contents = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(PKCS8_VERSION) - .encode(encoder->alg_id()) - .encode(encoder->key_bits(), OCTET_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(contents, "PRIVATE KEY")); - else - pipe.write(contents); - } - -/* -* Encode and encrypt a PKCS #8 private key -*/ -void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, const std::string& pbe_algo, - X509_Encoding encoding) - { - const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"; - - Pipe raw_key; - raw_key.start_msg(); - encode(key, raw_key, RAW_BER); - raw_key.end_msg(); - - std::auto_ptr pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); - - pbe->new_params(rng); - pbe->set_key(pass); - - AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); - - Pipe key_encrytor(pbe.release()); - key_encrytor.process_msg(raw_key); - - SecureVector enc_key = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(pbe_algid) - .encode(key_encrytor.read_all(), OCTET_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(enc_key, "ENCRYPTED PRIVATE KEY")); - else - pipe.write(enc_key); - } - -/* -* PEM encode a PKCS #8 private key -*/ -std::string PEM_encode(const Private_Key& key) - { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Encrypt and PEM encode a PKCS #8 private key -*/ -std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo) - { - if(pass == "") - return PEM_encode(key); - - Pipe pem; - pem.start_msg(); - encrypt_key(key, pem, rng, pass, pbe_algo, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - AlgorithmIdentifier alg_id; - SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); - - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "" || alg_name == alg_id.oid.as_string()) - throw PKCS8_Exception("Unknown algorithm OID: " + - alg_id.oid.as_string()); - - std::auto_ptr key(get_private_key(alg_name)); - - if(!key.get()) - throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " + - alg_id.oid.as_string()); - - std::auto_ptr decoder(key->pkcs8_decoder(rng)); - - if(!decoder.get()) - throw Decoding_Error("Key does not support PKCS #8 decoding"); - - decoder->alg_id(alg_id); - decoder->key_bits(pkcs8_key); - - return key.release(); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - DataSource_Stream source(fsname, true); - return PKCS8::load_key(source, rng, ui); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(source, rng, User_Interface(pass)); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(fsname, rng, User_Interface(pass)); - } - -/* -* Make a copy of this private key -*/ -Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng) - { - Pipe bits; - - bits.start_msg(); - PKCS8::encode(key, bits); - bits.end_msg(); - - DataSource_Memory source(bits.read_all()); - return PKCS8::load_key(source, rng); - } - -} - -} diff --git a/src/pubkey/pubkey/pkcs8.h b/src/pubkey/pubkey/pkcs8.h deleted file mode 100644 index 87f8ba326..000000000 --- a/src/pubkey/pubkey/pkcs8.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -* PKCS #8 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_PKCS8_H__ -#define BOTAN_PKCS8_H__ - -#include -#include - -namespace Botan { - -/** -* PKCS #8 Private Key Encoder. -*/ -class BOTAN_DLL PKCS8_Encoder - { - public: - /** - * Get the algorithm identifier associated with the scheme - * this encoders key is part of. - * @return the algorithm identifier - */ - virtual AlgorithmIdentifier alg_id() const = 0; - - /** - * Get the DER encoded key. - * @return the DER encoded key - */ - // XXX: Why not SecureVector? - virtual MemoryVector key_bits() const = 0; - virtual ~PKCS8_Encoder() {} - }; - -/* -* PKCS #8 Private Key Decoder -*/ -class BOTAN_DLL PKCS8_Decoder - { - public: - /** - * Set the algorithm identifier associated with the scheme - * this decoders key is part of. - * @param alg_id the algorithm identifier - */ - virtual void alg_id(const AlgorithmIdentifier&) = 0; - - /** - * Set the DER encoded key. - * @param key the DER encoded key - */ - virtual void key_bits(const MemoryRegion&) = 0; - virtual ~PKCS8_Decoder() {} - }; - -/** -* PKCS #8 General Exception -*/ -struct BOTAN_DLL PKCS8_Exception : public Decoding_Error - { - PKCS8_Exception(const std::string& error) : - Decoding_Error("PKCS #8: " + error) {} - }; - -namespace PKCS8 { - -/** -* Encode a private key into a pipe. -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use -*/ -BOTAN_DLL void encode(const Private_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); - -/** -* Encode and encrypt a private key into a pipe. -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param pass the password to use for encryption -* @param rng the rng to use -* @param pbe_algo the name of the desired password-based encryption algorithm. -* Provide an empty string to use the default PBE defined in the configuration -* under base/default_pbe. -* @param enc the encoding type to use -*/ -BOTAN_DLL void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = "", - X509_Encoding enc = PEM); - - -/** -* Get a string containing a PEM encoded private key. -* @param key the key to encode -* @return the encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key); - -/** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption algorithm. -* Provide an empty string to use the default PBE defined in the configuration -* under base/default_pbe. -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = ""); - -BOTAN_DLL std::string PEM_encode(const Private_Key&, - const std::string&, - const std::string& = ""); - - -/** -* Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Copy an existing encoded key object. -* @param key the key to copy -* @param rng the rng to use -* @return the new copy of the key -*/ -BOTAN_DLL Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng); - -} - -} - -#endif diff --git a/src/pubkey/pubkey/pubkey.cpp b/src/pubkey/pubkey/pubkey.cpp deleted file mode 100644 index 4ddaa6fb6..000000000 --- a/src/pubkey/pubkey/pubkey.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* -* Public Key Base -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -/* -* Encrypt a message -*/ -SecureVector PK_Encryptor::encrypt(const byte in[], u32bit len, - RandomNumberGenerator& rng) const - { - return enc(in, len, rng); - } - -/* -* Encrypt a message -*/ -SecureVector PK_Encryptor::encrypt(const MemoryRegion& in, - RandomNumberGenerator& rng) const - { - return enc(in.begin(), in.size(), rng); - } - -/* -* Decrypt a message -*/ -SecureVector PK_Decryptor::decrypt(const byte in[], u32bit len) const - { - return dec(in, len); - } - -/* -* Decrypt a message -*/ -SecureVector PK_Decryptor::decrypt(const MemoryRegion& in) const - { - return dec(in.begin(), in.size()); - } - -/* -* PK_Encryptor_MR_with_EME Constructor -*/ -PK_Encryptor_MR_with_EME::PK_Encryptor_MR_with_EME(const PK_Encrypting_Key& k, - EME* eme_obj) : - key(k), encoder(eme_obj) - { - } - -/* -* Encrypt a message -*/ -SecureVector -PK_Encryptor_MR_with_EME::enc(const byte msg[], - u32bit length, - RandomNumberGenerator& rng) const - { - SecureVector message; - if(encoder) - message = encoder->encode(msg, length, key.max_input_bits(), rng); - else - message.set(msg, length); - - if(8*(message.size() - 1) + high_bit(message[0]) > key.max_input_bits()) - throw Exception("PK_Encryptor_MR_with_EME: Input is too large"); - - return key.encrypt(message, message.size(), rng); - } - -/* -* Return the max size, in bytes, of a message -*/ -u32bit PK_Encryptor_MR_with_EME::maximum_input_size() const - { - if(!encoder) - return (key.max_input_bits() / 8); - else - return encoder->maximum_input_size(key.max_input_bits()); - } - -/* -* PK_Decryptor_MR_with_EME Constructor -*/ -PK_Decryptor_MR_with_EME::PK_Decryptor_MR_with_EME(const PK_Decrypting_Key& k, - EME* eme_obj) : - key(k), encoder(eme_obj) - { - } - -/* -* Decrypt a message -*/ -SecureVector PK_Decryptor_MR_with_EME::dec(const byte msg[], - u32bit length) const - { - try { - SecureVector decrypted = key.decrypt(msg, length); - if(encoder) - return encoder->decode(decrypted, key.max_input_bits()); - else - return decrypted; - } - catch(Invalid_Argument) - { - throw Exception("PK_Decryptor_MR_with_EME: Input is invalid"); - } - catch(Decoding_Error) - { - throw Exception("PK_Decryptor_MR_with_EME: Input is invalid"); - } - } - -/* -* PK_Signer Constructor -*/ -PK_Signer::PK_Signer(const PK_Signing_Key& k, EMSA* emsa_obj) : - key(k), emsa(emsa_obj) - { - sig_format = IEEE_1363; - } - -/* -* Set the signature format -*/ -void PK_Signer::set_output_format(Signature_Format format) - { - if(key.message_parts() == 1 && format != IEEE_1363) - throw Invalid_State("PK_Signer: Cannot set the output format for " + - key.algo_name() + " keys"); - sig_format = format; - } - -/* -* Sign a message -*/ -SecureVector PK_Signer::sign_message(const byte msg[], u32bit length, - RandomNumberGenerator& rng) - { - update(msg, length); - return signature(rng); - } - -/* -* Sign a message -*/ -SecureVector PK_Signer::sign_message(const MemoryRegion& msg, - RandomNumberGenerator& rng) - { - return sign_message(msg, msg.size(), rng); - } - -/* -* Add more to the message to be signed -*/ -void PK_Signer::update(const byte in[], u32bit length) - { - emsa->update(in, length); - } - -/* -* Add more to the message to be signed -*/ -void PK_Signer::update(byte in) - { - update(&in, 1); - } - -/* -* Add more to the message to be signed -*/ -void PK_Signer::update(const MemoryRegion& in) - { - update(in, in.size()); - } - -/* -* Create a signature -*/ -SecureVector PK_Signer::signature(RandomNumberGenerator& rng) - { - SecureVector encoded = emsa->encoding_of(emsa->raw_data(), - key.max_input_bits(), - rng); - - SecureVector plain_sig = key.sign(encoded, encoded.size(), rng); - - if(key.message_parts() == 1 || sig_format == IEEE_1363) - return plain_sig; - - if(sig_format == DER_SEQUENCE) - { - if(plain_sig.size() % key.message_parts()) - throw Encoding_Error("PK_Signer: strange signature size found"); - const u32bit SIZE_OF_PART = plain_sig.size() / key.message_parts(); - - std::vector sig_parts(key.message_parts()); - for(u32bit j = 0; j != sig_parts.size(); ++j) - sig_parts[j].binary_decode(plain_sig + SIZE_OF_PART*j, SIZE_OF_PART); - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode_list(sig_parts) - .end_cons() - .get_contents(); - } - else - throw Encoding_Error("PK_Signer: Unknown signature format " + - to_string(sig_format)); - } - -/* -* PK_Verifier Constructor -*/ -PK_Verifier::PK_Verifier(EMSA* emsa_obj) - { - emsa = emsa_obj; - sig_format = IEEE_1363; - } - -/* -* PK_Verifier Destructor -*/ -PK_Verifier::~PK_Verifier() - { - delete emsa; - } - -/* -* Set the signature format -*/ -void PK_Verifier::set_input_format(Signature_Format format) - { - if(key_message_parts() == 1 && format != IEEE_1363) - throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363"); - sig_format = format; - } - -/* -* Verify a message -*/ -bool PK_Verifier::verify_message(const MemoryRegion& msg, - const MemoryRegion& sig) - { - return verify_message(msg, msg.size(), sig, sig.size()); - } - -/* -* Verify a message -*/ -bool PK_Verifier::verify_message(const byte msg[], u32bit msg_length, - const byte sig[], u32bit sig_length) - { - update(msg, msg_length); - return check_signature(sig, sig_length); - } - -/* -* Append to the message -*/ -void PK_Verifier::update(const byte in[], u32bit length) - { - emsa->update(in, length); - } - -/* -* Append to the message -*/ -void PK_Verifier::update(byte in) - { - update(&in, 1); - } - -/* -* Append to the message -*/ -void PK_Verifier::update(const MemoryRegion& in) - { - update(in, in.size()); - } - -/* -* Check a signature -*/ -bool PK_Verifier::check_signature(const MemoryRegion& sig) - { - return check_signature(sig, sig.size()); - } - -/* -* Check a signature -*/ -bool PK_Verifier::check_signature(const byte sig[], u32bit length) - { - try { - if(sig_format == IEEE_1363) - return validate_signature(emsa->raw_data(), sig, length); - else if(sig_format == DER_SEQUENCE) - { - BER_Decoder decoder(sig, length); - BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); - - u32bit count = 0; - SecureVector real_sig; - while(ber_sig.more_items()) - { - BigInt sig_part; - ber_sig.decode(sig_part); - real_sig.append(BigInt::encode_1363(sig_part, - key_message_part_size())); - ++count; - } - if(count != key_message_parts()) - throw Decoding_Error("PK_Verifier: signature size invalid"); - - return validate_signature(emsa->raw_data(), - real_sig, real_sig.size()); - } - else - throw Decoding_Error("PK_Verifier: Unknown signature format " + - to_string(sig_format)); - } - catch(Invalid_Argument) { return false; } - catch(Decoding_Error) { return false; } - } - -/* -* Verify a signature -*/ -bool PK_Verifier_with_MR::validate_signature(const MemoryRegion& msg, - const byte sig[], u32bit sig_len) - { - SecureVector output_of_key = key.verify(sig, sig_len); - return emsa->verify(output_of_key, msg, key.max_input_bits()); - } - -/* -* Verify a signature -*/ -bool PK_Verifier_wo_MR::validate_signature(const MemoryRegion& msg, - const byte sig[], u32bit sig_len) - { - Null_RNG rng; - - SecureVector encoded = - emsa->encoding_of(msg, key.max_input_bits(), rng); - - return key.verify(encoded, encoded.size(), sig, sig_len); - } - -/* -* PK_Key_Agreement Constructor -*/ -PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& k, - KDF* kdf_obj) : - key(k), kdf(kdf_obj) - { - } - -/* -* Perform Key Agreement Operation -*/ -SymmetricKey PK_Key_Agreement::derive_key(u32bit key_len, - const byte in[], u32bit in_len, - const std::string& params) const - { - return derive_key(key_len, in, in_len, - reinterpret_cast(params.data()), - params.length()); - } - -/* -* Perform Key Agreement Operation -*/ -SymmetricKey PK_Key_Agreement::derive_key(u32bit key_len, const byte in[], - u32bit in_len, const byte params[], - u32bit params_len) const - { - OctetString z = key.derive_key(in, in_len); - if(!kdf) - return z; - - return kdf->derive_key(key_len, z.bits_of(), params, params_len); - } - -} diff --git a/src/pubkey/pubkey/pubkey.h b/src/pubkey/pubkey/pubkey.h deleted file mode 100644 index 815550edd..000000000 --- a/src/pubkey/pubkey/pubkey.h +++ /dev/null @@ -1,392 +0,0 @@ -/* -* Public Key Interface -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_PUBKEY_H__ -#define BOTAN_PUBKEY_H__ - -#include -#include -#include -#include -#include -#include - -namespace Botan { - -/** -* The two types of signature format supported by Botan. -*/ -enum Signature_Format { IEEE_1363, DER_SEQUENCE }; - -/** -* Public Key Encryptor -*/ -class BOTAN_DLL PK_Encryptor - { - public: - - /** - * Encrypt a message. - * @param in the message as a byte array - * @param length the length of the above byte array - * @param rng the random number source to use - * @return the encrypted message - */ - SecureVector encrypt(const byte in[], u32bit length, - RandomNumberGenerator& rng) const; - - /** - * Encrypt a message. - * @param in the message - * @param rng the random number source to use - * @return the encrypted message - */ - SecureVector encrypt(const MemoryRegion& in, - RandomNumberGenerator& rng) const; - - /** - * Return the maximum allowed message size in bytes. - * @return the maximum message size in bytes - */ - virtual u32bit maximum_input_size() const = 0; - - virtual ~PK_Encryptor() {} - private: - virtual SecureVector enc(const byte[], u32bit, - RandomNumberGenerator&) const = 0; - }; - -/** -* Public Key Decryptor -*/ -class BOTAN_DLL PK_Decryptor - { - public: - /** - * Decrypt a ciphertext. - * @param in the ciphertext as a byte array - * @param length the length of the above byte array - * @return the decrypted message - */ - SecureVector decrypt(const byte in[], u32bit length) const; - - /** - * Decrypt a ciphertext. - * @param in the ciphertext - * @return the decrypted message - */ - SecureVector decrypt(const MemoryRegion& in) const; - - virtual ~PK_Decryptor() {} - private: - virtual SecureVector dec(const byte[], u32bit) const = 0; - }; - -/** -* Public Key Signer. Use the sign_message() functions for small -* messages. Use multiple calls update() to process large messages and -* generate the signature by finally calling signature(). -*/ -class BOTAN_DLL PK_Signer - { - public: - /** - * Sign a message. - * @param in the message to sign as a byte array - * @param length the length of the above byte array - * @param rng the rng to use - * @return the signature - */ - SecureVector sign_message(const byte in[], u32bit length, - RandomNumberGenerator& rng); - - /** - * Sign a message. - * @param in the message to sign - * @param rng the rng to use - * @return the signature - */ - SecureVector sign_message(const MemoryRegion& in, - RandomNumberGenerator& rng); - - /** - * Add a message part (single byte). - * @param the byte to add - */ - void update(byte in); - - /** - * Add a message part. - * @param in the message part to add as a byte array - * @param length the length of the above byte array - */ - void update(const byte in[], u32bit length); - - /** - * Add a message part. - * @param in the message part to add - */ - void update(const MemoryRegion& in); - - /** - * Get the signature of the so far processed message (provided by the - * calls to update()). - * @param rng the rng to use - * @return the signature of the total message - */ - SecureVector signature(RandomNumberGenerator& rng); - - /** - * Set the output format of the signature. - * @param format the signature format to use - */ - void set_output_format(Signature_Format format); - - /** - * Construct a PK Signer. - * @param key the key to use inside this signer - * @param emsa the EMSA to use - * An example would be "EMSA1(SHA-224)". - */ - PK_Signer(const PK_Signing_Key& key, EMSA* emsa); - - ~PK_Signer() { delete emsa; } - private: - PK_Signer(const PK_Signer&); - PK_Signer& operator=(const PK_Signer&); - - const PK_Signing_Key& key; - Signature_Format sig_format; - EMSA* emsa; - }; - -/** -* Public Key Verifier. Use the verify_message() functions for small -* messages. Use multiple calls update() to process large messages and -* verify the signature by finally calling check_signature(). -*/ -class BOTAN_DLL PK_Verifier - { - public: - /** - * Verify a signature. - * @param msg the message that the signature belongs to, as a byte array - * @param msg_length the length of the above byte array msg - * @param sig the signature as a byte array - * @param sig_length the length of the above byte array sig - * @return true if the signature is valid - */ - bool verify_message(const byte msg[], u32bit msg_length, - const byte sig[], u32bit sig_length); - /** - * Verify a signature. - * @param msg the message that the signature belongs to - * @param sig the signature - * @return true if the signature is valid - */ - bool verify_message(const MemoryRegion& msg, - const MemoryRegion& sig); - - /** - * Add a message part (single byte) of the message corresponding to the - * signature to be verified. - * @param msg_part the byte to add - */ - void update(byte msg_part); - - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param msg_part the new message part as a byte array - * @param length the length of the above byte array - */ - void update(const byte msg_part[], u32bit length); - - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param msg_part the new message part - */ - void update(const MemoryRegion& msg_part); - - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified as a byte array - * @param length the length of the above byte array - * @return true if the signature is valid, false otherwise - */ - bool check_signature(const byte sig[], u32bit length); - - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified - * @return true if the signature is valid, false otherwise - */ - bool check_signature(const MemoryRegion& sig); - - /** - * Set the format of the signatures fed to this verifier. - * @param format the signature format to use - */ - void set_input_format(Signature_Format format); - - /** - * Construct a PK Verifier. - * @param emsa the EMSA to use - * An example would be new EMSA1(new SHA_224) - */ - PK_Verifier(EMSA* emsa); - - virtual ~PK_Verifier(); - protected: - virtual bool validate_signature(const MemoryRegion&, - const byte[], u32bit) = 0; - virtual u32bit key_message_parts() const = 0; - virtual u32bit key_message_part_size() const = 0; - - Signature_Format sig_format; - EMSA* emsa; - private: - PK_Verifier(const PK_Verifier&); - PK_Verifier& operator=(const PK_Verifier&); - }; - -/* -* Key Agreement -*/ -class BOTAN_DLL PK_Key_Agreement - { - public: - SymmetricKey derive_key(u32bit, const byte[], u32bit, - const std::string& = "") const; - SymmetricKey derive_key(u32bit, const byte[], u32bit, - const byte[], u32bit) const; - - /** - * Construct a PK Key Agreement. - * @param key the key to use - * @param kdf the KDF to use - */ - PK_Key_Agreement(const PK_Key_Agreement_Key& key, KDF* kdf); - - ~PK_Key_Agreement() { delete kdf; } - private: - PK_Key_Agreement(const PK_Key_Agreement_Key&); - PK_Key_Agreement& operator=(const PK_Key_Agreement&); - - const PK_Key_Agreement_Key& key; - KDF* kdf; - }; - -/** -* Encryption with an MR algorithm and an EME. -*/ -class BOTAN_DLL PK_Encryptor_MR_with_EME : public PK_Encryptor - { - public: - u32bit maximum_input_size() const; - - /** - * Construct an instance. - * @param key the key to use inside the decryptor - * @param eme the EME to use - */ - PK_Encryptor_MR_with_EME(const PK_Encrypting_Key& key, - EME* eme); - - ~PK_Encryptor_MR_with_EME() { delete encoder; } - private: - PK_Encryptor_MR_with_EME(const PK_Encryptor_MR_with_EME&); - PK_Encryptor_MR_with_EME& operator=(const PK_Encryptor_MR_with_EME&); - - SecureVector enc(const byte[], u32bit, - RandomNumberGenerator& rng) const; - - const PK_Encrypting_Key& key; - const EME* encoder; - }; - -/** -* Decryption with an MR algorithm and an EME. -*/ -class BOTAN_DLL PK_Decryptor_MR_with_EME : public PK_Decryptor - { - public: - /** - * Construct an instance. - * @param key the key to use inside the encryptor - * @param eme the EME to use - */ - PK_Decryptor_MR_with_EME(const PK_Decrypting_Key& key, - EME* eme); - - ~PK_Decryptor_MR_with_EME() { delete encoder; } - private: - PK_Decryptor_MR_with_EME(const PK_Decryptor_MR_with_EME&); - PK_Decryptor_MR_with_EME& operator=(const PK_Decryptor_MR_with_EME&); - - SecureVector dec(const byte[], u32bit) const; - - const PK_Decrypting_Key& key; - const EME* encoder; - }; - -/** -* Public Key Verifier with Message Recovery. -*/ -class BOTAN_DLL PK_Verifier_with_MR : public PK_Verifier - { - public: - /** - * Construct an instance. - * @param key the key to use inside the verifier - * @param emsa_name the name of the EMSA to use - */ - PK_Verifier_with_MR(const PK_Verifying_with_MR_Key& k, - EMSA* emsa_obj) : PK_Verifier(emsa_obj), key(k) {} - - private: - PK_Verifier_with_MR(const PK_Verifying_with_MR_Key&); - PK_Verifier_with_MR& operator=(const PK_Verifier_with_MR&); - - bool validate_signature(const MemoryRegion&, const byte[], u32bit); - u32bit key_message_parts() const { return key.message_parts(); } - u32bit key_message_part_size() const { return key.message_part_size(); } - - const PK_Verifying_with_MR_Key& key; - }; - -/** -* Public Key Verifier without Message Recovery -*/ -class BOTAN_DLL PK_Verifier_wo_MR : public PK_Verifier - { - public: - /** - * Construct an instance. - * @param key the key to use inside the verifier - * @param emsa_name the name of the EMSA to use - */ - PK_Verifier_wo_MR(const PK_Verifying_wo_MR_Key& k, - EMSA* emsa_obj) : PK_Verifier(emsa_obj), key(k) {} - - private: - PK_Verifier_wo_MR(const PK_Verifying_wo_MR_Key&); - PK_Verifier_wo_MR& operator=(const PK_Verifier_wo_MR&); - - bool validate_signature(const MemoryRegion&, const byte[], u32bit); - u32bit key_message_parts() const { return key.message_parts(); } - u32bit key_message_part_size() const { return key.message_part_size(); } - - const PK_Verifying_wo_MR_Key& key; - }; - -} - -#endif diff --git a/src/pubkey/pubkey/pubkey_enums.cpp b/src/pubkey/pubkey/pubkey_enums.cpp deleted file mode 100644 index 327107dd1..000000000 --- a/src/pubkey/pubkey/pubkey_enums.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -* KeyUsage -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -namespace BER { - -/* -* Decode a BER encoded KeyUsage -*/ -void decode(BER_Decoder& source, Key_Constraints& key_usage) - { - BER_Object obj = source.get_next_object(); - - if(obj.type_tag != BIT_STRING || obj.class_tag != UNIVERSAL) - throw BER_Bad_Tag("Bad tag for usage constraint", - obj.type_tag, obj.class_tag); - if(obj.value.size() != 2 && obj.value.size() != 3) - throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint"); - if(obj.value[0] >= 8) - throw BER_Decoding_Error("Invalid unused bits in usage constraint"); - - const byte mask = (0xFF << obj.value[0]); - obj.value[obj.value.size()-1] &= mask; - - u16bit usage = 0; - for(u32bit j = 1; j != obj.value.size(); ++j) - usage = (obj.value[j] << 8) | usage; - - key_usage = Key_Constraints(usage); - } - -} - -} diff --git a/src/pubkey/pubkey/pubkey_enums.h b/src/pubkey/pubkey/pubkey_enums.h deleted file mode 100644 index 53e319f38..000000000 --- a/src/pubkey/pubkey/pubkey_enums.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* Enumerations -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ENUMS_H__ -#define BOTAN_ENUMS_H__ - -#include - -namespace Botan { - -/** -* X.509v3 Key Constraints. -*/ -enum Key_Constraints { - NO_CONSTRAINTS = 0, - DIGITAL_SIGNATURE = 32768, - NON_REPUDIATION = 16384, - KEY_ENCIPHERMENT = 8192, - DATA_ENCIPHERMENT = 4096, - KEY_AGREEMENT = 2048, - KEY_CERT_SIGN = 1024, - CRL_SIGN = 512, - ENCIPHER_ONLY = 256, - DECIPHER_ONLY = 128 -}; - -/** -* BER Decoding Function for key constraints -*/ -namespace BER { - -void BOTAN_DLL decode(BER_Decoder&, Key_Constraints&); - -} - -/** -* X.509v2 CRL Reason Code. -*/ -enum CRL_Code { - UNSPECIFIED = 0, - KEY_COMPROMISE = 1, - CA_COMPROMISE = 2, - AFFILIATION_CHANGED = 3, - SUPERSEDED = 4, - CESSATION_OF_OPERATION = 5, - CERTIFICATE_HOLD = 6, - REMOVE_FROM_CRL = 8, - PRIVLEDGE_WITHDRAWN = 9, - AA_COMPROMISE = 10, - - DELETE_CRL_ENTRY = 0xFF00, - OCSP_GOOD = 0xFF01, - OCSP_UNKNOWN = 0xFF02 -}; - -/* -* Various Other Enumerations -*/ - -/** -* The two types of X509 encoding supported by Botan. -*/ -enum X509_Encoding { RAW_BER, PEM }; - -/** -* Value to encode in case of no path limit in the X509 -* BasicConstraints extension. -*/ -static const u32bit NO_CERT_PATH_LIMIT = 0xFFFFFFF0; - -} - -#endif diff --git a/src/pubkey/pubkey/x509_key.cpp b/src/pubkey/pubkey/x509_key.cpp deleted file mode 100644 index 455e627f3..000000000 --- a/src/pubkey/pubkey/x509_key.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* -* X.509 Public Key -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -namespace X509 { - -/* -* DER or PEM encode a X.509 public key -*/ -void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) - { - std::auto_ptr encoder(key.x509_encoder()); - if(!encoder.get()) - throw Encoding_Error("X509::encode: Key does not support encoding"); - - MemoryVector der = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(encoder->alg_id()) - .encode(encoder->key_bits(), BIT_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(der, "PUBLIC KEY")); - else - pipe.write(der); - } - -/* -* PEM encode a X.509 public key -*/ -std::string PEM_encode(const Public_Key& key) - { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(DataSource& source) - { - try { - AlgorithmIdentifier alg_id; - MemoryVector key_bits; - - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - else - { - DataSource_Memory ber( - PEM_Code::decode_check_label(source, "PUBLIC KEY") - ); - - BER_Decoder(ber) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - - if(key_bits.is_empty()) - throw Decoding_Error("X.509 public key decoding failed"); - - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "") - throw Decoding_Error("Unknown algorithm OID: " + - alg_id.oid.as_string()); - - std::auto_ptr key_obj(get_public_key(alg_name)); - if(!key_obj.get()) - throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " + - alg_id.oid.as_string()); - - std::auto_ptr decoder(key_obj->x509_decoder()); - - if(!decoder.get()) - throw Decoding_Error("Key does not support X.509 decoding"); - - decoder->alg_id(alg_id); - decoder->key_bits(key_bits); - - return key_obj.release(); - } - catch(Decoding_Error) - { - throw Decoding_Error("X.509 public key decoding failed"); - } - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const std::string& fsname) - { - DataSource_Stream source(fsname, true); - return X509::load_key(source); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const MemoryRegion& mem) - { - DataSource_Memory source(mem); - return X509::load_key(source); - } - -/* -* Make a copy of this public key -*/ -Public_Key* copy_key(const Public_Key& key) - { - Pipe bits; - bits.start_msg(); - X509::encode(key, bits, RAW_BER); - bits.end_msg(); - DataSource_Memory source(bits.read_all()); - return X509::load_key(source); - } - -/* -* Find the allowable key constraints -*/ -Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits) - { - const Public_Key* key = &pub_key; - u32bit constraints = 0; - - if(dynamic_cast(key)) - constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; - - if(dynamic_cast(key)) - constraints |= KEY_AGREEMENT; - - if(dynamic_cast(key) || - dynamic_cast(key)) - constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION; - - if(limits) - constraints &= limits; - - return Key_Constraints(constraints); - } - -} - -} diff --git a/src/pubkey/pubkey/x509_key.h b/src/pubkey/pubkey/x509_key.h deleted file mode 100644 index 9404b7ecc..000000000 --- a/src/pubkey/pubkey/x509_key.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -* X.509 Public Key -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_X509_PUBLIC_KEY_H__ -#define BOTAN_X509_PUBLIC_KEY_H__ - -#include -#include -#include -#include - -namespace Botan { - -/** -* This class represents abstract X.509 public key encoders. -*/ -class BOTAN_DLL X509_Encoder - { - public: - virtual AlgorithmIdentifier alg_id() const = 0; - virtual MemoryVector key_bits() const = 0; - virtual ~X509_Encoder() {} - }; - -/** -* This class represents abstract X.509 public key decoders. -*/ -class BOTAN_DLL X509_Decoder - { - public: - virtual void alg_id(const AlgorithmIdentifier&) = 0; - virtual void key_bits(const MemoryRegion&) = 0; - virtual ~X509_Decoder() {} - }; - -/** -* This namespace contains functions for handling X509 objects. -*/ -namespace X509 { - -/* -* X.509 Public Key Encoding/Decoding -*/ - -/** -* Encode a key into a pipe. -* @param key the public key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use -*/ -BOTAN_DLL void encode(const Public_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); - -/** -* PEM encode a public key into a string. -* @param key the key to encode -* @return the PEM encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Public_Key& key); - -/** -* Create a public key from a data source. -* @param source the source providing the DER or PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(DataSource& source); - -/** -* Create a public key from a string. -* @param enc the string containing the PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(const std::string& enc); - -/** -* Create a public key from a memory region. -* @param enc the memory region containing the DER or PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(const MemoryRegion& enc); - -/** -* Copy a key. -* @param key the public key to copy -* @return the new public key object -*/ -BOTAN_DLL Public_Key* copy_key(const Public_Key& key); - -/** -* Create the key constraints for a specific public key. -* @param pub_key the public key from which the basic set of -* constraints to be placed in the return value is derived -* @param limits additional limits that will be incorporated into the -* return value -* @return the combination of key type specific constraints and -* additional limits -*/ - -BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits); - -} - -} - -#endif diff --git a/src/pubkey/pubkey_enums.cpp b/src/pubkey/pubkey_enums.cpp new file mode 100644 index 000000000..327107dd1 --- /dev/null +++ b/src/pubkey/pubkey_enums.cpp @@ -0,0 +1,42 @@ +/* +* KeyUsage +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +namespace Botan { + +namespace BER { + +/* +* Decode a BER encoded KeyUsage +*/ +void decode(BER_Decoder& source, Key_Constraints& key_usage) + { + BER_Object obj = source.get_next_object(); + + if(obj.type_tag != BIT_STRING || obj.class_tag != UNIVERSAL) + throw BER_Bad_Tag("Bad tag for usage constraint", + obj.type_tag, obj.class_tag); + if(obj.value.size() != 2 && obj.value.size() != 3) + throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint"); + if(obj.value[0] >= 8) + throw BER_Decoding_Error("Invalid unused bits in usage constraint"); + + const byte mask = (0xFF << obj.value[0]); + obj.value[obj.value.size()-1] &= mask; + + u16bit usage = 0; + for(u32bit j = 1; j != obj.value.size(); ++j) + usage = (obj.value[j] << 8) | usage; + + key_usage = Key_Constraints(usage); + } + +} + +} diff --git a/src/pubkey/pubkey_enums.h b/src/pubkey/pubkey_enums.h new file mode 100644 index 000000000..53e319f38 --- /dev/null +++ b/src/pubkey/pubkey_enums.h @@ -0,0 +1,77 @@ +/* +* Enumerations +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ENUMS_H__ +#define BOTAN_ENUMS_H__ + +#include + +namespace Botan { + +/** +* X.509v3 Key Constraints. +*/ +enum Key_Constraints { + NO_CONSTRAINTS = 0, + DIGITAL_SIGNATURE = 32768, + NON_REPUDIATION = 16384, + KEY_ENCIPHERMENT = 8192, + DATA_ENCIPHERMENT = 4096, + KEY_AGREEMENT = 2048, + KEY_CERT_SIGN = 1024, + CRL_SIGN = 512, + ENCIPHER_ONLY = 256, + DECIPHER_ONLY = 128 +}; + +/** +* BER Decoding Function for key constraints +*/ +namespace BER { + +void BOTAN_DLL decode(BER_Decoder&, Key_Constraints&); + +} + +/** +* X.509v2 CRL Reason Code. +*/ +enum CRL_Code { + UNSPECIFIED = 0, + KEY_COMPROMISE = 1, + CA_COMPROMISE = 2, + AFFILIATION_CHANGED = 3, + SUPERSEDED = 4, + CESSATION_OF_OPERATION = 5, + CERTIFICATE_HOLD = 6, + REMOVE_FROM_CRL = 8, + PRIVLEDGE_WITHDRAWN = 9, + AA_COMPROMISE = 10, + + DELETE_CRL_ENTRY = 0xFF00, + OCSP_GOOD = 0xFF01, + OCSP_UNKNOWN = 0xFF02 +}; + +/* +* Various Other Enumerations +*/ + +/** +* The two types of X509 encoding supported by Botan. +*/ +enum X509_Encoding { RAW_BER, PEM }; + +/** +* Value to encode in case of no path limit in the X509 +* BasicConstraints extension. +*/ +static const u32bit NO_CERT_PATH_LIMIT = 0xFFFFFFF0; + +} + +#endif diff --git a/src/pubkey/rsa/info.txt b/src/pubkey/rsa/info.txt index ac2b6dde7..a75c69ae5 100644 --- a/src/pubkey/rsa/info.txt +++ b/src/pubkey/rsa/info.txt @@ -10,7 +10,6 @@ bigint if_algo keypair numbertheory -pubkey diff --git a/src/pubkey/rw/info.txt b/src/pubkey/rw/info.txt index 40c849d1c..83265399f 100644 --- a/src/pubkey/rw/info.txt +++ b/src/pubkey/rw/info.txt @@ -10,7 +10,6 @@ bigint if_algo keypair numbertheory -pubkey -- cgit v1.2.3 From 1172c616fa849af893c1935b8b1dee085f8aaac8 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 15 Jul 2009 15:31:08 +0000 Subject: Add a script that reads the output of print_deps.py and rewrites the info.txt files with the right module dependencies. Apply it across the codebase. --- doc/scripts/update_deps.py | 37 ++++++++++++++++++++++++++++++++++ src/algo_factory/info.txt | 13 ++++++++---- src/alloc/alloc_mmap/info.txt | 4 ++++ src/alloc/mem_pool/info.txt | 8 ++++---- src/alloc/system_alloc/info.txt | 9 +++++---- src/asn1/info.txt | 10 ++++----- src/benchmark/info.txt | 9 +++++++++ src/block/info.txt | 9 ++++----- src/block/lion/info.txt | 5 +++++ src/block/lubyrack/info.txt | 4 ++++ src/block/serpent_ia32/info.txt | 11 +++++----- src/cert/cvc/info.txt | 18 ++++++++++++----- src/cert/x509/info.txt | 20 +++++++++++------- src/checksum/adler32/info.txt | 4 ++++ src/checksum/crc24/info.txt | 4 ++++ src/checksum/crc32/info.txt | 4 ++++ src/cms/info.txt | 23 +++++++++++++-------- src/codec/base64/info.txt | 8 ++++---- src/codec/bzip2/info.txt | 8 ++++---- src/codec/hex/info.txt | 8 ++++---- src/codec/openpgp/info.txt | 1 - src/codec/pem/info.txt | 1 - src/codec/zlib/info.txt | 8 ++++---- src/engine/def_engine/info.txt | 7 +++++++ src/engine/gnump/info.txt | 4 ++++ src/engine/info.txt | 8 ++++++++ src/engine/openssl/info.txt | 4 ++++ src/filters/info.txt | 11 ++++++++++ src/hash/md4_ia32/info.txt | 11 +++++----- src/hash/md5_ia32/info.txt | 12 +++++------ src/hash/sha1_amd64/info.txt | 12 +++++------ src/hash/sha1_ia32/info.txt | 12 +++++------ src/hash/sha1_sse2/info.txt | 10 ++++----- src/kdf/kdf1/info.txt | 7 +++---- src/kdf/kdf2/info.txt | 8 ++++---- src/kdf/mgf1/info.txt | 8 ++++---- src/kdf/ssl_prf/info.txt | 12 +++++------ src/kdf/tls_prf/info.txt | 12 +++++------ src/kdf/x942_prf/info.txt | 12 +++++------ src/libstate/info.txt | 31 +++++++++++++++++++--------- src/libstate/oid_lookup/info.txt | 9 ++++----- src/mac/cbc_mac/info.txt | 4 ++++ src/mac/cmac/info.txt | 4 ++++ src/mac/hmac/info.txt | 4 ++++ src/mac/info.txt | 8 ++++---- src/mac/ssl3mac/info.txt | 4 ++++ src/mac/x919_mac/info.txt | 4 ++++ src/math/bigint/info.txt | 15 +++++++------- src/math/bigint/monty_amd64/info.txt | 8 ++++---- src/math/bigint/monty_generic/info.txt | 5 +++++ src/math/bigint/mp_ia32_msvc/info.txt | 4 ++++ src/math/bigint/mulop_amd64/info.txt | 10 +++++---- src/math/bigint/mulop_generic/info.txt | 5 +++++ src/math/bigint/mulop_ia32/info.txt | 8 ++++---- src/math/gfpmath/info.txt | 12 ++++++----- src/math/numbertheory/info.txt | 12 +++++++---- src/modes/cbc/info.txt | 3 +-- src/modes/cts/info.txt | 4 ++-- src/modes/eax/info.txt | 7 +++++-- src/modes/ecb/info.txt | 4 ++-- src/modes/info.txt | 1 + src/modes/ofb/info.txt | 4 ++-- src/modes/xts/info.txt | 5 +++-- src/pbe/info.txt | 12 +++++------ src/pbe/pbes1/info.txt | 6 +++++- src/pbe/pbes2/info.txt | 19 +++++++++++------ src/pk_pad/eme1/info.txt | 11 +++++----- src/pk_pad/emsa1/info.txt | 4 ++++ src/pk_pad/emsa1_bsi/info.txt | 8 ++++---- src/pk_pad/emsa2/info.txt | 1 + src/pk_pad/emsa3/info.txt | 1 + src/pk_pad/emsa4/info.txt | 2 ++ src/pk_pad/info.txt | 4 ++++ src/pubkey/dh/info.txt | 4 ++-- src/pubkey/dl_algo/info.txt | 4 +++- src/pubkey/dl_group/info.txt | 4 ++++ src/pubkey/dlies/info.txt | 5 +++-- src/pubkey/dsa/info.txt | 16 +++++++-------- src/pubkey/ec_dompar/info.txt | 3 ++- src/pubkey/ecc_key/info.txt | 13 ++++++------ src/pubkey/ecdsa/info.txt | 19 ++++++++--------- src/pubkey/eckaeg/info.txt | 18 ++++++++--------- src/pubkey/elgamal/info.txt | 17 ++++++++-------- src/pubkey/if_algo/info.txt | 14 +++++++------ src/pubkey/info.txt | 22 ++++++++++---------- src/pubkey/nr/info.txt | 4 ++-- src/pubkey/pk_codecs/info.txt | 18 +++++++++++++++++ src/pubkey/rsa/info.txt | 13 ++++++------ src/pubkey/rw/info.txt | 13 ++++++------ src/rng/auto_rng/info.txt | 12 +++++------ src/rng/hmac_rng/info.txt | 4 ++++ src/rng/info.txt | 4 ++++ src/rng/randpool/info.txt | 5 +++++ src/rng/x931_rng/info.txt | 2 +- src/s2k/info.txt | 10 ++++----- src/s2k/pbkdf1/info.txt | 4 ++++ src/s2k/pbkdf2/info.txt | 4 ++++ src/s2k/pgps2k/info.txt | 4 ++++ src/selftest/info.txt | 23 +++++++++------------ src/stream/info.txt | 9 ++++----- src/sym_algo/info.txt | 10 +++++---- src/timer/info.txt | 4 ++++ src/utils/info.txt | 10 +++++---- 103 files changed, 583 insertions(+), 328 deletions(-) create mode 100755 doc/scripts/update_deps.py create mode 100644 src/pubkey/pk_codecs/info.txt (limited to 'src/pubkey') diff --git a/doc/scripts/update_deps.py b/doc/scripts/update_deps.py new file mode 100755 index 000000000..8bada9d7e --- /dev/null +++ b/doc/scripts/update_deps.py @@ -0,0 +1,37 @@ +#!/usr/bin/python + +import sys +import re +import os.path + +def update_requires(dir, deps): + lines = map(lambda x: x.strip(), + open(os.path.join(dir, 'info.txt')).readlines()) + + if '' in lines: + start = lines.index('') + + while lines.pop(start) != '': + pass + + lines.append('') + lines.append('') + for dep in deps: + lines.append(dep) + lines.append('') + lines.append('') + + lines = "\n".join(lines).replace("\n\n\n", "\n\n") + + output = open(os.path.join(dir, 'info.txt'), 'w') + output.write(lines) + output.close() + +def main(): + for line in sys.stdin.readlines(): + (dirname, deps) = line.split(':') + deps = deps.strip().split(' ') + update_requires(dirname, deps) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/algo_factory/info.txt b/src/algo_factory/info.txt index 937b91353..dfc42230a 100644 --- a/src/algo_factory/info.txt +++ b/src/algo_factory/info.txt @@ -4,13 +4,18 @@ load_on auto define ALGORITHM_FACTORY - -utils - - algo_factory.cpp algo_factory.h algo_cache.h prov_weight.cpp + + +block +engine +hash +mac +mutex +stream + diff --git a/src/alloc/alloc_mmap/info.txt b/src/alloc/alloc_mmap/info.txt index 8cc2b206e..d8c766d55 100644 --- a/src/alloc/alloc_mmap/info.txt +++ b/src/alloc/alloc_mmap/info.txt @@ -23,3 +23,7 @@ tru64 # Only without -ansi, otherwise can't get mkstemp #cygwin + + +mem_pool + diff --git a/src/alloc/mem_pool/info.txt b/src/alloc/mem_pool/info.txt index ec987a0e0..0a762ccc4 100644 --- a/src/alloc/mem_pool/info.txt +++ b/src/alloc/mem_pool/info.txt @@ -2,11 +2,11 @@ realname "Memory Pool Allocator" load_on auto - -utils - - mem_pool.cpp mem_pool.h + + +mutex + diff --git a/src/alloc/system_alloc/info.txt b/src/alloc/system_alloc/info.txt index 0e8de9ff7..5fade38cf 100644 --- a/src/alloc/system_alloc/info.txt +++ b/src/alloc/system_alloc/info.txt @@ -2,11 +2,12 @@ realname "Default (Malloc) Allocators" load_on auto - -utils - - defalloc.cpp defalloc.h + + +libstate +mem_pool + diff --git a/src/asn1/info.txt b/src/asn1/info.txt index 279cbb1e9..3c69319b8 100644 --- a/src/asn1/info.txt +++ b/src/asn1/info.txt @@ -4,11 +4,6 @@ define ASN1 load_on auto - -bigint -oid_lookup - - alg_id.cpp asn1_alt.cpp @@ -27,3 +22,8 @@ asn1_oid.h ber_dec.h der_enc.h + + +bigint +oid_lookup + diff --git a/src/benchmark/info.txt b/src/benchmark/info.txt index e9718dbb3..958c19ebc 100644 --- a/src/benchmark/info.txt +++ b/src/benchmark/info.txt @@ -9,3 +9,12 @@ benchmark.cpp benchmark.h + +algo_factory +block +hash +mac +rng +stream +timer + diff --git a/src/block/info.txt b/src/block/info.txt index 5df789736..ff48fb04a 100644 --- a/src/block/info.txt +++ b/src/block/info.txt @@ -4,11 +4,10 @@ load_on auto define BLOCK_CIPHER - -utils -sym_algo - - block_cipher.h + + +sym_algo + diff --git a/src/block/lion/info.txt b/src/block/lion/info.txt index 558d71d0c..81ef58511 100644 --- a/src/block/lion/info.txt +++ b/src/block/lion/info.txt @@ -8,3 +8,8 @@ load_on auto lion.cpp lion.h + + +hash +stream + diff --git a/src/block/lubyrack/info.txt b/src/block/lubyrack/info.txt index d83df2409..a478526f4 100644 --- a/src/block/lubyrack/info.txt +++ b/src/block/lubyrack/info.txt @@ -8,3 +8,7 @@ load_on auto lubyrack.cpp lubyrack.h + + +hash + diff --git a/src/block/serpent_ia32/info.txt b/src/block/serpent_ia32/info.txt index 8aca9b2ba..13b171fe9 100644 --- a/src/block/serpent_ia32/info.txt +++ b/src/block/serpent_ia32/info.txt @@ -10,12 +10,6 @@ serp_ia32.cpp serp_ia32.h - -ia32_eng -asm_ia32 -utils - - ia32 @@ -33,3 +27,8 @@ netbsd openbsd solaris + + +asm_ia32 +serpent + diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index 69f144340..e3e11f5fe 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -6,11 +6,6 @@ uses_tr1 yes load_on auto - -asn1 -ecdsa - - asn1_eac_str.cpp asn1_eac_tm.cpp @@ -34,3 +29,16 @@ signed_obj.cpp signed_obj.h freestore.h + + +asn1 +bigint +ecdsa +filters +libstate +oid_lookup +pem +pk_codecs +pubkey +x509 + diff --git a/src/cert/x509/info.txt b/src/cert/x509/info.txt index 922aeae4d..726a4ad4f 100644 --- a/src/cert/x509/info.txt +++ b/src/cert/x509/info.txt @@ -4,13 +4,6 @@ define X509 load_on auto - -asn1 -bigint -pk_codecs -oid_lookup - - certstor.h certstor.cpp @@ -36,3 +29,16 @@ x509self.h x509stor.cpp x509stor.h + + +asn1 +bigint +filters +libstate +oid_lookup +pem +pk_codecs +pubkey +rng +sha1 + diff --git a/src/checksum/adler32/info.txt b/src/checksum/adler32/info.txt index fb0f3c9cb..76662cdec 100644 --- a/src/checksum/adler32/info.txt +++ b/src/checksum/adler32/info.txt @@ -8,3 +8,7 @@ load_on auto adler32.cpp adler32.h + + +hash + diff --git a/src/checksum/crc24/info.txt b/src/checksum/crc24/info.txt index b61cabbc8..33b86a9da 100644 --- a/src/checksum/crc24/info.txt +++ b/src/checksum/crc24/info.txt @@ -8,3 +8,7 @@ load_on auto crc24.cpp crc24.h + + +hash + diff --git a/src/checksum/crc32/info.txt b/src/checksum/crc32/info.txt index 17ccca0a3..15933b375 100644 --- a/src/checksum/crc32/info.txt +++ b/src/checksum/crc32/info.txt @@ -8,3 +8,7 @@ load_on auto crc32.cpp crc32.h + + +hash + diff --git a/src/cms/info.txt b/src/cms/info.txt index a85841e21..82c31b564 100644 --- a/src/cms/info.txt +++ b/src/cms/info.txt @@ -4,14 +4,6 @@ define CMS load_on auto - -asn1 -filters -oid_lookup -pk_codecs -x509 - - cms_algo.cpp cms_comp.cpp @@ -22,3 +14,18 @@ cms_ealg.cpp cms_enc.cpp cms_enc.h + + +asn1 +bigint +cbc +filters +hash +libstate +oid_lookup +pem +pk_codecs +sha1 +sym_algo +x509 + diff --git a/src/codec/base64/info.txt b/src/codec/base64/info.txt index 591581afb..d4ed80976 100644 --- a/src/codec/base64/info.txt +++ b/src/codec/base64/info.txt @@ -4,12 +4,12 @@ define BASE64_CODEC load_on auto - -filters - - base64.cpp b64_char.cpp base64.h + + +filters + diff --git a/src/codec/bzip2/info.txt b/src/codec/bzip2/info.txt index 51e1feed1..1be84e405 100644 --- a/src/codec/bzip2/info.txt +++ b/src/codec/bzip2/info.txt @@ -7,10 +7,6 @@ modset compression load_on request - -filters - - bzip2.h bzip2.cpp @@ -19,3 +15,7 @@ bzip2.cpp all -> bz2 + + +filters + diff --git a/src/codec/hex/info.txt b/src/codec/hex/info.txt index 71b33a6ad..512a5de8b 100644 --- a/src/codec/hex/info.txt +++ b/src/codec/hex/info.txt @@ -4,12 +4,12 @@ define HEX_CODEC load_on auto - -filters - - hex.cpp hex_char.cpp hex.h + + +filters + diff --git a/src/codec/openpgp/info.txt b/src/codec/openpgp/info.txt index d43c72843..6b30850d0 100644 --- a/src/codec/openpgp/info.txt +++ b/src/codec/openpgp/info.txt @@ -11,6 +11,5 @@ openpgp.h crc24 -base64 filters diff --git a/src/codec/pem/info.txt b/src/codec/pem/info.txt index bbe8d4c70..b12dbf378 100644 --- a/src/codec/pem/info.txt +++ b/src/codec/pem/info.txt @@ -10,6 +10,5 @@ pem.h -base64 filters diff --git a/src/codec/zlib/info.txt b/src/codec/zlib/info.txt index 49e9658a9..9b1c35d84 100644 --- a/src/codec/zlib/info.txt +++ b/src/codec/zlib/info.txt @@ -7,10 +7,6 @@ define COMPRESSOR_ZLIB load_on request modset compression - -filters - - zlib.h zlib.cpp @@ -21,3 +17,7 @@ zlib.cpp all -> z + + +filters + diff --git a/src/engine/def_engine/info.txt b/src/engine/def_engine/info.txt index 503a4392f..eb96b0dc5 100644 --- a/src/engine/def_engine/info.txt +++ b/src/engine/def_engine/info.txt @@ -14,3 +14,10 @@ lookup_hash.cpp lookup_mac.cpp lookup_stream.cpp + + +algo_factory +filters +mode_pad +numbertheory + diff --git a/src/engine/gnump/info.txt b/src/engine/gnump/info.txt index 84c286bc8..67a9bcd70 100644 --- a/src/engine/gnump/info.txt +++ b/src/engine/gnump/info.txt @@ -20,3 +20,7 @@ gmp_powm.cpp gmp_wrap.cpp gmp_wrap.h + + +bigint + diff --git a/src/engine/info.txt b/src/engine/info.txt index 0a22ec285..bd962e4cf 100644 --- a/src/engine/info.txt +++ b/src/engine/info.txt @@ -7,3 +7,11 @@ load_on auto engine.h + + +block +hash +mac +numbertheory +stream + diff --git a/src/engine/openssl/info.txt b/src/engine/openssl/info.txt index 67afcab74..3f2f1ab14 100644 --- a/src/engine/openssl/info.txt +++ b/src/engine/openssl/info.txt @@ -22,3 +22,7 @@ ossl_if.cpp ossl_md.cpp ossl_nr.cpp + + +bigint + diff --git a/src/filters/info.txt b/src/filters/info.txt index 947e36596..40d952b0d 100644 --- a/src/filters/info.txt +++ b/src/filters/info.txt @@ -25,3 +25,14 @@ pipe_rw.cpp secqueue.cpp secqueue.h + + +asn1 +block +hash +libstate +mac +rng +stream +sym_algo + diff --git a/src/hash/md4_ia32/info.txt b/src/hash/md4_ia32/info.txt index e7249ad5f..e5287dc5d 100644 --- a/src/hash/md4_ia32/info.txt +++ b/src/hash/md4_ia32/info.txt @@ -10,12 +10,6 @@ md4_ia32.cpp md4_ia32.h - -ia32_eng -asm_ia32 -md4 - - ia32 @@ -33,3 +27,8 @@ netbsd openbsd solaris + + +asm_ia32 +md4 + diff --git a/src/hash/md5_ia32/info.txt b/src/hash/md5_ia32/info.txt index 7133e1ddd..f69ab82e6 100644 --- a/src/hash/md5_ia32/info.txt +++ b/src/hash/md5_ia32/info.txt @@ -10,13 +10,6 @@ md5_ia32.cpp md5_ia32.h - -ia32_eng -asm_ia32 -mdx_hash -utils - - ia32 @@ -34,3 +27,8 @@ netbsd openbsd solaris + + +asm_ia32 +md5 + diff --git a/src/hash/sha1_amd64/info.txt b/src/hash/sha1_amd64/info.txt index 662d60c69..88e4ec6c0 100644 --- a/src/hash/sha1_amd64/info.txt +++ b/src/hash/sha1_amd64/info.txt @@ -10,13 +10,6 @@ sha1_amd64.cpp sha1_amd64.h - -amd64_eng -asm_amd64 -sha1 -utils - - amd64 @@ -33,3 +26,8 @@ netbsd openbsd solaris + + +asm_ia32 +sha1 + diff --git a/src/hash/sha1_ia32/info.txt b/src/hash/sha1_ia32/info.txt index 8c333dc57..ca14028b8 100644 --- a/src/hash/sha1_ia32/info.txt +++ b/src/hash/sha1_ia32/info.txt @@ -10,13 +10,6 @@ sha1_ia32.cpp sha1_ia32.h - -ia32_eng -asm_ia32 -sha1 -utils - - ia32 @@ -34,3 +27,8 @@ netbsd openbsd solaris + + +asm_ia32 +sha1 + diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt index e33bb1859..d8dc069ad 100644 --- a/src/hash/sha1_sse2/info.txt +++ b/src/hash/sha1_sse2/info.txt @@ -10,12 +10,6 @@ sha1_sse2.cpp sha1_sse2.h - -sse2_eng -sha1 -utils - - pentium-m pentium4 @@ -27,3 +21,7 @@ amd64 gcc icc + + +sha1 + diff --git a/src/kdf/kdf1/info.txt b/src/kdf/kdf1/info.txt index 04d8db096..ede10017e 100644 --- a/src/kdf/kdf1/info.txt +++ b/src/kdf/kdf1/info.txt @@ -4,12 +4,11 @@ define KDF1 load_on auto - -kdf - - kdf1.h kdf1.cpp + +hash + diff --git a/src/kdf/kdf2/info.txt b/src/kdf/kdf2/info.txt index 80b562824..1858f8929 100644 --- a/src/kdf/kdf2/info.txt +++ b/src/kdf/kdf2/info.txt @@ -4,11 +4,11 @@ define KDF2 load_on auto - -kdf - - kdf2.cpp kdf2.h + + +hash + diff --git a/src/kdf/mgf1/info.txt b/src/kdf/mgf1/info.txt index 0616f43b7..f9e952f82 100644 --- a/src/kdf/mgf1/info.txt +++ b/src/kdf/mgf1/info.txt @@ -4,11 +4,11 @@ define MGF1 load_on dep - -kdf - - mgf1.h mgf1.cpp + + +hash + diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/ssl_prf/info.txt index 890789988..f862905a2 100644 --- a/src/kdf/ssl_prf/info.txt +++ b/src/kdf/ssl_prf/info.txt @@ -4,13 +4,13 @@ define SSL_V3_PRF load_on auto - -kdf -md5 -sha1 - - prf_ssl3.h prf_ssl3.cpp + + +md5 +sha1 +sym_algo + diff --git a/src/kdf/tls_prf/info.txt b/src/kdf/tls_prf/info.txt index c775c90ba..f95ef9c24 100644 --- a/src/kdf/tls_prf/info.txt +++ b/src/kdf/tls_prf/info.txt @@ -4,14 +4,14 @@ define TLS_V10_PRF load_on auto + +prf_tls.h +prf_tls.cpp + + hmac -kdf +mac md5 sha1 - - -prf_tls.h -prf_tls.cpp - diff --git a/src/kdf/x942_prf/info.txt b/src/kdf/x942_prf/info.txt index df5719de4..295c2cde6 100644 --- a/src/kdf/x942_prf/info.txt +++ b/src/kdf/x942_prf/info.txt @@ -4,13 +4,13 @@ define X942_PRF load_on auto - -md5 -sha1 -#oid_lookup - - prf_x942.cpp prf_x942.h + + +asn1 +oid_lookup +sha1 + diff --git a/src/libstate/info.txt b/src/libstate/info.txt index f3111a31e..6e200ee3f 100644 --- a/src/libstate/info.txt +++ b/src/libstate/info.txt @@ -4,15 +4,6 @@ load_on auto define LIBSTATE_MODULE - -algo_factory -def_engine -mode_pad -pk_pad -s2k -system_alloc - - botan.h get_enc.cpp @@ -28,3 +19,25 @@ pk_engine.cpp pk_engine.h policy.cpp + + +algo_factory +alloc +bigint +block +def_engine +engine +filters +hash +kdf +mac +mode_pad +mutex +noop_mutex +pk_pad +pubkey +rng +s2k +stream +system_alloc + diff --git a/src/libstate/oid_lookup/info.txt b/src/libstate/oid_lookup/info.txt index b5f4ef21f..609eb9199 100644 --- a/src/libstate/oid_lookup/info.txt +++ b/src/libstate/oid_lookup/info.txt @@ -4,12 +4,11 @@ load_on dep define OID_LOOKUP - -#libstate -#asn1 - - oids.cpp oids.h + + +asn1 + diff --git a/src/mac/cbc_mac/info.txt b/src/mac/cbc_mac/info.txt index 3a7a6e781..3a5434974 100644 --- a/src/mac/cbc_mac/info.txt +++ b/src/mac/cbc_mac/info.txt @@ -8,3 +8,7 @@ load_on auto cbc_mac.cpp cbc_mac.h + + +block + diff --git a/src/mac/cmac/info.txt b/src/mac/cmac/info.txt index 5188af0c0..b593c9d38 100644 --- a/src/mac/cmac/info.txt +++ b/src/mac/cmac/info.txt @@ -8,3 +8,7 @@ load_on auto cmac.cpp cmac.h + + +block + diff --git a/src/mac/hmac/info.txt b/src/mac/hmac/info.txt index 534d2e036..cdf2e67ab 100644 --- a/src/mac/hmac/info.txt +++ b/src/mac/hmac/info.txt @@ -8,3 +8,7 @@ load_on auto hmac.cpp hmac.h + + +hash + diff --git a/src/mac/info.txt b/src/mac/info.txt index 0e4dc11a2..4891d7498 100644 --- a/src/mac/info.txt +++ b/src/mac/info.txt @@ -2,11 +2,11 @@ realname "Message Authentication Codes" load_on auto - -utils - - mac.h mac.cpp + + +sym_algo + diff --git a/src/mac/ssl3mac/info.txt b/src/mac/ssl3mac/info.txt index d7a86e571..f8791169c 100644 --- a/src/mac/ssl3mac/info.txt +++ b/src/mac/ssl3mac/info.txt @@ -8,3 +8,7 @@ load_on auto ssl3_mac.cpp ssl3_mac.h + + +hash + diff --git a/src/mac/x919_mac/info.txt b/src/mac/x919_mac/info.txt index 24c78b1c6..f2ebd5b35 100644 --- a/src/mac/x919_mac/info.txt +++ b/src/mac/x919_mac/info.txt @@ -8,3 +8,7 @@ load_on auto x919_mac.cpp x919_mac.h + + +block + diff --git a/src/math/bigint/info.txt b/src/math/bigint/info.txt index 908304c9f..9c8e1fa17 100644 --- a/src/math/bigint/info.txt +++ b/src/math/bigint/info.txt @@ -4,14 +4,6 @@ load_on auto define BIGINT - -hex -rng -mp_amd64|mp_asm64|mp_ia32|mp_ia32_msvc|mp_generic -monty_generic -mulop_generic - - bigint.h divide.h @@ -30,3 +22,10 @@ mp_karat.cpp mp_misc.cpp mp_shift.cpp + + +hex +mp_ia32 +mp_ia32_msvc +rng + diff --git a/src/math/bigint/monty_amd64/info.txt b/src/math/bigint/monty_amd64/info.txt index 5f80a0b1e..dff74c611 100644 --- a/src/math/bigint/monty_amd64/info.txt +++ b/src/math/bigint/monty_amd64/info.txt @@ -8,10 +8,6 @@ load_on never mp_monty.S - -asm_amd64 - - amd64 @@ -29,3 +25,7 @@ netbsd openbsd solaris + + +asm_ia32 + diff --git a/src/math/bigint/monty_generic/info.txt b/src/math/bigint/monty_generic/info.txt index 6f5f0e722..e99e5e083 100644 --- a/src/math/bigint/monty_generic/info.txt +++ b/src/math/bigint/monty_generic/info.txt @@ -5,3 +5,8 @@ load_on dep mp_monty.cpp + + +mp_ia32 +mp_ia32_msvc + diff --git a/src/math/bigint/mp_ia32_msvc/info.txt b/src/math/bigint/mp_ia32_msvc/info.txt index 9c7ac9b43..9ca22a2da 100644 --- a/src/math/bigint/mp_ia32_msvc/info.txt +++ b/src/math/bigint/mp_ia32_msvc/info.txt @@ -16,3 +16,7 @@ ia32 msvc + + +mp_ia32 + diff --git a/src/math/bigint/mulop_amd64/info.txt b/src/math/bigint/mulop_amd64/info.txt index 15bde7bf3..0f512251c 100644 --- a/src/math/bigint/mulop_amd64/info.txt +++ b/src/math/bigint/mulop_amd64/info.txt @@ -8,10 +8,6 @@ load_on never mp_mulop_amd64.S - -asm_amd64 - - amd64 @@ -29,3 +25,9 @@ netbsd openbsd solaris + + +asm_ia32 +mp_ia32 +mp_ia32_msvc + diff --git a/src/math/bigint/mulop_generic/info.txt b/src/math/bigint/mulop_generic/info.txt index 28ebe41eb..8700e9332 100644 --- a/src/math/bigint/mulop_generic/info.txt +++ b/src/math/bigint/mulop_generic/info.txt @@ -5,3 +5,8 @@ load_on dep mp_mulop.cpp + + +mp_ia32 +mp_ia32_msvc + diff --git a/src/math/bigint/mulop_ia32/info.txt b/src/math/bigint/mulop_ia32/info.txt index 1c89e95c1..a7b525bfb 100644 --- a/src/math/bigint/mulop_ia32/info.txt +++ b/src/math/bigint/mulop_ia32/info.txt @@ -10,10 +10,6 @@ load_on request mp_mulop.S - -asm_ia32 - - ia32 @@ -31,3 +27,7 @@ netbsd openbsd solaris + + +asm_ia32 + diff --git a/src/math/gfpmath/info.txt b/src/math/gfpmath/info.txt index e90569d26..0fadcc819 100644 --- a/src/math/gfpmath/info.txt +++ b/src/math/gfpmath/info.txt @@ -6,11 +6,6 @@ load_on auto define BIGINT_GFP - -bigint -numbertheory - - curve_gfp.cpp curve_gfp.h @@ -20,3 +15,10 @@ gfp_modulus.h point_gfp.cpp point_gfp.h + + +bigint +mp_ia32 +mp_ia32_msvc +numbertheory + diff --git a/src/math/numbertheory/info.txt b/src/math/numbertheory/info.txt index 6ce3583c8..1595c7305 100644 --- a/src/math/numbertheory/info.txt +++ b/src/math/numbertheory/info.txt @@ -4,10 +4,6 @@ load_on auto define BIGINT_MATH - -bigint - - blinding.cpp blinding.h @@ -27,3 +23,11 @@ reducer.cpp reducer.h ressol.cpp + + +algo_factory +bigint +hash +libstate +rng + diff --git a/src/modes/cbc/info.txt b/src/modes/cbc/info.txt index 6cc0e1a14..9dd6d827e 100644 --- a/src/modes/cbc/info.txt +++ b/src/modes/cbc/info.txt @@ -9,8 +9,7 @@ cbc.cpp cbc.h + -modes mode_pad - diff --git a/src/modes/cts/info.txt b/src/modes/cts/info.txt index bfb26c987..26f5cae52 100644 --- a/src/modes/cts/info.txt +++ b/src/modes/cts/info.txt @@ -9,7 +9,7 @@ cts.cpp cts.h + -modes +block - diff --git a/src/modes/eax/info.txt b/src/modes/eax/info.txt index 54890d6a2..a1757cada 100644 --- a/src/modes/eax/info.txt +++ b/src/modes/eax/info.txt @@ -10,7 +10,10 @@ eax.h eax_dec.cpp + -modes +block +cmac +filters +mac - diff --git a/src/modes/ecb/info.txt b/src/modes/ecb/info.txt index 43ff1ac1c..6d4ce93a7 100644 --- a/src/modes/ecb/info.txt +++ b/src/modes/ecb/info.txt @@ -9,8 +9,8 @@ ecb.cpp ecb.h + -modes +block mode_pad - diff --git a/src/modes/info.txt b/src/modes/info.txt index 6fc874bd6..e089e74a9 100644 --- a/src/modes/info.txt +++ b/src/modes/info.txt @@ -10,5 +10,6 @@ modebase.h +block filters diff --git a/src/modes/ofb/info.txt b/src/modes/ofb/info.txt index 03cb23677..1b33c38d5 100644 --- a/src/modes/ofb/info.txt +++ b/src/modes/ofb/info.txt @@ -9,7 +9,7 @@ ofb.cpp ofb.h + -modes +block - diff --git a/src/modes/xts/info.txt b/src/modes/xts/info.txt index 30d8f3496..6669c1184 100644 --- a/src/modes/xts/info.txt +++ b/src/modes/xts/info.txt @@ -9,7 +9,8 @@ xts.cpp xts.h + -modes +block +filters - diff --git a/src/pbe/info.txt b/src/pbe/info.txt index 9a46c3a11..c4210b2a7 100644 --- a/src/pbe/info.txt +++ b/src/pbe/info.txt @@ -4,13 +4,13 @@ load_on dep define PASSWORD_BASED_ENCRYPTION - -filters -asn1 -oid_lookup - - get_pbe.cpp get_pbe.h + + +filters +libstate +oid_lookup + diff --git a/src/pbe/pbes1/info.txt b/src/pbe/pbes1/info.txt index 9a5a3aa1a..70c6baeee 100644 --- a/src/pbe/pbes1/info.txt +++ b/src/pbe/pbes1/info.txt @@ -10,6 +10,10 @@ pbes1.h -pbe +asn1 +block +cbc +filters +hash pbkdf1 diff --git a/src/pbe/pbes2/info.txt b/src/pbe/pbes2/info.txt index 42e5c42a0..cd37b1e69 100644 --- a/src/pbe/pbes2/info.txt +++ b/src/pbe/pbes2/info.txt @@ -4,13 +4,20 @@ define PBE_PKCS_V20 load_on auto - -oid_lookup -pbe -pbkdf2 - - pbes2.cpp pbes2.h + + +algo_factory +asn1 +block +cbc +filters +hash +hmac +libstate +oid_lookup +pbkdf2 + diff --git a/src/pk_pad/eme1/info.txt b/src/pk_pad/eme1/info.txt index 4e68aba4b..2f61265e2 100644 --- a/src/pk_pad/eme1/info.txt +++ b/src/pk_pad/eme1/info.txt @@ -4,12 +4,13 @@ define EME1 load_on auto - -mgf1 -utils - - eme1.h eme1.cpp + + +hash +kdf +mgf1 + diff --git a/src/pk_pad/emsa1/info.txt b/src/pk_pad/emsa1/info.txt index 4040dd580..086270b96 100644 --- a/src/pk_pad/emsa1/info.txt +++ b/src/pk_pad/emsa1/info.txt @@ -8,3 +8,7 @@ load_on auto emsa1.h emsa1.cpp + + +hash + diff --git a/src/pk_pad/emsa1_bsi/info.txt b/src/pk_pad/emsa1_bsi/info.txt index 8a8c46abb..14a9fd396 100644 --- a/src/pk_pad/emsa1_bsi/info.txt +++ b/src/pk_pad/emsa1_bsi/info.txt @@ -4,11 +4,11 @@ define EMSA1_BSI load_on auto - -emsa1 - - emsa1_bsi.h emsa1_bsi.cpp + + +emsa1 + diff --git a/src/pk_pad/emsa2/info.txt b/src/pk_pad/emsa2/info.txt index f0910d450..1c8161c5e 100644 --- a/src/pk_pad/emsa2/info.txt +++ b/src/pk_pad/emsa2/info.txt @@ -10,5 +10,6 @@ emsa2.cpp +hash hash_id diff --git a/src/pk_pad/emsa3/info.txt b/src/pk_pad/emsa3/info.txt index 284b9b07d..90e4b9bfc 100644 --- a/src/pk_pad/emsa3/info.txt +++ b/src/pk_pad/emsa3/info.txt @@ -10,5 +10,6 @@ emsa3.cpp +hash hash_id diff --git a/src/pk_pad/emsa4/info.txt b/src/pk_pad/emsa4/info.txt index e37d72d77..29ef4e0cf 100644 --- a/src/pk_pad/emsa4/info.txt +++ b/src/pk_pad/emsa4/info.txt @@ -10,5 +10,7 @@ emsa4.cpp +hash +kdf mgf1 diff --git a/src/pk_pad/info.txt b/src/pk_pad/info.txt index ff750a12c..ae773b440 100644 --- a/src/pk_pad/info.txt +++ b/src/pk_pad/info.txt @@ -9,3 +9,7 @@ emsa.h eme.cpp eme.h + + +rng + diff --git a/src/pubkey/dh/info.txt b/src/pubkey/dh/info.txt index 9e4ceb65b..33af9a8e5 100644 --- a/src/pubkey/dh/info.txt +++ b/src/pubkey/dh/info.txt @@ -13,8 +13,8 @@ dh_op.h -asn1 -bigint dl_algo +dl_group +libstate numbertheory diff --git a/src/pubkey/dl_algo/info.txt b/src/pubkey/dl_algo/info.txt index d3368765a..15a77516b 100644 --- a/src/pubkey/dl_algo/info.txt +++ b/src/pubkey/dl_algo/info.txt @@ -11,6 +11,8 @@ dl_algo.h asn1 -bigint dl_group +numbertheory +pk_codecs +rng diff --git a/src/pubkey/dl_group/info.txt b/src/pubkey/dl_group/info.txt index 62446091f..6b9884a4d 100644 --- a/src/pubkey/dl_group/info.txt +++ b/src/pubkey/dl_group/info.txt @@ -12,4 +12,8 @@ dl_group.h asn1 bigint +filters +libstate +numbertheory +pem diff --git a/src/pubkey/dlies/info.txt b/src/pubkey/dlies/info.txt index 9e32aeb2a..5138aafc5 100644 --- a/src/pubkey/dlies/info.txt +++ b/src/pubkey/dlies/info.txt @@ -10,6 +10,7 @@ dlies.h -dh -kdf2 +kdf +libstate +mac diff --git a/src/pubkey/dsa/info.txt b/src/pubkey/dsa/info.txt index 2d6287fbd..c70e02d90 100644 --- a/src/pubkey/dsa/info.txt +++ b/src/pubkey/dsa/info.txt @@ -4,14 +4,6 @@ define DSA load_on auto - -asn1 -bigint -dl_algo -keypair -numbertheory - - dsa.cpp dsa.h @@ -20,3 +12,11 @@ dsa_core.h dsa_op.cpp dsa_op.h + + +dl_algo +dl_group +keypair +libstate +numbertheory + diff --git a/src/pubkey/ec_dompar/info.txt b/src/pubkey/ec_dompar/info.txt index 59032ce90..212783725 100644 --- a/src/pubkey/ec_dompar/info.txt +++ b/src/pubkey/ec_dompar/info.txt @@ -12,6 +12,7 @@ ec_dompar.h asn1 bigint -numbertheory +filters gfpmath +hex diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt index a57de3d0c..c1972052d 100644 --- a/src/pubkey/ecc_key/info.txt +++ b/src/pubkey/ecc_key/info.txt @@ -4,15 +4,16 @@ define ECC_PUBLIC_KEY_CRYPTO load_on auto + +ecc_key.cpp +ecc_key.h + + asn1 bigint ec_dompar -numbertheory gfpmath +numbertheory +pk_codecs - - -ecc_key.cpp -ecc_key.h - diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt index c67122348..4ca020ad5 100644 --- a/src/pubkey/ecdsa/info.txt +++ b/src/pubkey/ecdsa/info.txt @@ -4,15 +4,6 @@ define ECDSA load_on auto - -asn1 -bigint -ec_dompar -ecc_key -numbertheory -gfpmath - - ecdsa.cpp ecdsa.h @@ -21,3 +12,13 @@ ecdsa_core.h ecdsa_op.cpp ecdsa_op.h + + +asn1 +ec_dompar +ecc_key +gfpmath +libstate +numbertheory +rng + diff --git a/src/pubkey/eckaeg/info.txt b/src/pubkey/eckaeg/info.txt index cdac09220..d18a805ee 100644 --- a/src/pubkey/eckaeg/info.txt +++ b/src/pubkey/eckaeg/info.txt @@ -4,15 +4,6 @@ define ECKAEG load_on auto - -asn1 -bigint -ec_dompar -ecc_key -numbertheory -gfpmath - - eckaeg.cpp eckaeg.h @@ -21,3 +12,12 @@ eckaeg_core.h eckaeg_op.cpp eckaeg_op.h + + +asn1 +ec_dompar +ecc_key +gfpmath +libstate +numbertheory + diff --git a/src/pubkey/elgamal/info.txt b/src/pubkey/elgamal/info.txt index 53a039585..d7ae614ea 100644 --- a/src/pubkey/elgamal/info.txt +++ b/src/pubkey/elgamal/info.txt @@ -4,15 +4,6 @@ define ELGAMAL load_on auto - -asn1 -bigint -bigint -dl_algo -keypair -numbertheory - - elgamal.cpp elgamal.h @@ -21,3 +12,11 @@ elg_core.h elg_op.cpp elg_op.h + + +dl_algo +dl_group +keypair +libstate +numbertheory + diff --git a/src/pubkey/if_algo/info.txt b/src/pubkey/if_algo/info.txt index 7686ed398..d2142f42f 100644 --- a/src/pubkey/if_algo/info.txt +++ b/src/pubkey/if_algo/info.txt @@ -4,12 +4,6 @@ define IF_PUBLIC_KEY_FAMILY load_on dep - -asn1 -bigint -filters - - if_algo.cpp if_algo.h @@ -18,3 +12,11 @@ if_core.h if_op.cpp if_op.h + + +asn1 +bigint +libstate +numbertheory +pk_codecs + diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index 74698503a..de58fd271 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -4,17 +4,6 @@ define PUBLIC_KEY_CRYPTO load_on auto - -asn1 -bigint -numbertheory -oid_lookup -pbe -pk_codecs -pk_pad -rng - - pk_algs.cpp pk_algs.h @@ -29,3 +18,14 @@ pubkey_enums.h x509_key.cpp x509_key.h + + +asn1 +bigint +filters +kdf +oid_lookup +pk_pad +rng +sym_algo + diff --git a/src/pubkey/nr/info.txt b/src/pubkey/nr/info.txt index a02be064d..c89820aeb 100644 --- a/src/pubkey/nr/info.txt +++ b/src/pubkey/nr/info.txt @@ -14,9 +14,9 @@ nr_op.h -asn1 -bigint dl_algo +dl_group keypair +libstate numbertheory diff --git a/src/pubkey/pk_codecs/info.txt b/src/pubkey/pk_codecs/info.txt new file mode 100644 index 000000000..96511a663 --- /dev/null +++ b/src/pubkey/pk_codecs/info.txt @@ -0,0 +1,18 @@ +realname "PK codecs (PKCS8, X.509)" + +load_on auto + + +pkcs8.h +pkcs8.cpp +x509_key.h +x509_key.cpp + + + +asn1 +filters +oid_lookup +pbe +pem + diff --git a/src/pubkey/rsa/info.txt b/src/pubkey/rsa/info.txt index a75c69ae5..7729fd83d 100644 --- a/src/pubkey/rsa/info.txt +++ b/src/pubkey/rsa/info.txt @@ -4,15 +4,14 @@ define RSA load_on auto + +rsa.cpp +rsa.h + + -asn1 -bigint if_algo keypair +libstate numbertheory - - -rsa.cpp -rsa.h - diff --git a/src/pubkey/rw/info.txt b/src/pubkey/rw/info.txt index 83265399f..ada6c37d6 100644 --- a/src/pubkey/rw/info.txt +++ b/src/pubkey/rw/info.txt @@ -4,15 +4,14 @@ define RW load_on auto + +rw.cpp +rw.h + + -asn1 -bigint if_algo keypair +libstate numbertheory - - -rw.cpp -rw.h - diff --git a/src/rng/auto_rng/info.txt b/src/rng/auto_rng/info.txt index aa316367e..2f41bc068 100644 --- a/src/rng/auto_rng/info.txt +++ b/src/rng/auto_rng/info.txt @@ -4,14 +4,14 @@ define AUTO_SEEDING_RNG load_on auto - -aes -sha2 -hmac - - auto_rng.h auto_rng.cpp + +aes +hmac +sha2 +timer + diff --git a/src/rng/hmac_rng/info.txt b/src/rng/hmac_rng/info.txt index f23f9018a..2c7f13e0a 100644 --- a/src/rng/hmac_rng/info.txt +++ b/src/rng/hmac_rng/info.txt @@ -8,3 +8,7 @@ load_on auto hmac_rng.cpp hmac_rng.h + + +mac + diff --git a/src/rng/info.txt b/src/rng/info.txt index 8b542b68f..44a41665d 100644 --- a/src/rng/info.txt +++ b/src/rng/info.txt @@ -6,3 +6,7 @@ load_on auto rng.cpp rng.h + + +entropy + diff --git a/src/rng/randpool/info.txt b/src/rng/randpool/info.txt index 1b2f79b56..cc7f61552 100644 --- a/src/rng/randpool/info.txt +++ b/src/rng/randpool/info.txt @@ -8,3 +8,8 @@ load_on auto randpool.cpp randpool.h + + +block +mac + diff --git a/src/rng/x931_rng/info.txt b/src/rng/x931_rng/info.txt index 79e436822..633eb0268 100644 --- a/src/rng/x931_rng/info.txt +++ b/src/rng/x931_rng/info.txt @@ -10,5 +10,5 @@ x931_rng.h -randpool +block diff --git a/src/s2k/info.txt b/src/s2k/info.txt index 44510bbd7..e603fd937 100644 --- a/src/s2k/info.txt +++ b/src/s2k/info.txt @@ -2,12 +2,12 @@ realname "String to Key Functions" load_on auto - -utils -rng - - s2k.cpp s2k.h + + +rng +sym_algo + diff --git a/src/s2k/pbkdf1/info.txt b/src/s2k/pbkdf1/info.txt index 3c1ae802c..4c5b27546 100644 --- a/src/s2k/pbkdf1/info.txt +++ b/src/s2k/pbkdf1/info.txt @@ -8,3 +8,7 @@ load_on auto pbkdf1.cpp pbkdf1.h + + +hash + diff --git a/src/s2k/pbkdf2/info.txt b/src/s2k/pbkdf2/info.txt index e51a331c6..921aeb1ab 100644 --- a/src/s2k/pbkdf2/info.txt +++ b/src/s2k/pbkdf2/info.txt @@ -8,3 +8,7 @@ load_on auto pbkdf2.cpp pbkdf2.h + + +mac + diff --git a/src/s2k/pgps2k/info.txt b/src/s2k/pgps2k/info.txt index a3d5a146f..14b75a02b 100644 --- a/src/s2k/pgps2k/info.txt +++ b/src/s2k/pgps2k/info.txt @@ -8,3 +8,7 @@ load_on auto pgp_s2k.cpp pgp_s2k.h + + +hash + diff --git a/src/selftest/info.txt b/src/selftest/info.txt index 49df21643..323a610a6 100644 --- a/src/selftest/info.txt +++ b/src/selftest/info.txt @@ -4,21 +4,18 @@ define SELFTESTS load_on auto + +selftest.cpp +selftest.h + + -hex -des -aes -sha1 -sha2 -hmac -ecb +algo_factory cbc cfb -ofb ctr +ecb +filters +hmac +ofb - - -selftest.cpp -selftest.h - diff --git a/src/stream/info.txt b/src/stream/info.txt index b3d9649db..295c73708 100644 --- a/src/stream/info.txt +++ b/src/stream/info.txt @@ -4,12 +4,11 @@ load_on auto define STREAM_CIPHER - -utils -sym_algo - - stream_cipher.h stream_cipher.cpp + + +sym_algo + diff --git a/src/sym_algo/info.txt b/src/sym_algo/info.txt index 3f3adfd96..f176ed6fb 100644 --- a/src/sym_algo/info.txt +++ b/src/sym_algo/info.txt @@ -2,12 +2,14 @@ realname "Symmetric Algorithms" load_on auto - -rng - - sym_algo.h symkey.cpp symkey.h + + +filters +hex +rng + diff --git a/src/timer/info.txt b/src/timer/info.txt index c9a860a78..6408dca45 100644 --- a/src/timer/info.txt +++ b/src/timer/info.txt @@ -8,3 +8,7 @@ load_on auto timer.cpp timer.h + + +rng + diff --git a/src/utils/info.txt b/src/utils/info.txt index 815ad4efc..dcf4b9288 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -8,10 +8,6 @@ load_on auto tru64 -> rt - -filters - - bit_ops.h bswap.h @@ -43,3 +39,9 @@ version.cpp version.h xor_buf.h + + +alloc +filters +libstate + -- cgit v1.2.3 From bd58db8eb1384fe26222d021325382f57f178cc7 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 16 Jul 2009 15:07:59 +0000 Subject: Move some files around to break up dependencies between directories --- src/alloc/info.txt | 1 + src/alloc/secmem.h | 438 ++++++++++++++++++++++++++++++++++++++++ src/asn1/info.txt | 2 + src/benchmark/info.txt | 1 + src/cert/x509/info.txt | 1 + src/engine/def_engine/info.txt | 1 + src/engine/info.txt | 1 + src/entropy/info.txt | 4 + src/entropy/proc_walk/info.txt | 4 + src/entropy/unix_procs/info.txt | 4 + src/filters/data_src.cpp | 207 +++++++++++++++++++ src/filters/data_src.h | 150 ++++++++++++++ src/filters/info.txt | 3 + src/hash/info.txt | 8 +- src/hash/skein/info.txt | 4 + src/kdf/info.txt | 4 + src/libstate/info.txt | 2 + src/libstate/scan_name.cpp | 74 +++++++ src/libstate/scan_name.h | 77 +++++++ src/mac/info.txt | 1 + src/math/bigint/info.txt | 1 + src/pk_pad/hash_id/info.txt | 4 + src/pk_pad/info.txt | 1 + src/pubkey/ecc_key/info.txt | 1 + src/pubkey/ecdsa/info.txt | 1 + src/pubkey/eckaeg/info.txt | 1 + src/pubkey/info.txt | 1 + src/sym_algo/info.txt | 1 + src/utils/buf_comp.h | 126 ------------ src/utils/buf_comp/buf_comp.h | 126 ++++++++++++ src/utils/data_src.cpp | 207 ------------------- src/utils/data_src.h | 150 -------------- src/utils/datastor.cpp | 172 ---------------- src/utils/datastor.h | 61 ------ src/utils/datastor/datastor.cpp | 172 ++++++++++++++++ src/utils/datastor/datastor.h | 61 ++++++ src/utils/info.txt | 12 -- src/utils/scan_name.cpp | 74 ------- src/utils/scan_name.h | 77 ------- src/utils/secmem.h | 438 ---------------------------------------- 40 files changed, 1353 insertions(+), 1321 deletions(-) create mode 100644 src/alloc/secmem.h create mode 100644 src/filters/data_src.cpp create mode 100644 src/filters/data_src.h create mode 100644 src/libstate/scan_name.cpp create mode 100644 src/libstate/scan_name.h delete mode 100644 src/utils/buf_comp.h create mode 100644 src/utils/buf_comp/buf_comp.h delete mode 100644 src/utils/data_src.cpp delete mode 100644 src/utils/data_src.h delete mode 100644 src/utils/datastor.cpp delete mode 100644 src/utils/datastor.h create mode 100644 src/utils/datastor/datastor.cpp create mode 100644 src/utils/datastor/datastor.h delete mode 100644 src/utils/scan_name.cpp delete mode 100644 src/utils/scan_name.h delete mode 100644 src/utils/secmem.h (limited to 'src/pubkey') diff --git a/src/alloc/info.txt b/src/alloc/info.txt index 2430a4db4..fa50aa09f 100644 --- a/src/alloc/info.txt +++ b/src/alloc/info.txt @@ -4,4 +4,5 @@ load_on auto allocate.h +secmem.h diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h new file mode 100644 index 000000000..d64a376ca --- /dev/null +++ b/src/alloc/secmem.h @@ -0,0 +1,438 @@ +/* +* Secure Memory Buffers +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__ +#define BOTAN_SECURE_MEMORY_BUFFERS_H__ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents variable length memory buffers. +*/ +template +class MemoryRegion + { + public: + /** + * Find out the size of the buffer, i.e. how many objects of type T it + * contains. + * @return the size of the buffer + */ + u32bit size() const { return used; } + + /** + * Find out whether this buffer is empty. + * @return true if the buffer is empty, false otherwise + */ + bool is_empty() const { return (used == 0); } + + /** + * Find out whether this buffer is non-empty + * @return true if the buffer is non-empty, false otherwise + */ + bool has_items() const { return (used != 0); } + + /** + * Get a pointer to the first element in the buffer. + * @return a pointer to the first element in the buffer + */ + operator T* () { return buf; } + + /** + * Get a constant pointer to the first element in the buffer. + * @return a constant pointer to the first element in the buffer + */ + operator const T* () const { return buf; } + + /** + * Get a pointer to the first element in the buffer. + * @return a pointer to the first element in the buffer + */ + T* begin() { return buf; } + + /** + * Get a constant pointer to the first element in the buffer. + * @return a constant pointer to the first element in the buffer + */ + const T* begin() const { return buf; } + + /** + * Get a pointer to the last element in the buffer. + * @return a pointer to the last element in the buffer + */ + T* end() { return (buf + size()); } + + /** + * Get a constant pointer to the last element in the buffer. + * @return a constant pointer to the last element in the buffer + */ + const T* end() const { return (buf + size()); } + + /** + * Check two buffers for equality. + * @return true iff the content of both buffers is byte-wise equal + */ + bool operator==(const MemoryRegion& other) const + { + return (size() == other.size() && + same_mem(buf, other.buf, size())); + } + + /** + * Compare two buffers lexicographically. + * @return true if this buffer is lexicographically smaller than other. + */ + bool operator<(const MemoryRegion& other) const; + + /** + * Check two buffers for inequality. + * @return false if the content of both buffers is byte-wise equal, true + * otherwise. + */ + bool operator!=(const MemoryRegion& in) const + { return (!(*this == in)); } + + /** + * Copy the contents of another buffer into this buffer. + * The former contents of *this are discarded. + * @param in the buffer to copy the contents from. + * @return a reference to *this + */ + MemoryRegion& operator=(const MemoryRegion& in) + { if(this != &in) set(in); return (*this); } + + /** + * The use of this function is discouraged because of the risk of memory + * errors. Use MemoryRegion::set() + * instead. + * Copy the contents of an array of objects of type T into this buffer. + * The former contents of *this are discarded. + * The length of *this must be at least n, otherwise memory errors occur. + * @param in the array to copy the contents from + * @param n the length of in + */ + void copy(const T in[], u32bit n) + { copy(0, in, n); } + + /** + * The use of this function is discouraged because of the risk of memory + * errors. Use MemoryRegion::set() + * instead. + * Copy the contents of an array of objects of type T into this buffer. + * The former contents of *this are discarded. + * The length of *this must be at least n, otherwise memory errors occur. + * @param off the offset position inside this buffer to start inserting + * the copied bytes + * @param in the array to copy the contents from + * @param n the length of in + */ + void copy(u32bit off, const T in[], u32bit n) + { copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); } + + /** + * Set the contents of this according to the argument. The size of + * *this is increased if necessary. + * @param in the array of objects of type T to copy the contents from + * @param n the size of array in + */ + void set(const T in[], u32bit n) { create(n); copy(in, n); } + + /** + * Set the contents of this according to the argument. The size of + * *this is increased if necessary. + * @param in the buffer to copy the contents from + */ + void set(const MemoryRegion& in) { set(in.begin(), in.size()); } + + /** + * Append data to the end of this buffer. + * @param data the array containing the data to append + * @param n the size of the array data + */ + void append(const T data[], u32bit n) + { grow_to(size()+n); copy(size() - n, data, n); } + + /** + * Append a single element. + * @param x the element to append + */ + void append(T x) { append(&x, 1); } + + /** + * Append data to the end of this buffer. + * @param data the buffer containing the data to append + */ + void append(const MemoryRegion& x) { append(x.begin(), x.size()); } + + /** + * Zeroise the bytes of this buffer. The length remains unchanged. + */ + void clear() { clear_mem(buf, allocated); } + + /** + * Reset this buffer to an empty buffer with size zero. + */ + void destroy() { create(0); } + + /** + * Reset this buffer to a buffer of specified length. The content will be + * initialized to zero bytes. + * @param n the new length of the buffer + */ + void create(u32bit n); + + /** + * Preallocate memory, so that this buffer can grow up to size n without + * having to perform any actual memory allocations. (This is + * the same principle as for std::vector::reserve().) + */ + void grow_to(u32bit N); + + /** + * Swap this buffer with another object. + */ + void swap(MemoryRegion& other); + + ~MemoryRegion() { deallocate(buf, allocated); } + protected: + MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; } + MemoryRegion(const MemoryRegion& other) + { + buf = 0; + used = allocated = 0; + alloc = other.alloc; + set(other.buf, other.used); + } + + void init(bool locking, u32bit length = 0) + { alloc = Allocator::get(locking); create(length); } + private: + T* allocate(u32bit n) + { + return static_cast(alloc->allocate(sizeof(T)*n)); + } + + void deallocate(T* p, u32bit n) + { alloc->deallocate(p, sizeof(T)*n); } + + T* buf; + u32bit used; + u32bit allocated; + Allocator* alloc; + }; + +/* +* Create a new buffer +*/ +template +void MemoryRegion::create(u32bit n) + { + if(n <= allocated) { clear(); used = n; return; } + deallocate(buf, allocated); + buf = allocate(n); + allocated = used = n; + } + +/* +* Increase the size of the buffer +*/ +template +void MemoryRegion::grow_to(u32bit n) + { + if(n > used && n <= allocated) + { + clear_mem(buf + used, n - used); + used = n; + return; + } + else if(n > allocated) + { + T* new_buf = allocate(n); + copy_mem(new_buf, buf, used); + deallocate(buf, allocated); + buf = new_buf; + allocated = used = n; + } + } + +/* +* Compare this buffer with another one +*/ +template +bool MemoryRegion::operator<(const MemoryRegion& in) const + { + if(size() < in.size()) return true; + if(size() > in.size()) return false; + + for(u32bit j = 0; j != size(); j++) + { + if(buf[j] < in[j]) return true; + if(buf[j] > in[j]) return false; + } + + return false; + } + +/* +* Swap this buffer with another one +*/ +template +void MemoryRegion::swap(MemoryRegion& x) + { + std::swap(buf, x.buf); + std::swap(used, x.used); + std::swap(allocated, x.allocated); + std::swap(alloc, x.alloc); + } + +/** +* This class represents variable length buffers that do not +* make use of memory locking. +*/ +template +class MemoryVector : public MemoryRegion + { + public: + /** + * Copy the contents of another buffer into this buffer. + * @param in the buffer to copy the contents from + * @return a reference to *this + */ + MemoryVector& operator=(const MemoryRegion& in) + { if(this != &in) set(in); return (*this); } + + /** + * Create a buffer of the specified length. + * @param n the length of the buffer to create. + + */ + MemoryVector(u32bit n = 0) { MemoryRegion::init(false, n); } + + /** + * Create a buffer with the specified contents. + * @param in the array containing the data to be initially copied + * into the newly created buffer + * @param n the size of the arry in + */ + MemoryVector(const T in[], u32bit n) + { MemoryRegion::init(false); set(in, n); } + + /** + * Copy constructor. + */ + MemoryVector(const MemoryRegion& in) + { MemoryRegion::init(false); set(in); } + + /** + * Create a buffer whose content is the concatenation of two other + * buffers. + * @param in1 the first part of the new contents + * @param in2 the contents to be appended to in1 + */ + MemoryVector(const MemoryRegion& in1, const MemoryRegion& in2) + { MemoryRegion::init(false); set(in1); append(in2); } + }; + +/** +* This class represents variable length buffers using the operating +* systems capability to lock memory, i.e. keeping it from being +* swapped out to disk. In this way, a security hole allowing attackers +* to find swapped out secret keys is closed. Please refer to +* Botan::InitializerOptions::secure_memory() for restrictions and +* further details. +*/ +template +class SecureVector : public MemoryRegion + { + public: + /** + * Copy the contents of another buffer into this buffer. + * @param in the buffer to copy the contents from + * @return a reference to *this + */ + SecureVector& operator=(const MemoryRegion& in) + { if(this != &in) set(in); return (*this); } + + /** + * Create a buffer of the specified length. + * @param n the length of the buffer to create. + + */ + SecureVector(u32bit n = 0) { MemoryRegion::init(true, n); } + + /** + * Create a buffer with the specified contents. + * @param in the array containing the data to be initially copied + * into the newly created buffer + * @param n the size of the array in + */ + SecureVector(const T in[], u32bit n) + { MemoryRegion::init(true); set(in, n); } + + /** + * Create a buffer with contents specified contents. + * @param in the buffer holding the contents that will be + * copied into the newly created buffer. + */ + SecureVector(const MemoryRegion& in) + { MemoryRegion::init(true); set(in); } + + /** + * Create a buffer whose content is the concatenation of two other + * buffers. + * @param in1 the first part of the new contents + * @param in2 the contents to be appended to in1 + */ + SecureVector(const MemoryRegion& in1, const MemoryRegion& in2) + { MemoryRegion::init(true); set(in1); append(in2); } + }; + +/** +* This class represents fixed length buffers using the operating +* systems capability to lock memory, i.e. keeping it from being +* swapped out to disk. In this way, a security hole allowing attackers +* to find swapped out secret keys is closed. Please refer to +* Botan::InitializerOptions::secure_memory() for restrictions and +* further details. +*/ +template +class SecureBuffer : public MemoryRegion + { + public: + /** + * Copy the contents of another buffer into this buffer. + * @param in the buffer to copy the contents from + * @return a reference to *this + */ + SecureBuffer& operator=(const SecureBuffer& in) + { if(this != &in) set(in); return (*this); } + + /** + * Create a buffer of the length L. + */ + SecureBuffer() { MemoryRegion::init(true, L); } + + /** + * Create a buffer of size L with the specified contents. + * @param in the array containing the data to be initially copied + * into the newly created buffer + * @param n the size of the array in + */ + SecureBuffer(const T in[], u32bit n) + { MemoryRegion::init(true, L); copy(in, n); } + private: + SecureBuffer& operator=(const MemoryRegion& in) + { if(this != &in) set(in); return (*this); } + }; + +} + +#endif diff --git a/src/asn1/info.txt b/src/asn1/info.txt index 3c69319b8..7b8110c10 100644 --- a/src/asn1/info.txt +++ b/src/asn1/info.txt @@ -24,6 +24,8 @@ der_enc.h +alloc bigint +filters oid_lookup diff --git a/src/benchmark/info.txt b/src/benchmark/info.txt index 958c19ebc..0fbcdb2de 100644 --- a/src/benchmark/info.txt +++ b/src/benchmark/info.txt @@ -12,6 +12,7 @@ benchmark.h algo_factory block +buf_comp hash mac rng diff --git a/src/cert/x509/info.txt b/src/cert/x509/info.txt index 726a4ad4f..552e2aacb 100644 --- a/src/cert/x509/info.txt +++ b/src/cert/x509/info.txt @@ -33,6 +33,7 @@ x509stor.h asn1 bigint +datastor filters libstate oid_lookup diff --git a/src/engine/def_engine/info.txt b/src/engine/def_engine/info.txt index eb96b0dc5..fd31ee2d0 100644 --- a/src/engine/def_engine/info.txt +++ b/src/engine/def_engine/info.txt @@ -18,6 +18,7 @@ lookup_stream.cpp algo_factory filters +libstate mode_pad numbertheory diff --git a/src/engine/info.txt b/src/engine/info.txt index bd962e4cf..eef3c03b6 100644 --- a/src/engine/info.txt +++ b/src/engine/info.txt @@ -11,6 +11,7 @@ engine.h block hash +libstate mac numbertheory stream diff --git a/src/entropy/info.txt b/src/entropy/info.txt index bac1d593f..ec3be5f58 100644 --- a/src/entropy/info.txt +++ b/src/entropy/info.txt @@ -5,3 +5,7 @@ load_on auto entropy_src.h + + +buf_comp + diff --git a/src/entropy/proc_walk/info.txt b/src/entropy/proc_walk/info.txt index d932523fd..9f4836458 100644 --- a/src/entropy/proc_walk/info.txt +++ b/src/entropy/proc_walk/info.txt @@ -27,3 +27,7 @@ tru64 # big deal since it has /dev/*random #netbsd + + +alloc + diff --git a/src/entropy/unix_procs/info.txt b/src/entropy/unix_procs/info.txt index f16e21289..928ec13b3 100644 --- a/src/entropy/unix_procs/info.txt +++ b/src/entropy/unix_procs/info.txt @@ -27,3 +27,7 @@ qnx solaris tru64 + + +filters + diff --git a/src/filters/data_src.cpp b/src/filters/data_src.cpp new file mode 100644 index 000000000..e6387c4ba --- /dev/null +++ b/src/filters/data_src.cpp @@ -0,0 +1,207 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* 2005 Matthew Gregan +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +#include +#include + +namespace Botan { + +/* +* Read a single byte from the DataSource +*/ +u32bit DataSource::read_byte(byte& out) + { + return read(&out, 1); + } + +/* +* Peek a single byte from the DataSource +*/ +u32bit DataSource::peek_byte(byte& out) const + { + return peek(&out, 1, 0); + } + +/* +* Discard the next N bytes of the data +*/ +u32bit DataSource::discard_next(u32bit n) + { + u32bit discarded = 0; + byte dummy; + for(u32bit j = 0; j != n; ++j) + discarded += read_byte(dummy); + return discarded; + } + +/* +* Read from a memory buffer +*/ +u32bit DataSource_Memory::read(byte out[], u32bit length) + { + u32bit got = std::min(source.size() - offset, length); + copy_mem(out, source + offset, got); + offset += got; + return got; + } + +/* +* Peek into a memory buffer +*/ +u32bit DataSource_Memory::peek(byte out[], u32bit length, + u32bit peek_offset) const + { + const u32bit bytes_left = source.size() - offset; + if(peek_offset >= bytes_left) return 0; + + u32bit got = std::min(bytes_left - peek_offset, length); + copy_mem(out, source + offset + peek_offset, got); + return got; + } + +/* +* Check if the memory buffer is empty +*/ +bool DataSource_Memory::end_of_data() const + { + return (offset == source.size()); + } + +/* +* DataSource_Memory Constructor +*/ +DataSource_Memory::DataSource_Memory(const byte in[], u32bit length) + { + source.set(in, length); + offset = 0; + } + +/* +* DataSource_Memory Constructor +*/ +DataSource_Memory::DataSource_Memory(const MemoryRegion& in) + { + source = in; + offset = 0; + } + +/* +* DataSource_Memory Constructor +*/ +DataSource_Memory::DataSource_Memory(const std::string& in) + { + source.set(reinterpret_cast(in.data()), in.length()); + offset = 0; + } + +/* +* Read from a stream +*/ +u32bit DataSource_Stream::read(byte out[], u32bit length) + { + source->read(reinterpret_cast(out), length); + if(source->bad()) + throw Stream_IO_Error("DataSource_Stream::read: Source failure"); + + u32bit got = source->gcount(); + total_read += got; + return got; + } + +/* +* Peek into a stream +*/ +u32bit DataSource_Stream::peek(byte out[], u32bit length, u32bit offset) const + { + if(end_of_data()) + throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); + + u32bit got = 0; + + if(offset) + { + SecureVector buf(offset); + source->read(reinterpret_cast(buf.begin()), buf.size()); + if(source->bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source->gcount(); + } + + if(got == offset) + { + source->read(reinterpret_cast(out), length); + if(source->bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source->gcount(); + } + + if(source->eof()) + source->clear(); + source->seekg(total_read, std::ios::beg); + + return got; + } + +/* +* Check if the stream is empty or in error +*/ +bool DataSource_Stream::end_of_data() const + { + return (!source->good()); + } + +/* +* Return a human-readable ID for this stream +*/ +std::string DataSource_Stream::id() const + { + return identifier; + } + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(const std::string& path, + bool use_binary) : + identifier(path), owner(true) + { + if(use_binary) + source = new std::ifstream(path.c_str(), std::ios::binary); + else + source = new std::ifstream(path.c_str()); + + if(!source->good()) + throw Stream_IO_Error("DataSource: Failure opening file " + path); + + total_read = 0; + } + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(std::istream& in, + const std::string& name) : + identifier(name), owner(false) + { + source = ∈ + total_read = 0; + } + +/* +* DataSource_Stream Destructor +*/ +DataSource_Stream::~DataSource_Stream() + { + if(owner) + delete source; + } + +} diff --git a/src/filters/data_src.h b/src/filters/data_src.h new file mode 100644 index 000000000..e16217e0f --- /dev/null +++ b/src/filters/data_src.h @@ -0,0 +1,150 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_DATA_SRC_H__ +#define BOTAN_DATA_SRC_H__ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents an abstract data source object. +*/ +class BOTAN_DLL DataSource + { + public: + /** + * Read from the source. Moves the internal offset so that + * every call to read will return a new portion of the source. + * @param out the byte array to write the result to + * @param length the length of the byte array out + * @return the length in bytes that was actually read and put + * into out + */ + virtual u32bit read(byte out[], u32bit length) = 0; + + /** + * Read from the source but do not modify the internal offset. Consecutive + * calls to peek() will return portions of the source starting at the same + * position. + * @param out the byte array to write the output to + * @param length the length of the byte array out + * @return the length in bytes that was actually read and put + * into out + */ + virtual u32bit peek(byte out[], u32bit length, + u32bit peek_offset) const = 0; + + /** + * Test whether the source still has data that can be read. + * @return true if there is still data to read, false otherwise + */ + virtual bool end_of_data() const = 0; + /** + * return the id of this data source + * @return the std::string representing the id of this data source + */ + virtual std::string id() const { return ""; } + + /** + * Read one byte. + * @param the byte to read to + * @return the length in bytes that was actually read and put + * into out + */ + u32bit read_byte(byte& out); + + /** + * Peek at one byte. + * @param the byte to read to + * @return the length in bytes that was actually read and put + * into out + */ + u32bit peek_byte(byte& out) const; + + /** + * Discard the next N bytes of the data + * @param N the number of bytes to discard + * @return the number of bytes actually discarded + */ + u32bit discard_next(u32bit N); + + DataSource() {} + virtual ~DataSource() {} + private: + DataSource& operator=(const DataSource&) { return (*this); } + DataSource(const DataSource&); + }; + +/** +* This class represents a Memory-Based DataSource +*/ +class BOTAN_DLL DataSource_Memory : public DataSource + { + public: + u32bit read(byte[], u32bit); + u32bit peek(byte[], u32bit, u32bit) const; + bool end_of_data() const; + + /** + * Construct a memory source that reads from a string + * @param in the string to read from + */ + DataSource_Memory(const std::string& in); + + /** + * Construct a memory source that reads from a byte array + * @param in the byte array to read from + * @param length the length of the byte array + */ + DataSource_Memory(const byte in[], u32bit length); + + /** + * Construct a memory source that reads from a MemoryRegion + * @param in the MemoryRegion to read from + */ + DataSource_Memory(const MemoryRegion& in); + private: + SecureVector source; + u32bit offset; + }; + +/** +* This class represents a Stream-Based DataSource. +*/ +class BOTAN_DLL DataSource_Stream : public DataSource + { + public: + u32bit read(byte[], u32bit); + u32bit peek(byte[], u32bit, u32bit) const; + bool end_of_data() const; + std::string id() const; + + DataSource_Stream(std::istream&, const std::string& id = ""); + + /** + * Construct a Stream-Based DataSource from file + * @param file the name of the file + * @param use_binary whether to treat the file as binary or not + */ + DataSource_Stream(const std::string& file, bool use_binary = false); + + ~DataSource_Stream(); + private: + const std::string identifier; + const bool owner; + + std::istream* source; + u32bit total_read; + }; + +} + +#endif diff --git a/src/filters/info.txt b/src/filters/info.txt index 40d952b0d..79a92a9c5 100644 --- a/src/filters/info.txt +++ b/src/filters/info.txt @@ -12,6 +12,8 @@ buf_filt.cpp buf_filt.h data_snk.cpp data_snk.h +data_src.cpp +data_src.h filter.cpp filter.h filters.h @@ -27,6 +29,7 @@ secqueue.h +alloc asn1 block hash diff --git a/src/hash/info.txt b/src/hash/info.txt index fb1f734d7..ce55f7ddc 100644 --- a/src/hash/info.txt +++ b/src/hash/info.txt @@ -2,10 +2,10 @@ realname "Hash Functions" load_on auto - -utils - - hash.h + + +buf_comp + diff --git a/src/hash/skein/info.txt b/src/hash/skein/info.txt index d2d482d81..bab8497c5 100644 --- a/src/hash/skein/info.txt +++ b/src/hash/skein/info.txt @@ -8,3 +8,7 @@ load_on auto skein_512.cpp skein_512.h + + +alloc + diff --git a/src/kdf/info.txt b/src/kdf/info.txt index fa5cca334..1965a2098 100644 --- a/src/kdf/info.txt +++ b/src/kdf/info.txt @@ -8,3 +8,7 @@ load_on auto kdf.cpp kdf.h + + +alloc + diff --git a/src/libstate/info.txt b/src/libstate/info.txt index 6e200ee3f..7ca35c5a4 100644 --- a/src/libstate/info.txt +++ b/src/libstate/info.txt @@ -18,6 +18,8 @@ lookup.h pk_engine.cpp pk_engine.h policy.cpp +scan_name.cpp +scan_name.h diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp new file mode 100644 index 000000000..ef771871d --- /dev/null +++ b/src/libstate/scan_name.cpp @@ -0,0 +1,74 @@ +/** +SCAN Name Abstraction +(C) 2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +std::vector +parse_and_deref_aliases(const std::string& algo_spec) + { + std::vector parts = parse_algorithm_name(algo_spec); + std::vector out; + + for(size_t i = 0; i != parts.size(); ++i) + { + std::string part_i = global_state().deref_alias(parts[i]); + + if(i == 0 && part_i.find_first_of(",()") != std::string::npos) + { + std::vector parts_i = parse_and_deref_aliases(part_i); + + for(size_t j = 0; j != parts_i.size(); ++j) + out.push_back(parts_i[j]); + } + else + out.push_back(part_i); + } + + return out; + } + +} + +SCAN_Name::SCAN_Name(const std::string& algo_spec) + { + orig_algo_spec = algo_spec; + + name = parse_and_deref_aliases(algo_spec); + + if(name.size() == 0) + throw Decoding_Error("Bad SCAN name " + algo_spec); + } + +std::string SCAN_Name::arg(u32bit i) const + { + if(i >= arg_count()) + throw std::range_error("SCAN_Name::argument"); + return name[i+1]; + } + +std::string SCAN_Name::arg(u32bit i, const std::string& def_value) const + { + if(i >= arg_count()) + return def_value; + return name[i+1]; + } + +u32bit SCAN_Name::arg_as_u32bit(u32bit i, u32bit def_value) const + { + if(i >= arg_count()) + return def_value; + return to_u32bit(name[i+1]); + } + +} diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h new file mode 100644 index 000000000..9e7af40d6 --- /dev/null +++ b/src/libstate/scan_name.h @@ -0,0 +1,77 @@ +/** +SCAN Name Abstraction +(C) 2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SCAN_NAME_H__ +#define BOTAN_SCAN_NAME_H__ + +#include +#include +#include +#include + +namespace Botan { + +/** +A class encapsulating a SCAN name (similar to JCE conventions) +http://www.users.zetnet.co.uk/hopwood/crypto/scan/ +*/ +class SCAN_Name + { + public: + /** + @param algo_spec A SCAN name + */ + SCAN_Name(const std::string& algo_spec); + + /** + @return the original input string + */ + std::string as_string() const { return orig_algo_spec; } + + /** + @return the algorithm name + */ + std::string algo_name() const { return name[0]; } + + /** + @return the number of arguments + */ + u32bit arg_count() const { return name.size() - 1; } + + /** + @return if the number of arguments is between lower and upper + */ + bool arg_count_between(u32bit lower, u32bit upper) const + { return ((arg_count() >= lower) && (arg_count() <= upper)); } + + /** + @param i which argument + @return the ith argument + */ + std::string arg(u32bit i) const; + + /** + @param i which argument + @param def_value the default value + @return the ith argument or the default value + */ + std::string arg(u32bit i, const std::string& def_value) const; + + /** + @param i which argument + @param def_value the default value + @return the ith argument as a u32bit, or the default value + */ + u32bit arg_as_u32bit(u32bit i, u32bit def_value) const; + private: + std::string orig_algo_spec; + std::vector name; + }; + +} + +#endif diff --git a/src/mac/info.txt b/src/mac/info.txt index 4891d7498..239eb633f 100644 --- a/src/mac/info.txt +++ b/src/mac/info.txt @@ -8,5 +8,6 @@ mac.cpp +buf_comp sym_algo diff --git a/src/math/bigint/info.txt b/src/math/bigint/info.txt index 9c8e1fa17..07b254683 100644 --- a/src/math/bigint/info.txt +++ b/src/math/bigint/info.txt @@ -24,6 +24,7 @@ mp_shift.cpp +alloc hex mp_ia32 mp_ia32_msvc diff --git a/src/pk_pad/hash_id/info.txt b/src/pk_pad/hash_id/info.txt index 6a9b7f0da..935432588 100644 --- a/src/pk_pad/hash_id/info.txt +++ b/src/pk_pad/hash_id/info.txt @@ -8,3 +8,7 @@ load_on auto hash_id.cpp hash_id.h + + +alloc + diff --git a/src/pk_pad/info.txt b/src/pk_pad/info.txt index ae773b440..c281b1563 100644 --- a/src/pk_pad/info.txt +++ b/src/pk_pad/info.txt @@ -11,5 +11,6 @@ eme.h +alloc rng diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt index c1972052d..2a3c9a3b2 100644 --- a/src/pubkey/ecc_key/info.txt +++ b/src/pubkey/ecc_key/info.txt @@ -10,6 +10,7 @@ ecc_key.h +alloc asn1 bigint ec_dompar diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt index 4ca020ad5..743440f8f 100644 --- a/src/pubkey/ecdsa/info.txt +++ b/src/pubkey/ecdsa/info.txt @@ -14,6 +14,7 @@ ecdsa_op.h +alloc asn1 ec_dompar ecc_key diff --git a/src/pubkey/eckaeg/info.txt b/src/pubkey/eckaeg/info.txt index d18a805ee..6b78f7de5 100644 --- a/src/pubkey/eckaeg/info.txt +++ b/src/pubkey/eckaeg/info.txt @@ -14,6 +14,7 @@ eckaeg_op.h +alloc asn1 ec_dompar ecc_key diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index de58fd271..e33e8e305 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -20,6 +20,7 @@ x509_key.h +alloc asn1 bigint filters diff --git a/src/sym_algo/info.txt b/src/sym_algo/info.txt index f176ed6fb..03804a92d 100644 --- a/src/sym_algo/info.txt +++ b/src/sym_algo/info.txt @@ -9,6 +9,7 @@ symkey.h +alloc filters hex rng diff --git a/src/utils/buf_comp.h b/src/utils/buf_comp.h deleted file mode 100644 index 3f1e90bad..000000000 --- a/src/utils/buf_comp.h +++ /dev/null @@ -1,126 +0,0 @@ -/** -* BufferedComputation -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_BUFFERED_COMPUTATION_H__ -#define BOTAN_BUFFERED_COMPUTATION_H__ - -#include - -namespace Botan { - -/** -* This class represents any kind of computation which -* uses an internal state, -* such as hash functions. -*/ -class BOTAN_DLL BufferedComputation - { - public: - - /** - * The length of the output of this function in bytes. - */ - const u32bit OUTPUT_LENGTH; - - /** - * Add new input to process. - * @param in the input to process as a byte array - * @param the length of the byte array - */ - void update(const byte in[], u32bit length) { add_data(in, length); } - - /** - * Add new input to process. - * @param in the input to process as a MemoryRegion - */ - void update(const MemoryRegion& in) { add_data(in, in.size()); } - - /** - * Add new input to process. - * @param str the input to process as a std::string. Will be interpreted - * as a byte array based on - * the strings encoding. - */ - void update(const std::string& str) - { - add_data(reinterpret_cast(str.data()), str.size()); - } - - /** - * Process a single byte. - * @param in the byte to process - */ - void update(byte in) { add_data(&in, 1); } - - /** - * Complete the computation and retrieve the - * final result. - * @param out The byte array to be filled with the result. - * Must be of length OUTPUT_LENGTH. - */ - void final(byte out[]) { final_result(out); } - - /** - * Complete the computation and retrieve the - * final result. - * @return a SecureVector holding the result - */ - SecureVector final() - { - SecureVector output(OUTPUT_LENGTH); - final_result(output); - return output; - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a byte array - * @param length the length of the byte array - * @result the result of the call to final() - */ - SecureVector process(const byte in[], u32bit length) - { - add_data(in, length); - return final(); - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process - * @result the result of the call to final() - */ - SecureVector process(const MemoryRegion& in) - { - add_data(in, in.size()); - return final(); - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a string - * @result the result of the call to final() - */ - SecureVector process(const std::string& in) - { - update(in); - return final(); - } - - BufferedComputation(u32bit out_len) : OUTPUT_LENGTH(out_len) {} - virtual ~BufferedComputation() {} - private: - BufferedComputation& operator=(const BufferedComputation&); - virtual void add_data(const byte[], u32bit) = 0; - virtual void final_result(byte[]) = 0; - }; - -} - -#endif diff --git a/src/utils/buf_comp/buf_comp.h b/src/utils/buf_comp/buf_comp.h new file mode 100644 index 000000000..3f1e90bad --- /dev/null +++ b/src/utils/buf_comp/buf_comp.h @@ -0,0 +1,126 @@ +/** +* BufferedComputation +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_BUFFERED_COMPUTATION_H__ +#define BOTAN_BUFFERED_COMPUTATION_H__ + +#include + +namespace Botan { + +/** +* This class represents any kind of computation which +* uses an internal state, +* such as hash functions. +*/ +class BOTAN_DLL BufferedComputation + { + public: + + /** + * The length of the output of this function in bytes. + */ + const u32bit OUTPUT_LENGTH; + + /** + * Add new input to process. + * @param in the input to process as a byte array + * @param the length of the byte array + */ + void update(const byte in[], u32bit length) { add_data(in, length); } + + /** + * Add new input to process. + * @param in the input to process as a MemoryRegion + */ + void update(const MemoryRegion& in) { add_data(in, in.size()); } + + /** + * Add new input to process. + * @param str the input to process as a std::string. Will be interpreted + * as a byte array based on + * the strings encoding. + */ + void update(const std::string& str) + { + add_data(reinterpret_cast(str.data()), str.size()); + } + + /** + * Process a single byte. + * @param in the byte to process + */ + void update(byte in) { add_data(&in, 1); } + + /** + * Complete the computation and retrieve the + * final result. + * @param out The byte array to be filled with the result. + * Must be of length OUTPUT_LENGTH. + */ + void final(byte out[]) { final_result(out); } + + /** + * Complete the computation and retrieve the + * final result. + * @return a SecureVector holding the result + */ + SecureVector final() + { + SecureVector output(OUTPUT_LENGTH); + final_result(output); + return output; + } + + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process as a byte array + * @param length the length of the byte array + * @result the result of the call to final() + */ + SecureVector process(const byte in[], u32bit length) + { + add_data(in, length); + return final(); + } + + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process + * @result the result of the call to final() + */ + SecureVector process(const MemoryRegion& in) + { + add_data(in, in.size()); + return final(); + } + + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process as a string + * @result the result of the call to final() + */ + SecureVector process(const std::string& in) + { + update(in); + return final(); + } + + BufferedComputation(u32bit out_len) : OUTPUT_LENGTH(out_len) {} + virtual ~BufferedComputation() {} + private: + BufferedComputation& operator=(const BufferedComputation&); + virtual void add_data(const byte[], u32bit) = 0; + virtual void final_result(byte[]) = 0; + }; + +} + +#endif diff --git a/src/utils/data_src.cpp b/src/utils/data_src.cpp deleted file mode 100644 index e6387c4ba..000000000 --- a/src/utils/data_src.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* -* DataSource -* (C) 1999-2007 Jack Lloyd -* 2005 Matthew Gregan -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -#include -#include - -namespace Botan { - -/* -* Read a single byte from the DataSource -*/ -u32bit DataSource::read_byte(byte& out) - { - return read(&out, 1); - } - -/* -* Peek a single byte from the DataSource -*/ -u32bit DataSource::peek_byte(byte& out) const - { - return peek(&out, 1, 0); - } - -/* -* Discard the next N bytes of the data -*/ -u32bit DataSource::discard_next(u32bit n) - { - u32bit discarded = 0; - byte dummy; - for(u32bit j = 0; j != n; ++j) - discarded += read_byte(dummy); - return discarded; - } - -/* -* Read from a memory buffer -*/ -u32bit DataSource_Memory::read(byte out[], u32bit length) - { - u32bit got = std::min(source.size() - offset, length); - copy_mem(out, source + offset, got); - offset += got; - return got; - } - -/* -* Peek into a memory buffer -*/ -u32bit DataSource_Memory::peek(byte out[], u32bit length, - u32bit peek_offset) const - { - const u32bit bytes_left = source.size() - offset; - if(peek_offset >= bytes_left) return 0; - - u32bit got = std::min(bytes_left - peek_offset, length); - copy_mem(out, source + offset + peek_offset, got); - return got; - } - -/* -* Check if the memory buffer is empty -*/ -bool DataSource_Memory::end_of_data() const - { - return (offset == source.size()); - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const byte in[], u32bit length) - { - source.set(in, length); - offset = 0; - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const MemoryRegion& in) - { - source = in; - offset = 0; - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const std::string& in) - { - source.set(reinterpret_cast(in.data()), in.length()); - offset = 0; - } - -/* -* Read from a stream -*/ -u32bit DataSource_Stream::read(byte out[], u32bit length) - { - source->read(reinterpret_cast(out), length); - if(source->bad()) - throw Stream_IO_Error("DataSource_Stream::read: Source failure"); - - u32bit got = source->gcount(); - total_read += got; - return got; - } - -/* -* Peek into a stream -*/ -u32bit DataSource_Stream::peek(byte out[], u32bit length, u32bit offset) const - { - if(end_of_data()) - throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); - - u32bit got = 0; - - if(offset) - { - SecureVector buf(offset); - source->read(reinterpret_cast(buf.begin()), buf.size()); - if(source->bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source->gcount(); - } - - if(got == offset) - { - source->read(reinterpret_cast(out), length); - if(source->bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source->gcount(); - } - - if(source->eof()) - source->clear(); - source->seekg(total_read, std::ios::beg); - - return got; - } - -/* -* Check if the stream is empty or in error -*/ -bool DataSource_Stream::end_of_data() const - { - return (!source->good()); - } - -/* -* Return a human-readable ID for this stream -*/ -std::string DataSource_Stream::id() const - { - return identifier; - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(const std::string& path, - bool use_binary) : - identifier(path), owner(true) - { - if(use_binary) - source = new std::ifstream(path.c_str(), std::ios::binary); - else - source = new std::ifstream(path.c_str()); - - if(!source->good()) - throw Stream_IO_Error("DataSource: Failure opening file " + path); - - total_read = 0; - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(std::istream& in, - const std::string& name) : - identifier(name), owner(false) - { - source = ∈ - total_read = 0; - } - -/* -* DataSource_Stream Destructor -*/ -DataSource_Stream::~DataSource_Stream() - { - if(owner) - delete source; - } - -} diff --git a/src/utils/data_src.h b/src/utils/data_src.h deleted file mode 100644 index e16217e0f..000000000 --- a/src/utils/data_src.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -* DataSource -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_DATA_SRC_H__ -#define BOTAN_DATA_SRC_H__ - -#include -#include -#include - -namespace Botan { - -/** -* This class represents an abstract data source object. -*/ -class BOTAN_DLL DataSource - { - public: - /** - * Read from the source. Moves the internal offset so that - * every call to read will return a new portion of the source. - * @param out the byte array to write the result to - * @param length the length of the byte array out - * @return the length in bytes that was actually read and put - * into out - */ - virtual u32bit read(byte out[], u32bit length) = 0; - - /** - * Read from the source but do not modify the internal offset. Consecutive - * calls to peek() will return portions of the source starting at the same - * position. - * @param out the byte array to write the output to - * @param length the length of the byte array out - * @return the length in bytes that was actually read and put - * into out - */ - virtual u32bit peek(byte out[], u32bit length, - u32bit peek_offset) const = 0; - - /** - * Test whether the source still has data that can be read. - * @return true if there is still data to read, false otherwise - */ - virtual bool end_of_data() const = 0; - /** - * return the id of this data source - * @return the std::string representing the id of this data source - */ - virtual std::string id() const { return ""; } - - /** - * Read one byte. - * @param the byte to read to - * @return the length in bytes that was actually read and put - * into out - */ - u32bit read_byte(byte& out); - - /** - * Peek at one byte. - * @param the byte to read to - * @return the length in bytes that was actually read and put - * into out - */ - u32bit peek_byte(byte& out) const; - - /** - * Discard the next N bytes of the data - * @param N the number of bytes to discard - * @return the number of bytes actually discarded - */ - u32bit discard_next(u32bit N); - - DataSource() {} - virtual ~DataSource() {} - private: - DataSource& operator=(const DataSource&) { return (*this); } - DataSource(const DataSource&); - }; - -/** -* This class represents a Memory-Based DataSource -*/ -class BOTAN_DLL DataSource_Memory : public DataSource - { - public: - u32bit read(byte[], u32bit); - u32bit peek(byte[], u32bit, u32bit) const; - bool end_of_data() const; - - /** - * Construct a memory source that reads from a string - * @param in the string to read from - */ - DataSource_Memory(const std::string& in); - - /** - * Construct a memory source that reads from a byte array - * @param in the byte array to read from - * @param length the length of the byte array - */ - DataSource_Memory(const byte in[], u32bit length); - - /** - * Construct a memory source that reads from a MemoryRegion - * @param in the MemoryRegion to read from - */ - DataSource_Memory(const MemoryRegion& in); - private: - SecureVector source; - u32bit offset; - }; - -/** -* This class represents a Stream-Based DataSource. -*/ -class BOTAN_DLL DataSource_Stream : public DataSource - { - public: - u32bit read(byte[], u32bit); - u32bit peek(byte[], u32bit, u32bit) const; - bool end_of_data() const; - std::string id() const; - - DataSource_Stream(std::istream&, const std::string& id = ""); - - /** - * Construct a Stream-Based DataSource from file - * @param file the name of the file - * @param use_binary whether to treat the file as binary or not - */ - DataSource_Stream(const std::string& file, bool use_binary = false); - - ~DataSource_Stream(); - private: - const std::string identifier; - const bool owner; - - std::istream* source; - u32bit total_read; - }; - -} - -#endif diff --git a/src/utils/datastor.cpp b/src/utils/datastor.cpp deleted file mode 100644 index 129dad9bf..000000000 --- a/src/utils/datastor.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* -* Data Store -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include - -namespace Botan { - -/* -* Default Matcher transform operation (identity) -*/ -std::pair -Data_Store::Matcher::transform(const std::string& key, - const std::string& value) const - { - return std::make_pair(key, value); - } - -/* -* Data_Store Equality Comparison -*/ -bool Data_Store::operator==(const Data_Store& other) const - { - return (contents == other.contents); - } - -/* -* Check if this key has at least one value -*/ -bool Data_Store::has_value(const std::string& key) const - { - return (contents.lower_bound(key) != contents.end()); - } - -/* -* Search based on an arbitrary predicate -*/ -std::multimap -Data_Store::search_with(const Matcher& matcher) const - { - std::multimap out; - - std::multimap::const_iterator i = - contents.begin(); - - while(i != contents.end()) - { - if(matcher(i->first, i->second)) - out.insert(matcher.transform(i->first, i->second)); - ++i; - } - - return out; - } - -/* -* Search based on key equality -*/ -std::vector Data_Store::get(const std::string& looking_for) const - { - typedef std::multimap::const_iterator iter; - - std::pair range = contents.equal_range(looking_for); - - std::vector out; - for(iter i = range.first; i != range.second; ++i) - out.push_back(i->second); - return out; - } - -/* -* Get a single atom -*/ -std::string Data_Store::get1(const std::string& key) const - { - std::vector vals = get(key); - - if(vals.empty()) - throw Invalid_State("Data_Store::get1: Not values for " + key); - if(vals.size() > 1) - throw Invalid_State("Data_Store::get1: More than one value for " + key); - - return vals[0]; - } - -/* -* Get a single MemoryVector atom -*/ -MemoryVector -Data_Store::get1_memvec(const std::string& key) const - { - std::vector vals = get(key); - - if(vals.size() > 1) - throw Invalid_State("Data_Store::get1_memvec: Multiple values for " + - key); - - if(vals.empty()) - return MemoryVector(); - - Pipe pipe(new Hex_Decoder(FULL_CHECK)); - pipe.start_msg(); - if(vals.size()) - pipe.write(vals[0]); - pipe.end_msg(); - return pipe.read_all(); - } - -/* -* Get a single u32bit atom -*/ -u32bit Data_Store::get1_u32bit(const std::string& key, - u32bit default_val) const - { - std::vector vals = get(key); - - if(vals.empty()) - return default_val; - else if(vals.size() > 1) - throw Invalid_State("Data_Store::get1_u32bit: Multiple values for " + - key); - - return to_u32bit(vals[0]); - } - -/* -* Insert a single key and value -*/ -void Data_Store::add(const std::string& key, const std::string& val) - { - multimap_insert(contents, key, val); - } - -/* -* Insert a single key and value -*/ -void Data_Store::add(const std::string& key, u32bit val) - { - add(key, to_string(val)); - } - -/* -* Insert a single key and value -*/ -void Data_Store::add(const std::string& key, const MemoryRegion& val) - { - Pipe pipe(new Hex_Encoder); - pipe.process_msg(val); - add(key, pipe.read_all_as_string()); - } - -/* -* Insert a mapping of key/value pairs -*/ -void Data_Store::add(const std::multimap& in) - { - std::multimap::const_iterator i = in.begin(); - while(i != in.end()) - { - contents.insert(*i); - ++i; - } - } - -} diff --git a/src/utils/datastor.h b/src/utils/datastor.h deleted file mode 100644 index 7ee626fda..000000000 --- a/src/utils/datastor.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* Data Store -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_DATA_STORE_H__ -#define BOTAN_DATA_STORE_H__ - -#include -#include -#include -#include -#include - -namespace Botan { - -/** -* Data Store -*/ -class BOTAN_DLL Data_Store - { - public: - class BOTAN_DLL Matcher - { - public: - virtual bool operator()(const std::string&, - const std::string&) const = 0; - - virtual std::pair - transform(const std::string&, const std::string&) const; - - virtual ~Matcher() {} - }; - - bool operator==(const Data_Store&) const; - - std::multimap - search_with(const Matcher&) const; - - std::vector get(const std::string&) const; - - std::string get1(const std::string&) const; - - MemoryVector get1_memvec(const std::string&) const; - u32bit get1_u32bit(const std::string&, u32bit = 0) const; - - bool has_value(const std::string&) const; - - void add(const std::multimap&); - void add(const std::string&, const std::string&); - void add(const std::string&, u32bit); - void add(const std::string&, const MemoryRegion&); - private: - std::multimap contents; - }; - -} - -#endif diff --git a/src/utils/datastor/datastor.cpp b/src/utils/datastor/datastor.cpp new file mode 100644 index 000000000..129dad9bf --- /dev/null +++ b/src/utils/datastor/datastor.cpp @@ -0,0 +1,172 @@ +/* +* Data Store +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* Default Matcher transform operation (identity) +*/ +std::pair +Data_Store::Matcher::transform(const std::string& key, + const std::string& value) const + { + return std::make_pair(key, value); + } + +/* +* Data_Store Equality Comparison +*/ +bool Data_Store::operator==(const Data_Store& other) const + { + return (contents == other.contents); + } + +/* +* Check if this key has at least one value +*/ +bool Data_Store::has_value(const std::string& key) const + { + return (contents.lower_bound(key) != contents.end()); + } + +/* +* Search based on an arbitrary predicate +*/ +std::multimap +Data_Store::search_with(const Matcher& matcher) const + { + std::multimap out; + + std::multimap::const_iterator i = + contents.begin(); + + while(i != contents.end()) + { + if(matcher(i->first, i->second)) + out.insert(matcher.transform(i->first, i->second)); + ++i; + } + + return out; + } + +/* +* Search based on key equality +*/ +std::vector Data_Store::get(const std::string& looking_for) const + { + typedef std::multimap::const_iterator iter; + + std::pair range = contents.equal_range(looking_for); + + std::vector out; + for(iter i = range.first; i != range.second; ++i) + out.push_back(i->second); + return out; + } + +/* +* Get a single atom +*/ +std::string Data_Store::get1(const std::string& key) const + { + std::vector vals = get(key); + + if(vals.empty()) + throw Invalid_State("Data_Store::get1: Not values for " + key); + if(vals.size() > 1) + throw Invalid_State("Data_Store::get1: More than one value for " + key); + + return vals[0]; + } + +/* +* Get a single MemoryVector atom +*/ +MemoryVector +Data_Store::get1_memvec(const std::string& key) const + { + std::vector vals = get(key); + + if(vals.size() > 1) + throw Invalid_State("Data_Store::get1_memvec: Multiple values for " + + key); + + if(vals.empty()) + return MemoryVector(); + + Pipe pipe(new Hex_Decoder(FULL_CHECK)); + pipe.start_msg(); + if(vals.size()) + pipe.write(vals[0]); + pipe.end_msg(); + return pipe.read_all(); + } + +/* +* Get a single u32bit atom +*/ +u32bit Data_Store::get1_u32bit(const std::string& key, + u32bit default_val) const + { + std::vector vals = get(key); + + if(vals.empty()) + return default_val; + else if(vals.size() > 1) + throw Invalid_State("Data_Store::get1_u32bit: Multiple values for " + + key); + + return to_u32bit(vals[0]); + } + +/* +* Insert a single key and value +*/ +void Data_Store::add(const std::string& key, const std::string& val) + { + multimap_insert(contents, key, val); + } + +/* +* Insert a single key and value +*/ +void Data_Store::add(const std::string& key, u32bit val) + { + add(key, to_string(val)); + } + +/* +* Insert a single key and value +*/ +void Data_Store::add(const std::string& key, const MemoryRegion& val) + { + Pipe pipe(new Hex_Encoder); + pipe.process_msg(val); + add(key, pipe.read_all_as_string()); + } + +/* +* Insert a mapping of key/value pairs +*/ +void Data_Store::add(const std::multimap& in) + { + std::multimap::const_iterator i = in.begin(); + while(i != in.end()) + { + contents.insert(*i); + ++i; + } + } + +} diff --git a/src/utils/datastor/datastor.h b/src/utils/datastor/datastor.h new file mode 100644 index 000000000..7ee626fda --- /dev/null +++ b/src/utils/datastor/datastor.h @@ -0,0 +1,61 @@ +/* +* Data Store +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_DATA_STORE_H__ +#define BOTAN_DATA_STORE_H__ + +#include +#include +#include +#include +#include + +namespace Botan { + +/** +* Data Store +*/ +class BOTAN_DLL Data_Store + { + public: + class BOTAN_DLL Matcher + { + public: + virtual bool operator()(const std::string&, + const std::string&) const = 0; + + virtual std::pair + transform(const std::string&, const std::string&) const; + + virtual ~Matcher() {} + }; + + bool operator==(const Data_Store&) const; + + std::multimap + search_with(const Matcher&) const; + + std::vector get(const std::string&) const; + + std::string get1(const std::string&) const; + + MemoryVector get1_memvec(const std::string&) const; + u32bit get1_u32bit(const std::string&, u32bit = 0) const; + + bool has_value(const std::string&) const; + + void add(const std::multimap&); + void add(const std::string&, const std::string&); + void add(const std::string&, u32bit); + void add(const std::string&, const MemoryRegion&); + private: + std::multimap contents; + }; + +} + +#endif diff --git a/src/utils/info.txt b/src/utils/info.txt index dcf4b9288..36b10df76 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -11,13 +11,10 @@ tru64 -> rt bit_ops.h bswap.h -buf_comp.h charset.cpp charset.h data_src.cpp data_src.h -datastor.cpp -datastor.h exceptn.cpp exceptn.h loadstor.h @@ -26,9 +23,6 @@ mlock.cpp parsing.cpp parsing.h rotate.h -scan_name.cpp -scan_name.h -secmem.h stl_util.h types.h ui.cpp @@ -39,9 +33,3 @@ version.cpp version.h xor_buf.h - - -alloc -filters -libstate - diff --git a/src/utils/scan_name.cpp b/src/utils/scan_name.cpp deleted file mode 100644 index ef771871d..000000000 --- a/src/utils/scan_name.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** -SCAN Name Abstraction -(C) 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include - -namespace Botan { - -namespace { - -std::vector -parse_and_deref_aliases(const std::string& algo_spec) - { - std::vector parts = parse_algorithm_name(algo_spec); - std::vector out; - - for(size_t i = 0; i != parts.size(); ++i) - { - std::string part_i = global_state().deref_alias(parts[i]); - - if(i == 0 && part_i.find_first_of(",()") != std::string::npos) - { - std::vector parts_i = parse_and_deref_aliases(part_i); - - for(size_t j = 0; j != parts_i.size(); ++j) - out.push_back(parts_i[j]); - } - else - out.push_back(part_i); - } - - return out; - } - -} - -SCAN_Name::SCAN_Name(const std::string& algo_spec) - { - orig_algo_spec = algo_spec; - - name = parse_and_deref_aliases(algo_spec); - - if(name.size() == 0) - throw Decoding_Error("Bad SCAN name " + algo_spec); - } - -std::string SCAN_Name::arg(u32bit i) const - { - if(i >= arg_count()) - throw std::range_error("SCAN_Name::argument"); - return name[i+1]; - } - -std::string SCAN_Name::arg(u32bit i, const std::string& def_value) const - { - if(i >= arg_count()) - return def_value; - return name[i+1]; - } - -u32bit SCAN_Name::arg_as_u32bit(u32bit i, u32bit def_value) const - { - if(i >= arg_count()) - return def_value; - return to_u32bit(name[i+1]); - } - -} diff --git a/src/utils/scan_name.h b/src/utils/scan_name.h deleted file mode 100644 index 9e7af40d6..000000000 --- a/src/utils/scan_name.h +++ /dev/null @@ -1,77 +0,0 @@ -/** -SCAN Name Abstraction -(C) 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SCAN_NAME_H__ -#define BOTAN_SCAN_NAME_H__ - -#include -#include -#include -#include - -namespace Botan { - -/** -A class encapsulating a SCAN name (similar to JCE conventions) -http://www.users.zetnet.co.uk/hopwood/crypto/scan/ -*/ -class SCAN_Name - { - public: - /** - @param algo_spec A SCAN name - */ - SCAN_Name(const std::string& algo_spec); - - /** - @return the original input string - */ - std::string as_string() const { return orig_algo_spec; } - - /** - @return the algorithm name - */ - std::string algo_name() const { return name[0]; } - - /** - @return the number of arguments - */ - u32bit arg_count() const { return name.size() - 1; } - - /** - @return if the number of arguments is between lower and upper - */ - bool arg_count_between(u32bit lower, u32bit upper) const - { return ((arg_count() >= lower) && (arg_count() <= upper)); } - - /** - @param i which argument - @return the ith argument - */ - std::string arg(u32bit i) const; - - /** - @param i which argument - @param def_value the default value - @return the ith argument or the default value - */ - std::string arg(u32bit i, const std::string& def_value) const; - - /** - @param i which argument - @param def_value the default value - @return the ith argument as a u32bit, or the default value - */ - u32bit arg_as_u32bit(u32bit i, u32bit def_value) const; - private: - std::string orig_algo_spec; - std::vector name; - }; - -} - -#endif diff --git a/src/utils/secmem.h b/src/utils/secmem.h deleted file mode 100644 index d64a376ca..000000000 --- a/src/utils/secmem.h +++ /dev/null @@ -1,438 +0,0 @@ -/* -* Secure Memory Buffers -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__ -#define BOTAN_SECURE_MEMORY_BUFFERS_H__ - -#include -#include -#include - -namespace Botan { - -/** -* This class represents variable length memory buffers. -*/ -template -class MemoryRegion - { - public: - /** - * Find out the size of the buffer, i.e. how many objects of type T it - * contains. - * @return the size of the buffer - */ - u32bit size() const { return used; } - - /** - * Find out whether this buffer is empty. - * @return true if the buffer is empty, false otherwise - */ - bool is_empty() const { return (used == 0); } - - /** - * Find out whether this buffer is non-empty - * @return true if the buffer is non-empty, false otherwise - */ - bool has_items() const { return (used != 0); } - - /** - * Get a pointer to the first element in the buffer. - * @return a pointer to the first element in the buffer - */ - operator T* () { return buf; } - - /** - * Get a constant pointer to the first element in the buffer. - * @return a constant pointer to the first element in the buffer - */ - operator const T* () const { return buf; } - - /** - * Get a pointer to the first element in the buffer. - * @return a pointer to the first element in the buffer - */ - T* begin() { return buf; } - - /** - * Get a constant pointer to the first element in the buffer. - * @return a constant pointer to the first element in the buffer - */ - const T* begin() const { return buf; } - - /** - * Get a pointer to the last element in the buffer. - * @return a pointer to the last element in the buffer - */ - T* end() { return (buf + size()); } - - /** - * Get a constant pointer to the last element in the buffer. - * @return a constant pointer to the last element in the buffer - */ - const T* end() const { return (buf + size()); } - - /** - * Check two buffers for equality. - * @return true iff the content of both buffers is byte-wise equal - */ - bool operator==(const MemoryRegion& other) const - { - return (size() == other.size() && - same_mem(buf, other.buf, size())); - } - - /** - * Compare two buffers lexicographically. - * @return true if this buffer is lexicographically smaller than other. - */ - bool operator<(const MemoryRegion& other) const; - - /** - * Check two buffers for inequality. - * @return false if the content of both buffers is byte-wise equal, true - * otherwise. - */ - bool operator!=(const MemoryRegion& in) const - { return (!(*this == in)); } - - /** - * Copy the contents of another buffer into this buffer. - * The former contents of *this are discarded. - * @param in the buffer to copy the contents from. - * @return a reference to *this - */ - MemoryRegion& operator=(const MemoryRegion& in) - { if(this != &in) set(in); return (*this); } - - /** - * The use of this function is discouraged because of the risk of memory - * errors. Use MemoryRegion::set() - * instead. - * Copy the contents of an array of objects of type T into this buffer. - * The former contents of *this are discarded. - * The length of *this must be at least n, otherwise memory errors occur. - * @param in the array to copy the contents from - * @param n the length of in - */ - void copy(const T in[], u32bit n) - { copy(0, in, n); } - - /** - * The use of this function is discouraged because of the risk of memory - * errors. Use MemoryRegion::set() - * instead. - * Copy the contents of an array of objects of type T into this buffer. - * The former contents of *this are discarded. - * The length of *this must be at least n, otherwise memory errors occur. - * @param off the offset position inside this buffer to start inserting - * the copied bytes - * @param in the array to copy the contents from - * @param n the length of in - */ - void copy(u32bit off, const T in[], u32bit n) - { copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); } - - /** - * Set the contents of this according to the argument. The size of - * *this is increased if necessary. - * @param in the array of objects of type T to copy the contents from - * @param n the size of array in - */ - void set(const T in[], u32bit n) { create(n); copy(in, n); } - - /** - * Set the contents of this according to the argument. The size of - * *this is increased if necessary. - * @param in the buffer to copy the contents from - */ - void set(const MemoryRegion& in) { set(in.begin(), in.size()); } - - /** - * Append data to the end of this buffer. - * @param data the array containing the data to append - * @param n the size of the array data - */ - void append(const T data[], u32bit n) - { grow_to(size()+n); copy(size() - n, data, n); } - - /** - * Append a single element. - * @param x the element to append - */ - void append(T x) { append(&x, 1); } - - /** - * Append data to the end of this buffer. - * @param data the buffer containing the data to append - */ - void append(const MemoryRegion& x) { append(x.begin(), x.size()); } - - /** - * Zeroise the bytes of this buffer. The length remains unchanged. - */ - void clear() { clear_mem(buf, allocated); } - - /** - * Reset this buffer to an empty buffer with size zero. - */ - void destroy() { create(0); } - - /** - * Reset this buffer to a buffer of specified length. The content will be - * initialized to zero bytes. - * @param n the new length of the buffer - */ - void create(u32bit n); - - /** - * Preallocate memory, so that this buffer can grow up to size n without - * having to perform any actual memory allocations. (This is - * the same principle as for std::vector::reserve().) - */ - void grow_to(u32bit N); - - /** - * Swap this buffer with another object. - */ - void swap(MemoryRegion& other); - - ~MemoryRegion() { deallocate(buf, allocated); } - protected: - MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; } - MemoryRegion(const MemoryRegion& other) - { - buf = 0; - used = allocated = 0; - alloc = other.alloc; - set(other.buf, other.used); - } - - void init(bool locking, u32bit length = 0) - { alloc = Allocator::get(locking); create(length); } - private: - T* allocate(u32bit n) - { - return static_cast(alloc->allocate(sizeof(T)*n)); - } - - void deallocate(T* p, u32bit n) - { alloc->deallocate(p, sizeof(T)*n); } - - T* buf; - u32bit used; - u32bit allocated; - Allocator* alloc; - }; - -/* -* Create a new buffer -*/ -template -void MemoryRegion::create(u32bit n) - { - if(n <= allocated) { clear(); used = n; return; } - deallocate(buf, allocated); - buf = allocate(n); - allocated = used = n; - } - -/* -* Increase the size of the buffer -*/ -template -void MemoryRegion::grow_to(u32bit n) - { - if(n > used && n <= allocated) - { - clear_mem(buf + used, n - used); - used = n; - return; - } - else if(n > allocated) - { - T* new_buf = allocate(n); - copy_mem(new_buf, buf, used); - deallocate(buf, allocated); - buf = new_buf; - allocated = used = n; - } - } - -/* -* Compare this buffer with another one -*/ -template -bool MemoryRegion::operator<(const MemoryRegion& in) const - { - if(size() < in.size()) return true; - if(size() > in.size()) return false; - - for(u32bit j = 0; j != size(); j++) - { - if(buf[j] < in[j]) return true; - if(buf[j] > in[j]) return false; - } - - return false; - } - -/* -* Swap this buffer with another one -*/ -template -void MemoryRegion::swap(MemoryRegion& x) - { - std::swap(buf, x.buf); - std::swap(used, x.used); - std::swap(allocated, x.allocated); - std::swap(alloc, x.alloc); - } - -/** -* This class represents variable length buffers that do not -* make use of memory locking. -*/ -template -class MemoryVector : public MemoryRegion - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param in the buffer to copy the contents from - * @return a reference to *this - */ - MemoryVector& operator=(const MemoryRegion& in) - { if(this != &in) set(in); return (*this); } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - - */ - MemoryVector(u32bit n = 0) { MemoryRegion::init(false, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the arry in - */ - MemoryVector(const T in[], u32bit n) - { MemoryRegion::init(false); set(in, n); } - - /** - * Copy constructor. - */ - MemoryVector(const MemoryRegion& in) - { MemoryRegion::init(false); set(in); } - - /** - * Create a buffer whose content is the concatenation of two other - * buffers. - * @param in1 the first part of the new contents - * @param in2 the contents to be appended to in1 - */ - MemoryVector(const MemoryRegion& in1, const MemoryRegion& in2) - { MemoryRegion::init(false); set(in1); append(in2); } - }; - -/** -* This class represents variable length buffers using the operating -* systems capability to lock memory, i.e. keeping it from being -* swapped out to disk. In this way, a security hole allowing attackers -* to find swapped out secret keys is closed. Please refer to -* Botan::InitializerOptions::secure_memory() for restrictions and -* further details. -*/ -template -class SecureVector : public MemoryRegion - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param in the buffer to copy the contents from - * @return a reference to *this - */ - SecureVector& operator=(const MemoryRegion& in) - { if(this != &in) set(in); return (*this); } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - - */ - SecureVector(u32bit n = 0) { MemoryRegion::init(true, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the array in - */ - SecureVector(const T in[], u32bit n) - { MemoryRegion::init(true); set(in, n); } - - /** - * Create a buffer with contents specified contents. - * @param in the buffer holding the contents that will be - * copied into the newly created buffer. - */ - SecureVector(const MemoryRegion& in) - { MemoryRegion::init(true); set(in); } - - /** - * Create a buffer whose content is the concatenation of two other - * buffers. - * @param in1 the first part of the new contents - * @param in2 the contents to be appended to in1 - */ - SecureVector(const MemoryRegion& in1, const MemoryRegion& in2) - { MemoryRegion::init(true); set(in1); append(in2); } - }; - -/** -* This class represents fixed length buffers using the operating -* systems capability to lock memory, i.e. keeping it from being -* swapped out to disk. In this way, a security hole allowing attackers -* to find swapped out secret keys is closed. Please refer to -* Botan::InitializerOptions::secure_memory() for restrictions and -* further details. -*/ -template -class SecureBuffer : public MemoryRegion - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param in the buffer to copy the contents from - * @return a reference to *this - */ - SecureBuffer& operator=(const SecureBuffer& in) - { if(this != &in) set(in); return (*this); } - - /** - * Create a buffer of the length L. - */ - SecureBuffer() { MemoryRegion::init(true, L); } - - /** - * Create a buffer of size L with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the array in - */ - SecureBuffer(const T in[], u32bit n) - { MemoryRegion::init(true, L); copy(in, n); } - private: - SecureBuffer& operator=(const MemoryRegion& in) - { if(this != &in) set(in); return (*this); } - }; - -} - -#endif -- cgit v1.2.3 From 74a282ecd3324bcd49b56a3ce1e388ec1a285123 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 16 Jul 2009 15:11:33 +0000 Subject: Correct source listings for moved files --- src/pubkey/info.txt | 2 -- src/utils/info.txt | 2 -- 2 files changed, 4 deletions(-) (limited to 'src/pubkey') diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index e33e8e305..ee8da5b9d 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -15,8 +15,6 @@ pubkey.cpp pubkey.h pubkey_enums.cpp pubkey_enums.h -x509_key.cpp -x509_key.h diff --git a/src/utils/info.txt b/src/utils/info.txt index 36b10df76..95ea5fc2e 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -13,8 +13,6 @@ bit_ops.h bswap.h charset.cpp charset.h -data_src.cpp -data_src.h exceptn.cpp exceptn.h loadstor.h -- cgit v1.2.3 From 75f5829775ec225e5295822ab2ca1d4ecf9ca5bf Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 21 Jul 2009 04:22:23 +0000 Subject: Move from pk_codecs to pubkey to solve merge problem --- src/pubkey/pk_codecs/pkcs8.cpp | 313 -------------------------------------- src/pubkey/pk_codecs/pkcs8.h | 182 ---------------------- src/pubkey/pk_codecs/x509_key.cpp | 176 --------------------- src/pubkey/pk_codecs/x509_key.h | 110 -------------- src/pubkey/pkcs8.cpp | 313 ++++++++++++++++++++++++++++++++++++++ src/pubkey/pkcs8.h | 182 ++++++++++++++++++++++ src/pubkey/x509_key.cpp | 176 +++++++++++++++++++++ src/pubkey/x509_key.h | 110 ++++++++++++++ 8 files changed, 781 insertions(+), 781 deletions(-) delete mode 100644 src/pubkey/pk_codecs/pkcs8.cpp delete mode 100644 src/pubkey/pk_codecs/pkcs8.h delete mode 100644 src/pubkey/pk_codecs/x509_key.cpp delete mode 100644 src/pubkey/pk_codecs/x509_key.h create mode 100644 src/pubkey/pkcs8.cpp create mode 100644 src/pubkey/pkcs8.h create mode 100644 src/pubkey/x509_key.cpp create mode 100644 src/pubkey/x509_key.h (limited to 'src/pubkey') diff --git a/src/pubkey/pk_codecs/pkcs8.cpp b/src/pubkey/pk_codecs/pkcs8.cpp deleted file mode 100644 index 8a464ecfe..000000000 --- a/src/pubkey/pk_codecs/pkcs8.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* -* PKCS #8 -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -namespace PKCS8 { - -namespace { - -/* -* Get info from an EncryptedPrivateKeyInfo -*/ -SecureVector PKCS8_extract(DataSource& source, - AlgorithmIdentifier& pbe_alg_id) - { - SecureVector key_data; - - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(pbe_alg_id) - .decode(key_data, OCTET_STRING) - .verify_end(); - - return key_data; - } - -/* -* PEM decode and/or decrypt a private key -*/ -SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, - AlgorithmIdentifier& pk_alg_id) - { - AlgorithmIdentifier pbe_alg_id; - SecureVector key_data, key; - bool is_encrypted = true; - - try { - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - key_data = PKCS8_extract(source, pbe_alg_id); - else - { - std::string label; - key_data = PEM_Code::decode(source, label); - if(label == "PRIVATE KEY") - is_encrypted = false; - else if(label == "ENCRYPTED PRIVATE KEY") - { - DataSource_Memory key_source(key_data); - key_data = PKCS8_extract(key_source, pbe_alg_id); - } - else - throw PKCS8_Exception("Unknown PEM label " + label); - } - - if(key_data.is_empty()) - throw PKCS8_Exception("No key data found"); - } - catch(Decoding_Error) - { - throw Decoding_Error("PKCS #8 private key decoding failed"); - } - - if(!is_encrypted) - key = key_data; - - const u32bit MAX_TRIES = 3; - - u32bit tries = 0; - while(true) - { - try { - if(MAX_TRIES && tries >= MAX_TRIES) - break; - - if(is_encrypted) - { - DataSource_Memory params(pbe_alg_id.parameters); - std::auto_ptr pbe(get_pbe(pbe_alg_id.oid, params)); - - User_Interface::UI_Result result = User_Interface::OK; - const std::string passphrase = - ui.get_passphrase("PKCS #8 private key", source.id(), result); - - if(result == User_Interface::CANCEL_ACTION) - break; - - pbe->set_key(passphrase); - Pipe decryptor(pbe.release()); - - decryptor.process_msg(key_data, key_data.size()); - key = decryptor.read_all(); - } - - u32bit version; - - BER_Decoder(key) - .start_cons(SEQUENCE) - .decode(version) - .decode(pk_alg_id) - .decode(key, OCTET_STRING) - .discard_remaining() - .end_cons(); - - if(version != 0) - throw Decoding_Error("PKCS #8: Unknown version number"); - - break; - } - catch(Decoding_Error) - { - ++tries; - } - } - - if(key.is_empty()) - throw Decoding_Error("PKCS #8 private key decoding failed"); - return key; - } - -} - -/* -* DER or PEM encode a PKCS #8 private key -*/ -void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding) - { - std::auto_ptr encoder(key.pkcs8_encoder()); - if(!encoder.get()) - throw Encoding_Error("PKCS8::encode: Key does not support encoding"); - - const u32bit PKCS8_VERSION = 0; - - SecureVector contents = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(PKCS8_VERSION) - .encode(encoder->alg_id()) - .encode(encoder->key_bits(), OCTET_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(contents, "PRIVATE KEY")); - else - pipe.write(contents); - } - -/* -* Encode and encrypt a PKCS #8 private key -*/ -void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, const std::string& pbe_algo, - X509_Encoding encoding) - { - const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"; - - Pipe raw_key; - raw_key.start_msg(); - encode(key, raw_key, RAW_BER); - raw_key.end_msg(); - - std::auto_ptr pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); - - pbe->new_params(rng); - pbe->set_key(pass); - - AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); - - Pipe key_encrytor(pbe.release()); - key_encrytor.process_msg(raw_key); - - SecureVector enc_key = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(pbe_algid) - .encode(key_encrytor.read_all(), OCTET_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(enc_key, "ENCRYPTED PRIVATE KEY")); - else - pipe.write(enc_key); - } - -/* -* PEM encode a PKCS #8 private key -*/ -std::string PEM_encode(const Private_Key& key) - { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Encrypt and PEM encode a PKCS #8 private key -*/ -std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo) - { - if(pass == "") - return PEM_encode(key); - - Pipe pem; - pem.start_msg(); - encrypt_key(key, pem, rng, pass, pbe_algo, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - AlgorithmIdentifier alg_id; - SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); - - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "" || alg_name == alg_id.oid.as_string()) - throw PKCS8_Exception("Unknown algorithm OID: " + - alg_id.oid.as_string()); - - std::auto_ptr key(get_private_key(alg_name)); - - if(!key.get()) - throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " + - alg_id.oid.as_string()); - - std::auto_ptr decoder(key->pkcs8_decoder(rng)); - - if(!decoder.get()) - throw Decoding_Error("Key does not support PKCS #8 decoding"); - - decoder->alg_id(alg_id); - decoder->key_bits(pkcs8_key); - - return key.release(); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - DataSource_Stream source(fsname, true); - return PKCS8::load_key(source, rng, ui); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(source, rng, User_Interface(pass)); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(fsname, rng, User_Interface(pass)); - } - -/* -* Make a copy of this private key -*/ -Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng) - { - Pipe bits; - - bits.start_msg(); - PKCS8::encode(key, bits); - bits.end_msg(); - - DataSource_Memory source(bits.read_all()); - return PKCS8::load_key(source, rng); - } - -} - -} diff --git a/src/pubkey/pk_codecs/pkcs8.h b/src/pubkey/pk_codecs/pkcs8.h deleted file mode 100644 index 87f8ba326..000000000 --- a/src/pubkey/pk_codecs/pkcs8.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -* PKCS #8 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_PKCS8_H__ -#define BOTAN_PKCS8_H__ - -#include -#include - -namespace Botan { - -/** -* PKCS #8 Private Key Encoder. -*/ -class BOTAN_DLL PKCS8_Encoder - { - public: - /** - * Get the algorithm identifier associated with the scheme - * this encoders key is part of. - * @return the algorithm identifier - */ - virtual AlgorithmIdentifier alg_id() const = 0; - - /** - * Get the DER encoded key. - * @return the DER encoded key - */ - // XXX: Why not SecureVector? - virtual MemoryVector key_bits() const = 0; - virtual ~PKCS8_Encoder() {} - }; - -/* -* PKCS #8 Private Key Decoder -*/ -class BOTAN_DLL PKCS8_Decoder - { - public: - /** - * Set the algorithm identifier associated with the scheme - * this decoders key is part of. - * @param alg_id the algorithm identifier - */ - virtual void alg_id(const AlgorithmIdentifier&) = 0; - - /** - * Set the DER encoded key. - * @param key the DER encoded key - */ - virtual void key_bits(const MemoryRegion&) = 0; - virtual ~PKCS8_Decoder() {} - }; - -/** -* PKCS #8 General Exception -*/ -struct BOTAN_DLL PKCS8_Exception : public Decoding_Error - { - PKCS8_Exception(const std::string& error) : - Decoding_Error("PKCS #8: " + error) {} - }; - -namespace PKCS8 { - -/** -* Encode a private key into a pipe. -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use -*/ -BOTAN_DLL void encode(const Private_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); - -/** -* Encode and encrypt a private key into a pipe. -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param pass the password to use for encryption -* @param rng the rng to use -* @param pbe_algo the name of the desired password-based encryption algorithm. -* Provide an empty string to use the default PBE defined in the configuration -* under base/default_pbe. -* @param enc the encoding type to use -*/ -BOTAN_DLL void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = "", - X509_Encoding enc = PEM); - - -/** -* Get a string containing a PEM encoded private key. -* @param key the key to encode -* @return the encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key); - -/** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption algorithm. -* Provide an empty string to use the default PBE defined in the configuration -* under base/default_pbe. -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = ""); - -BOTAN_DLL std::string PEM_encode(const Private_Key&, - const std::string&, - const std::string& = ""); - - -/** -* Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Copy an existing encoded key object. -* @param key the key to copy -* @param rng the rng to use -* @return the new copy of the key -*/ -BOTAN_DLL Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng); - -} - -} - -#endif diff --git a/src/pubkey/pk_codecs/x509_key.cpp b/src/pubkey/pk_codecs/x509_key.cpp deleted file mode 100644 index 455e627f3..000000000 --- a/src/pubkey/pk_codecs/x509_key.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* -* X.509 Public Key -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -namespace X509 { - -/* -* DER or PEM encode a X.509 public key -*/ -void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) - { - std::auto_ptr encoder(key.x509_encoder()); - if(!encoder.get()) - throw Encoding_Error("X509::encode: Key does not support encoding"); - - MemoryVector der = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(encoder->alg_id()) - .encode(encoder->key_bits(), BIT_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(der, "PUBLIC KEY")); - else - pipe.write(der); - } - -/* -* PEM encode a X.509 public key -*/ -std::string PEM_encode(const Public_Key& key) - { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(DataSource& source) - { - try { - AlgorithmIdentifier alg_id; - MemoryVector key_bits; - - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - else - { - DataSource_Memory ber( - PEM_Code::decode_check_label(source, "PUBLIC KEY") - ); - - BER_Decoder(ber) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - - if(key_bits.is_empty()) - throw Decoding_Error("X.509 public key decoding failed"); - - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "") - throw Decoding_Error("Unknown algorithm OID: " + - alg_id.oid.as_string()); - - std::auto_ptr key_obj(get_public_key(alg_name)); - if(!key_obj.get()) - throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " + - alg_id.oid.as_string()); - - std::auto_ptr decoder(key_obj->x509_decoder()); - - if(!decoder.get()) - throw Decoding_Error("Key does not support X.509 decoding"); - - decoder->alg_id(alg_id); - decoder->key_bits(key_bits); - - return key_obj.release(); - } - catch(Decoding_Error) - { - throw Decoding_Error("X.509 public key decoding failed"); - } - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const std::string& fsname) - { - DataSource_Stream source(fsname, true); - return X509::load_key(source); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const MemoryRegion& mem) - { - DataSource_Memory source(mem); - return X509::load_key(source); - } - -/* -* Make a copy of this public key -*/ -Public_Key* copy_key(const Public_Key& key) - { - Pipe bits; - bits.start_msg(); - X509::encode(key, bits, RAW_BER); - bits.end_msg(); - DataSource_Memory source(bits.read_all()); - return X509::load_key(source); - } - -/* -* Find the allowable key constraints -*/ -Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits) - { - const Public_Key* key = &pub_key; - u32bit constraints = 0; - - if(dynamic_cast(key)) - constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; - - if(dynamic_cast(key)) - constraints |= KEY_AGREEMENT; - - if(dynamic_cast(key) || - dynamic_cast(key)) - constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION; - - if(limits) - constraints &= limits; - - return Key_Constraints(constraints); - } - -} - -} diff --git a/src/pubkey/pk_codecs/x509_key.h b/src/pubkey/pk_codecs/x509_key.h deleted file mode 100644 index 9404b7ecc..000000000 --- a/src/pubkey/pk_codecs/x509_key.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -* X.509 Public Key -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_X509_PUBLIC_KEY_H__ -#define BOTAN_X509_PUBLIC_KEY_H__ - -#include -#include -#include -#include - -namespace Botan { - -/** -* This class represents abstract X.509 public key encoders. -*/ -class BOTAN_DLL X509_Encoder - { - public: - virtual AlgorithmIdentifier alg_id() const = 0; - virtual MemoryVector key_bits() const = 0; - virtual ~X509_Encoder() {} - }; - -/** -* This class represents abstract X.509 public key decoders. -*/ -class BOTAN_DLL X509_Decoder - { - public: - virtual void alg_id(const AlgorithmIdentifier&) = 0; - virtual void key_bits(const MemoryRegion&) = 0; - virtual ~X509_Decoder() {} - }; - -/** -* This namespace contains functions for handling X509 objects. -*/ -namespace X509 { - -/* -* X.509 Public Key Encoding/Decoding -*/ - -/** -* Encode a key into a pipe. -* @param key the public key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use -*/ -BOTAN_DLL void encode(const Public_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); - -/** -* PEM encode a public key into a string. -* @param key the key to encode -* @return the PEM encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Public_Key& key); - -/** -* Create a public key from a data source. -* @param source the source providing the DER or PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(DataSource& source); - -/** -* Create a public key from a string. -* @param enc the string containing the PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(const std::string& enc); - -/** -* Create a public key from a memory region. -* @param enc the memory region containing the DER or PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(const MemoryRegion& enc); - -/** -* Copy a key. -* @param key the public key to copy -* @return the new public key object -*/ -BOTAN_DLL Public_Key* copy_key(const Public_Key& key); - -/** -* Create the key constraints for a specific public key. -* @param pub_key the public key from which the basic set of -* constraints to be placed in the return value is derived -* @param limits additional limits that will be incorporated into the -* return value -* @return the combination of key type specific constraints and -* additional limits -*/ - -BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits); - -} - -} - -#endif diff --git a/src/pubkey/pkcs8.cpp b/src/pubkey/pkcs8.cpp new file mode 100644 index 000000000..8a464ecfe --- /dev/null +++ b/src/pubkey/pkcs8.cpp @@ -0,0 +1,313 @@ +/* +* PKCS #8 +* (C) 1999-2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace PKCS8 { + +namespace { + +/* +* Get info from an EncryptedPrivateKeyInfo +*/ +SecureVector PKCS8_extract(DataSource& source, + AlgorithmIdentifier& pbe_alg_id) + { + SecureVector key_data; + + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(pbe_alg_id) + .decode(key_data, OCTET_STRING) + .verify_end(); + + return key_data; + } + +/* +* PEM decode and/or decrypt a private key +*/ +SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, + AlgorithmIdentifier& pk_alg_id) + { + AlgorithmIdentifier pbe_alg_id; + SecureVector key_data, key; + bool is_encrypted = true; + + try { + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + key_data = PKCS8_extract(source, pbe_alg_id); + else + { + std::string label; + key_data = PEM_Code::decode(source, label); + if(label == "PRIVATE KEY") + is_encrypted = false; + else if(label == "ENCRYPTED PRIVATE KEY") + { + DataSource_Memory key_source(key_data); + key_data = PKCS8_extract(key_source, pbe_alg_id); + } + else + throw PKCS8_Exception("Unknown PEM label " + label); + } + + if(key_data.is_empty()) + throw PKCS8_Exception("No key data found"); + } + catch(Decoding_Error) + { + throw Decoding_Error("PKCS #8 private key decoding failed"); + } + + if(!is_encrypted) + key = key_data; + + const u32bit MAX_TRIES = 3; + + u32bit tries = 0; + while(true) + { + try { + if(MAX_TRIES && tries >= MAX_TRIES) + break; + + if(is_encrypted) + { + DataSource_Memory params(pbe_alg_id.parameters); + std::auto_ptr pbe(get_pbe(pbe_alg_id.oid, params)); + + User_Interface::UI_Result result = User_Interface::OK; + const std::string passphrase = + ui.get_passphrase("PKCS #8 private key", source.id(), result); + + if(result == User_Interface::CANCEL_ACTION) + break; + + pbe->set_key(passphrase); + Pipe decryptor(pbe.release()); + + decryptor.process_msg(key_data, key_data.size()); + key = decryptor.read_all(); + } + + u32bit version; + + BER_Decoder(key) + .start_cons(SEQUENCE) + .decode(version) + .decode(pk_alg_id) + .decode(key, OCTET_STRING) + .discard_remaining() + .end_cons(); + + if(version != 0) + throw Decoding_Error("PKCS #8: Unknown version number"); + + break; + } + catch(Decoding_Error) + { + ++tries; + } + } + + if(key.is_empty()) + throw Decoding_Error("PKCS #8 private key decoding failed"); + return key; + } + +} + +/* +* DER or PEM encode a PKCS #8 private key +*/ +void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding) + { + std::auto_ptr encoder(key.pkcs8_encoder()); + if(!encoder.get()) + throw Encoding_Error("PKCS8::encode: Key does not support encoding"); + + const u32bit PKCS8_VERSION = 0; + + SecureVector contents = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(PKCS8_VERSION) + .encode(encoder->alg_id()) + .encode(encoder->key_bits(), OCTET_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(contents, "PRIVATE KEY")); + else + pipe.write(contents); + } + +/* +* Encode and encrypt a PKCS #8 private key +*/ +void encrypt_key(const Private_Key& key, + Pipe& pipe, + RandomNumberGenerator& rng, + const std::string& pass, const std::string& pbe_algo, + X509_Encoding encoding) + { + const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"; + + Pipe raw_key; + raw_key.start_msg(); + encode(key, raw_key, RAW_BER); + raw_key.end_msg(); + + std::auto_ptr pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); + + pbe->new_params(rng); + pbe->set_key(pass); + + AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); + + Pipe key_encrytor(pbe.release()); + key_encrytor.process_msg(raw_key); + + SecureVector enc_key = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(pbe_algid) + .encode(key_encrytor.read_all(), OCTET_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(enc_key, "ENCRYPTED PRIVATE KEY")); + else + pipe.write(enc_key); + } + +/* +* PEM encode a PKCS #8 private key +*/ +std::string PEM_encode(const Private_Key& key) + { + Pipe pem; + pem.start_msg(); + encode(key, pem, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Encrypt and PEM encode a PKCS #8 private key +*/ +std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo) + { + if(pass == "") + return PEM_encode(key); + + Pipe pem; + pem.start_msg(); + encrypt_key(key, pem, rng, pass, pbe_algo, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const User_Interface& ui) + { + AlgorithmIdentifier alg_id; + SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); + + const std::string alg_name = OIDS::lookup(alg_id.oid); + if(alg_name == "" || alg_name == alg_id.oid.as_string()) + throw PKCS8_Exception("Unknown algorithm OID: " + + alg_id.oid.as_string()); + + std::auto_ptr key(get_private_key(alg_name)); + + if(!key.get()) + throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " + + alg_id.oid.as_string()); + + std::auto_ptr decoder(key->pkcs8_decoder(rng)); + + if(!decoder.get()) + throw Decoding_Error("Key does not support PKCS #8 decoding"); + + decoder->alg_id(alg_id); + decoder->key_bits(pkcs8_key); + + return key.release(); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + const User_Interface& ui) + { + DataSource_Stream source(fsname, true); + return PKCS8::load_key(source, rng, ui); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass) + { + return PKCS8::load_key(source, rng, User_Interface(pass)); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + const std::string& pass) + { + return PKCS8::load_key(fsname, rng, User_Interface(pass)); + } + +/* +* Make a copy of this private key +*/ +Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng) + { + Pipe bits; + + bits.start_msg(); + PKCS8::encode(key, bits); + bits.end_msg(); + + DataSource_Memory source(bits.read_all()); + return PKCS8::load_key(source, rng); + } + +} + +} diff --git a/src/pubkey/pkcs8.h b/src/pubkey/pkcs8.h new file mode 100644 index 000000000..87f8ba326 --- /dev/null +++ b/src/pubkey/pkcs8.h @@ -0,0 +1,182 @@ +/* +* PKCS #8 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PKCS8_H__ +#define BOTAN_PKCS8_H__ + +#include +#include + +namespace Botan { + +/** +* PKCS #8 Private Key Encoder. +*/ +class BOTAN_DLL PKCS8_Encoder + { + public: + /** + * Get the algorithm identifier associated with the scheme + * this encoders key is part of. + * @return the algorithm identifier + */ + virtual AlgorithmIdentifier alg_id() const = 0; + + /** + * Get the DER encoded key. + * @return the DER encoded key + */ + // XXX: Why not SecureVector? + virtual MemoryVector key_bits() const = 0; + virtual ~PKCS8_Encoder() {} + }; + +/* +* PKCS #8 Private Key Decoder +*/ +class BOTAN_DLL PKCS8_Decoder + { + public: + /** + * Set the algorithm identifier associated with the scheme + * this decoders key is part of. + * @param alg_id the algorithm identifier + */ + virtual void alg_id(const AlgorithmIdentifier&) = 0; + + /** + * Set the DER encoded key. + * @param key the DER encoded key + */ + virtual void key_bits(const MemoryRegion&) = 0; + virtual ~PKCS8_Decoder() {} + }; + +/** +* PKCS #8 General Exception +*/ +struct BOTAN_DLL PKCS8_Exception : public Decoding_Error + { + PKCS8_Exception(const std::string& error) : + Decoding_Error("PKCS #8: " + error) {} + }; + +namespace PKCS8 { + +/** +* Encode a private key into a pipe. +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param enc the encoding type to use +*/ +BOTAN_DLL void encode(const Private_Key& key, Pipe& pipe, + X509_Encoding enc = PEM); + +/** +* Encode and encrypt a private key into a pipe. +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param pass the password to use for encryption +* @param rng the rng to use +* @param pbe_algo the name of the desired password-based encryption algorithm. +* Provide an empty string to use the default PBE defined in the configuration +* under base/default_pbe. +* @param enc the encoding type to use +*/ +BOTAN_DLL void encrypt_key(const Private_Key& key, + Pipe& pipe, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = "", + X509_Encoding enc = PEM); + + +/** +* Get a string containing a PEM encoded private key. +* @param key the key to encode +* @return the encoded key +*/ +BOTAN_DLL std::string PEM_encode(const Private_Key& key); + +/** +* Get a string containing a PEM encoded private key, encrypting it with a +* password. +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbe_algo the name of the desired password-based encryption algorithm. +* Provide an empty string to use the default PBE defined in the configuration +* under base/default_pbe. +*/ +BOTAN_DLL std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = ""); + +BOTAN_DLL std::string PEM_encode(const Private_Key&, + const std::string&, + const std::string& = ""); + + +/** +* Load a key from a data source. +* @param source the data source providing the encoded key +* @param rng the rng to use +* @param ui the user interface to be used for passphrase dialog +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const User_Interface& ui); + +/** Load a key from a data source. +* @param source the data source providing the encoded key +* @param rng the rng to use +* @param pass the passphrase to decrypt the key. Provide an empty +* string if the key is not encoded. +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass = ""); + +/** +* Load a key from a file. +* @param filename the path to the file containing the encoded key +* @param rng the rng to use +* @param ui the user interface to be used for passphrase dialog +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const User_Interface& ui); + +/** Load a key from a file. +* @param filename the path to the file containing the encoded key +* @param rng the rng to use +* @param pass the passphrase to decrypt the key. Provide an empty +* string if the key is not encoded. +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const std::string& pass = ""); + +/** +* Copy an existing encoded key object. +* @param key the key to copy +* @param rng the rng to use +* @return the new copy of the key +*/ +BOTAN_DLL Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng); + +} + +} + +#endif diff --git a/src/pubkey/x509_key.cpp b/src/pubkey/x509_key.cpp new file mode 100644 index 000000000..455e627f3 --- /dev/null +++ b/src/pubkey/x509_key.cpp @@ -0,0 +1,176 @@ +/* +* X.509 Public Key +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace X509 { + +/* +* DER or PEM encode a X.509 public key +*/ +void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) + { + std::auto_ptr encoder(key.x509_encoder()); + if(!encoder.get()) + throw Encoding_Error("X509::encode: Key does not support encoding"); + + MemoryVector der = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(encoder->alg_id()) + .encode(encoder->key_bits(), BIT_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(der, "PUBLIC KEY")); + else + pipe.write(der); + } + +/* +* PEM encode a X.509 public key +*/ +std::string PEM_encode(const Public_Key& key) + { + Pipe pem; + pem.start_msg(); + encode(key, pem, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(DataSource& source) + { + try { + AlgorithmIdentifier alg_id; + MemoryVector key_bits; + + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + { + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .verify_end() + .end_cons(); + } + else + { + DataSource_Memory ber( + PEM_Code::decode_check_label(source, "PUBLIC KEY") + ); + + BER_Decoder(ber) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .verify_end() + .end_cons(); + } + + if(key_bits.is_empty()) + throw Decoding_Error("X.509 public key decoding failed"); + + const std::string alg_name = OIDS::lookup(alg_id.oid); + if(alg_name == "") + throw Decoding_Error("Unknown algorithm OID: " + + alg_id.oid.as_string()); + + std::auto_ptr key_obj(get_public_key(alg_name)); + if(!key_obj.get()) + throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " + + alg_id.oid.as_string()); + + std::auto_ptr decoder(key_obj->x509_decoder()); + + if(!decoder.get()) + throw Decoding_Error("Key does not support X.509 decoding"); + + decoder->alg_id(alg_id); + decoder->key_bits(key_bits); + + return key_obj.release(); + } + catch(Decoding_Error) + { + throw Decoding_Error("X.509 public key decoding failed"); + } + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const std::string& fsname) + { + DataSource_Stream source(fsname, true); + return X509::load_key(source); + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const MemoryRegion& mem) + { + DataSource_Memory source(mem); + return X509::load_key(source); + } + +/* +* Make a copy of this public key +*/ +Public_Key* copy_key(const Public_Key& key) + { + Pipe bits; + bits.start_msg(); + X509::encode(key, bits, RAW_BER); + bits.end_msg(); + DataSource_Memory source(bits.read_all()); + return X509::load_key(source); + } + +/* +* Find the allowable key constraints +*/ +Key_Constraints find_constraints(const Public_Key& pub_key, + Key_Constraints limits) + { + const Public_Key* key = &pub_key; + u32bit constraints = 0; + + if(dynamic_cast(key)) + constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; + + if(dynamic_cast(key)) + constraints |= KEY_AGREEMENT; + + if(dynamic_cast(key) || + dynamic_cast(key)) + constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION; + + if(limits) + constraints &= limits; + + return Key_Constraints(constraints); + } + +} + +} diff --git a/src/pubkey/x509_key.h b/src/pubkey/x509_key.h new file mode 100644 index 000000000..9404b7ecc --- /dev/null +++ b/src/pubkey/x509_key.h @@ -0,0 +1,110 @@ +/* +* X.509 Public Key +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_X509_PUBLIC_KEY_H__ +#define BOTAN_X509_PUBLIC_KEY_H__ + +#include +#include +#include +#include + +namespace Botan { + +/** +* This class represents abstract X.509 public key encoders. +*/ +class BOTAN_DLL X509_Encoder + { + public: + virtual AlgorithmIdentifier alg_id() const = 0; + virtual MemoryVector key_bits() const = 0; + virtual ~X509_Encoder() {} + }; + +/** +* This class represents abstract X.509 public key decoders. +*/ +class BOTAN_DLL X509_Decoder + { + public: + virtual void alg_id(const AlgorithmIdentifier&) = 0; + virtual void key_bits(const MemoryRegion&) = 0; + virtual ~X509_Decoder() {} + }; + +/** +* This namespace contains functions for handling X509 objects. +*/ +namespace X509 { + +/* +* X.509 Public Key Encoding/Decoding +*/ + +/** +* Encode a key into a pipe. +* @param key the public key to encode +* @param pipe the pipe to feed the encoded key into +* @param enc the encoding type to use +*/ +BOTAN_DLL void encode(const Public_Key& key, Pipe& pipe, + X509_Encoding enc = PEM); + +/** +* PEM encode a public key into a string. +* @param key the key to encode +* @return the PEM encoded key +*/ +BOTAN_DLL std::string PEM_encode(const Public_Key& key); + +/** +* Create a public key from a data source. +* @param source the source providing the DER or PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(DataSource& source); + +/** +* Create a public key from a string. +* @param enc the string containing the PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(const std::string& enc); + +/** +* Create a public key from a memory region. +* @param enc the memory region containing the DER or PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(const MemoryRegion& enc); + +/** +* Copy a key. +* @param key the public key to copy +* @return the new public key object +*/ +BOTAN_DLL Public_Key* copy_key(const Public_Key& key); + +/** +* Create the key constraints for a specific public key. +* @param pub_key the public key from which the basic set of +* constraints to be placed in the return value is derived +* @param limits additional limits that will be incorporated into the +* return value +* @return the combination of key type specific constraints and +* additional limits +*/ + +BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, + Key_Constraints limits); + +} + +} + +#endif -- cgit v1.2.3 From 57d64c1026cfa0fba775d393920aebaa02bf0f56 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 21 Jul 2009 04:25:37 +0000 Subject: Move back to pk_codecs, propagate to pubkey-refactor done --- src/pubkey/pk_codecs/pkcs8.cpp | 313 ++++++++++++++++++++++++++++++++++++++ src/pubkey/pk_codecs/pkcs8.h | 182 ++++++++++++++++++++++ src/pubkey/pk_codecs/x509_key.cpp | 176 +++++++++++++++++++++ src/pubkey/pk_codecs/x509_key.h | 110 ++++++++++++++ src/pubkey/pkcs8.cpp | 313 -------------------------------------- src/pubkey/pkcs8.h | 182 ---------------------- src/pubkey/x509_key.cpp | 176 --------------------- src/pubkey/x509_key.h | 110 -------------- 8 files changed, 781 insertions(+), 781 deletions(-) create mode 100644 src/pubkey/pk_codecs/pkcs8.cpp create mode 100644 src/pubkey/pk_codecs/pkcs8.h create mode 100644 src/pubkey/pk_codecs/x509_key.cpp create mode 100644 src/pubkey/pk_codecs/x509_key.h delete mode 100644 src/pubkey/pkcs8.cpp delete mode 100644 src/pubkey/pkcs8.h delete mode 100644 src/pubkey/x509_key.cpp delete mode 100644 src/pubkey/x509_key.h (limited to 'src/pubkey') diff --git a/src/pubkey/pk_codecs/pkcs8.cpp b/src/pubkey/pk_codecs/pkcs8.cpp new file mode 100644 index 000000000..8a464ecfe --- /dev/null +++ b/src/pubkey/pk_codecs/pkcs8.cpp @@ -0,0 +1,313 @@ +/* +* PKCS #8 +* (C) 1999-2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace PKCS8 { + +namespace { + +/* +* Get info from an EncryptedPrivateKeyInfo +*/ +SecureVector PKCS8_extract(DataSource& source, + AlgorithmIdentifier& pbe_alg_id) + { + SecureVector key_data; + + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(pbe_alg_id) + .decode(key_data, OCTET_STRING) + .verify_end(); + + return key_data; + } + +/* +* PEM decode and/or decrypt a private key +*/ +SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, + AlgorithmIdentifier& pk_alg_id) + { + AlgorithmIdentifier pbe_alg_id; + SecureVector key_data, key; + bool is_encrypted = true; + + try { + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + key_data = PKCS8_extract(source, pbe_alg_id); + else + { + std::string label; + key_data = PEM_Code::decode(source, label); + if(label == "PRIVATE KEY") + is_encrypted = false; + else if(label == "ENCRYPTED PRIVATE KEY") + { + DataSource_Memory key_source(key_data); + key_data = PKCS8_extract(key_source, pbe_alg_id); + } + else + throw PKCS8_Exception("Unknown PEM label " + label); + } + + if(key_data.is_empty()) + throw PKCS8_Exception("No key data found"); + } + catch(Decoding_Error) + { + throw Decoding_Error("PKCS #8 private key decoding failed"); + } + + if(!is_encrypted) + key = key_data; + + const u32bit MAX_TRIES = 3; + + u32bit tries = 0; + while(true) + { + try { + if(MAX_TRIES && tries >= MAX_TRIES) + break; + + if(is_encrypted) + { + DataSource_Memory params(pbe_alg_id.parameters); + std::auto_ptr pbe(get_pbe(pbe_alg_id.oid, params)); + + User_Interface::UI_Result result = User_Interface::OK; + const std::string passphrase = + ui.get_passphrase("PKCS #8 private key", source.id(), result); + + if(result == User_Interface::CANCEL_ACTION) + break; + + pbe->set_key(passphrase); + Pipe decryptor(pbe.release()); + + decryptor.process_msg(key_data, key_data.size()); + key = decryptor.read_all(); + } + + u32bit version; + + BER_Decoder(key) + .start_cons(SEQUENCE) + .decode(version) + .decode(pk_alg_id) + .decode(key, OCTET_STRING) + .discard_remaining() + .end_cons(); + + if(version != 0) + throw Decoding_Error("PKCS #8: Unknown version number"); + + break; + } + catch(Decoding_Error) + { + ++tries; + } + } + + if(key.is_empty()) + throw Decoding_Error("PKCS #8 private key decoding failed"); + return key; + } + +} + +/* +* DER or PEM encode a PKCS #8 private key +*/ +void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding) + { + std::auto_ptr encoder(key.pkcs8_encoder()); + if(!encoder.get()) + throw Encoding_Error("PKCS8::encode: Key does not support encoding"); + + const u32bit PKCS8_VERSION = 0; + + SecureVector contents = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(PKCS8_VERSION) + .encode(encoder->alg_id()) + .encode(encoder->key_bits(), OCTET_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(contents, "PRIVATE KEY")); + else + pipe.write(contents); + } + +/* +* Encode and encrypt a PKCS #8 private key +*/ +void encrypt_key(const Private_Key& key, + Pipe& pipe, + RandomNumberGenerator& rng, + const std::string& pass, const std::string& pbe_algo, + X509_Encoding encoding) + { + const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"; + + Pipe raw_key; + raw_key.start_msg(); + encode(key, raw_key, RAW_BER); + raw_key.end_msg(); + + std::auto_ptr pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); + + pbe->new_params(rng); + pbe->set_key(pass); + + AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); + + Pipe key_encrytor(pbe.release()); + key_encrytor.process_msg(raw_key); + + SecureVector enc_key = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(pbe_algid) + .encode(key_encrytor.read_all(), OCTET_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(enc_key, "ENCRYPTED PRIVATE KEY")); + else + pipe.write(enc_key); + } + +/* +* PEM encode a PKCS #8 private key +*/ +std::string PEM_encode(const Private_Key& key) + { + Pipe pem; + pem.start_msg(); + encode(key, pem, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Encrypt and PEM encode a PKCS #8 private key +*/ +std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo) + { + if(pass == "") + return PEM_encode(key); + + Pipe pem; + pem.start_msg(); + encrypt_key(key, pem, rng, pass, pbe_algo, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const User_Interface& ui) + { + AlgorithmIdentifier alg_id; + SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); + + const std::string alg_name = OIDS::lookup(alg_id.oid); + if(alg_name == "" || alg_name == alg_id.oid.as_string()) + throw PKCS8_Exception("Unknown algorithm OID: " + + alg_id.oid.as_string()); + + std::auto_ptr key(get_private_key(alg_name)); + + if(!key.get()) + throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " + + alg_id.oid.as_string()); + + std::auto_ptr decoder(key->pkcs8_decoder(rng)); + + if(!decoder.get()) + throw Decoding_Error("Key does not support PKCS #8 decoding"); + + decoder->alg_id(alg_id); + decoder->key_bits(pkcs8_key); + + return key.release(); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + const User_Interface& ui) + { + DataSource_Stream source(fsname, true); + return PKCS8::load_key(source, rng, ui); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass) + { + return PKCS8::load_key(source, rng, User_Interface(pass)); + } + +/* +* Extract a private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + const std::string& pass) + { + return PKCS8::load_key(fsname, rng, User_Interface(pass)); + } + +/* +* Make a copy of this private key +*/ +Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng) + { + Pipe bits; + + bits.start_msg(); + PKCS8::encode(key, bits); + bits.end_msg(); + + DataSource_Memory source(bits.read_all()); + return PKCS8::load_key(source, rng); + } + +} + +} diff --git a/src/pubkey/pk_codecs/pkcs8.h b/src/pubkey/pk_codecs/pkcs8.h new file mode 100644 index 000000000..87f8ba326 --- /dev/null +++ b/src/pubkey/pk_codecs/pkcs8.h @@ -0,0 +1,182 @@ +/* +* PKCS #8 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PKCS8_H__ +#define BOTAN_PKCS8_H__ + +#include +#include + +namespace Botan { + +/** +* PKCS #8 Private Key Encoder. +*/ +class BOTAN_DLL PKCS8_Encoder + { + public: + /** + * Get the algorithm identifier associated with the scheme + * this encoders key is part of. + * @return the algorithm identifier + */ + virtual AlgorithmIdentifier alg_id() const = 0; + + /** + * Get the DER encoded key. + * @return the DER encoded key + */ + // XXX: Why not SecureVector? + virtual MemoryVector key_bits() const = 0; + virtual ~PKCS8_Encoder() {} + }; + +/* +* PKCS #8 Private Key Decoder +*/ +class BOTAN_DLL PKCS8_Decoder + { + public: + /** + * Set the algorithm identifier associated with the scheme + * this decoders key is part of. + * @param alg_id the algorithm identifier + */ + virtual void alg_id(const AlgorithmIdentifier&) = 0; + + /** + * Set the DER encoded key. + * @param key the DER encoded key + */ + virtual void key_bits(const MemoryRegion&) = 0; + virtual ~PKCS8_Decoder() {} + }; + +/** +* PKCS #8 General Exception +*/ +struct BOTAN_DLL PKCS8_Exception : public Decoding_Error + { + PKCS8_Exception(const std::string& error) : + Decoding_Error("PKCS #8: " + error) {} + }; + +namespace PKCS8 { + +/** +* Encode a private key into a pipe. +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param enc the encoding type to use +*/ +BOTAN_DLL void encode(const Private_Key& key, Pipe& pipe, + X509_Encoding enc = PEM); + +/** +* Encode and encrypt a private key into a pipe. +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param pass the password to use for encryption +* @param rng the rng to use +* @param pbe_algo the name of the desired password-based encryption algorithm. +* Provide an empty string to use the default PBE defined in the configuration +* under base/default_pbe. +* @param enc the encoding type to use +*/ +BOTAN_DLL void encrypt_key(const Private_Key& key, + Pipe& pipe, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = "", + X509_Encoding enc = PEM); + + +/** +* Get a string containing a PEM encoded private key. +* @param key the key to encode +* @return the encoded key +*/ +BOTAN_DLL std::string PEM_encode(const Private_Key& key); + +/** +* Get a string containing a PEM encoded private key, encrypting it with a +* password. +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbe_algo the name of the desired password-based encryption algorithm. +* Provide an empty string to use the default PBE defined in the configuration +* under base/default_pbe. +*/ +BOTAN_DLL std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = ""); + +BOTAN_DLL std::string PEM_encode(const Private_Key&, + const std::string&, + const std::string& = ""); + + +/** +* Load a key from a data source. +* @param source the data source providing the encoded key +* @param rng the rng to use +* @param ui the user interface to be used for passphrase dialog +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const User_Interface& ui); + +/** Load a key from a data source. +* @param source the data source providing the encoded key +* @param rng the rng to use +* @param pass the passphrase to decrypt the key. Provide an empty +* string if the key is not encoded. +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass = ""); + +/** +* Load a key from a file. +* @param filename the path to the file containing the encoded key +* @param rng the rng to use +* @param ui the user interface to be used for passphrase dialog +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const User_Interface& ui); + +/** Load a key from a file. +* @param filename the path to the file containing the encoded key +* @param rng the rng to use +* @param pass the passphrase to decrypt the key. Provide an empty +* string if the key is not encoded. +* @return the loaded private key object +*/ +BOTAN_DLL Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const std::string& pass = ""); + +/** +* Copy an existing encoded key object. +* @param key the key to copy +* @param rng the rng to use +* @return the new copy of the key +*/ +BOTAN_DLL Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng); + +} + +} + +#endif diff --git a/src/pubkey/pk_codecs/x509_key.cpp b/src/pubkey/pk_codecs/x509_key.cpp new file mode 100644 index 000000000..455e627f3 --- /dev/null +++ b/src/pubkey/pk_codecs/x509_key.cpp @@ -0,0 +1,176 @@ +/* +* X.509 Public Key +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace X509 { + +/* +* DER or PEM encode a X.509 public key +*/ +void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) + { + std::auto_ptr encoder(key.x509_encoder()); + if(!encoder.get()) + throw Encoding_Error("X509::encode: Key does not support encoding"); + + MemoryVector der = + DER_Encoder() + .start_cons(SEQUENCE) + .encode(encoder->alg_id()) + .encode(encoder->key_bits(), BIT_STRING) + .end_cons() + .get_contents(); + + if(encoding == PEM) + pipe.write(PEM_Code::encode(der, "PUBLIC KEY")); + else + pipe.write(der); + } + +/* +* PEM encode a X.509 public key +*/ +std::string PEM_encode(const Public_Key& key) + { + Pipe pem; + pem.start_msg(); + encode(key, pem, PEM); + pem.end_msg(); + return pem.read_all_as_string(); + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(DataSource& source) + { + try { + AlgorithmIdentifier alg_id; + MemoryVector key_bits; + + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + { + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .verify_end() + .end_cons(); + } + else + { + DataSource_Memory ber( + PEM_Code::decode_check_label(source, "PUBLIC KEY") + ); + + BER_Decoder(ber) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .verify_end() + .end_cons(); + } + + if(key_bits.is_empty()) + throw Decoding_Error("X.509 public key decoding failed"); + + const std::string alg_name = OIDS::lookup(alg_id.oid); + if(alg_name == "") + throw Decoding_Error("Unknown algorithm OID: " + + alg_id.oid.as_string()); + + std::auto_ptr key_obj(get_public_key(alg_name)); + if(!key_obj.get()) + throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " + + alg_id.oid.as_string()); + + std::auto_ptr decoder(key_obj->x509_decoder()); + + if(!decoder.get()) + throw Decoding_Error("Key does not support X.509 decoding"); + + decoder->alg_id(alg_id); + decoder->key_bits(key_bits); + + return key_obj.release(); + } + catch(Decoding_Error) + { + throw Decoding_Error("X.509 public key decoding failed"); + } + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const std::string& fsname) + { + DataSource_Stream source(fsname, true); + return X509::load_key(source); + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const MemoryRegion& mem) + { + DataSource_Memory source(mem); + return X509::load_key(source); + } + +/* +* Make a copy of this public key +*/ +Public_Key* copy_key(const Public_Key& key) + { + Pipe bits; + bits.start_msg(); + X509::encode(key, bits, RAW_BER); + bits.end_msg(); + DataSource_Memory source(bits.read_all()); + return X509::load_key(source); + } + +/* +* Find the allowable key constraints +*/ +Key_Constraints find_constraints(const Public_Key& pub_key, + Key_Constraints limits) + { + const Public_Key* key = &pub_key; + u32bit constraints = 0; + + if(dynamic_cast(key)) + constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; + + if(dynamic_cast(key)) + constraints |= KEY_AGREEMENT; + + if(dynamic_cast(key) || + dynamic_cast(key)) + constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION; + + if(limits) + constraints &= limits; + + return Key_Constraints(constraints); + } + +} + +} diff --git a/src/pubkey/pk_codecs/x509_key.h b/src/pubkey/pk_codecs/x509_key.h new file mode 100644 index 000000000..9404b7ecc --- /dev/null +++ b/src/pubkey/pk_codecs/x509_key.h @@ -0,0 +1,110 @@ +/* +* X.509 Public Key +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_X509_PUBLIC_KEY_H__ +#define BOTAN_X509_PUBLIC_KEY_H__ + +#include +#include +#include +#include + +namespace Botan { + +/** +* This class represents abstract X.509 public key encoders. +*/ +class BOTAN_DLL X509_Encoder + { + public: + virtual AlgorithmIdentifier alg_id() const = 0; + virtual MemoryVector key_bits() const = 0; + virtual ~X509_Encoder() {} + }; + +/** +* This class represents abstract X.509 public key decoders. +*/ +class BOTAN_DLL X509_Decoder + { + public: + virtual void alg_id(const AlgorithmIdentifier&) = 0; + virtual void key_bits(const MemoryRegion&) = 0; + virtual ~X509_Decoder() {} + }; + +/** +* This namespace contains functions for handling X509 objects. +*/ +namespace X509 { + +/* +* X.509 Public Key Encoding/Decoding +*/ + +/** +* Encode a key into a pipe. +* @param key the public key to encode +* @param pipe the pipe to feed the encoded key into +* @param enc the encoding type to use +*/ +BOTAN_DLL void encode(const Public_Key& key, Pipe& pipe, + X509_Encoding enc = PEM); + +/** +* PEM encode a public key into a string. +* @param key the key to encode +* @return the PEM encoded key +*/ +BOTAN_DLL std::string PEM_encode(const Public_Key& key); + +/** +* Create a public key from a data source. +* @param source the source providing the DER or PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(DataSource& source); + +/** +* Create a public key from a string. +* @param enc the string containing the PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(const std::string& enc); + +/** +* Create a public key from a memory region. +* @param enc the memory region containing the DER or PEM encoded key +* @return the new public key object +*/ +BOTAN_DLL Public_Key* load_key(const MemoryRegion& enc); + +/** +* Copy a key. +* @param key the public key to copy +* @return the new public key object +*/ +BOTAN_DLL Public_Key* copy_key(const Public_Key& key); + +/** +* Create the key constraints for a specific public key. +* @param pub_key the public key from which the basic set of +* constraints to be placed in the return value is derived +* @param limits additional limits that will be incorporated into the +* return value +* @return the combination of key type specific constraints and +* additional limits +*/ + +BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, + Key_Constraints limits); + +} + +} + +#endif diff --git a/src/pubkey/pkcs8.cpp b/src/pubkey/pkcs8.cpp deleted file mode 100644 index 8a464ecfe..000000000 --- a/src/pubkey/pkcs8.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* -* PKCS #8 -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -namespace PKCS8 { - -namespace { - -/* -* Get info from an EncryptedPrivateKeyInfo -*/ -SecureVector PKCS8_extract(DataSource& source, - AlgorithmIdentifier& pbe_alg_id) - { - SecureVector key_data; - - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(pbe_alg_id) - .decode(key_data, OCTET_STRING) - .verify_end(); - - return key_data; - } - -/* -* PEM decode and/or decrypt a private key -*/ -SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, - AlgorithmIdentifier& pk_alg_id) - { - AlgorithmIdentifier pbe_alg_id; - SecureVector key_data, key; - bool is_encrypted = true; - - try { - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - key_data = PKCS8_extract(source, pbe_alg_id); - else - { - std::string label; - key_data = PEM_Code::decode(source, label); - if(label == "PRIVATE KEY") - is_encrypted = false; - else if(label == "ENCRYPTED PRIVATE KEY") - { - DataSource_Memory key_source(key_data); - key_data = PKCS8_extract(key_source, pbe_alg_id); - } - else - throw PKCS8_Exception("Unknown PEM label " + label); - } - - if(key_data.is_empty()) - throw PKCS8_Exception("No key data found"); - } - catch(Decoding_Error) - { - throw Decoding_Error("PKCS #8 private key decoding failed"); - } - - if(!is_encrypted) - key = key_data; - - const u32bit MAX_TRIES = 3; - - u32bit tries = 0; - while(true) - { - try { - if(MAX_TRIES && tries >= MAX_TRIES) - break; - - if(is_encrypted) - { - DataSource_Memory params(pbe_alg_id.parameters); - std::auto_ptr pbe(get_pbe(pbe_alg_id.oid, params)); - - User_Interface::UI_Result result = User_Interface::OK; - const std::string passphrase = - ui.get_passphrase("PKCS #8 private key", source.id(), result); - - if(result == User_Interface::CANCEL_ACTION) - break; - - pbe->set_key(passphrase); - Pipe decryptor(pbe.release()); - - decryptor.process_msg(key_data, key_data.size()); - key = decryptor.read_all(); - } - - u32bit version; - - BER_Decoder(key) - .start_cons(SEQUENCE) - .decode(version) - .decode(pk_alg_id) - .decode(key, OCTET_STRING) - .discard_remaining() - .end_cons(); - - if(version != 0) - throw Decoding_Error("PKCS #8: Unknown version number"); - - break; - } - catch(Decoding_Error) - { - ++tries; - } - } - - if(key.is_empty()) - throw Decoding_Error("PKCS #8 private key decoding failed"); - return key; - } - -} - -/* -* DER or PEM encode a PKCS #8 private key -*/ -void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding) - { - std::auto_ptr encoder(key.pkcs8_encoder()); - if(!encoder.get()) - throw Encoding_Error("PKCS8::encode: Key does not support encoding"); - - const u32bit PKCS8_VERSION = 0; - - SecureVector contents = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(PKCS8_VERSION) - .encode(encoder->alg_id()) - .encode(encoder->key_bits(), OCTET_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(contents, "PRIVATE KEY")); - else - pipe.write(contents); - } - -/* -* Encode and encrypt a PKCS #8 private key -*/ -void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, const std::string& pbe_algo, - X509_Encoding encoding) - { - const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"; - - Pipe raw_key; - raw_key.start_msg(); - encode(key, raw_key, RAW_BER); - raw_key.end_msg(); - - std::auto_ptr pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); - - pbe->new_params(rng); - pbe->set_key(pass); - - AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); - - Pipe key_encrytor(pbe.release()); - key_encrytor.process_msg(raw_key); - - SecureVector enc_key = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(pbe_algid) - .encode(key_encrytor.read_all(), OCTET_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(enc_key, "ENCRYPTED PRIVATE KEY")); - else - pipe.write(enc_key); - } - -/* -* PEM encode a PKCS #8 private key -*/ -std::string PEM_encode(const Private_Key& key) - { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Encrypt and PEM encode a PKCS #8 private key -*/ -std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo) - { - if(pass == "") - return PEM_encode(key); - - Pipe pem; - pem.start_msg(); - encrypt_key(key, pem, rng, pass, pbe_algo, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - AlgorithmIdentifier alg_id; - SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); - - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "" || alg_name == alg_id.oid.as_string()) - throw PKCS8_Exception("Unknown algorithm OID: " + - alg_id.oid.as_string()); - - std::auto_ptr key(get_private_key(alg_name)); - - if(!key.get()) - throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " + - alg_id.oid.as_string()); - - std::auto_ptr decoder(key->pkcs8_decoder(rng)); - - if(!decoder.get()) - throw Decoding_Error("Key does not support PKCS #8 decoding"); - - decoder->alg_id(alg_id); - decoder->key_bits(pkcs8_key); - - return key.release(); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - DataSource_Stream source(fsname, true); - return PKCS8::load_key(source, rng, ui); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(source, rng, User_Interface(pass)); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(fsname, rng, User_Interface(pass)); - } - -/* -* Make a copy of this private key -*/ -Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng) - { - Pipe bits; - - bits.start_msg(); - PKCS8::encode(key, bits); - bits.end_msg(); - - DataSource_Memory source(bits.read_all()); - return PKCS8::load_key(source, rng); - } - -} - -} diff --git a/src/pubkey/pkcs8.h b/src/pubkey/pkcs8.h deleted file mode 100644 index 87f8ba326..000000000 --- a/src/pubkey/pkcs8.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -* PKCS #8 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_PKCS8_H__ -#define BOTAN_PKCS8_H__ - -#include -#include - -namespace Botan { - -/** -* PKCS #8 Private Key Encoder. -*/ -class BOTAN_DLL PKCS8_Encoder - { - public: - /** - * Get the algorithm identifier associated with the scheme - * this encoders key is part of. - * @return the algorithm identifier - */ - virtual AlgorithmIdentifier alg_id() const = 0; - - /** - * Get the DER encoded key. - * @return the DER encoded key - */ - // XXX: Why not SecureVector? - virtual MemoryVector key_bits() const = 0; - virtual ~PKCS8_Encoder() {} - }; - -/* -* PKCS #8 Private Key Decoder -*/ -class BOTAN_DLL PKCS8_Decoder - { - public: - /** - * Set the algorithm identifier associated with the scheme - * this decoders key is part of. - * @param alg_id the algorithm identifier - */ - virtual void alg_id(const AlgorithmIdentifier&) = 0; - - /** - * Set the DER encoded key. - * @param key the DER encoded key - */ - virtual void key_bits(const MemoryRegion&) = 0; - virtual ~PKCS8_Decoder() {} - }; - -/** -* PKCS #8 General Exception -*/ -struct BOTAN_DLL PKCS8_Exception : public Decoding_Error - { - PKCS8_Exception(const std::string& error) : - Decoding_Error("PKCS #8: " + error) {} - }; - -namespace PKCS8 { - -/** -* Encode a private key into a pipe. -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use -*/ -BOTAN_DLL void encode(const Private_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); - -/** -* Encode and encrypt a private key into a pipe. -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param pass the password to use for encryption -* @param rng the rng to use -* @param pbe_algo the name of the desired password-based encryption algorithm. -* Provide an empty string to use the default PBE defined in the configuration -* under base/default_pbe. -* @param enc the encoding type to use -*/ -BOTAN_DLL void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = "", - X509_Encoding enc = PEM); - - -/** -* Get a string containing a PEM encoded private key. -* @param key the key to encode -* @return the encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key); - -/** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption algorithm. -* Provide an empty string to use the default PBE defined in the configuration -* under base/default_pbe. -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = ""); - -BOTAN_DLL std::string PEM_encode(const Private_Key&, - const std::string&, - const std::string& = ""); - - -/** -* Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return the loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Copy an existing encoded key object. -* @param key the key to copy -* @param rng the rng to use -* @return the new copy of the key -*/ -BOTAN_DLL Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng); - -} - -} - -#endif diff --git a/src/pubkey/x509_key.cpp b/src/pubkey/x509_key.cpp deleted file mode 100644 index 455e627f3..000000000 --- a/src/pubkey/x509_key.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* -* X.509 Public Key -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -namespace X509 { - -/* -* DER or PEM encode a X.509 public key -*/ -void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) - { - std::auto_ptr encoder(key.x509_encoder()); - if(!encoder.get()) - throw Encoding_Error("X509::encode: Key does not support encoding"); - - MemoryVector der = - DER_Encoder() - .start_cons(SEQUENCE) - .encode(encoder->alg_id()) - .encode(encoder->key_bits(), BIT_STRING) - .end_cons() - .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(der, "PUBLIC KEY")); - else - pipe.write(der); - } - -/* -* PEM encode a X.509 public key -*/ -std::string PEM_encode(const Public_Key& key) - { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(DataSource& source) - { - try { - AlgorithmIdentifier alg_id; - MemoryVector key_bits; - - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - else - { - DataSource_Memory ber( - PEM_Code::decode_check_label(source, "PUBLIC KEY") - ); - - BER_Decoder(ber) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - - if(key_bits.is_empty()) - throw Decoding_Error("X.509 public key decoding failed"); - - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "") - throw Decoding_Error("Unknown algorithm OID: " + - alg_id.oid.as_string()); - - std::auto_ptr key_obj(get_public_key(alg_name)); - if(!key_obj.get()) - throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " + - alg_id.oid.as_string()); - - std::auto_ptr decoder(key_obj->x509_decoder()); - - if(!decoder.get()) - throw Decoding_Error("Key does not support X.509 decoding"); - - decoder->alg_id(alg_id); - decoder->key_bits(key_bits); - - return key_obj.release(); - } - catch(Decoding_Error) - { - throw Decoding_Error("X.509 public key decoding failed"); - } - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const std::string& fsname) - { - DataSource_Stream source(fsname, true); - return X509::load_key(source); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const MemoryRegion& mem) - { - DataSource_Memory source(mem); - return X509::load_key(source); - } - -/* -* Make a copy of this public key -*/ -Public_Key* copy_key(const Public_Key& key) - { - Pipe bits; - bits.start_msg(); - X509::encode(key, bits, RAW_BER); - bits.end_msg(); - DataSource_Memory source(bits.read_all()); - return X509::load_key(source); - } - -/* -* Find the allowable key constraints -*/ -Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits) - { - const Public_Key* key = &pub_key; - u32bit constraints = 0; - - if(dynamic_cast(key)) - constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; - - if(dynamic_cast(key)) - constraints |= KEY_AGREEMENT; - - if(dynamic_cast(key) || - dynamic_cast(key)) - constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION; - - if(limits) - constraints &= limits; - - return Key_Constraints(constraints); - } - -} - -} diff --git a/src/pubkey/x509_key.h b/src/pubkey/x509_key.h deleted file mode 100644 index 9404b7ecc..000000000 --- a/src/pubkey/x509_key.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -* X.509 Public Key -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_X509_PUBLIC_KEY_H__ -#define BOTAN_X509_PUBLIC_KEY_H__ - -#include -#include -#include -#include - -namespace Botan { - -/** -* This class represents abstract X.509 public key encoders. -*/ -class BOTAN_DLL X509_Encoder - { - public: - virtual AlgorithmIdentifier alg_id() const = 0; - virtual MemoryVector key_bits() const = 0; - virtual ~X509_Encoder() {} - }; - -/** -* This class represents abstract X.509 public key decoders. -*/ -class BOTAN_DLL X509_Decoder - { - public: - virtual void alg_id(const AlgorithmIdentifier&) = 0; - virtual void key_bits(const MemoryRegion&) = 0; - virtual ~X509_Decoder() {} - }; - -/** -* This namespace contains functions for handling X509 objects. -*/ -namespace X509 { - -/* -* X.509 Public Key Encoding/Decoding -*/ - -/** -* Encode a key into a pipe. -* @param key the public key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use -*/ -BOTAN_DLL void encode(const Public_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); - -/** -* PEM encode a public key into a string. -* @param key the key to encode -* @return the PEM encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Public_Key& key); - -/** -* Create a public key from a data source. -* @param source the source providing the DER or PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(DataSource& source); - -/** -* Create a public key from a string. -* @param enc the string containing the PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(const std::string& enc); - -/** -* Create a public key from a memory region. -* @param enc the memory region containing the DER or PEM encoded key -* @return the new public key object -*/ -BOTAN_DLL Public_Key* load_key(const MemoryRegion& enc); - -/** -* Copy a key. -* @param key the public key to copy -* @return the new public key object -*/ -BOTAN_DLL Public_Key* copy_key(const Public_Key& key); - -/** -* Create the key constraints for a specific public key. -* @param pub_key the public key from which the basic set of -* constraints to be placed in the return value is derived -* @param limits additional limits that will be incorporated into the -* return value -* @return the combination of key type specific constraints and -* additional limits -*/ - -BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits); - -} - -} - -#endif -- cgit v1.2.3