aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/credits.txt3
-rw-r--r--include/asn1_obj.h2
-rw-r--r--include/parsing.h6
-rw-r--r--include/x509self.h2
-rw-r--r--src/asn1_alt.cpp29
-rw-r--r--src/init_def.cpp7
-rw-r--r--src/libstate.cpp7
-rw-r--r--src/parsing.cpp44
-rw-r--r--src/prf_x942.cpp2
-rw-r--r--src/tea.cpp24
-rw-r--r--src/twofish.cpp5
-rw-r--r--src/x509cert.cpp2
-rw-r--r--src/x509self.cpp2
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);
}