diff options
51 files changed, 349 insertions, 238 deletions
diff --git a/configure.py b/configure.py index e04a0b79a..4739a8937 100755 --- a/configure.py +++ b/configure.py @@ -269,9 +269,6 @@ def process_command_line(args): build_group.add_option('--with-debug-info', action='store_true', default=False, dest='with_debug_info', help='enable debug info') - # For compat and convenience: - build_group.add_option('--debug-mode', action='store_true', default=False, dest='with_debug_info', - help=optparse.SUPPRESS_HELP) build_group.add_option('--with-sanitizers', action='store_true', default=False, dest='with_sanitizers', help='enable runtime checks') @@ -290,6 +287,9 @@ def process_command_line(args): action='store_true', default=False, help='disable all optimizations (for debugging)') + build_group.add_option('--debug-mode', action='store_true', default=False, dest='debug_mode', + help='enable debug info and disable optimizations') + build_group.add_option('--gen-amalgamation', dest='gen_amalgamation', default=False, action='store_true', help='generate amalgamation files') @@ -451,6 +451,10 @@ def process_command_line(args): raise Exception('Bad value to --with-endian "%s"' % ( options.with_endian)) + if options.debug_mode: + options.no_optimizations = True + options.with_debug_info = True + def parse_multiple_enable(modules): if modules is None: return [] diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index a1d8890db..6412fdcdf 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -167,6 +167,22 @@ softare-based entropy polling is still used. */ #define BOTAN_ENTROPY_ESTIMATE_HARDWARE_RNG 0.0 +/* +How often should the RdRand/RdSeed RNGs be polled + +Each poll generates 32 bit entropy +*/ +#define BOTAN_ENTROPY_INTEL_RNG_POLLS 32 + +// According to Intel RdRand is guaranteed to generate a random number within 10 retries on a working CPU +#define BOTAN_ENTROPY_RDRAND_RETRIES 10 + +/* +* RdSeed is not guaranteed to generate a random number within a specific number of retries +* Define the number of retries here +*/ +#define BOTAN_ENTROPY_RDSEED_RETRIES 20 + // The output of a PRNG we are trusting to be strong #define BOTAN_ENTROPY_ESTIMATE_STRONG_RNG 7.0 diff --git a/src/lib/asn1/alg_id.cpp b/src/lib/asn1/alg_id.cpp index 7d476a225..75ea78c18 100644 --- a/src/lib/asn1/alg_id.cpp +++ b/src/lib/asn1/alg_id.cpp @@ -16,32 +16,24 @@ namespace Botan { * Create an AlgorithmIdentifier */ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, - const std::vector<byte>& param) - { - oid = alg_id; - parameters = param; - } + const std::vector<byte>& param) : oid(alg_id), parameters(param) + {} /* * Create an AlgorithmIdentifier */ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, - const std::vector<byte>& param) - { - oid = OIDS::lookup(alg_id); - parameters = param; - } + const std::vector<byte>& param) : oid(OIDS::lookup(alg_id)), parameters(param) + {} /* * Create an AlgorithmIdentifier */ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, - Encoding_Option option) + Encoding_Option option) : oid(alg_id), parameters() { const byte DER_NULL[] = { 0x05, 0x00 }; - oid = alg_id; - if(option == USE_NULL_PARAM) parameters += std::pair<const byte*, size_t>(DER_NULL, sizeof(DER_NULL)); } @@ -50,12 +42,10 @@ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, * Create an AlgorithmIdentifier */ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, - Encoding_Option option) + Encoding_Option option) : oid(OIDS::lookup(alg_id)), parameters() { const byte DER_NULL[] = { 0x05, 0x00 }; - oid = OIDS::lookup(alg_id); - if(option == USE_NULL_PARAM) parameters += std::pair<const byte*, size_t>(DER_NULL, sizeof(DER_NULL)); } diff --git a/src/lib/asn1/asn1_attribute.cpp b/src/lib/asn1/asn1_attribute.cpp index 406a57d9a..bd7e5bf11 100644 --- a/src/lib/asn1/asn1_attribute.cpp +++ b/src/lib/asn1/asn1_attribute.cpp @@ -15,21 +15,15 @@ namespace Botan { /* * Create an Attribute */ -Attribute::Attribute(const OID& attr_oid, const std::vector<byte>& attr_value) - { - oid = attr_oid; - parameters = attr_value; - } +Attribute::Attribute(const OID& attr_oid, const std::vector<byte>& attr_value) : oid(attr_oid), parameters(attr_value) + {} /* * Create an Attribute */ Attribute::Attribute(const std::string& attr_oid, - const std::vector<byte>& attr_value) - { - oid = OIDS::lookup(attr_oid); - parameters = attr_value; - } + const std::vector<byte>& attr_value) : oid(OIDS::lookup(attr_oid)), parameters(attr_value) + {} /* * DER encode a Attribute diff --git a/src/lib/asn1/asn1_str.cpp b/src/lib/asn1/asn1_str.cpp index 809448888..c378d5dfe 100644 --- a/src/lib/asn1/asn1_str.cpp +++ b/src/lib/asn1/asn1_str.cpp @@ -62,9 +62,8 @@ ASN1_Tag choose_encoding(const std::string& str, /* * Create an ASN1_String */ -ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_tag(t) +ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_iso_8859_str(Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET)), m_tag(t) { - m_iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET); if(m_tag == DIRECTORY_STRING) m_tag = choose_encoding(m_iso_8859_str, "latin1"); @@ -83,11 +82,8 @@ ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_tag(t) /* * Create an ASN1_String */ -ASN1_String::ASN1_String(const std::string& str) - { - m_iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET); - m_tag = choose_encoding(m_iso_8859_str, "latin1"); - } +ASN1_String::ASN1_String(const std::string& str) : m_iso_8859_str(Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET)), m_tag(choose_encoding(m_iso_8859_str, "latin1")) + {} /* * Return this string in ISO 8859-1 encoding @@ -141,7 +137,7 @@ void ASN1_String::decode_from(BER_Decoder& source) charset_is = LATIN1_CHARSET; *this = ASN1_String( - Charset::transcode(ASN1::to_string(obj), charset_is, LOCAL_CHARSET), + Charset::transcode(ASN1::to_string(obj), LOCAL_CHARSET, charset_is), obj.type_tag); } diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h index 162770730..ebc23bfca 100644 --- a/src/lib/base/algo_registry.h +++ b/src/lib/base/algo_registry.h @@ -213,7 +213,7 @@ class Algo_Registry }; template<typename T> T* -make_a(const typename T::Spec& spec, const std::string provider = "") +make_a(const typename T::Spec& spec, const std::string& provider = "") { return Algo_Registry<T>::global_registry().make(spec, provider); } diff --git a/src/lib/base/scan_name.cpp b/src/lib/base/scan_name.cpp index 4688d0871..08f5e8702 100644 --- a/src/lib/base/scan_name.cpp +++ b/src/lib/base/scan_name.cpp @@ -70,10 +70,8 @@ SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec)) { } -SCAN_Name::SCAN_Name(std::string algo_spec) +SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info() { - m_orig_algo_spec = algo_spec; - std::vector<std::pair<size_t, std::string> > name; size_t level = 0; std::pair<size_t, std::string> accum = std::make_pair(level, ""); diff --git a/src/lib/block/aes/aes.cpp b/src/lib/block/aes/aes.cpp index 6cca701af..aac277b4f 100644 --- a/src/lib/block/aes/aes.cpp +++ b/src/lib/block/aes/aes.cpp @@ -345,6 +345,12 @@ void aes_key_schedule(const byte key[], size_t length, secure_vector<byte>& ME, secure_vector<byte>& MD) { + + // if length is < 4, X = 0, the first for loop is not entered and in + // the second for loop "RC[(i-X)/X]" = division by zero + // But obviously valid aes length values are only 16, 24 and 32 + BOTAN_ASSERT( length >= 4, "aes key length has valid size" ); + static const u32bit RC[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; diff --git a/src/lib/block/aes_ssse3/aes_ssse3.cpp b/src/lib/block/aes_ssse3/aes_ssse3.cpp index fa0cb787c..54e8fcbd8 100644 --- a/src/lib/block/aes_ssse3/aes_ssse3.cpp +++ b/src/lib/block/aes_ssse3/aes_ssse3.cpp @@ -59,8 +59,6 @@ __m128i aes_schedule_transform(__m128i input, __m128i i_1 = _mm_and_si128(low_nibs, input); __m128i i_2 = _mm_srli_epi32(_mm_andnot_si128(low_nibs, input), 4); - input = _mm_and_si128(low_nibs, input); - return _mm_xor_si128( _mm_shuffle_epi8(table_1, i_1), _mm_shuffle_epi8(table_2, i_2)); diff --git a/src/lib/cert/cvc/asn1_eac_str.cpp b/src/lib/cert/cvc/asn1_eac_str.cpp index 0134399d8..72ad24926 100644 --- a/src/lib/cert/cvc/asn1_eac_str.cpp +++ b/src/lib/cert/cvc/asn1_eac_str.cpp @@ -85,7 +85,7 @@ void ASN1_EAC_String::decode_from(BER_Decoder& source) try { *this = ASN1_EAC_String( - Charset::transcode(ASN1::to_string(obj), charset_is, LOCAL_CHARSET), + Charset::transcode(ASN1::to_string(obj), LOCAL_CHARSET, charset_is), obj.type_tag); } catch(Invalid_Argument& inv_arg) diff --git a/src/lib/cert/x509/x509_ext.cpp b/src/lib/cert/x509/x509_ext.cpp index b2a53181b..f8f9adb2b 100644 --- a/src/lib/cert/x509/x509_ext.cpp +++ b/src/lib/cert/x509/x509_ext.cpp @@ -53,14 +53,12 @@ Extensions::Extensions(const Extensions& extensions) : ASN1_Object() * Extensions Assignment Operator */ Extensions& Extensions::operator=(const Extensions& other) - { - for(size_t i = 0; i != m_extensions.size(); ++i) - delete m_extensions[i].first; + { m_extensions.clear(); for(size_t i = 0; i != other.m_extensions.size(); ++i) m_extensions.push_back( - std::make_pair(other.m_extensions[i].first->copy(), + std::make_pair(std::unique_ptr<Certificate_Extension>(other.m_extensions[i].first->copy()), other.m_extensions[i].second)); m_throw_on_unknown_critical = other.m_throw_on_unknown_critical; @@ -78,7 +76,14 @@ OID Certificate_Extension::oid_of() const void Extensions::add(Certificate_Extension* extn, bool critical) { - m_extensions.push_back(std::make_pair(extn, critical)); + m_extensions.push_back(std::make_pair(std::unique_ptr<Certificate_Extension>(extn), critical)); + m_extensions_raw.emplace(extn->oid_of(), std::make_pair(extn->encode_inner(), critical)); + } + + +std::map<OID, std::pair<std::vector<byte>, bool>> Extensions::extensions_raw() const + { + return m_extensions_raw; } /* @@ -88,7 +93,7 @@ void Extensions::encode_into(DER_Encoder& to_object) const { for(size_t i = 0; i != m_extensions.size(); ++i) { - const Certificate_Extension* ext = m_extensions[i].first; + const Certificate_Extension* ext = m_extensions[i].first.get(); const bool is_critical = m_extensions[i].second; const bool should_encode = ext->should_encode(); @@ -109,9 +114,8 @@ void Extensions::encode_into(DER_Encoder& to_object) const */ void Extensions::decode_from(BER_Decoder& from_source) { - for(size_t i = 0; i != m_extensions.size(); ++i) - delete m_extensions[i].first; m_extensions.clear(); + m_extensions_raw.clear(); BER_Decoder sequence = from_source.start_cons(SEQUENCE); @@ -128,7 +132,9 @@ void Extensions::decode_from(BER_Decoder& from_source) .verify_end() .end_cons(); - Certificate_Extension* ext = get_extension(oid); + m_extensions_raw.emplace(oid, std::make_pair(value, critical)); + + std::unique_ptr<Certificate_Extension> ext(get_extension(oid)); if(!ext && critical && m_throw_on_unknown_critical) throw Decoding_Error("Encountered unknown X.509 extension marked " @@ -146,7 +152,7 @@ void Extensions::decode_from(BER_Decoder& from_source) oid.as_string() + ": " + e.what()); } - m_extensions.push_back(std::make_pair(ext, critical)); + m_extensions.push_back(std::make_pair(std::move(ext), critical)); } } @@ -163,14 +169,6 @@ void Extensions::contents_to(Data_Store& subject_info, m_extensions[i].first->contents_to(subject_info, issuer_info); } -/* -* Delete an Extensions list -*/ -Extensions::~Extensions() - { - for(size_t i = 0; i != m_extensions.size(); ++i) - delete m_extensions[i].first; - } namespace Cert_Extension { @@ -309,11 +307,8 @@ void Subject_Key_ID::contents_to(Data_Store& subject, Data_Store&) const /* * Subject_Key_ID Constructor */ -Subject_Key_ID::Subject_Key_ID(const std::vector<byte>& pub_key) - { - SHA_160 hash; - m_key_id = unlock(hash.process(pub_key)); - } +Subject_Key_ID::Subject_Key_ID(const std::vector<byte>& pub_key) : m_key_id(unlock(SHA_160().process(pub_key))) + {} /* * Encode the extension @@ -384,11 +379,8 @@ void Alternative_Name::contents_to(Data_Store& subject_info, * Alternative_Name Constructor */ Alternative_Name::Alternative_Name(const AlternativeName& alt_name, - const std::string& oid_name_str) - { - this->m_alt_name = alt_name; - this->m_oid_name_str = oid_name_str; - } + const std::string& oid_name_str) : m_alt_name(alt_name), m_oid_name_str(oid_name_str) + {} /* * Subject_Alternative_Name Constructor @@ -476,7 +468,7 @@ std::vector<byte> Certificate_Policies::encode_inner() const std::vector<Policy_Information> policies; for(size_t i = 0; i != m_oids.size(); ++i) - policies.push_back(Policy_Information( m_oids[i] )); + policies.push_back(Policy_Information(m_oids[i])); return DER_Encoder() .start_cons(SEQUENCE) diff --git a/src/lib/cert/x509/x509_ext.h b/src/lib/cert/x509/x509_ext.h index 0614b9a52..8d2dcb52b 100644 --- a/src/lib/cert/x509/x509_ext.h +++ b/src/lib/cert/x509/x509_ext.h @@ -67,16 +67,20 @@ class BOTAN_DLL Extensions : public ASN1_Object void add(Certificate_Extension* extn, bool critical = false); + std::map<OID, std::pair<std::vector<byte>, bool>> extensions_raw() const; + Extensions& operator=(const Extensions&); Extensions(const Extensions&); + explicit Extensions(bool st = true) : m_throw_on_unknown_critical(st) {} - ~Extensions(); + private: static Certificate_Extension* get_extension(const OID&); - std::vector<std::pair<Certificate_Extension*, bool> > m_extensions; + std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> m_extensions; bool m_throw_on_unknown_critical; + std::map<OID, std::pair<std::vector<byte>, bool>> m_extensions_raw; }; namespace Cert_Extension { diff --git a/src/lib/cert/x509/x509cert.cpp b/src/lib/cert/x509/x509cert.cpp index cb24a7a03..8d6d9a70a 100644 --- a/src/lib/cert/x509/x509cert.cpp +++ b/src/lib/cert/x509/x509cert.cpp @@ -124,6 +124,7 @@ void X509_Certificate::force_decode() BER_Decoder(v3_exts_data.value).decode(extensions).verify_end(); + m_v3_extensions = extensions.extensions_raw(); extensions.contents_to(m_subject, m_issuer); } else if(v3_exts_data.type_tag != NO_OBJECT) @@ -303,6 +304,11 @@ std::vector<std::string> X509_Certificate::policies() const return lookup_oids(m_subject.get("X509v3.CertificatePolicies")); } +std::map<OID, std::pair<std::vector<byte>, bool>> X509_Certificate::v3_extensions() const + { + return m_v3_extensions; + } + std::string X509_Certificate::ocsp_responder() const { return m_subject.get1("OCSP.responder", ""); diff --git a/src/lib/cert/x509/x509cert.h b/src/lib/cert/x509/x509cert.h index 0329fde47..32f2bba9f 100644 --- a/src/lib/cert/x509/x509cert.h +++ b/src/lib/cert/x509/x509cert.h @@ -178,6 +178,12 @@ class BOTAN_DLL X509_Certificate final : public X509_Object std::vector<std::string> policies() const; /** + * Get all extensions of this certificate indexed by oid. + * @return extension values and critical flag + */ + std::map<OID, std::pair<std::vector<byte>, bool>> v3_extensions() const; + + /** * Return the listed address of an OCSP responder, or empty if not set */ std::string ocsp_responder() const; @@ -240,6 +246,7 @@ class BOTAN_DLL X509_Certificate final : public X509_Object Data_Store m_subject, m_issuer; bool m_self_signed; + std::map<OID, std::pair<std::vector<byte>, bool>> m_v3_extensions; }; /** diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp index 178de245f..54faec7b8 100644 --- a/src/lib/compression/compression.cpp +++ b/src/lib/compression/compression.cpp @@ -56,7 +56,7 @@ void Compression_Alloc_Info::do_free(void* ptr) namespace { -Compressor_Transform* do_make_compressor(const std::string& type, const std::string suffix) +Compressor_Transform* do_make_compressor(const std::string& type, const std::string& suffix) { const std::map<std::string, std::string> trans{ {"zlib", "Zlib"}, diff --git a/src/lib/entropy/rdrand/rdrand.cpp b/src/lib/entropy/rdrand/rdrand.cpp index 24fe98cf8..13263bb63 100644 --- a/src/lib/entropy/rdrand/rdrand.cpp +++ b/src/lib/entropy/rdrand/rdrand.cpp @@ -1,12 +1,14 @@ /* * Entropy Source Using Intel's rdrand instruction * (C) 2012,2015 Jack Lloyd +* (C) 2015 Daniel Neus * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/internal/rdrand.h> #include <botan/cpuid.h> +#include <botan/build.h> #if !defined(BOTAN_USE_GCC_INLINE_ASM) #include <immintrin.h> @@ -14,32 +16,31 @@ namespace Botan { -/* -* Get the timestamp -*/ -void Intel_Rdrand::poll(Entropy_Accumulator& accum) - { +void Intel_Rdrand::poll(Entropy_Accumulator& accum) { if(!CPUID::has_rdrand()) return; - const size_t RDRAND_POLLS = 32; - - for(size_t i = 0; i != RDRAND_POLLS; ++i) + for(size_t i = 0; i != BOTAN_ENTROPY_INTEL_RNG_POLLS; ++i) { - unsigned int r = 0; + for(size_t i = 0; i != BOTAN_ENTROPY_RDRAND_RETRIES; ++i) + { + uint32_t r = 0; #if defined(BOTAN_USE_GCC_INLINE_ASM) - int cf = 0; + int cf = 0; - // Encoding of rdrand %eax - asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" : - "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc"); + // Encoding of rdrand %eax + asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" : + "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc"); #else - int cf = _rdrand32_step(&r); + int cf = _rdrand32_step(&r); #endif - - if(cf == 1) - accum.add(r, BOTAN_ENTROPY_ESTIMATE_HARDWARE_RNG); + if(1 == cf) + { + accum.add(r, BOTAN_ENTROPY_ESTIMATE_HARDWARE_RNG); + break; + } + } } } diff --git a/src/lib/entropy/rdseed/rdseed.cpp b/src/lib/entropy/rdseed/rdseed.cpp index 91306769d..bcef9ad83 100644 --- a/src/lib/entropy/rdseed/rdseed.cpp +++ b/src/lib/entropy/rdseed/rdseed.cpp @@ -7,6 +7,7 @@ #include <botan/internal/rdseed.h> #include <botan/cpuid.h> +#include <botan/build.h> #if !defined(BOTAN_USE_GCC_INLINE_ASM) #include <immintrin.h> @@ -14,32 +15,31 @@ namespace Botan { -/* -* Get the timestamp -*/ -void Intel_Rdseed::poll(Entropy_Accumulator& accum) - { +void Intel_Rdseed::poll(Entropy_Accumulator& accum) { if(!CPUID::has_rdseed()) return; - const size_t RDSEED_POLLS = 32; - - for(size_t i = 0; i != RDSEED_POLLS; ++i) + for(size_t i = 0; i != BOTAN_ENTROPY_INTEL_RNG_POLLS; ++i) { - unsigned int r = 0; + for(size_t i = 0; i != BOTAN_ENTROPY_RDSEED_RETRIES; ++i) + { + uint32_t r = 0; #if defined(BOTAN_USE_GCC_INLINE_ASM) - int cf = 0; + int cf = 0; - // Encoding of rdseed %eax - asm(".byte 0x0F, 0xC7, 0xF8; adcl $0,%1" : - "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc"); + // Encoding of rdseed %eax + asm(".byte 0x0F, 0xC7, 0xF8; adcl $0,%1" : + "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc"); #else - int cf = _rdseed32_step(&r); + int cf = _rdseed32_step(&r); #endif - - if(cf == 1) - accum.add(r, BOTAN_ENTROPY_ESTIMATE_HARDWARE_RNG); + if(1 == cf) + { + accum.add(r, BOTAN_ENTROPY_ESTIMATE_HARDWARE_RNG); + break; + } + } } } diff --git a/src/lib/entropy/win32_stats/es_win32.cpp b/src/lib/entropy/win32_stats/es_win32.cpp index 7cb0988db..ce0edea83 100644 --- a/src/lib/entropy/win32_stats/es_win32.cpp +++ b/src/lib/entropy/win32_stats/es_win32.cpp @@ -72,7 +72,6 @@ void Win32_EntropySource::poll(Entropy_Accumulator& accum) if(!accum.polling_finished()) { - size_t heap_lists_found = 0; HEAPLIST32 heap_list; heap_list.dwSize = sizeof(HEAPLIST32); @@ -81,6 +80,7 @@ void Win32_EntropySource::poll(Entropy_Accumulator& accum) if(Heap32ListFirst(snapshot, &heap_list)) { + size_t heap_lists_found = 0; do { accum.add(heap_list, BOTAN_ENTROPY_ESTIMATE_SYSTEM_DATA); @@ -88,12 +88,12 @@ void Win32_EntropySource::poll(Entropy_Accumulator& accum) if(++heap_lists_found > HEAP_LISTS_MAX) break; - size_t heap_objs_found = 0; HEAPENTRY32 heap_entry; heap_entry.dwSize = sizeof(HEAPENTRY32); if(Heap32First(&heap_entry, heap_list.th32ProcessID, heap_list.th32HeapID)) { + size_t heap_objs_found = 0; do { if(heap_objs_found++ > HEAP_OBJS_PER_LIST) diff --git a/src/lib/filters/filter.cpp b/src/lib/filters/filter.cpp index 18ea02b9e..6ae713314 100644 --- a/src/lib/filters/filter.cpp +++ b/src/lib/filters/filter.cpp @@ -6,7 +6,6 @@ */ #include <botan/filter.h> -#include <botan/secqueue.h> #include <botan/exceptn.h> namespace Botan { diff --git a/src/lib/filters/pipe_rw.cpp b/src/lib/filters/pipe_rw.cpp index 4d31f43f5..646752e7c 100644 --- a/src/lib/filters/pipe_rw.cpp +++ b/src/lib/filters/pipe_rw.cpp @@ -8,7 +8,6 @@ #include <botan/pipe.h> #include <botan/internal/out_buf.h> -#include <botan/secqueue.h> namespace Botan { diff --git a/src/lib/filters/secqueue.cpp b/src/lib/filters/secqueue.cpp index 4546ae398..6f4070813 100644 --- a/src/lib/filters/secqueue.cpp +++ b/src/lib/filters/secqueue.cpp @@ -104,6 +104,7 @@ void SecureQueue::destroy() SecureQueue& SecureQueue::operator=(const SecureQueue& input) { destroy(); + m_bytes_read = input.get_bytes_read(); m_head = m_tail = new SecureQueueNode; SecureQueueNode* temp = input.m_head; while(temp) diff --git a/src/lib/hash/md2/md2.h b/src/lib/hash/md2/md2.h index ab29a49cb..58629495a 100644 --- a/src/lib/hash/md2/md2.h +++ b/src/lib/hash/md2/md2.h @@ -25,7 +25,7 @@ class BOTAN_DLL MD2 final : public HashFunction void clear() override; - MD2() : m_X(48), m_checksum(16), m_buffer(16) + MD2() : m_X(48), m_checksum(16), m_buffer(16), m_position(0) { clear(); } private: void add_data(const byte[], size_t) override; diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index bb5643b59..a3917141d 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -38,7 +38,7 @@ namespace Botan { std::unique_ptr<MessageAuthenticationCode> MessageAuthenticationCode::create(const std::string& algo_spec, const std::string& provider) { - return std::unique_ptr<MessageAuthenticationCode>(make_a<MessageAuthenticationCode>(Botan::MessageAuthenticationCode::Spec(algo_spec), provider)); + return std::unique_ptr<MessageAuthenticationCode>(make_a<MessageAuthenticationCode>(MessageAuthenticationCode::Spec(algo_spec), provider)); } std::vector<std::string> MessageAuthenticationCode::providers(const std::string& algo_spec) diff --git a/src/lib/math/numbertheory/pow_mod.cpp b/src/lib/math/numbertheory/pow_mod.cpp index 49ff6cca2..5503f313c 100644 --- a/src/lib/math/numbertheory/pow_mod.cpp +++ b/src/lib/math/numbertheory/pow_mod.cpp @@ -34,10 +34,15 @@ Power_Mod::Power_Mod(const Power_Mod& other) */ Power_Mod& Power_Mod::operator=(const Power_Mod& other) { - delete m_core; - m_core = nullptr; - if(other.m_core) - m_core = other.m_core->copy(); + if(this != &other) + { + delete m_core; + m_core = nullptr; + if(other.m_core) + { + m_core = other.m_core->copy(); + } + } return (*this); } diff --git a/src/lib/math/numbertheory/powm_fw.cpp b/src/lib/math/numbertheory/powm_fw.cpp index 02e9bbe83..7369959a9 100644 --- a/src/lib/math/numbertheory/powm_fw.cpp +++ b/src/lib/math/numbertheory/powm_fw.cpp @@ -60,10 +60,7 @@ BigInt Fixed_Window_Exponentiator::execute() const */ Fixed_Window_Exponentiator::Fixed_Window_Exponentiator(const BigInt& n, Power_Mod::Usage_Hints hints) - { - m_reducer = Modular_Reducer(n); - m_hints = hints; - m_window_bits = 0; - } + : m_reducer{Modular_Reducer(n)}, m_exp{}, m_window_bits{}, m_g{}, m_hints{hints} + {} } diff --git a/src/lib/pubkey/blinding.cpp b/src/lib/pubkey/blinding.cpp index 4a5c5acff..b20a30fa1 100644 --- a/src/lib/pubkey/blinding.cpp +++ b/src/lib/pubkey/blinding.cpp @@ -19,11 +19,8 @@ namespace Botan { Blinder::Blinder(const BigInt& modulus, std::function<BigInt (const BigInt&)> fwd, std::function<BigInt (const BigInt&)> inv) : - m_fwd_fn(fwd), m_inv_fn(inv) + m_reducer{Modular_Reducer(modulus)}, m_rng{}, m_fwd_fn(fwd), m_inv_fn(inv), m_modulus_bits{modulus.bits()}, m_e{}, m_d{}, m_counter{} { - m_reducer = Modular_Reducer(modulus); - m_modulus_bits = modulus.bits(); - #if defined(BOTAN_HAS_SYSTEM_RNG) m_rng.reset(new System_RNG); #else diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index 63b7bd07e..471189cd8 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -140,13 +140,10 @@ class DSA_Verification_Operation : public PK_Ops::Verification_with_EMSA DSA_Verification_Operation(const DSA_PublicKey& dsa, const std::string& emsa) : PK_Ops::Verification_with_EMSA(emsa), - m_q(dsa.group_q()), m_y(dsa.get_y()) - { - m_powermod_g_p = Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p()); - m_powermod_y_p = Fixed_Base_Power_Mod(m_y, dsa.group_p()); - m_mod_p = Modular_Reducer(dsa.group_p()); - m_mod_q = Modular_Reducer(dsa.group_q()); - } + m_q(dsa.group_q()), m_y(dsa.get_y()), m_powermod_g_p{Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p())}, + m_powermod_y_p{Fixed_Base_Power_Mod(m_y, dsa.group_p())}, m_mod_p{Modular_Reducer(dsa.group_p())}, + m_mod_q{Modular_Reducer(dsa.group_q())} + {} size_t message_parts() const override { return 2; } size_t message_part_size() const override { return m_q.bytes(); } diff --git a/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/lib/pubkey/ecc_key/ecc_key.cpp index a3f0ea93d..2dca20725 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.cpp +++ b/src/lib/pubkey/ecc_key/ecc_key.cpp @@ -33,13 +33,8 @@ EC_PublicKey::EC_PublicKey(const EC_Group& dom_par, } EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, - const secure_vector<byte>& key_bits) - { - m_domain_params = EC_Group(alg_id.parameters); - m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - - m_public_key = OS2ECP(key_bits, domain().get_curve()); - } + const secure_vector<byte>& key_bits) : m_domain_params{EC_Group(alg_id.parameters)}, m_public_key{OS2ECP(key_bits, domain().get_curve())}, m_domain_encoding{EC_DOMPAR_ENC_EXPLICIT} + {} bool EC_PublicKey::check_key(RandomNumberGenerator&, bool) const diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h index 3557d0266..3f93a908c 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.h +++ b/src/lib/pubkey/ecc_key/ecc_key.h @@ -81,7 +81,8 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key size_t estimated_strength() const override; protected: - EC_PublicKey() : m_domain_encoding(EC_DOMPAR_ENC_EXPLICIT) {} + EC_PublicKey() : m_domain_params{}, m_public_key{}, m_domain_encoding(EC_DOMPAR_ENC_EXPLICIT) + {} EC_Group m_domain_params; PointGFp m_public_key; diff --git a/src/lib/pubkey/if_algo/if_algo.cpp b/src/lib/pubkey/if_algo/if_algo.cpp index a79cad116..e5f3ae20f 100644 --- a/src/lib/pubkey/if_algo/if_algo.cpp +++ b/src/lib/pubkey/if_algo/if_algo.cpp @@ -97,13 +97,11 @@ IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng, const BigInt& prime2, const BigInt& exp, const BigInt& d_exp, - const BigInt& mod) + const BigInt& mod) : + m_d{ d_exp }, m_p{ prime1 }, m_q{ prime2 }, m_d1{}, m_d2{}, m_c{ inverse_mod( m_q, m_p ) } { - m_p = prime1; - m_q = prime2; - m_e = exp; - m_d = d_exp; m_n = mod.is_nonzero() ? mod : m_p * m_q; + m_e = exp; if(m_d == 0) { @@ -116,7 +114,6 @@ IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng, m_d1 = m_d % (m_p - 1); m_d2 = m_d % (m_q - 1); - m_c = inverse_mod(m_q, m_p); load_check(rng); } diff --git a/src/lib/pubkey/mce/polyn_gf2m.cpp b/src/lib/pubkey/mce/polyn_gf2m.cpp index a957b8cc1..e0d1c5a65 100644 --- a/src/lib/pubkey/mce/polyn_gf2m.cpp +++ b/src/lib/pubkey/mce/polyn_gf2m.cpp @@ -644,13 +644,11 @@ polyn_gf2m::polyn_gf2m(int t, Botan::RandomNumberGenerator& rng, std::shared_ptr coeff(t+1), msp_field(sp_field) { - int i; (*this).set_coef( t, 1); - i = 0; int degree = 0; do { - for (i = 0; i < t; ++i) + for (int i = 0; i < t; ++i) { (*this).set_coef( i, random_code_element(sp_field->get_cardinality(), rng)); } diff --git a/src/lib/pubkey/nr/nr.cpp b/src/lib/pubkey/nr/nr.cpp index 64e08a111..5e2cb1be5 100644 --- a/src/lib/pubkey/nr/nr.cpp +++ b/src/lib/pubkey/nr/nr.cpp @@ -144,13 +144,10 @@ class NR_Verification_Operation : public PK_Ops::Verification_with_EMSA typedef NR_PublicKey Key_Type; NR_Verification_Operation(const NR_PublicKey& nr, const std::string& emsa) : PK_Ops::Verification_with_EMSA(emsa), - m_q(nr.group_q()), m_y(nr.get_y()) - { - m_powermod_g_p = Fixed_Base_Power_Mod(nr.group_g(), nr.group_p()); - m_powermod_y_p = Fixed_Base_Power_Mod(m_y, nr.group_p()); - m_mod_p = Modular_Reducer(nr.group_p()); - m_mod_q = Modular_Reducer(nr.group_q()); - } + m_q(nr.group_q()), m_y(nr.get_y()), m_powermod_g_p{Fixed_Base_Power_Mod(nr.group_g(), nr.group_p())}, + m_powermod_y_p{Fixed_Base_Power_Mod(m_y, nr.group_p())}, m_mod_p{Modular_Reducer(nr.group_p())}, + m_mod_q{Modular_Reducer(nr.group_q())} + {} size_t message_parts() const override { return 2; } size_t message_part_size() const override { return m_q.bytes(); } diff --git a/src/lib/tls/msg_cert_verify.cpp b/src/lib/tls/msg_cert_verify.cpp index be6c8a069..0d157dc57 100644 --- a/src/lib/tls/msg_cert_verify.cpp +++ b/src/lib/tls/msg_cert_verify.cpp @@ -77,12 +77,14 @@ std::vector<byte> Certificate_Verify::serialize() const * Verify a Certificate Verify message */ bool Certificate_Verify::verify(const X509_Certificate& cert, - const Handshake_State& state) const + const Handshake_State& state, + const Policy& policy) const { std::unique_ptr<Public_Key> key(cert.subject_public_key()); std::pair<std::string, Signature_Format> format = - state.understand_sig_format(*key.get(), m_hash_algo, m_sig_algo); + state.parse_sig_format(*key.get(), m_hash_algo, m_sig_algo, + true, policy); PK_Verifier verifier(*key, format.first, format.second); diff --git a/src/lib/tls/msg_finished.cpp b/src/lib/tls/msg_finished.cpp index b837172b6..2d6b11995 100644 --- a/src/lib/tls/msg_finished.cpp +++ b/src/lib/tls/msg_finished.cpp @@ -48,9 +48,8 @@ std::vector<byte> finished_compute_verify(const Handshake_State& state, */ Finished::Finished(Handshake_IO& io, Handshake_State& state, - Connection_Side side) + Connection_Side side) : m_verification_data(finished_compute_verify( state, side )) { - m_verification_data = finished_compute_verify(state, side); state.hash().update(io.send(*this)); } @@ -65,10 +64,8 @@ std::vector<byte> Finished::serialize() const /* * Deserialize a Finished message */ -Finished::Finished(const std::vector<byte>& buf) - { - m_verification_data = buf; - } +Finished::Finished(const std::vector<byte>& buf) : m_verification_data(buf) + {} /* * Verify a Finished message diff --git a/src/lib/tls/msg_server_hello.cpp b/src/lib/tls/msg_server_hello.cpp index f9962a8ee..f8d0c63c7 100644 --- a/src/lib/tls/msg_server_hello.cpp +++ b/src/lib/tls/msg_server_hello.cpp @@ -28,7 +28,7 @@ Server_Hello::Server_Hello(Handshake_IO& io, u16bit ciphersuite, byte compression, bool offer_session_ticket, - const std::string next_protocol) : + const std::string& next_protocol) : m_version(new_session_version), m_session_id(new_session_id), m_random(make_hello_random(rng, policy)), diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index 7389cb35b..98e3ad1f0 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -233,10 +233,12 @@ std::vector<byte> Server_Key_Exchange::serialize() const * Verify a Server Key Exchange message */ bool Server_Key_Exchange::verify(const Public_Key& server_key, - const Handshake_State& state) const + const Handshake_State& state, + const Policy& policy) const { std::pair<std::string, Signature_Format> format = - state.understand_sig_format(server_key, m_hash_algo, m_sig_algo); + state.parse_sig_format(server_key, m_hash_algo, m_sig_algo, + false, policy); PK_Verifier verifier(server_key, format.first, format.second); diff --git a/src/lib/tls/tls_blocking.cpp b/src/lib/tls/tls_blocking.cpp index f88b7896c..a1867b6b5 100644 --- a/src/lib/tls/tls_blocking.cpp +++ b/src/lib/tls/tls_blocking.cpp @@ -20,7 +20,7 @@ Blocking_Client::Blocking_Client(read_fn reader, const Policy& policy, RandomNumberGenerator& rng, const Server_Information& server_info, - const Protocol_Version offer_version, + const Protocol_Version& offer_version, const std::vector<std::string>& next) : m_read(reader), m_channel(writer, @@ -42,7 +42,7 @@ bool Blocking_Client::handshake_cb(const Session& session) return this->handshake_complete(session); } -void Blocking_Client::alert_cb(const Alert alert, const byte[], size_t) +void Blocking_Client::alert_cb(const Alert& alert, const byte[], size_t) { this->alert_notification(alert); } diff --git a/src/lib/tls/tls_blocking.h b/src/lib/tls/tls_blocking.h index 89421f5f5..00e65cbaf 100644 --- a/src/lib/tls/tls_blocking.h +++ b/src/lib/tls/tls_blocking.h @@ -39,7 +39,7 @@ class BOTAN_DLL Blocking_Client const Policy& policy, RandomNumberGenerator& rng, const Server_Information& server_info = Server_Information(), - const Protocol_Version offer_version = Protocol_Version::latest_tls_version(), + const Protocol_Version& offer_version = Protocol_Version::latest_tls_version(), const std::vector<std::string>& next_protos = {}); /** @@ -89,7 +89,7 @@ class BOTAN_DLL Blocking_Client void data_cb(const byte data[], size_t data_len); - void alert_cb(const Alert alert, const byte data[], size_t data_len); + void alert_cb(const Alert& alert, const byte data[], size_t data_len); read_fn m_read; TLS::Client m_channel; diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp index 368e4569e..301c77c6b 100644 --- a/src/lib/tls/tls_client.cpp +++ b/src/lib/tls/tls_client.cpp @@ -51,7 +51,7 @@ Client::Client(output_fn output_fn, const Policy& policy, RandomNumberGenerator& rng, const Server_Information& info, - const Protocol_Version offer_version, + const Protocol_Version& offer_version, const std::vector<std::string>& next_protos, size_t io_buf_sz) : Channel(output_fn, proc_cb, alert_cb, handshake_cb, Channel::handshake_msg_cb(), @@ -75,7 +75,7 @@ Client::Client(output_fn output_fn, const Policy& policy, RandomNumberGenerator& rng, const Server_Information& info, - const Protocol_Version offer_version, + const Protocol_Version& offer_version, const std::vector<std::string>& next_protos) : Channel(output_fn, proc_cb, alert_cb, handshake_cb, hs_msg_cb, session_manager, rng, policy, offer_version.is_datagram_protocol()), @@ -394,7 +394,7 @@ void Client::process_handshake_msg(const Handshake_State* active_state, { const Public_Key& server_key = state.get_server_public_Key(); - if(!state.server_kex()->verify(server_key, state)) + if(!state.server_kex()->verify(server_key, state, policy())) { throw TLS_Exception(Alert::DECRYPT_ERROR, "Bad signature on server key exchange"); diff --git a/src/lib/tls/tls_client.h b/src/lib/tls/tls_client.h index d17ea74d0..45a741878 100644 --- a/src/lib/tls/tls_client.h +++ b/src/lib/tls/tls_client.h @@ -62,7 +62,7 @@ class BOTAN_DLL Client final : public Channel const Policy& policy, RandomNumberGenerator& rng, const Server_Information& server_info = Server_Information(), - const Protocol_Version offer_version = Protocol_Version::latest_tls_version(), + const Protocol_Version& offer_version = Protocol_Version::latest_tls_version(), const std::vector<std::string>& next_protocols = {}, size_t reserved_io_buffer_size = 16*1024 ); @@ -77,7 +77,7 @@ class BOTAN_DLL Client final : public Channel const Policy& policy, RandomNumberGenerator& rng, const Server_Information& server_info = Server_Information(), - const Protocol_Version offer_version = Protocol_Version::latest_tls_version(), + const Protocol_Version& offer_version = Protocol_Version::latest_tls_version(), const std::vector<std::string>& next_protocols = {} ); diff --git a/src/lib/tls/tls_extensions.cpp b/src/lib/tls/tls_extensions.cpp index 35c39ddab..4acf9a6fe 100644 --- a/src/lib/tls/tls_extensions.cpp +++ b/src/lib/tls/tls_extensions.cpp @@ -180,10 +180,8 @@ std::vector<byte> Server_Name_Indicator::serialize() const #if defined(BOTAN_HAS_SRP6) SRP_Identifier::SRP_Identifier(TLS_Data_Reader& reader, - u16bit extension_size) + u16bit extension_size) : m_srp_identifier(reader.get_string(1, 1, 255)) { - m_srp_identifier = reader.get_string(1, 1, 255); - if(m_srp_identifier.size() + 1 != extension_size) throw Decoding_Error("Bad encoding for SRP identifier extension"); } @@ -203,10 +201,8 @@ std::vector<byte> SRP_Identifier::serialize() const #endif Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, - u16bit extension_size) + u16bit extension_size) : m_reneg_data(reader.get_range<byte>(1, 0, 255)) { - m_reneg_data = reader.get_range<byte>(1, 0, 255); - if(m_reneg_data.size() + 1 != extension_size) throw Decoding_Error("Bad encoding for secure renegotiation extn"); } @@ -516,16 +512,12 @@ Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, } Session_Ticket::Session_Ticket(TLS_Data_Reader& reader, - u16bit extension_size) - { - m_ticket = reader.get_elem<byte, std::vector<byte> >(extension_size); - } + u16bit extension_size) : m_ticket(reader.get_elem<byte, std::vector<byte>>(extension_size)) + {} SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, - u16bit extension_size) + u16bit extension_size) : m_pp(reader.get_range<u16bit>(2, 0, 65535)) { - m_pp = reader.get_range<u16bit>(2, 0, 65535); - const std::vector<byte> mki = reader.get_range<byte>(1, 0, 255); if(m_pp.size() * 2 + mki.size() + 3 != extension_size) diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp index 3799c9e7d..67ba43265 100644 --- a/src/lib/tls/tls_handshake_state.cpp +++ b/src/lib/tls/tls_handshake_state.cpp @@ -1,6 +1,6 @@ /* * TLS Handshaking -* (C) 2004-2006,2011,2012,2015 Jack Lloyd +* (C) 2004-2006,2011,2012,2015,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -449,58 +449,111 @@ Handshake_State::choose_sig_format(const Private_Key& key, throw Invalid_Argument(sig_algo + " is invalid/unknown for TLS signatures"); } +namespace { + +bool supported_algos_include( + const std::vector<std::pair<std::string, std::string>>& algos, + const std::string& key_type, + const std::string& hash_type) + { + for(auto&& algo : algos) + { + if(algo.first == hash_type && algo.second == key_type) + { + return true; + } + } + + return false; + } + +} + std::pair<std::string, Signature_Format> -Handshake_State::understand_sig_format(const Public_Key& key, - std::string hash_algo, - std::string sig_algo) const +Handshake_State::parse_sig_format(const Public_Key& key, + const std::string& input_hash_algo, + const std::string& input_sig_algo, + bool for_client_auth, + const Policy& policy) const { - const std::string algo_name = key.algo_name(); + const std::string key_type = key.algo_name(); - /* - FIXME: This should check what was sent against the client hello - preferences, or the certificate request, to ensure it was allowed - by those restrictions. + if(!policy.allowed_signature_method(key_type)) + { + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, + "Rejecting " + key_type + " signature"); + } - Or not? - */ + std::string hash_algo; if(this->version().supports_negotiable_signature_algorithms()) { - if(hash_algo.empty()) + if(input_sig_algo != key_type) + throw Decoding_Error("Counterparty sent inconsistent key and sig types"); + + if(input_hash_algo == "") throw Decoding_Error("Counterparty did not send hash/sig IDS"); - if(sig_algo != algo_name) - throw Decoding_Error("Counterparty sent inconsistent key and sig types"); + hash_algo = input_hash_algo; + + if(for_client_auth && !cert_req()) + { + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, + "No certificate verify set"); + } + + /* + Confirm the signature type we just received against the + supported_algos list that we sent; it better be there. + */ + + const auto supported_algos = + for_client_auth ? cert_req()->supported_algos() : + client_hello()->supported_algos(); + + if(!supported_algos_include(supported_algos, key_type, hash_algo)) + { + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, + "TLS signature extension did not allow for " + + key_type + "/" + hash_algo + " signature"); + } } else { - if(!hash_algo.empty() || !sig_algo.empty()) + if(input_hash_algo != "" || input_sig_algo != "") throw Decoding_Error("Counterparty sent hash/sig IDs with old version"); - } - if(algo_name == "RSA") - { - if(!this->version().supports_negotiable_signature_algorithms()) + if(key_type == "RSA") { hash_algo = "Parallel(MD5,SHA-160)"; } + else if(key_type == "DSA" || key_type == "ECDSA") + { + hash_algo = "SHA-1"; + } + else + { + throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures"); + } + + /* + There is no check on the acceptability of a v1.0/v1.1 hash type, + since it's implicit with use of the protocol + */ + } + if(key_type == "RSA") + { const std::string padding = "EMSA3(" + hash_algo + ")"; return std::make_pair(padding, IEEE_1363); } - else if(algo_name == "DSA" || algo_name == "ECDSA") + else if(key_type == "DSA" || key_type == "ECDSA") { - if(!this->version().supports_negotiable_signature_algorithms()) - { - hash_algo = "SHA-1"; - } - const std::string padding = "EMSA1(" + hash_algo + ")"; - return std::make_pair(padding, DER_SEQUENCE); } - throw Invalid_Argument(algo_name + " is invalid/unknown for TLS signatures"); + throw Invalid_Argument(key_type + " is invalid/unknown for TLS signatures"); } } diff --git a/src/lib/tls/tls_handshake_state.h b/src/lib/tls/tls_handshake_state.h index 6260b090f..2943a8637 100644 --- a/src/lib/tls/tls_handshake_state.h +++ b/src/lib/tls/tls_handshake_state.h @@ -80,9 +80,11 @@ class Handshake_State std::vector<byte> session_ticket() const; std::pair<std::string, Signature_Format> - understand_sig_format(const Public_Key& key, - std::string hash_algo, - std::string sig_algo) const; + parse_sig_format(const Public_Key& key, + const std::string& hash_algo, + const std::string& sig_algo, + bool for_client_auth, + const Policy& policy) const; std::pair<std::string, Signature_Format> choose_sig_format(const Private_Key& key, diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index 281333f88..3bee89e13 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -267,7 +267,7 @@ class Server_Hello final : public Handshake_Message u16bit ciphersuite, byte compression, bool offer_session_ticket, - const std::string next_protocol); + const std::string& next_protocol); Server_Hello(Handshake_IO& io, Handshake_Hash& hash, @@ -395,7 +395,8 @@ class Certificate_Verify final : public Handshake_Message * @param state the handshake state */ bool verify(const X509_Certificate& cert, - const Handshake_State& state) const; + const Handshake_State& state, + const Policy& policy) const; Certificate_Verify(Handshake_IO& io, Handshake_State& state, @@ -463,7 +464,8 @@ class Server_Key_Exchange final : public Handshake_Message const std::vector<byte>& params() const { return m_params; } bool verify(const Public_Key& server_key, - const Handshake_State& state) const; + const Handshake_State& state, + const Policy& policy) const; // Only valid for certain kex types const Private_Key& server_kex_key() const; diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp index 3100db50d..be4c61b16 100644 --- a/src/lib/tls/tls_policy.cpp +++ b/src/lib/tls/tls_policy.cpp @@ -84,6 +84,11 @@ std::vector<std::string> Policy::allowed_signature_methods() const }; } +bool Policy::allowed_signature_method(const std::string& sig_method) const + { + return value_exists(allowed_signature_methods(), sig_method); + } + std::vector<std::string> Policy::allowed_ecc_curves() const { return { diff --git a/src/lib/tls/tls_policy.h b/src/lib/tls/tls_policy.h index 032de81ad..67388b115 100644 --- a/src/lib/tls/tls_policy.h +++ b/src/lib/tls/tls_policy.h @@ -57,6 +57,8 @@ class BOTAN_DLL Policy */ virtual std::vector<std::string> allowed_signature_methods() const; + bool allowed_signature_method(const std::string& sig_method) const; + /** * Return list of ECC curves we are willing to use in order of preference */ @@ -306,10 +308,8 @@ class BOTAN_DLL Text_Policy : public Policy m_kv = read_cfg(iss); } - explicit Text_Policy(std::istream& in) - { - m_kv = read_cfg(in); - } + explicit Text_Policy(std::istream& in) : m_kv(read_cfg(in)) + {} private: diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index 5ababe621..41b14ae08 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -618,7 +618,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state, state.client_certs()->cert_chain(); const bool sig_valid = - state.client_verify()->verify(client_certs[0], state); + state.client_verify()->verify(client_certs[0], state, policy()); state.hash().update(state.handshake_io().format(contents, type)); diff --git a/src/lib/utils/donna128.h b/src/lib/utils/donna128.h index c72ccb55c..c2a3e0d2e 100644 --- a/src/lib/utils/donna128.h +++ b/src/lib/utils/donna128.h @@ -104,8 +104,8 @@ inline u64bit carry_shift(const donna128& a, size_t shift) return (a >> shift).lo(); } -inline u64bit combine_lower(const donna128 a, size_t s1, - const donna128 b, size_t s2) +inline u64bit combine_lower(const donna128& a, size_t s1, + const donna128& b, size_t s2) { donna128 z = (a >> s1) | (b << s2); return z.lo(); diff --git a/src/tests/test_filters.cpp b/src/tests/test_filters.cpp new file mode 100644 index 000000000..35d578789 --- /dev/null +++ b/src/tests/test_filters.cpp @@ -0,0 +1,63 @@ +/* +* (C) 2016 Daniel Neus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "tests.h" + +#if defined(BOTAN_HAS_FILTERS) + #include <botan/secqueue.h> +#endif + +namespace Botan_Tests { + +#if defined(BOTAN_HAS_FILTERS) + +class Filter_Tests : public Test + { + public: + std::vector<Test::Result> run() override + { + std::vector<Test::Result> results; + Test::Result secqueue_result("SecureQueue"); + + try + { + using Botan::SecureQueue; + SecureQueue queue_a; + std::vector<uint8_t> test_data = {0x24, 0xB2, 0xBF, 0xC2, 0xE6, 0xD4, 0x7E, 0x04, 0x67, 0xB3}; + queue_a.write(test_data.data(), test_data.size()); + + secqueue_result.test_eq("size of SecureQueue is correct", queue_a.size(), test_data.size()); + secqueue_result.test_eq("0 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 0); + + uint8_t byte; + size_t bytes_read = queue_a.read_byte(byte); + secqueue_result.test_eq("1 byte read", bytes_read, 1); + + Botan::secure_vector<uint8_t> produced(byte); + Botan::secure_vector<uint8_t> expected(test_data.at(0)); + secqueue_result.test_eq("byte read is correct", produced, expected); + + secqueue_result.test_eq("1 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 1); + + SecureQueue queue_b; + queue_a = queue_b; + secqueue_result.test_eq("bytes_read is set correctly", queue_a.get_bytes_read(), 0); + } + catch (std::exception& e) + { + secqueue_result.test_failure("SecureQueue", e.what()); + } + + results.push_back(secqueue_result); + return results; + } + }; + + BOTAN_REGISTER_TEST("filter", Filter_Tests); + +#endif + +} diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp index 5b750e7fb..ecafb3c7f 100644 --- a/src/tests/unit_ecdsa.cpp +++ b/src/tests/unit_ecdsa.cpp @@ -61,7 +61,7 @@ Test::Result test_hash_larger_than_n() try { - std::vector<byte> signature_224 = pk_signer_224.sign_message(message, Test::rng()); + pk_signer_224.sign_message(message, Test::rng()); result.test_failure("bad key/hash combination not rejected"); } catch(Botan::Encoding_Error) @@ -152,8 +152,6 @@ Test::Result test_ec_sign() { Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); Botan::ECDSA_PrivateKey priv_key(Test::rng(), dom_pars); - std::string pem_encoded_key = Botan::PKCS8::PEM_encode(priv_key); - Botan::PK_Signer signer(priv_key, "EMSA1(SHA-224)"); Botan::PK_Verifier verifier(priv_key, "EMSA1(SHA-224)"); diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp index 0fa208858..f125bfcb5 100644 --- a/src/tests/unit_tls.cpp +++ b/src/tests/unit_tls.cpp @@ -527,7 +527,7 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, { input.resize(needed); Test::rng().randomize(input.data(), input.size()); - needed = client.received_data(input.data(), input.size()); + client.received_data(input.data(), input.size()); } } catch(std::exception&) @@ -567,7 +567,7 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, { input.resize(needed); Test::rng().randomize(input.data(), input.size()); - needed = client.received_data(input.data(), input.size()); + client.received_data(input.data(), input.size()); } } catch(std::exception&) |