diff options
-rw-r--r-- | doc/credits.txt | 3 | ||||
-rw-r--r-- | include/asn1_obj.h | 2 | ||||
-rw-r--r-- | include/parsing.h | 6 | ||||
-rw-r--r-- | include/x509self.h | 2 | ||||
-rw-r--r-- | src/asn1_alt.cpp | 29 | ||||
-rw-r--r-- | src/init_def.cpp | 7 | ||||
-rw-r--r-- | src/libstate.cpp | 7 | ||||
-rw-r--r-- | src/parsing.cpp | 44 | ||||
-rw-r--r-- | src/prf_x942.cpp | 2 | ||||
-rw-r--r-- | src/tea.cpp | 24 | ||||
-rw-r--r-- | src/twofish.cpp | 5 | ||||
-rw-r--r-- | src/x509cert.cpp | 2 | ||||
-rw-r--r-- | src/x509self.cpp | 2 |
13 files changed, 105 insertions, 30 deletions
diff --git a/doc/credits.txt b/doc/credits.txt index 2805b3ed6..3db695235 100644 --- a/doc/credits.txt +++ b/doc/credits.txt @@ -20,6 +20,7 @@ D: Windows porting N: Yves Jerschow D: Optimizations for memory load/store and HMAC +D: Support for IPv4 addresses in X.509 alternative names S: Germany N: Matt Johnston @@ -42,5 +43,5 @@ S: New York NY, USA N: Luca Piccarreta -D: x86/amd64 assembler, BigInt optimizations, Win32 mutex +D: x86/amd64 assembler, BigInt optimizations, Win32 mutex module S: Italy diff --git a/include/asn1_obj.h b/include/asn1_obj.h index 46ba5c678..99aefbca3 100644 --- a/include/asn1_obj.h +++ b/include/asn1_obj.h @@ -129,7 +129,7 @@ class AlternativeName : public ASN1_Object bool has_items() const; AlternativeName(const std::string& = "", const std::string& = "", - const std::string& = ""); + const std::string& = "", const std::string& = ""); private: std::multimap<std::string, std::string> alt_info; std::multimap<OID, ASN1_String> othernames; diff --git a/include/parsing.h b/include/parsing.h index ce36365fe..dcfde9568 100644 --- a/include/parsing.h +++ b/include/parsing.h @@ -27,6 +27,12 @@ u32bit parse_expr(const std::string&); std::string to_string(u64bit, u32bit = 0); u32bit to_u32bit(const std::string&); +/************************************************* +* String/Network Address Conversions * +*************************************************/ +u32bit string_to_ipv4(const std::string&); +std::string ipv4_to_string(u32bit); + } #endif diff --git a/include/x509self.h b/include/x509self.h index 30acbdbaa..eb9628a0b 100644 --- a/include/x509self.h +++ b/include/x509self.h @@ -26,7 +26,7 @@ class X509_Cert_Options std::string state; std::string serial_number; - std::string email, uri, dns, xmpp; + std::string email, uri, dns, ip, xmpp; std::string challenge; diff --git a/src/asn1_alt.cpp b/src/asn1_alt.cpp index 3a1eca625..9941ef567 100644 --- a/src/asn1_alt.cpp +++ b/src/asn1_alt.cpp @@ -9,6 +9,8 @@ #include <botan/oids.h> #include <botan/stl_util.h> #include <botan/charset.h> +#include <botan/parsing.h> +#include <botan/loadstor.h> namespace Botan { @@ -17,11 +19,13 @@ namespace Botan { *************************************************/ AlternativeName::AlternativeName(const std::string& email_addr, const std::string& uri, - const std::string& dns) + const std::string& dns, + const std::string& ip) { add_attribute("RFC822", email_addr); add_attribute("DNS", dns); add_attribute("URI", uri); + add_attribute("IP", ip); } /************************************************* @@ -109,8 +113,18 @@ void encode_entries(DER_Encoder& encoder, std::pair<iter, iter> range = attr.equal_range(type); for(iter j = range.first; j != range.second; ++j) { - ASN1_String asn1_string(j->second, IA5_STRING); - encoder.add_object(tagging, CONTEXT_SPECIFIC, asn1_string.iso_8859()); + if(type == "RFC822" || type == "DNS" || type == "URI") + { + ASN1_String asn1_string(j->second, IA5_STRING); + encoder.add_object(tagging, CONTEXT_SPECIFIC, asn1_string.iso_8859()); + } + else if(type == "IP") + { + u32bit ip = string_to_ipv4(j->second); + byte ip_buf[4] = { 0 }; + store_be(ip, ip_buf); + encoder.add_object(tagging, CONTEXT_SPECIFIC, ip_buf, 4); + } } } @@ -126,6 +140,7 @@ void AlternativeName::encode_into(DER_Encoder& der) const encode_entries(der, alt_info, "RFC822", ASN1_Tag(1)); encode_entries(der, alt_info, "DNS", ASN1_Tag(2)); encode_entries(der, alt_info, "URI", ASN1_Tag(6)); + encode_entries(der, alt_info, "IP", ASN1_Tag(7)); std::multimap<OID, ASN1_String>::const_iterator i; for(i = othernames.begin(); i != othernames.end(); ++i) @@ -195,6 +210,14 @@ void AlternativeName::decode_from(BER_Decoder& source) if(tag == 2) add_attribute("DNS", value); if(tag == 6) add_attribute("URI", value); } + else if(tag == 7) + { + if(obj.value.size() == 4) + { + u32bit ip = load_be<u32bit>(obj.value.begin(), 0); + add_attribute("IP", ipv4_to_string(ip)); + } + } } } diff --git a/src/init_def.cpp b/src/init_def.cpp index abfbe646e..f77b65453 100644 --- a/src/init_def.cpp +++ b/src/init_def.cpp @@ -6,7 +6,6 @@ #include <botan/init.h> #include <botan/libstate.h> #include <botan/modules.h> -#include <botan/fips140.h> namespace Botan { @@ -21,12 +20,6 @@ void LibraryInitializer::initialize(const InitializerOptions& args, set_global_state(new Library_State); global_state().initialize(args, modules); - - if(args.fips_mode() || args.self_test()) - { - if(!FIPS140::passes_self_tests()) - throw Self_Test_Failure("FIPS-140 startup tests"); - } } catch(...) { diff --git a/src/libstate.cpp b/src/libstate.cpp index 04a5760cb..9dda38b1f 100644 --- a/src/libstate.cpp +++ b/src/libstate.cpp @@ -13,6 +13,7 @@ #include <botan/timers.h> #include <botan/charset.h> #include <botan/x931_rng.h> +#include <botan/fips140.h> #include <algorithm> namespace Botan { @@ -378,6 +379,12 @@ void Library_State::initialize(const InitializerOptions& args, if(!rng_is_seeded()) throw PRNG_Unseeded("Unable to collect sufficient entropy"); } + + if(args.fips_mode() || args.self_test()) + { + if(!FIPS140::passes_self_tests()) + throw Self_Test_Failure("FIPS-140 startup tests"); + } } /************************************************* diff --git a/src/parsing.cpp b/src/parsing.cpp index f4d17318d..cfe7a5563 100644 --- a/src/parsing.cpp +++ b/src/parsing.cpp @@ -6,6 +6,7 @@ #include <botan/parsing.h> #include <botan/exceptn.h> #include <botan/charset.h> +#include <botan/bit_ops.h> namespace Botan { @@ -30,7 +31,6 @@ u32bit to_u32bit(const std::string& number) return n; } - /************************************************* * Convert an integer into a string * *************************************************/ @@ -238,4 +238,46 @@ u32bit parse_expr(const std::string& expr) return to_u32bit(expr); } +/************************************************* +* Convert a decimal-dotted string to binary IP * +*************************************************/ +u32bit string_to_ipv4(const std::string& str) + { + std::vector<std::string> parts = split_on(str, '.'); + + if(parts.size() != 4) + throw Decoding_Error("Invalid IP string " + str); + + u32bit ip = 0; + + for(size_t j = 0; j != parts.size(); j++) + { + u32bit octet = to_u32bit(parts[j]); + + if(octet > 255) + throw Decoding_Error("Invalid IP string " + str); + + ip = (ip << 8) | (octet & 0xFF); + } + + return ip; + } + +/************************************************* +* Convert an IP address to decimal-dotted string * +*************************************************/ +std::string ipv4_to_string(u32bit ip) + { + std::string str; + + for(size_t j = 0; j != sizeof(ip); j++) + { + if(j) + str += "."; + str += to_string(get_byte(j, ip)); + } + + return str; + } + } diff --git a/src/prf_x942.cpp b/src/prf_x942.cpp index fd29aecdd..99f223107 100644 --- a/src/prf_x942.cpp +++ b/src/prf_x942.cpp @@ -40,7 +40,7 @@ SecureVector<byte> X942_PRF::derive(u32bit key_len, SecureVector<byte> key; u32bit counter = 1; - while(key.size() != key_len) + while(key.size() != key_len && counter) { hash->update(secret, secret_len); diff --git a/src/tea.cpp b/src/tea.cpp index aa04b1df8..cb1cac79a 100644 --- a/src/tea.cpp +++ b/src/tea.cpp @@ -13,17 +13,17 @@ namespace Botan { *************************************************/ void TEA::enc(const byte in[], byte out[]) const { - u32bit left = load_be<u32bit>(in, 0), right = load_be<u32bit>(in, 1); + u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); - u32bit sum = 0; + u32bit S = 0; for(u32bit j = 0; j != 32; ++j) { - sum += 0x9E3779B9; - left += ((right << 4) + K[0]) ^ (right + sum) ^ ((right >> 5) + K[1]); - right += ((left << 4) + K[2]) ^ (left + sum) ^ ((left >> 5) + K[3]); + S += 0x9E3779B9; + L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); + R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); } - store_be(out, left, right); + store_be(out, L, R); } /************************************************* @@ -31,17 +31,17 @@ void TEA::enc(const byte in[], byte out[]) const *************************************************/ void TEA::dec(const byte in[], byte out[]) const { - u32bit left = load_be<u32bit>(in, 0), right = load_be<u32bit>(in, 1); + u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); - u32bit sum = 0xC6EF3720; + u32bit S = 0xC6EF3720; for(u32bit j = 0; j != 32; ++j) { - right -= ((left << 4) + K[2]) ^ (left + sum) ^ ((left >> 5) + K[3]); - left -= ((right << 4) + K[0]) ^ (right + sum) ^ ((right >> 5) + K[1]); - sum -= 0x9E3779B9; + R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); + L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); + S -= 0x9E3779B9; } - store_be(out, left, right); + store_be(out, L, R); } /************************************************* diff --git a/src/twofish.cpp b/src/twofish.cpp index 25359f635..f25891ebf 100644 --- a/src/twofish.cpp +++ b/src/twofish.cpp @@ -90,7 +90,10 @@ void Twofish::dec(const byte in[], byte out[]) const B = rotate_right(B ^ Y, 1); } - C ^= round_key[0]; D ^= round_key[1]; A ^= round_key[2]; B ^= round_key[3]; + C ^= round_key[0]; + D ^= round_key[1]; + A ^= round_key[2]; + B ^= round_key[3]; store_le(out, C, D, A, B); } diff --git a/src/x509cert.cpp b/src/x509cert.cpp index 404e56f29..549b916c5 100644 --- a/src/x509cert.cpp +++ b/src/x509cert.cpp @@ -350,7 +350,7 @@ AlternativeName create_alt_name(const Data_Store& info) }; std::multimap<std::string, std::string> names = - info.search_with(AltName_Matcher("RFC822/DNS/URI")); + info.search_with(AltName_Matcher("RFC822/DNS/URI/IP")); AlternativeName alt_name; diff --git a/src/x509self.cpp b/src/x509self.cpp index 255ee6219..1c94324ed 100644 --- a/src/x509self.cpp +++ b/src/x509self.cpp @@ -50,7 +50,7 @@ void load_info(const X509_Cert_Options& opts, X509_DN& subject_dn, subject_dn.add_attribute("X520.Organization", opts.organization); subject_dn.add_attribute("X520.OrganizationalUnit", opts.org_unit); subject_dn.add_attribute("X520.SerialNumber", opts.serial_number); - subject_alt = AlternativeName(opts.email, opts.uri, opts.dns); + subject_alt = AlternativeName(opts.email, opts.uri, opts.dns, opts.ip); subject_alt.add_othername(OIDS::lookup("PKIX.XMPPAddr"), opts.xmpp, UTF8_STRING); } |