diff options
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/pubkey')
19 files changed, 226 insertions, 107 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp index ae6e9c589b..75b0db2f65 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp @@ -93,6 +93,8 @@ class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF [this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); }) {} + size_t agreed_value_size() const override { return m_p.bytes(); } + secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override; private: const BigInt& m_p; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp index abc14ec0c7..8048590448 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp @@ -67,6 +67,7 @@ class DL_Group_Data final size_t p_bits() const { return m_p_bits; } size_t q_bits() const { return m_q_bits; } size_t p_bytes() const { return (m_p_bits + 7) / 8; } + size_t q_bytes() const { return (m_q_bits + 7) / 8; } size_t estimated_strength() const { return m_estimated_strength; } @@ -448,6 +449,12 @@ size_t DL_Group::q_bits() const return data().q_bits(); } +size_t DL_Group::q_bytes() const + { + data().assert_q_is_set("q_bytes"); + return data().q_bytes(); + } + size_t DL_Group::estimated_strength() const { return data().estimated_strength(); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h index 6bc9187613..43756c8065 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h @@ -269,6 +269,13 @@ class BOTAN_PUBLIC_API(2,0) DL_Group final size_t q_bits() const; /** + * Return the size of q in bytes + * Same as get_q().bytes() + * Throws if q is unset + */ + size_t q_bytes() const; + + /** * Return size in bits of a secret exponent * * This attempts to balance between the attack costs of NFS diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp index 35240292c1..4122701730 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp @@ -89,7 +89,8 @@ class DSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA m_b_inv = m_group.inverse_mod_q(m_b); } - size_t max_input_bits() const override { return m_group.get_q().bits(); } + size_t signature_length() const override { return 2*m_group.q_bytes(); } + size_t max_input_bits() const override { return m_group.q_bits(); } secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) override; @@ -157,7 +158,7 @@ class DSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA { } - size_t max_input_bits() const override { return m_group.get_q().bits(); } + size_t max_input_bits() const override { return m_group.q_bits(); } bool with_recovery() const override { return false; } diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp index 586603507e..f4419c7f0b 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp @@ -10,6 +10,7 @@ #include <botan/ec_group.h> #include <botan/internal/point_mul.h> +#include <botan/internal/primality.h> #include <botan/ber_dec.h> #include <botan/der_enc.h> #include <botan/oids.h> @@ -19,12 +20,6 @@ #include <botan/rng.h> #include <vector> -#if defined(BOTAN_HAS_SYSTEM_RNG) - #include <botan/system_rng.h> -#elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) - #include <botan/hmac_drbg.h> -#endif - namespace Botan { class EC_Group_Data final @@ -318,23 +313,7 @@ std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[ .end_cons() .verify_end(); -#if defined(BOTAN_HAS_SYSTEM_RNG) - System_RNG rng; -#elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) - /* - * This is not ideal because the data is attacker controlled, but - * it seems like it would be difficult for someone to come up - * with an valid ASN.1 encoding where the prime happened to pass - * Miller-Rabin test with exactly the values chosen when - * HMAC_DRBG is seeded with the overall data. - */ - HMAC_DRBG rng("SHA-256"); - rng.add_entropy(bits, len); -#else - Null_RNG rng; -#endif - - if(p.bits() < 64 || p.is_negative() || (is_prime(p, rng) == false)) + if(p.bits() < 64 || p.is_negative() || !is_bailie_psw_probable_prime(p)) throw Decoding_Error("Invalid ECC p parameter"); if(a.is_negative() || a >= p) @@ -343,7 +322,7 @@ std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[ if(b <= 0 || b >= p) throw Decoding_Error("Invalid ECC b parameter"); - if(order <= 0) + if(order <= 0 || !is_bailie_psw_probable_prime(order)) throw Decoding_Error("Invalid ECC order parameter"); if(cofactor <= 0 || cofactor >= 16) @@ -547,6 +526,15 @@ const OID& EC_Group::get_curve_oid() const return data().oid(); } +size_t EC_Group::point_size(PointGFp::Compression_Type format) const + { + // Hybrid and standard format are (x,y), compressed is y, +1 format byte + if(format == PointGFp::COMPRESSED) + return (1 + get_p_bytes()); + else + return (1 + 2*get_p_bytes()); + } + PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const { return Botan::OS2ECP(bits, len, data().curve()); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h index f8c1c1a123..8a22cebce1 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h @@ -302,6 +302,8 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final */ PointGFp zero_point() const; + size_t point_size(PointGFp::Compression_Type format) const; + PointGFp OS2ECP(const uint8_t bits[], size_t len) const; template<typename Alloc> diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp index 760f060ced..da3abaacc6 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp @@ -170,7 +170,7 @@ PointGFp_Var_Point_Precompute::PointGFp_Var_Point_Precompute(const PointGFp& poi if(ws.size() < PointGFp::WORKSPACE_SIZE) ws.resize(PointGFp::WORKSPACE_SIZE); - std::vector<PointGFp> U(1U << m_window_bits); + std::vector<PointGFp> U(static_cast<size_t>(1) << m_window_bits); U[0] = point.zero(); U[1] = point; @@ -354,10 +354,10 @@ PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1, H.mult2i(2, ws); } - const uint8_t z1_b = z1.get_substring(z_bits - i - 2, 2); - const uint8_t z2_b = z2.get_substring(z_bits - i - 2, 2); + const uint32_t z1_b = z1.get_substring(z_bits - i - 2, 2); + const uint32_t z2_b = z2.get_substring(z_bits - i - 2, 2); - const uint8_t z12 = (4*z2_b) + z1_b; + const uint32_t z12 = (4*z2_b) + z1_b; // This function is not intended to be const time if(z12) diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp index 2c23c1b47e..767a799bf0 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp @@ -147,8 +147,10 @@ secure_vector<uint8_t> EC_PrivateKey::private_key_bits() const return DER_Encoder() .start_cons(SEQUENCE) .encode(static_cast<size_t>(1)) - .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), - OCTET_STRING) + .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), OCTET_STRING) + .start_cons(ASN1_Tag(1), PRIVATE) + .encode(m_public_key.encode(PointGFp::Compression_Type::UNCOMPRESSED), BIT_STRING) + .end_cons() .end_cons() .get_contents(); } diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp index 59f245a00c..e7e49a74fd 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp @@ -34,6 +34,8 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF m_l_times_priv = m_group.inverse_mod_order(m_group.get_cofactor()) * key.private_value(); } + size_t agreed_value_size() const override { return m_group.get_p_bytes(); } + secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override { PointGFp input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp index 2409d8f0d2..cbb9eba679 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -65,6 +65,8 @@ class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA m_b_inv = m_group.inverse_mod_order(m_b); } + size_t signature_length() const override { return 2*m_group.get_order_bytes(); } + size_t max_input_bits() const override { return m_group.get_order_bits(); } secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len, @@ -106,10 +108,10 @@ ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, m_b = m_group.square_mod_order(m_b); m_b_inv = m_group.square_mod_order(m_b_inv); - m = m_group.multiply_mod_order(m_b, m); - const BigInt xr = m_group.multiply_mod_order(m_x, m_b, r); + m = m_group.multiply_mod_order(m_b, m_group.mod_order(m)); + const BigInt xr_m = m_group.mod_order(m_group.multiply_mod_order(m_x, m_b, r) + m); - const BigInt s = m_group.multiply_mod_order(k_inv, xr + m, m_b_inv); + const BigInt s = m_group.multiply_mod_order(k_inv, xr_m, m_b_inv); // With overwhelming probability, a bug rather than actual zero r/s if(r.is_zero() || s.is_zero()) diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp index cfac722d7c..263263843c 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp @@ -1,6 +1,7 @@ /* * PKCS #5 PBES2 * (C) 1999-2008,2014 Jack Lloyd +* (C) 2018 Ribose Inc * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -23,6 +24,11 @@ namespace Botan { namespace { +bool known_pbes_cipher_mode(const std::string& mode) + { + return (mode == "CBC" || mode == "GCM" || mode == "SIV"); + } + SymmetricKey derive_key(const std::string& passphrase, const AlgorithmIdentifier& kdf_algo, size_t default_key_size) @@ -46,13 +52,11 @@ SymmetricKey derive_key(const std::string& passphrase, if(salt.size() < 8) throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); - const std::string prf = OIDS::lookup(prf_algo.get_oid()); - - std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); - if(key_length == 0) key_length = default_key_size; + const std::string prf = OIDS::lookup(prf_algo.get_oid()); + std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); return pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations); } #if defined(BOTAN_HAS_SCRYPT) @@ -101,24 +105,39 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase, { #if defined(BOTAN_HAS_SCRYPT) - Scrypt_Params params(32768, 8, 4); + std::unique_ptr<PasswordHashFamily> pwhash_fam = PasswordHashFamily::create_or_throw("Scrypt"); + + std::unique_ptr<PasswordHash> pwhash; if(msec_in_iterations_out) - params = Scrypt_Params(std::chrono::milliseconds(*msec_in_iterations_out)); + { + const std::chrono::milliseconds msec(*msec_in_iterations_out); + pwhash = pwhash_fam->tune(key_length, msec); + } else - params = Scrypt_Params(iterations_if_msec_null); + { + pwhash = pwhash_fam->from_iterations(iterations_if_msec_null); + } secure_vector<uint8_t> key(key_length); - scrypt(key.data(), key.size(), passphrase, - salt.data(), salt.size(), params); + pwhash->derive_key(key.data(), key.size(), + passphrase.c_str(), passphrase.size(), + salt.data(), salt.size()); + + const size_t N = pwhash->memory_param(); + const size_t r = pwhash->iterations(); + const size_t p = pwhash->parallelism(); + + if(msec_in_iterations_out) + *msec_in_iterations_out = 0; std::vector<uint8_t> scrypt_params; DER_Encoder(scrypt_params) .start_cons(SEQUENCE) .encode(salt, OCTET_STRING) - .encode(params.N()) - .encode(params.r()) - .encode(params.p()) + .encode(N) + .encode(r) + .encode(p) .encode(key_length) .end_cons(); @@ -131,26 +150,36 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase, else { const std::string prf = "HMAC(" + digest + ")"; + const std::string pbkdf_name = "PBKDF2(" + prf + ")"; - std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); - - size_t iterations = iterations_if_msec_null; + std::unique_ptr<PasswordHashFamily> pwhash_fam = PasswordHashFamily::create(pbkdf_name); + if(!pwhash_fam) + throw Invalid_Argument("Unknown password hash digest " + digest); - secure_vector<uint8_t> key; + std::unique_ptr<PasswordHash> pwhash; if(msec_in_iterations_out) { - std::chrono::milliseconds msec(*msec_in_iterations_out); - key = pbkdf->derive_key(key_length, passphrase, salt.data(), salt.size(), msec, iterations).bits_of(); - *msec_in_iterations_out = iterations; + const std::chrono::milliseconds msec(*msec_in_iterations_out); + pwhash = pwhash_fam->tune(key_length, msec); } else { - key = pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations); + pwhash = pwhash_fam->from_iterations(iterations_if_msec_null); } + secure_vector<uint8_t> key(key_length); + pwhash->derive_key(key.data(), key.size(), + passphrase.c_str(), passphrase.size(), + salt.data(), salt.size()); + std::vector<uint8_t> pbkdf2_params; + const size_t iterations = pwhash->iterations(); + + if(msec_in_iterations_out) + *msec_in_iterations_out = iterations; + DER_Encoder(pbkdf2_params) .start_cons(SEQUENCE) .encode(salt, OCTET_STRING) @@ -181,7 +210,7 @@ pbes2_encrypt_shared(const secure_vector<uint8_t>& key_bits, if(cipher_spec.size() != 2) throw Encoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); - if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") + if(!known_pbes_cipher_mode(cipher_spec[1])) throw Encoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); const OID cipher_oid = OIDS::lookup(cipher); @@ -289,7 +318,7 @@ pbes2_decrypt(const secure_vector<uint8_t>& key_bits, const std::vector<std::string> cipher_spec = split_on(cipher, '/'); if(cipher_spec.size() != 2) throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); - if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") + if(!known_pbes_cipher_mode(cipher_spec[1])) throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); secure_vector<uint8_t> iv; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp index 89ef7c708e..9ea89c59f0 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp @@ -71,7 +71,6 @@ #if defined(BOTAN_HAS_SM2) #include <botan/sm2.h> - #include <botan/sm2_enc.h> #endif #if defined(BOTAN_HAS_OPENSSL) @@ -152,10 +151,8 @@ load_public_key(const AlgorithmIdentifier& alg_id, #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2_Sig") - return std::unique_ptr<Public_Key>(new SM2_Signature_PublicKey(alg_id, key_bits)); - if(alg_name == "SM2_Enc") - return std::unique_ptr<Public_Key>(new SM2_Encryption_PublicKey(alg_id, key_bits)); + if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr<Public_Key>(new SM2_PublicKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_XMSS) @@ -230,10 +227,8 @@ load_private_key(const AlgorithmIdentifier& alg_id, #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2_Sig") - return std::unique_ptr<Private_Key>(new SM2_Signature_PrivateKey(alg_id, key_bits)); - if(alg_name == "SM2_Enc") - return std::unique_ptr<Private_Key>(new SM2_Encryption_PrivateKey(alg_id, key_bits)); + if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr<Private_Key>(new SM2_PrivateKey(alg_id, key_bits)); #endif #if defined(BOTAN_HAS_ELGAMAL) @@ -255,7 +250,7 @@ namespace { std::string default_ec_group_for(const std::string& alg_name) { - if(alg_name == "SM2_Enc" || alg_name == "SM2_Sig") + if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") return "sm2p256v1"; if(alg_name == "GOST-34.10") return "gost_256A"; @@ -341,6 +336,7 @@ create_private_key(const std::string& alg_name, alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || + alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10") @@ -368,10 +364,8 @@ create_private_key(const std::string& alg_name, #endif #if defined(BOTAN_HAS_SM2) - if(alg_name == "SM2_Sig") - return std::unique_ptr<Private_Key>(new SM2_Signature_PrivateKey(rng, ec_group)); - if(alg_name == "SM2_Enc") - return std::unique_ptr<Private_Key>(new SM2_Encryption_PrivateKey(rng, ec_group)); + if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") + return std::unique_ptr<Private_Key>(new SM2_PrivateKey(rng, ec_group)); #endif #if defined(BOTAN_HAS_ECGDSA) diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h index 0aaf0b0dfe..63ef9fa9bd 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h @@ -42,6 +42,8 @@ class BOTAN_PUBLIC_API(2,0) Encryption virtual size_t max_input_bits() const = 0; + virtual size_t ciphertext_length(size_t ptext_len) const = 0; + virtual ~Encryption() = default; }; @@ -55,6 +57,8 @@ class BOTAN_PUBLIC_API(2,0) Decryption const uint8_t ciphertext[], size_t ciphertext_len) = 0; + virtual size_t plaintext_length(size_t ctext_len) const = 0; + virtual ~Decryption() = default; }; @@ -99,6 +103,11 @@ class BOTAN_PUBLIC_API(2,0) Signature */ virtual secure_vector<uint8_t> sign(RandomNumberGenerator& rng) = 0; + /* + * Return an upper bound on the length of the output signature + */ + virtual size_t signature_length() const = 0; + virtual ~Signature() = default; }; @@ -109,8 +118,10 @@ class BOTAN_PUBLIC_API(2,0) Key_Agreement { public: virtual secure_vector<uint8_t> agree(size_t key_len, - const uint8_t other_key[], size_t other_key_len, - const uint8_t salt[], size_t salt_len) = 0; + const uint8_t other_key[], size_t other_key_len, + const uint8_t salt[], size_t salt_len) = 0; + + virtual size_t agreed_value_size() const = 0; virtual ~Key_Agreement() = default; }; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp index 8d3eba6dc7..f6d50256d0 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp @@ -97,7 +97,7 @@ secure_vector<uint8_t> PKCS8_decode( } catch(Decoding_Error& e) { - throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); + throw Decoding_Error("PKCS #8 private key decoding", e); } try @@ -126,7 +126,7 @@ secure_vector<uint8_t> PKCS8_decode( } catch(std::exception& e) { - throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); + throw Decoding_Error("PKCS #8 private key decoding", e); } return key; } @@ -167,7 +167,9 @@ choose_pbe_params(const std::string& pbe_algo, const std::string& key_algo) } SCAN_Name request(pbe_algo); - if(request.algo_name() != "PBE-PKCS5v20" || request.arg_count() != 2) + if(request.arg_count() != 2) + throw Exception("Unsupported PBE " + pbe_algo); + if(request.algo_name() != "PBE-PKCS5v20" && request.algo_name() != "PBES2") throw Exception("Unsupported PBE " + pbe_algo); return std::make_pair(request.arg(0), request.arg(1)); } diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h index 0bc9a18f14..a243c4fda4 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h @@ -180,7 +180,7 @@ PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, /** * Load an encrypted key from a data source. * @param source the data source providing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param get_passphrase a function that returns passphrases * @return loaded private key object */ @@ -190,7 +190,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, /** Load an encrypted key from a data source. * @param source the data source providing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param pass the passphrase to decrypt the key * @return loaded private key object */ @@ -200,7 +200,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, /** Load an unencrypted key from a data source. * @param source the data source providing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @return loaded private key object */ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, @@ -210,7 +210,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, /** * Load an encrypted key from a file. * @param filename the path to the file containing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param get_passphrase a function that returns passphrases * @return loaded private key object */ @@ -220,7 +220,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, /** Load an encrypted key from a file. * @param filename the path to the file containing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @param pass the passphrase to decrypt the key * @return loaded private key object */ @@ -230,7 +230,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, /** Load an unencrypted key from a file. * @param filename the path to the file containing the encoded key -* @param rng ignored for compatability +* @param rng ignored for compatibility * @return loaded private key object */ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, @@ -240,7 +240,7 @@ BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, /** * Copy an existing encoded key object. * @param key the key to copy -* @param rng ignored for compatability +* @param rng ignored for compatibility * @return new copy of the key */ BOTAN_PUBLIC_API(2,0) Private_Key* copy_key(const Private_Key& key, diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp index 99d8927663..bb01705488 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp @@ -96,6 +96,11 @@ PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, PK_Encryptor_EME::~PK_Encryptor_EME() { /* for unique_ptr */ } +size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const + { + return m_op->ciphertext_length(ptext_len); + } + std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const { @@ -119,6 +124,11 @@ PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, PK_Decryptor_EME::~PK_Decryptor_EME() { /* for unique_ptr */ } +size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const + { + return m_op->plaintext_length(ctext_len); + } + secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const { @@ -200,6 +210,11 @@ PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) : m_op(std::move(other.m_op)) {} +size_t PK_Key_Agreement::agreed_value_size() const + { + return m_op->agreed_value_size(); + } + SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], @@ -252,6 +267,22 @@ std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, } +size_t PK_Signer::signature_length() const + { + if(m_sig_format == IEEE_1363) + { + return m_op->signature_length(); + } + else if(m_sig_format == DER_SEQUENCE) + { + // This is a large over-estimate but its easier than computing + // the exact value + return m_op->signature_length() + (8 + 4*m_parts); + } + else + throw Internal_Error("PK_Signer: Invalid signature format enum"); + } + std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) { const std::vector<uint8_t> sig = unlock(m_op->sign(rng)); diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h index a33142079f..2e2557ff88 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h @@ -66,6 +66,11 @@ class BOTAN_PUBLIC_API(2,0) PK_Encryptor */ virtual size_t maximum_input_size() const = 0; + /** + * Return an upper bound on the ciphertext length + */ + virtual size_t ciphertext_length(size_t ctext_len) const = 0; + PK_Encryptor() = default; virtual ~PK_Encryptor() = default; @@ -140,6 +145,12 @@ class BOTAN_PUBLIC_API(2,0) PK_Decryptor const uint8_t required_content_offsets[], size_t required_contents) const; + /** + * Return an upper bound on the plaintext length for a particular + * ciphertext input length + */ + virtual size_t plaintext_length(size_t ctext_len) const = 0; + PK_Decryptor() = default; virtual ~PK_Decryptor() = default; @@ -217,19 +228,12 @@ class BOTAN_PUBLIC_API(2,0) PK_Signer final * @param rng the rng to use * @return signature */ - std::vector<uint8_t> sign_message(const std::vector<uint8_t>& in, - RandomNumberGenerator& rng) - { return sign_message(in.data(), in.size(), rng); } - - /** - * Sign a message. - * @param in the message to sign - * @param rng the rng to use - * @return signature - */ - std::vector<uint8_t> sign_message(const secure_vector<uint8_t>& in, - RandomNumberGenerator& rng) - { return sign_message(in.data(), in.size(), rng); } + template<typename Alloc> + std::vector<uint8_t> sign_message(const std::vector<uint8_t, Alloc>& in, + RandomNumberGenerator& rng) + { + return sign_message(in.data(), in.size(), rng); + } /** * Add a message part (single byte). @@ -248,7 +252,11 @@ class BOTAN_PUBLIC_API(2,0) PK_Signer final * Add a message part. * @param in the message part to add */ - void update(const std::vector<uint8_t>& in) { update(in.data(), in.size()); } + template<typename Alloc> + void update(const std::vector<uint8_t, Alloc>& in) + { + update(in.data(), in.size()); + } /** * Add a message part. @@ -267,11 +275,19 @@ class BOTAN_PUBLIC_API(2,0) PK_Signer final */ std::vector<uint8_t> signature(RandomNumberGenerator& rng); + /** * Set the output format of the signature. * @param format the signature format to use */ void set_output_format(Signature_Format format) { m_sig_format = format; } + + /** + * Return an upper bound on the length of the signatures this + * PK_Signer will produce + */ + size_t signature_length() const; + private: std::unique_ptr<PK_Ops::Signature> m_op; Signature_Format m_sig_format; @@ -347,8 +363,11 @@ class BOTAN_PUBLIC_API(2,0) PK_Verifier final * signature to be verified. * @param in the new message part */ - void update(const std::vector<uint8_t>& in) - { update(in.data(), in.size()); } + template<typename Alloc> + void update(const std::vector<uint8_t, Alloc>& in) + { + update(in.data(), in.size()); + } /** * Add a message part of the message corresponding to the @@ -393,7 +412,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Verifier final }; /** -* Key used for key agreement +* Object used for key agreement */ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final { @@ -435,7 +454,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final PK_Key_Agreement& operator=(const PK_Key_Agreement&) = delete; PK_Key_Agreement(const PK_Key_Agreement&) = delete; - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key @@ -449,11 +468,10 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final const uint8_t params[], size_t params_len) const; - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key - * @param in_len the length of in in bytes * @param params extra derivation params * @param params_len the length of params in bytes */ @@ -466,7 +484,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final params, params_len); } - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key @@ -482,7 +500,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final params.length()); } - /* + /** * Perform Key Agreement Operation * @param key_len the desired key output size * @param in the other parties key @@ -497,6 +515,13 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final params.length()); } + /** + * Return the underlying size of the value that is agreed. + * If derive_key is called with a length of 0 with a "Raw" + * KDF, it will return a value of this size. + */ + size_t agreed_value_size() const; + private: std::unique_ptr<PK_Ops::Key_Agreement> m_op; }; @@ -539,6 +564,12 @@ class BOTAN_PUBLIC_API(2,0) PK_Encryptor_EME final : public PK_Encryptor PK_Encryptor_EME& operator=(const PK_Encryptor_EME&) = delete; PK_Encryptor_EME(const PK_Encryptor_EME&) = delete; + + /** + * Return an upper bound on the ciphertext length for a particular + * plaintext input length + */ + size_t ciphertext_length(size_t ptext_len) const override; private: std::vector<uint8_t> enc(const uint8_t[], size_t, RandomNumberGenerator& rng) const override; @@ -578,6 +609,8 @@ class BOTAN_PUBLIC_API(2,0) PK_Decryptor_EME final : public PK_Decryptor PK_Decryptor_EME(key, system_rng(), eme, provider) {} #endif + size_t plaintext_length(size_t ptext_len) const override; + ~PK_Decryptor_EME(); PK_Decryptor_EME& operator=(const PK_Decryptor_EME&) = delete; PK_Decryptor_EME(const PK_Decryptor_EME&) = delete; diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp index eb4c612ae0..ec3c35ef1c 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp @@ -298,6 +298,8 @@ class RSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA, size_t max_input_bits() const override { return get_max_input_bits(); } + size_t signature_length() const override { return m_key.get_n().bytes(); } + RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string& emsa, RandomNumberGenerator& rng) : PK_Ops::Signature_with_EMSA(emsa), RSA_Private_Operation(rsa, rng) @@ -326,6 +328,8 @@ class RSA_Decryption_Operation final : public PK_Ops::Decryption_with_EME, { } + size_t plaintext_length(size_t) const override { return m_mod_bytes; } + secure_vector<uint8_t> raw_decrypt(const uint8_t msg[], size_t msg_len) override { const BigInt m(msg, msg_len); @@ -403,6 +407,8 @@ class RSA_Encryption_Operation final : public PK_Ops::Encryption_with_EME, { } + size_t ciphertext_length(size_t) const override { return m_n.bytes(); } + size_t max_raw_input_bits() const override { return get_max_input_bits(); } secure_vector<uint8_t> raw_encrypt(const uint8_t msg[], size_t msg_len, diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp index 6e49d953a4..fff75ec441 100644 --- a/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp +++ b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp @@ -62,13 +62,13 @@ Public_Key* load_key(DataSource& source) } if(key_bits.empty()) - throw Decoding_Error("X.509 public key decoding failed"); + throw Decoding_Error("X.509 public key decoding"); return load_public_key(alg_id, key_bits).release(); } catch(Decoding_Error& e) { - throw Decoding_Error("X.509 public key decoding failed: " + std::string(e.what())); + throw Decoding_Error("X.509 public key decoding", e); } } |