aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asn1/ber_dec.cpp3
-rw-r--r--src/asn1/ber_dec.h2
-rw-r--r--src/asn1/der_enc.cpp7
-rw-r--r--src/asn1/der_enc.h1
-rw-r--r--src/libstate/policy.cpp2
-rw-r--r--src/pbe/get_pbe.cpp3
-rw-r--r--src/pbe/pbes2/pbes2.cpp76
-rw-r--r--src/pbe/pbes2/pbes2.h12
8 files changed, 45 insertions, 61 deletions
diff --git a/src/asn1/ber_dec.cpp b/src/asn1/ber_dec.cpp
index 497f2615f..25c412600 100644
--- a/src/asn1/ber_dec.cpp
+++ b/src/asn1/ber_dec.cpp
@@ -221,10 +221,7 @@ BER_Object BER_Decoder::get_next_object()
size_t length = decode_length(source);
next.value.resize(length);
if(source->read(&next.value[0], length) != length)
- {
- abort();
throw BER_Decoding_Error("Value truncated");
- }
if(next.type_tag == EOC && next.class_tag == UNIVERSAL)
return get_next_object();
diff --git a/src/asn1/ber_dec.h b/src/asn1/ber_dec.h
index ee930da21..e9f519d59 100644
--- a/src/asn1/ber_dec.h
+++ b/src/asn1/ber_dec.h
@@ -154,7 +154,7 @@ BER_Decoder& BER_Decoder::decode_optional(T& out,
if(obj.type_tag == type_tag && obj.class_tag == class_tag)
{
- if(class_tag & CONSTRUCTED)
+ if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC))
BER_Decoder(obj.value).decode(out).verify_end();
else
{
diff --git a/src/asn1/der_enc.cpp b/src/asn1/der_enc.cpp
index 594c32539..c451eae34 100644
--- a/src/asn1/der_enc.cpp
+++ b/src/asn1/der_enc.cpp
@@ -357,6 +357,13 @@ DER_Encoder& DER_Encoder::encode_if(bool cond, DER_Encoder& codec)
return (*this);
}
+DER_Encoder& DER_Encoder::encode_if(bool cond, const ASN1_Object& obj)
+ {
+ if(cond)
+ encode(obj);
+ return (*this);
+ }
+
/*
* Request for an object to encode itself
*/
diff --git a/src/asn1/der_enc.h b/src/asn1/der_enc.h
index adab02247..3234445ca 100644
--- a/src/asn1/der_enc.h
+++ b/src/asn1/der_enc.h
@@ -91,6 +91,7 @@ class BOTAN_DLL DER_Encoder
DER_Encoder& encode(const ASN1_Object& obj);
DER_Encoder& encode_if(bool pred, DER_Encoder& enc);
+ DER_Encoder& encode_if(bool pred, const ASN1_Object& obj);
DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
const byte rep[], size_t length);
diff --git a/src/libstate/policy.cpp b/src/libstate/policy.cpp
index 00e95d2c0..527833e61 100644
--- a/src/libstate/policy.cpp
+++ b/src/libstate/policy.cpp
@@ -74,7 +74,7 @@ void set_default_oids(Library_State& config)
add_oid(config, "2.16.840.1.101.3.4.2.3", "SHA-512");
/* MACs */
- add_oid(config, "1.2.840.113549.2.7", "HMAC(SHA-1)");
+ add_oid(config, "1.2.840.113549.2.7", "HMAC(SHA-160)");
add_oid(config, "1.2.840.113549.2.8", "HMAC(SHA-224)");
add_oid(config, "1.2.840.113549.2.9", "HMAC(SHA-256)");
add_oid(config, "1.2.840.113549.2.10", "HMAC(SHA-384)");
diff --git a/src/pbe/get_pbe.cpp b/src/pbe/get_pbe.cpp
index 9ce830639..65c73eb31 100644
--- a/src/pbe/get_pbe.cpp
+++ b/src/pbe/get_pbe.cpp
@@ -17,6 +17,7 @@
#if defined(BOTAN_HAS_PBE_PKCS_V20)
#include <botan/pbes2.h>
+ #include <botan/hmac.h>
#endif
namespace Botan {
@@ -70,7 +71,7 @@ PBE* get_pbe(const std::string& algo_spec,
#if defined(BOTAN_HAS_PBE_PKCS_V20)
if(pbe == "PBE-PKCS5v20")
return new PBE_PKCS5v20(block_cipher->clone(),
- hash_function->clone(),
+ new HMAC(hash_function->clone()),
passphrase,
msec,
rng);
diff --git a/src/pbe/pbes2/pbes2.cpp b/src/pbe/pbes2/pbes2.cpp
index dc8ffbbcd..3d9ebc56e 100644
--- a/src/pbe/pbes2/pbes2.cpp
+++ b/src/pbe/pbes2/pbes2.cpp
@@ -7,7 +7,6 @@
#include <botan/pbes2.h>
#include <botan/pbkdf2.h>
-#include <botan/hmac.h>
#include <botan/cbc.h>
#include <botan/algo_factory.h>
#include <botan/libstate.h>
@@ -89,15 +88,17 @@ std::vector<byte> PBE_PKCS5v20::encode_params() const
.encode(salt, OCTET_STRING)
.encode(iterations)
.encode(key_length)
+ .encode_if(
+ m_prf->name() != "HMAC(SHA-160)",
+ AlgorithmIdentifier(m_prf->name(),
+ AlgorithmIdentifier::USE_NULL_PARAM))
.end_cons()
.get_contents_unlocked()
)
)
.encode(
AlgorithmIdentifier(block_cipher->name() + "/CBC",
- DER_Encoder()
- .encode(iv, OCTET_STRING)
- .get_contents_unlocked()
+ DER_Encoder().encode(iv, OCTET_STRING).get_contents_unlocked()
)
)
.end_cons()
@@ -112,48 +113,29 @@ OID PBE_PKCS5v20::get_oid() const
return OIDS::lookup("PBE-PKCS5v20");
}
-/*
-* Check if this is a known PBES2 cipher
-*/
-bool PBE_PKCS5v20::known_cipher(const std::string& algo)
- {
- if(algo == "AES-128" || algo == "AES-192" || algo == "AES-256")
- return true;
-
- if(algo == "DES" || algo == "TripleDES")
- return true;
-
- return false;
- }
-
std::string PBE_PKCS5v20::name() const
{
return "PBE-PKCS5v20(" + block_cipher->name() + "," +
- hash_function->name() + ")";
+ m_prf->name() + ")";
}
/*
* PKCS#5 v2.0 PBE Constructor
*/
PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher,
- HashFunction* digest,
+ MessageAuthenticationCode* mac,
const std::string& passphrase,
std::chrono::milliseconds msec,
RandomNumberGenerator& rng) :
direction(ENCRYPTION),
block_cipher(cipher),
- hash_function(digest),
+ m_prf(mac),
salt(rng.random_vec(12)),
iv(rng.random_vec(block_cipher->block_size())),
iterations(0),
key_length(block_cipher->maximum_keylength())
{
- if(!known_cipher(block_cipher->name()))
- throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid cipher " + cipher->name());
- if(hash_function->name() != "SHA-160")
- throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid digest " + digest->name());
-
- PKCS5_PBKDF2 pbkdf(new HMAC(hash_function->clone()));
+ PKCS5_PBKDF2 pbkdf(m_prf->clone());
key = pbkdf.derive_key(key_length, passphrase,
&salt[0], salt.size(),
@@ -165,11 +147,10 @@ PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher,
*/
PBE_PKCS5v20::PBE_PKCS5v20(const std::vector<byte>& params,
const std::string& passphrase) :
-direction(DECRYPTION)
+ direction(DECRYPTION),
+ block_cipher(nullptr),
+ m_prf(nullptr)
{
- hash_function = nullptr;
- block_cipher = nullptr;
-
AlgorithmIdentifier kdf_algo, enc_algo;
BER_Decoder(params)
@@ -179,20 +160,23 @@ direction(DECRYPTION)
.verify_end()
.end_cons();
- if(kdf_algo.oid == OIDS::lookup("PKCS5.PBKDF2"))
- {
- BER_Decoder(kdf_algo.parameters)
- .start_cons(SEQUENCE)
- .decode(salt, OCTET_STRING)
- .decode(iterations)
- .decode_optional(key_length, INTEGER, UNIVERSAL)
- .verify_end()
- .end_cons();
- }
- else
+ AlgorithmIdentifier prf_algo;
+
+ if(kdf_algo.oid != OIDS::lookup("PKCS5.PBKDF2"))
throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " +
kdf_algo.oid.as_string());
+ BER_Decoder(kdf_algo.parameters)
+ .start_cons(SEQUENCE)
+ .decode(salt, OCTET_STRING)
+ .decode(iterations)
+ .decode_optional(key_length, INTEGER, UNIVERSAL)
+ .decode_optional(prf_algo, SEQUENCE, CONSTRUCTED,
+ AlgorithmIdentifier("HMAC(SHA-1)",
+ AlgorithmIdentifier::USE_NULL_PARAM))
+ .verify_end()
+ .end_cons();
+
Algorithm_Factory& af = global_state().algorithm_factory();
std::string cipher = OIDS::lookup(enc_algo.oid);
@@ -200,14 +184,14 @@ direction(DECRYPTION)
if(cipher_spec.size() != 2)
throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher);
- if(!known_cipher(cipher_spec[0]) || cipher_spec[1] != "CBC")
+ if(cipher_spec[1] != "CBC")
throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " +
cipher);
BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end();
block_cipher = af.make_block_cipher(cipher_spec[0]);
- hash_function = af.make_hash_function("SHA-160");
+ m_prf = af.make_mac(OIDS::lookup(prf_algo.oid));
if(key_length == 0)
key_length = block_cipher->maximum_keylength();
@@ -215,7 +199,7 @@ direction(DECRYPTION)
if(salt.size() < 8)
throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small");
- PKCS5_PBKDF2 pbkdf(new HMAC(hash_function->clone()));
+ PKCS5_PBKDF2 pbkdf(m_prf->clone());
key = pbkdf.derive_key(key_length, passphrase,
&salt[0], salt.size(),
@@ -224,7 +208,7 @@ direction(DECRYPTION)
PBE_PKCS5v20::~PBE_PKCS5v20()
{
- delete hash_function;
+ delete m_prf;
delete block_cipher;
}
diff --git a/src/pbe/pbes2/pbes2.h b/src/pbe/pbes2/pbes2.h
index 635837b42..4c9eb9b8a 100644
--- a/src/pbe/pbes2/pbes2.h
+++ b/src/pbe/pbes2/pbes2.h
@@ -10,7 +10,7 @@
#include <botan/pbe.h>
#include <botan/block_cipher.h>
-#include <botan/hash.h>
+#include <botan/mac.h>
#include <botan/pipe.h>
namespace Botan {
@@ -21,12 +21,6 @@ namespace Botan {
class BOTAN_DLL PBE_PKCS5v20 : public PBE
{
public:
- /**
- * @param cipher names a block cipher
- * @return true iff PKCS #5 knows how to use this cipher
- */
- static bool known_cipher(const std::string& cipher);
-
OID get_oid() const;
std::vector<byte> encode_params() const;
@@ -49,7 +43,7 @@ class BOTAN_DLL PBE_PKCS5v20 : public PBE
* @param hash the hash function to use
*/
PBE_PKCS5v20(BlockCipher* cipher,
- HashFunction* hash,
+ MessageAuthenticationCode* mac,
const std::string& passphrase,
std::chrono::milliseconds msec,
RandomNumberGenerator& rng);
@@ -60,7 +54,7 @@ class BOTAN_DLL PBE_PKCS5v20 : public PBE
Cipher_Dir direction;
BlockCipher* block_cipher;
- HashFunction* hash_function;
+ MessageAuthenticationCode* m_prf;
secure_vector<byte> salt, key, iv;
size_t iterations, key_length;
Pipe pipe;