aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build-data/buildh.in15
-rw-r--r--src/cmd/dl_group.cpp85
-rw-r--r--src/cmd/implementation/speed.h4
-rw-r--r--src/cmd/implementation/speed_public_key.cpp30
-rw-r--r--src/cmd/prime.cpp48
-rw-r--r--src/cmd/speed.cpp13
-rw-r--r--src/lib/asn1/info.txt1
-rw-r--r--src/lib/ffi/ffi.cpp28
-rw-r--r--src/lib/ffi/info.txt1
-rw-r--r--src/lib/filters/info.txt2
-rw-r--r--src/lib/math/numbertheory/make_prm.cpp56
-rw-r--r--src/lib/misc/pbes2/pbes2.cpp4
-rw-r--r--src/lib/misc/pem/info.txt2
-rw-r--r--src/lib/misc/pem/pem.cpp42
-rw-r--r--src/lib/pubkey/blinding.cpp40
-rw-r--r--src/lib/pubkey/blinding.h16
-rw-r--r--src/lib/pubkey/dl_group/dl_group.cpp4
-rw-r--r--src/lib/pubkey/elgamal/elgamal.cpp15
-rw-r--r--src/lib/pubkey/pubkey.cpp36
-rw-r--r--src/lib/pubkey/pubkey.h68
-rw-r--r--src/lib/pubkey/x509_key.h2
-rw-r--r--src/lib/rng/system_rng/system_rng.cpp16
-rw-r--r--src/lib/rng/system_rng/system_rng.h25
-rw-r--r--src/lib/utils/data_src.cpp (renamed from src/lib/filters/data_src.cpp)0
-rw-r--r--src/lib/utils/data_src.h (renamed from src/lib/filters/data_src.h)0
-rw-r--r--src/lib/utils/info.txt1
-rw-r--r--src/lib/vendor/openssl/openssl_rsa.cpp145
-rwxr-xr-xsrc/scripts/ci/travis/build.sh2
-rwxr-xr-xsrc/scripts/website.sh4
-rw-r--r--src/tests/test_modes.cpp20
-rw-r--r--src/tests/test_pubkey.cpp11
-rw-r--r--src/tests/test_rsa.cpp4
-rw-r--r--src/tests/unit_x509.cpp24
33 files changed, 558 insertions, 206 deletions
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index eaf4181b5..31069f0ae 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -71,9 +71,20 @@
* representation of an ECC point. Set to zero to diable this
* side-channel countermeasure.
*/
-#define BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS 64
+#define BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS 80
-#define BOTAN_CURVE_GFP_USE_MONTGOMERY_LADDER 0
+/*
+* Normally blinding is performed by choosing a random starting point (plus
+* its inverse, of a form appropriate to the algorithm being blinded), and
+* then choosing new blinding operands by successive squaring of both
+* values. This is much faster than computing a new starting point but
+* introduces some possible coorelation
+*
+* To avoid possible leakage problems in long-running processes, the blinder
+* periodically reinitializes the sequence. This value specifies how often
+* a new sequence should be started.
+*/
+#define BOTAN_BLINDING_REINIT_INTERVAL 32
/* PK key consistency checking toggles */
#define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1
diff --git a/src/cmd/dl_group.cpp b/src/cmd/dl_group.cpp
new file mode 100644
index 000000000..2db65ded2
--- /dev/null
+++ b/src/cmd/dl_group.cpp
@@ -0,0 +1,85 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "apps.h"
+
+#if defined(BOTAN_HAS_DL_GROUP)
+
+#include <botan/dl_group.h>
+#include <fstream>
+
+namespace {
+
+std::string read_file_contents(const std::string& filename)
+ {
+ std::ifstream in(filename.c_str());
+ if(!in.good())
+ throw std::runtime_error("Failure reading " + filename);
+
+ std::vector<std::string> contents;
+ size_t total_size = 0;
+ while(in.good())
+ {
+ std::string line;
+ std::getline(in, line);
+ total_size += line.size();
+ contents.push_back(std::move(line));
+ }
+
+ std::string res;
+ contents.reserve(total_size);
+ for(auto&& line : contents)
+ res += line;
+ return res;
+ }
+
+int dl_group(int argc, char* argv[])
+ {
+ if(argc < 2)
+ {
+ std::cout << "Usage: " << argv[0] << " [create bits|info file]" << std::endl;
+ return 1;
+ }
+
+ const std::string cmd = argv[1];
+
+ if(cmd == "create")
+ {
+ AutoSeeded_RNG rng;
+ const size_t bits = to_u32bit(argv[2]);
+
+ const DL_Group::PrimeType prime_type = DL_Group::Strong;
+ //const DL_Group::PrimeType prime_type = DL_Group::Prime_Subgroup;
+
+ DL_Group grp(rng, prime_type, bits);
+
+ std::cout << grp.PEM_encode(DL_Group::DSA_PARAMETERS);
+ }
+ else if(cmd == "info")
+ {
+ DL_Group grp;
+ std::string pem = read_file_contents(argv[2]);
+ std::cout << pem << "\n";
+
+ std::cout << "DL_Group " << grp.get_p().bits() << " bits\n";
+ std::cout << "p=" << grp.get_p() << "\n";
+ std::cout << "q=" << grp.get_q() << "\n";
+ std::cout << "g=" << grp.get_g() << "\n";
+ }
+ else
+ {
+ std::cout << "ERROR: Unknown command\n";
+ return 1;
+ }
+
+ return 0;
+ }
+
+REGISTER_APP(dl_group);
+
+}
+
+#endif
diff --git a/src/cmd/implementation/speed.h b/src/cmd/implementation/speed.h
index 1f082eb52..3cfd0ef61 100644
--- a/src/cmd/implementation/speed.h
+++ b/src/cmd/implementation/speed.h
@@ -13,7 +13,9 @@
#include <chrono>
void benchmark_public_key(Botan::RandomNumberGenerator& rng,
- const std::string& algo, double seconds);
+ const std::string& algo,
+ const std::string& provider,
+ double seconds);
std::map<std::string, double> benchmark_is_prime(Botan::RandomNumberGenerator &rng,
const std::chrono::milliseconds runtime);
diff --git a/src/cmd/implementation/speed_public_key.cpp b/src/cmd/implementation/speed_public_key.cpp
index 83c0156ae..2ff49bd15 100644
--- a/src/cmd/implementation/speed_public_key.cpp
+++ b/src/cmd/implementation/speed_public_key.cpp
@@ -202,7 +202,8 @@ void benchmark_sig_ver(PK_Verifier& ver, PK_Signer& sig,
*/
#if defined(BOTAN_HAS_RSA)
-void benchmark_rsa(RandomNumberGenerator& rng,
+void benchmark_rsa(const std::string& provider,
+ RandomNumberGenerator& rng,
double seconds,
Benchmark_Report& report)
{
@@ -213,8 +214,8 @@ void benchmark_rsa(RandomNumberGenerator& rng,
{
size_t keylen = keylens[i];
- //const std::string sig_padding = "EMSA4(SHA-1)";
- //const std::string enc_padding = "EME1(SHA-1)";
+ //const std::string sig_padding = "PSSR(SHA-256)";
+ //const std::string enc_padding = "OAEP(SHA-1)";
const std::string sig_padding = "EMSA-PKCS1-v1_5(SHA-1)";
const std::string enc_padding = "EME-PKCS1-v1_5";
@@ -243,14 +244,14 @@ void benchmark_rsa(RandomNumberGenerator& rng,
while(verify_timer.seconds() < seconds ||
sig_timer.seconds() < seconds)
{
- PK_Encryptor_EME enc(key, enc_padding);
- PK_Decryptor_EME dec(key, enc_padding);
+ PK_Encryptor_EME enc(key, enc_padding, provider);
+ PK_Decryptor_EME dec(key, enc_padding, provider);
benchmark_enc_dec(enc, dec, enc_timer, dec_timer,
rng, 10000, seconds);
- PK_Signer sig(key, sig_padding);
- PK_Verifier ver(key, sig_padding);
+ PK_Signer sig(key, sig_padding, IEEE_1363, provider);
+ PK_Verifier ver(key, sig_padding, IEEE_1363, provider);
benchmark_sig_ver(ver, sig, verify_timer,
sig_timer, rng, 10000, seconds);
@@ -318,7 +319,8 @@ void benchmark_rw(RandomNumberGenerator& rng,
#if defined(BOTAN_HAS_ECDSA)
-void benchmark_ecdsa(RandomNumberGenerator& rng,
+void benchmark_ecdsa(const std::string& provider,
+ RandomNumberGenerator& rng,
double seconds,
Benchmark_Report& report)
{
@@ -348,8 +350,8 @@ void benchmark_ecdsa(RandomNumberGenerator& rng,
ECDSA_PrivateKey key(rng, params);
keygen_timer.stop();
- PK_Signer sig(key, padding, IEEE_1363);
- PK_Verifier ver(key, padding);
+ PK_Signer sig(key, padding, IEEE_1363, provider);
+ PK_Verifier ver(key, padding, IEEE_1363, provider);
benchmark_sig_ver(ver, sig, verify_timer,
sig_timer, rng, 1000, seconds);
@@ -791,7 +793,9 @@ void benchmark_mce(RandomNumberGenerator& rng,
}
void benchmark_public_key(RandomNumberGenerator& rng,
- const std::string& algo, double seconds)
+ const std::string& algo,
+ const std::string& provider,
+ double seconds)
{
/*
There is some strangeness going on here. It looks like algorithms
@@ -823,7 +827,7 @@ void benchmark_public_key(RandomNumberGenerator& rng,
#if defined(BOTAN_HAS_RSA)
if(algo == "All" || algo == "RSA")
- benchmark_rsa(rng, seconds, report);
+ benchmark_rsa(provider, rng, seconds, report);
#endif
#if defined(BOTAN_HAS_DSA)
@@ -833,7 +837,7 @@ void benchmark_public_key(RandomNumberGenerator& rng,
#if defined(BOTAN_HAS_ECDSA)
if(algo == "All" || algo == "ECDSA")
- benchmark_ecdsa(rng, seconds, report);
+ benchmark_ecdsa(provider, rng, seconds, report);
#endif
#if defined(BOTAN_HAS_ECDH)
diff --git a/src/cmd/prime.cpp b/src/cmd/prime.cpp
new file mode 100644
index 000000000..61f535dd7
--- /dev/null
+++ b/src/cmd/prime.cpp
@@ -0,0 +1,48 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "apps.h"
+
+#if defined(BOTAN_HAS_NUMBERTHEORY)
+
+#include <botan/numthry.h>
+
+#include <algorithm>
+#include <iostream>
+
+namespace {
+
+int prime(int argc, char* argv[])
+ {
+ if(argc < 2)
+ {
+ std::cout << "Usage: " << argv[0] << " bits count" << std::endl;
+ return 1;
+ }
+
+ AutoSeeded_RNG rng;
+ const size_t bits = to_u32bit(argv[1]);
+ const size_t cnt = argv[2] != nullptr ? to_u32bit(argv[2]) : 1;
+
+ for(size_t i = 0; i != cnt; ++i)
+ {
+ const BigInt p = random_prime(rng, bits);
+ std::cout << p << "\n";
+
+ if(p.bits() != bits)
+ {
+ std::cout << "Result not exactly requested bit size, got " << p.bits() << "\n";
+ }
+ }
+
+ return 0;
+ }
+
+}
+
+REGISTER_APP(prime);
+
+#endif
diff --git a/src/cmd/speed.cpp b/src/cmd/speed.cpp
index 91b2f4fbd..990c6a364 100644
--- a/src/cmd/speed.cpp
+++ b/src/cmd/speed.cpp
@@ -118,6 +118,7 @@ void report_results(const std::string& algo,
}
void bench_algo(const std::string& algo,
+ const std::string& provider,
RandomNumberGenerator& rng,
double seconds,
size_t buf_size)
@@ -151,7 +152,7 @@ void bench_algo(const std::string& algo,
catch (No_Provider_Found)
{
#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
- benchmark_public_key(rng, algo, seconds);
+ benchmark_public_key(rng, algo, provider, seconds);
#endif
}
}
@@ -159,7 +160,7 @@ void bench_algo(const std::string& algo,
int speed(int argc, char* argv[])
{
BOTAN_UNUSED(argc);
- OptionParser opts("seconds=|buf-size=");
+ OptionParser opts("seconds=|buf-size=|provider=");
opts.parse(argv);
double seconds = .5;
@@ -185,7 +186,9 @@ int speed(int argc, char* argv[])
}
}
- auto args = opts.arguments();
+ const std::string provider = opts.value_if_set("provider");
+
+ std::vector<std::string> args = opts.arguments();
if(args.empty())
args = default_benchmark_list;
@@ -199,7 +202,9 @@ int speed(int argc, char* argv[])
AutoSeeded_RNG rng;
for(auto alg: args)
- bench_algo(alg, rng, seconds, buf_size);
+ {
+ bench_algo(alg, provider, rng, seconds, buf_size);
+ }
return 0;
}
diff --git a/src/lib/asn1/info.txt b/src/lib/asn1/info.txt
index c6c3db537..a067168e4 100644
--- a/src/lib/asn1/info.txt
+++ b/src/lib/asn1/info.txt
@@ -3,7 +3,6 @@ define ASN1 20131128
load_on auto
<requires>
-filters
bigint
oid_lookup
</requires>
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 27dcc6015..eb30b4831 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -20,8 +20,6 @@
#include <botan/hex.h>
#include <botan/mem_ops.h>
#include <botan/x509_key.h>
-#include <botan/tls_client.h>
-#include <botan/tls_server.h>
#include <cstring>
#include <memory>
@@ -49,11 +47,15 @@
#include <botan/mceies.h>
#endif
-
#if defined(BOTAN_HAS_BCRYPT)
#include <botan/bcrypt.h>
#endif
+#if defined(BOTAN_HAS_TLS)
+ #include <botan/tls_client.h>
+ #include <botan/tls_server.h>
+#endif
+
namespace {
#define BOTAN_ASSERT_ARG_NON_NULL(p) \
@@ -185,7 +187,10 @@ BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_verify_struct, Botan::PK_Verifier, 0x2B91F9
BOTAN_FFI_DECLARE_STRUCT(botan_pk_op_ka_struct, Botan::PK_Key_Agreement, 0x2939CAB1);
BOTAN_FFI_DECLARE_STRUCT(botan_x509_cert_struct, Botan::X509_Certificate, 0x8F628937);
+
+#if defined(BOTAN_HAS_TLS)
BOTAN_FFI_DECLARE_STRUCT(botan_tls_channel_struct, Botan::TLS::Channel, 0x0212FE99);
+#endif
/*
* Versioning
@@ -228,21 +233,6 @@ int botan_hex_encode(const uint8_t* in, size_t len, char* out, uint32_t flags)
int botan_rng_init(botan_rng_t* rng_out, const char* rng_type)
{
- // Just gives unique_ptr something to delete, really
- class RNG_Wrapper : public Botan::RandomNumberGenerator
- {
- public:
- RNG_Wrapper(Botan::RandomNumberGenerator& rng) : m_rng(rng) {}
- void randomize(Botan::byte out[], size_t len) override { m_rng.randomize(out, len); }
- bool is_seeded() const override { return m_rng.is_seeded(); }
- void clear() override { m_rng.clear(); }
- std::string name() const override { return m_rng.name(); }
- void reseed(size_t poll_bits = 256) override { m_rng.reseed(poll_bits); }
- void add_entropy(const Botan::byte in[], size_t len) override { m_rng.add_entropy(in, len); }
- private:
- Botan::RandomNumberGenerator& m_rng;
- };
-
try
{
BOTAN_ASSERT_ARG_NON_NULL(rng_out);
@@ -255,7 +245,7 @@ int botan_rng_init(botan_rng_t* rng_out, const char* rng_type)
std::unique_ptr<Botan::RandomNumberGenerator> rng;
if(rng_type_s == "system")
- rng.reset(new RNG_Wrapper(Botan::system_rng()));
+ rng.reset(new Botan::System_RNG);
else if(rng_type_s == "user")
rng.reset(new Botan::AutoSeeded_RNG);
diff --git a/src/lib/ffi/info.txt b/src/lib/ffi/info.txt
index 8d6c5237e..4018e4064 100644
--- a/src/lib/ffi/info.txt
+++ b/src/lib/ffi/info.txt
@@ -2,7 +2,6 @@ define FFI 20151001
<requires>
aead
-filters
kdf
pbkdf
pubkey
diff --git a/src/lib/filters/info.txt b/src/lib/filters/info.txt
index da6827833..fbecd9c87 100644
--- a/src/lib/filters/info.txt
+++ b/src/lib/filters/info.txt
@@ -6,7 +6,6 @@ basefilt.cpp
buf_filt.cpp
comp_filter.cpp
data_snk.cpp
-data_src.cpp
filter.cpp
key_filt.cpp
out_buf.cpp
@@ -23,7 +22,6 @@ basefilt.h
buf_filt.h
data_snk.h
comp_filter.h
-data_src.h
filter.h
filters.h
key_filt.h
diff --git a/src/lib/math/numbertheory/make_prm.cpp b/src/lib/math/numbertheory/make_prm.cpp
index 1333fdf04..3d82adf06 100644
--- a/src/lib/math/numbertheory/make_prm.cpp
+++ b/src/lib/math/numbertheory/make_prm.cpp
@@ -18,22 +18,37 @@ BigInt random_prime(RandomNumberGenerator& rng,
size_t bits, const BigInt& coprime,
size_t equiv, size_t modulo)
{
+ if(coprime <= 0)
+ {
+ throw Invalid_Argument("random_prime: coprime must be > 0");
+ }
+ if(modulo % 2 == 1 || modulo == 0)
+ {
+ throw Invalid_Argument("random_prime: Invalid modulo value");
+ }
+ if(equiv >= modulo || equiv % 2 == 0)
+ {
+ throw Invalid_Argument("random_prime: equiv must be < modulo, and odd");
+ }
+
+ // Handle small values:
if(bits <= 1)
+ {
throw Invalid_Argument("random_prime: Can't make a prime of " +
std::to_string(bits) + " bits");
+ }
else if(bits == 2)
+ {
return ((rng.next_byte() % 2) ? 2 : 3);
+ }
else if(bits == 3)
+ {
return ((rng.next_byte() % 2) ? 5 : 7);
+ }
else if(bits == 4)
+ {
return ((rng.next_byte() % 2) ? 11 : 13);
-
- if(coprime <= 0)
- throw Invalid_Argument("random_prime: coprime must be > 0");
- if(modulo % 2 == 1 || modulo == 0)
- throw Invalid_Argument("random_prime: Invalid modulo value");
- if(equiv >= modulo || equiv % 2 == 0)
- throw Invalid_Argument("random_prime: equiv must be < modulo, and odd");
+ }
while(true)
{
@@ -56,27 +71,39 @@ BigInt random_prime(RandomNumberGenerator& rng,
size_t counter = 0;
while(true)
{
- if(counter == 4096 || p.bits() > bits)
- break;
-
- bool passes_sieve = true;
++counter;
+
+ if(counter >= 4096)
+ {
+ break; // don't try forever, choose a new starting point
+ }
+
p += modulo;
if(p.bits() > bits)
break;
+ bool passes_sieve = true;
for(size_t j = 0; j != sieve.size(); ++j)
{
sieve[j] = (sieve[j] + modulo) % PRIMES[j];
if(sieve[j] == 0)
+ {
passes_sieve = false;
+ break;
+ }
}
- if(!passes_sieve || gcd(p - 1, coprime) != 1)
+ if(!passes_sieve)
+ continue;
+
+ if(gcd(p - 1, coprime) != 1)
continue;
- if(is_prime(p, rng, 64, true))
+
+ if(is_prime(p, rng, 128, true))
+ {
return p;
+ }
}
}
}
@@ -93,7 +120,8 @@ BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits)
BigInt p;
do
p = (random_prime(rng, bits - 1) << 1) + 1;
- while(!is_prime(p, rng, 64, true));
+ while(!is_prime(p, rng, 128, true));
+
return p;
}
diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp
index 470e33cb0..c66b293e8 100644
--- a/src/lib/misc/pbes2/pbes2.cpp
+++ b/src/lib/misc/pbes2/pbes2.cpp
@@ -82,7 +82,7 @@ pbes2_encrypt(const secure_vector<byte>& key_bits,
std::unique_ptr<Cipher_Mode> enc(get_cipher_mode(cipher, ENCRYPTION));
if(!enc)
- throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher);
+ throw Decoding_Error("PBE-PKCS5 cannot encrypt no cipher " + cipher);
std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")"));
@@ -157,6 +157,8 @@ pbes2_decrypt(const secure_vector<byte>& key_bits,
std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")"));
std::unique_ptr<Cipher_Mode> dec(get_cipher_mode(cipher, DECRYPTION));
+ if(!dec)
+ throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher);
if(key_length == 0)
key_length = dec->key_spec().maximum_keylength();
diff --git a/src/lib/misc/pem/info.txt b/src/lib/misc/pem/info.txt
index c614b5ca7..9340a7cef 100644
--- a/src/lib/misc/pem/info.txt
+++ b/src/lib/misc/pem/info.txt
@@ -1,5 +1,5 @@
define PEM_CODEC 20131128
<requires>
-codec_filt
+base64
</requires>
diff --git a/src/lib/misc/pem/pem.cpp b/src/lib/misc/pem/pem.cpp
index f33016c70..83b48c07b 100644
--- a/src/lib/misc/pem/pem.cpp
+++ b/src/lib/misc/pem/pem.cpp
@@ -6,25 +6,46 @@
*/
#include <botan/pem.h>
-#include <botan/filters.h>
+#include <botan/base64.h>
#include <botan/parsing.h>
+#include <botan/exceptn.h>
namespace Botan {
namespace PEM_Code {
+namespace {
+
+std::string linewrap(size_t width, const std::string& in)
+ {
+ std::string out;
+ for(size_t i = 0; i != in.size(); ++i)
+ {
+ if(i > 0 && i % width == 0)
+ {
+ out.push_back('\n');
+ }
+ out.push_back(in[i]);
+ }
+ if(out.size() > 0 && out[out.size()-1] != '\n')
+ {
+ out.push_back('\n');
+ }
+
+ return out;
+ }
+
+}
+
/*
* PEM encode BER/DER-encoded objects
*/
-std::string encode(const byte der[], size_t length, const std::string& label,
- size_t width)
+std::string encode(const byte der[], size_t length, const std::string& label, size_t width)
{
const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n";
const std::string PEM_TRAILER = "-----END " + label + "-----\n";
- Pipe pipe(new Base64_Encoder(true, width));
- pipe.process_msg(der, length);
- return (PEM_HEADER + pipe.read_all_as_string() + PEM_TRAILER);
+ return (PEM_HEADER + linewrap(width, base64_encode(der, length)) + PEM_TRAILER);
}
/*
@@ -79,8 +100,7 @@ secure_vector<byte> decode(DataSource& source, std::string& label)
label += static_cast<char>(b);
}
- Pipe base64(new Base64_Decoder);
- base64.start_msg();
+ std::vector<char> b64;
const std::string PEM_TRAILER = "-----END " + label + "-----";
position = 0;
@@ -95,10 +115,10 @@ secure_vector<byte> decode(DataSource& source, std::string& label)
throw Decoding_Error("PEM: Malformed PEM trailer");
if(position == 0)
- base64.write(b);
+ b64.push_back(b);
}
- base64.end_msg();
- return base64.read_all();
+
+ return base64_decode(b64.data(), b64.size());
}
secure_vector<byte> decode_check_label(const std::string& pem,
diff --git a/src/lib/pubkey/blinding.cpp b/src/lib/pubkey/blinding.cpp
index cd2b3d118..da9def797 100644
--- a/src/lib/pubkey/blinding.cpp
+++ b/src/lib/pubkey/blinding.cpp
@@ -1,6 +1,6 @@
/*
* Blinding for public key operations
-* (C) 1999-2010 Jack Lloyd
+* (C) 1999-2010,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -16,24 +16,28 @@
namespace Botan {
-// TODO: use Montgomery
-
Blinder::Blinder(const BigInt& modulus,
- std::function<BigInt (const BigInt&)> fwd_func,
- std::function<BigInt (const BigInt&)> inv_func)
+ 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_modulus_bits = modulus.bits();
#if defined(BOTAN_HAS_SYSTEM_RNG)
- auto& rng = system_rng();
+ m_rng.reset(new System_RNG);
#else
- AutoSeeded_RNG rng;
+ m_rng.reset(new AutoSeeded_RNG);
#endif
- const BigInt k(rng, modulus.bits() - 1);
+ const BigInt k = blinding_nonce();
+ m_e = m_fwd_fn(k);
+ m_d = m_inv_fn(k);
+ }
- m_e = fwd_func(k);
- m_d = inv_func(k);
+BigInt Blinder::blinding_nonce() const
+ {
+ return BigInt(*m_rng, m_modulus_bits - 1);
}
BigInt Blinder::blind(const BigInt& i) const
@@ -41,8 +45,20 @@ BigInt Blinder::blind(const BigInt& i) const
if(!m_reducer.initialized())
throw std::runtime_error("Blinder not initialized, cannot blind");
- m_e = m_reducer.square(m_e);
- m_d = m_reducer.square(m_d);
+ ++m_counter;
+
+ if(BOTAN_BLINDING_REINIT_INTERVAL > 0 && (m_counter % BOTAN_BLINDING_REINIT_INTERVAL == 0))
+ {
+ const BigInt k = blinding_nonce();
+ m_e = m_fwd_fn(k);
+ m_d = m_inv_fn(k);
+ }
+ else
+ {
+ m_e = m_reducer.square(m_e);
+ m_d = m_reducer.square(m_d);
+ }
+
return m_reducer.multiply(i, m_e);
}
diff --git a/src/lib/pubkey/blinding.h b/src/lib/pubkey/blinding.h
index e57c7888e..c1999feb7 100644
--- a/src/lib/pubkey/blinding.h
+++ b/src/lib/pubkey/blinding.h
@@ -1,6 +1,6 @@
/*
* Blinding for public key operations
-* (C) 1999-2010 Jack Lloyd
+* (C) 1999-2010,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -14,6 +14,8 @@
namespace Botan {
+class RandomNumberGenerator;
+
/**
* Blinding Function Object
*/
@@ -32,9 +34,21 @@ class BOTAN_DLL Blinder
std::function<BigInt (const BigInt&)> fwd_func,
std::function<BigInt (const BigInt&)> inv_func);
+ Blinder(const Blinder&) = delete;
+
+ Blinder& operator=(const Blinder&) = delete;
+
private:
+ BigInt blinding_nonce() const;
+
Modular_Reducer m_reducer;
+ std::unique_ptr<RandomNumberGenerator> m_rng;
+ std::function<BigInt (const BigInt&)> m_fwd_fn;
+ std::function<BigInt (const BigInt&)> m_inv_fn;
+ size_t m_modulus_bits = 0;
+
mutable BigInt m_e, m_d;
+ mutable size_t m_counter = 0;
};
}
diff --git a/src/lib/pubkey/dl_group/dl_group.cpp b/src/lib/pubkey/dl_group/dl_group.cpp
index c519dcb99..fbaa67eaa 100644
--- a/src/lib/pubkey/dl_group/dl_group.cpp
+++ b/src/lib/pubkey/dl_group/dl_group.cpp
@@ -1,6 +1,6 @@
/*
* Discrete Logarithm Parameters
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2008,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -42,7 +42,7 @@ DL_Group::DL_Group(const std::string& name)
DL_Group::DL_Group(RandomNumberGenerator& rng,
PrimeType type, size_t pbits, size_t qbits)
{
- if(pbits < 512)
+ if(pbits < 1024)
throw Invalid_Argument("DL_Group: prime size " + std::to_string(pbits) +
" is too small");
diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp
index 4d0344610..5bcdd5689 100644
--- a/src/lib/pubkey/elgamal/elgamal.cpp
+++ b/src/lib/pubkey/elgamal/elgamal.cpp
@@ -145,16 +145,13 @@ class ElGamal_Decryption_Operation : public PK_Ops::Decryption_with_EME
ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key,
const std::string& eme) :
- PK_Ops::Decryption_with_EME(eme)
+ PK_Ops::Decryption_with_EME(eme),
+ powermod_x_p(Fixed_Exponent_Power_Mod(key.get_x(), key.group_p())),
+ mod_p(Modular_Reducer(key.group_p())),
+ blinder(key.group_p(),
+ [](const BigInt& k) { return k; },
+ [this](const BigInt& k) { return powermod_x_p(k); })
{
- const BigInt& p = key.group_p();
-
- powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p);
- mod_p = Modular_Reducer(p);
-
- blinder = Blinder(p,
- [](const BigInt& k) { return k; },
- [this](const BigInt& k) { return powermod_x_p(k); });
}
secure_vector<byte>
diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp
index 74b6a2053..b9923f54b 100644
--- a/src/lib/pubkey/pubkey.cpp
+++ b/src/lib/pubkey/pubkey.cpp
@@ -15,19 +15,26 @@ namespace Botan {
namespace {
template<typename T, typename Key>
-T* get_pk_op(const std::string& what, const Key& key, const std::string& pad)
+T* get_pk_op(const std::string& what, const Key& key, const std::string& pad,
+ const std::string& provider = "")
{
- T* p = Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad));
- if(!p)
- throw Lookup_Error(what + " with " + key.algo_name() + "/" + pad + " not supported");
- return p;
+ if(T* p = Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad), provider))
+ return p;
+
+ const std::string err = what + " with " + key.algo_name() + "/" + pad + " not supported";
+ if(provider != "")
+ throw Lookup_Error(err + " with provider " + provider);
+ else
+ throw Lookup_Error(err);
}
}
-PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, const std::string& eme)
+PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
+ const std::string& padding,
+ const std::string& provider)
{
- m_op.reset(get_pk_op<PK_Ops::Encryption>("Encryption", key, eme));
+ m_op.reset(get_pk_op<PK_Ops::Encryption>("Encryption", key, padding, provider));
}
std::vector<byte>
@@ -41,9 +48,10 @@ size_t PK_Encryptor_EME::maximum_input_size() const
return m_op->max_input_bits() / 8;
}
-PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, const std::string& eme)
+PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, const std::string& padding,
+ const std::string& provider)
{
- m_op.reset(get_pk_op<PK_Ops::Decryption>("Decryption", key, eme));
+ m_op.reset(get_pk_op<PK_Ops::Decryption>("Decryption", key, padding, provider));
}
secure_vector<byte> PK_Decryptor_EME::dec(const byte msg[], size_t length) const
@@ -108,9 +116,10 @@ std::vector<byte> der_decode_signature(const byte sig[], size_t len,
PK_Signer::PK_Signer(const Private_Key& key,
const std::string& emsa,
- Signature_Format format)
+ Signature_Format format,
+ const std::string& provider)
{
- m_op.reset(get_pk_op<PK_Ops::Signature>("Signing", key, emsa));
+ m_op.reset(get_pk_op<PK_Ops::Signature>("Signing", key, emsa, provider));
m_sig_format = format;
}
@@ -135,9 +144,10 @@ std::vector<byte> PK_Signer::signature(RandomNumberGenerator& rng)
PK_Verifier::PK_Verifier(const Public_Key& key,
const std::string& emsa_name,
- Signature_Format format)
+ Signature_Format format,
+ const std::string& provider)
{
- m_op.reset(get_pk_op<PK_Ops::Verification>("Verification", key, emsa_name));
+ m_op.reset(get_pk_op<PK_Ops::Verification>("Verification", key, emsa_name, provider));
m_sig_format = format;
}
diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h
index 687485c68..67116a9ec 100644
--- a/src/lib/pubkey/pubkey.h
+++ b/src/lib/pubkey/pubkey.h
@@ -120,6 +120,19 @@ class BOTAN_DLL PK_Decryptor
class BOTAN_DLL PK_Signer
{
public:
+
+ /**
+ * Construct a PK Signer.
+ * @param key the key to use inside this signer
+ * @param emsa the EMSA to use
+ * An example would be "EMSA1(SHA-224)".
+ * @param format the signature format to use
+ */
+ PK_Signer(const Private_Key& key,
+ const std::string& emsa,
+ Signature_Format format = IEEE_1363,
+ const std::string& provider = "");
+
/**
* Sign a message.
* @param in the message to sign as a byte array
@@ -180,17 +193,6 @@ class BOTAN_DLL PK_Signer
* @param format the signature format to use
*/
void set_output_format(Signature_Format format) { m_sig_format = format; }
-
- /**
- * Construct a PK Signer.
- * @param key the key to use inside this signer
- * @param emsa the EMSA to use
- * An example would be "EMSA1(SHA-224)".
- * @param format the signature format to use
- */
- PK_Signer(const Private_Key& key,
- const std::string& emsa,
- Signature_Format format = IEEE_1363);
private:
std::unique_ptr<PK_Ops::Signature> m_op;
Signature_Format m_sig_format;
@@ -205,6 +207,17 @@ class BOTAN_DLL PK_Verifier
{
public:
/**
+ * Construct a PK Verifier.
+ * @param pub_key the public key to verify against
+ * @param emsa the EMSA to use (eg "EMSA3(SHA-1)")
+ * @param format the signature format to use
+ */
+ PK_Verifier(const Public_Key& pub_key,
+ const std::string& emsa,
+ Signature_Format format = IEEE_1363,
+ const std::string& provider = "");
+
+ /**
* Verify a signature.
* @param msg the message that the signature belongs to, as a byte array
* @param msg_length the length of the above byte array msg
@@ -278,15 +291,6 @@ class BOTAN_DLL PK_Verifier
*/
void set_input_format(Signature_Format format);
- /**
- * Construct a PK Verifier.
- * @param pub_key the public key to verify against
- * @param emsa the EMSA to use (eg "EMSA3(SHA-1)")
- * @param format the signature format to use
- */
- PK_Verifier(const Public_Key& pub_key,
- const std::string& emsa,
- Signature_Format format = IEEE_1363);
private:
std::unique_ptr<PK_Ops::Verification> m_op;
Signature_Format m_sig_format;
@@ -299,6 +303,13 @@ class BOTAN_DLL PK_Key_Agreement
{
public:
+ /**
+ * Construct a PK Key Agreement.
+ * @param key the key to use
+ * @param kdf name of the KDF to use (or 'Raw' for no KDF)
+ */
+ PK_Key_Agreement(const Private_Key& key, const std::string& kdf);
+
/*
* Perform Key Agreement Operation
* @param key_len the desired key output size
@@ -361,18 +372,13 @@ class BOTAN_DLL PK_Key_Agreement
params.length());
}
- /**
- * Construct a PK Key Agreement.
- * @param key the key to use
- * @param kdf name of the KDF to use (or 'Raw' for no KDF)
- */
- PK_Key_Agreement(const Private_Key& key, const std::string& kdf);
private:
std::unique_ptr<PK_Ops::Key_Agreement> m_op;
};
/**
-* Encryption with an MR algorithm and an EME.
+* Encryption using a standard message recovery algorithm like RSA or
+* ElGamal, paired with an encoding scheme like OAEP.
*/
class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor
{
@@ -382,10 +388,11 @@ class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor
/**
* Construct an instance.
* @param key the key to use inside the decryptor
- * @param eme the EME to use
+ * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)")
*/
PK_Encryptor_EME(const Public_Key& key,
- const std::string& eme);
+ const std::string& padding,
+ const std::string& provider = "");
private:
std::vector<byte> enc(const byte[], size_t,
RandomNumberGenerator& rng) const override;
@@ -405,7 +412,8 @@ class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor
* @param eme the EME to use
*/
PK_Decryptor_EME(const Private_Key& key,
- const std::string& eme);
+ const std::string& eme,
+ const std::string& provider = "");
private:
secure_vector<byte> dec(const byte[], size_t) const override;
diff --git a/src/lib/pubkey/x509_key.h b/src/lib/pubkey/x509_key.h
index 1bfa248ff..cbb0412d2 100644
--- a/src/lib/pubkey/x509_key.h
+++ b/src/lib/pubkey/x509_key.h
@@ -10,7 +10,7 @@
#include <botan/pk_keys.h>
#include <botan/alg_id.h>
-#include <botan/pipe.h>
+#include <botan/data_src.h>
#include <string>
namespace Botan {
diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp
index 1ab80669b..8b949d071 100644
--- a/src/lib/rng/system_rng/system_rng.cpp
+++ b/src/lib/rng/system_rng/system_rng.cpp
@@ -1,6 +1,6 @@
/*
* System RNG
-* (C) 2014 Jack Lloyd
+* (C) 2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -28,11 +28,11 @@ namespace Botan {
namespace {
-class System_RNG : public RandomNumberGenerator
+class System_RNG_Impl : public RandomNumberGenerator
{
public:
- System_RNG();
- ~System_RNG();
+ System_RNG_Impl();
+ ~System_RNG_Impl();
void randomize(byte buf[], size_t len) override;
@@ -51,7 +51,7 @@ class System_RNG : public RandomNumberGenerator
#endif
};
-System_RNG::System_RNG()
+System_RNG_Impl::System_RNG_Impl()
{
#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
@@ -66,7 +66,7 @@ System_RNG::System_RNG()
#endif
}
-System_RNG::~System_RNG()
+System_RNG_Impl::~System_RNG_Impl()
{
#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
::CryptReleaseContext(m_prov, 0);
@@ -76,7 +76,7 @@ System_RNG::~System_RNG()
#endif
}
-void System_RNG::randomize(byte buf[], size_t len)
+void System_RNG_Impl::randomize(byte buf[], size_t len)
{
#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf);
@@ -104,7 +104,7 @@ void System_RNG::randomize(byte buf[], size_t len)
RandomNumberGenerator& system_rng()
{
- static System_RNG g_system_rng;
+ static System_RNG_Impl g_system_rng;
return g_system_rng;
}
diff --git a/src/lib/rng/system_rng/system_rng.h b/src/lib/rng/system_rng/system_rng.h
index cac861618..0f4b94725 100644
--- a/src/lib/rng/system_rng/system_rng.h
+++ b/src/lib/rng/system_rng/system_rng.h
@@ -1,6 +1,6 @@
/*
* System RNG interface
-* (C) 2014 Jack Lloyd
+* (C) 2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -19,6 +19,29 @@ namespace Botan {
*/
BOTAN_DLL RandomNumberGenerator& system_rng();
+/*
+* Instantiatable reference to the system RNG.
+*/
+class BOTAN_DLL System_RNG : public RandomNumberGenerator
+ {
+ public:
+ System_RNG() : m_rng(system_rng()) {}
+
+ void randomize(Botan::byte out[], size_t len) override { m_rng.randomize(out, len); }
+
+ bool is_seeded() const override { return m_rng.is_seeded(); }
+
+ void clear() override { m_rng.clear(); }
+
+ std::string name() const override { return m_rng.name(); }
+
+ void reseed(size_t poll_bits = 256) override { m_rng.reseed(poll_bits); }
+
+ void add_entropy(const byte in[], size_t len) override { m_rng.add_entropy(in, len); }
+ private:
+ Botan::RandomNumberGenerator& m_rng;
+ };
+
}
#endif
diff --git a/src/lib/filters/data_src.cpp b/src/lib/utils/data_src.cpp
index 4e0725943..4e0725943 100644
--- a/src/lib/filters/data_src.cpp
+++ b/src/lib/utils/data_src.cpp
diff --git a/src/lib/filters/data_src.h b/src/lib/utils/data_src.h
index 2b6998448..2b6998448 100644
--- a/src/lib/filters/data_src.h
+++ b/src/lib/utils/data_src.h
diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt
index 7d3216b1c..79026d7a9 100644
--- a/src/lib/utils/info.txt
+++ b/src/lib/utils/info.txt
@@ -9,6 +9,7 @@ calendar.h
charset.h
cpuid.h
database.h
+data_src.h
exceptn.h
loadstor.h
mem_ops.h
diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp
index f8ab2bcd1..3a7cd0dcf 100644
--- a/src/lib/vendor/openssl/openssl_rsa.cpp
+++ b/src/lib/vendor/openssl/openssl_rsa.cpp
@@ -24,16 +24,33 @@ namespace {
std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme)
{
+ ERR_load_crypto_strings();
if(eme == "Raw")
return std::make_pair(RSA_NO_PADDING, 0);
else if(eme == "EME-PKCS1-v1_5")
return std::make_pair(RSA_PKCS1_PADDING, 11);
- else if(eme == "EME1(SHA-1)")
+ else if(eme == "OAEP(SHA-1)")
return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41);
else
throw Lookup_Error("OpenSSL RSA does not support EME " + eme);
}
+secure_vector<byte> strip_leading_zeros(const secure_vector<byte>& input)
+ {
+ size_t leading_zeros = 0;
+
+ for(size_t i = 0; i != input.size(); ++i)
+ {
+ if(input[i] != 0)
+ break;
+ ++leading_zeros;
+ }
+
+ secure_vector<byte> output(&input[leading_zeros],
+ &input[input.size()]);
+ return output;
+ }
+
class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption
{
public:
@@ -63,7 +80,7 @@ class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption
if(!m_openssl_rsa)
throw OpenSSL_Error("d2i_RSAPublicKey");
- m_bits = 8 * n_size() - pad_overhead;
+ m_bits = 8 * (n_size() - pad_overhead) - 1;
}
size_t max_input_bits() const override { return m_bits; };
@@ -133,11 +150,9 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption
m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
if(!m_openssl_rsa)
throw OpenSSL_Error("d2i_RSAPrivateKey");
-
- m_bits = 8 * ::RSA_size(m_openssl_rsa.get());
}
- size_t max_input_bits() const override { return m_bits; };
+ size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override
{
@@ -149,25 +164,129 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption
if(m_padding == RSA_NO_PADDING)
{
- size_t leading_0s = 0;
- while(leading_0s < buf.size() && buf[leading_0s] == 0)
- leading_0s++;
-
- if(leading_0s)
- return secure_vector<byte>(&buf[leading_0s], &buf[buf.size()]);
+ return strip_leading_zeros(buf);
}
-
return buf;
}
private:
std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
- size_t m_bits = 0;
int m_padding = 0;
};
+class OpenSSL_RSA_Verification_Operation : public PK_Ops::Verification_with_EMSA
+ {
+ public:
+ typedef RSA_PublicKey Key_Type;
+
+ static OpenSSL_RSA_Verification_Operation* make(const Spec& spec)
+ {
+ if(const RSA_PublicKey* rsa = dynamic_cast<const RSA_PublicKey*>(&spec.key()))
+ {
+ return new OpenSSL_RSA_Verification_Operation(*rsa, spec.padding());
+ }
+
+ return nullptr;
+ }
+
+ OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) :
+ PK_Ops::Verification_with_EMSA(emsa),
+ m_openssl_rsa(nullptr, ::RSA_free)
+ {
+ const std::vector<byte> der = rsa.x509_subject_public_key();
+ const byte* der_ptr = der.data();
+ m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
+ }
+
+ size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
+
+ bool with_recovery() const override { return true; }
+
+ secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) override
+ {
+ const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
+
+ if(msg_len > mod_sz)
+ throw Invalid_Argument("OpenSSL RSA verify input too large");
+
+ secure_vector<byte> inbuf(mod_sz);
+ copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
+
+ secure_vector<byte> outbuf(mod_sz);
+
+ int rc = ::RSA_public_decrypt(inbuf.size(), inbuf.data(), outbuf.data(),
+ m_openssl_rsa.get(), RSA_NO_PADDING);
+ if(rc < 0)
+ throw Invalid_Argument("RSA_public_decrypt");
+
+ return strip_leading_zeros(outbuf);
+ }
+ private:
+ std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
+ };
+
+class OpenSSL_RSA_Signing_Operation : public PK_Ops::Signature_with_EMSA
+ {
+ public:
+ typedef RSA_PrivateKey Key_Type;
+
+ static OpenSSL_RSA_Signing_Operation* make(const Spec& spec)
+ {
+ if(const RSA_PrivateKey* rsa = dynamic_cast<const RSA_PrivateKey*>(&spec.key()))
+ {
+ return new OpenSSL_RSA_Signing_Operation(*rsa, spec.padding());
+ }
+
+ return nullptr;
+ }
+
+ OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) :
+ PK_Ops::Signature_with_EMSA(emsa),
+ m_openssl_rsa(nullptr, ::RSA_free)
+ {
+ const secure_vector<byte> der = rsa.pkcs8_private_key();
+ const byte* der_ptr = der.data();
+ m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
+ if(!m_openssl_rsa)
+ throw OpenSSL_Error("d2i_RSAPrivateKey");
+ }
+
+ secure_vector<byte> raw_sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator&) override
+ {
+ const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
+
+ if(msg_len > mod_sz)
+ throw Invalid_Argument("OpenSSL RSA sign input too large");
+
+ secure_vector<byte> inbuf(mod_sz);
+ copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
+
+ secure_vector<byte> outbuf(mod_sz);
+
+ int rc = ::RSA_private_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
+ m_openssl_rsa.get(), RSA_NO_PADDING);
+ if(rc < 0)
+ throw OpenSSL_Error("RSA_private_encrypt");
+
+ return outbuf;
+ }
+
+ size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
+
+ private:
+ std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
+ };
+
+BOTAN_REGISTER_TYPE(PK_Ops::Verification, OpenSSL_RSA_Verification_Operation, "RSA",
+ OpenSSL_RSA_Verification_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
+
+BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_RSA_Signing_Operation, "RSA",
+ OpenSSL_RSA_Signing_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
+
BOTAN_REGISTER_TYPE(PK_Ops::Encryption, OpenSSL_RSA_Encryption_Operation, "RSA",
OpenSSL_RSA_Encryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
+
BOTAN_REGISTER_TYPE(PK_Ops::Decryption, OpenSSL_RSA_Decryption_Operation, "RSA",
OpenSSL_RSA_Decryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
diff --git a/src/scripts/ci/travis/build.sh b/src/scripts/ci/travis/build.sh
index 6834b6ae0..369450091 100755
--- a/src/scripts/ci/travis/build.sh
+++ b/src/scripts/ci/travis/build.sh
@@ -14,7 +14,7 @@ elif [ "$BUILD_MODE" = "sanitizer" ]; then
fi
if [ "$MODULES" = "min" ]; then
- CFG_FLAGS+=(--no-autoload --enable-modules=base)
+ CFG_FLAGS+=(--minimized-build --enable-modules=base)
fi
# Workaround for missing update-alternatives
diff --git a/src/scripts/website.sh b/src/scripts/website.sh
index 525b2fcca..5b7e1c6cb 100755
--- a/src/scripts/website.sh
+++ b/src/scripts/website.sh
@@ -12,8 +12,8 @@ rm -rf $WEBSITE_SRC_DIR $WEBSITE_DIR
mkdir -p $WEBSITE_SRC_DIR
cp readme.rst $WEBSITE_SRC_DIR/index.rst
-cp -r doc/news.rst $WEBSITE_SRC_DIR
-echo -e ".. toctree::\n\n index\n news\n" > $WEBSITE_SRC_DIR/contents.rst
+cp -r doc/news.rst doc/security.rst $WEBSITE_SRC_DIR
+echo -e ".. toctree::\n\n index\n news\n security\n" > $WEBSITE_SRC_DIR/contents.rst
sphinx-build -t website -c "$SPHINX_CONFIG" -b "$SPHINX_BUILDER" $WEBSITE_SRC_DIR $WEBSITE_DIR
sphinx-build -t website -c "$SPHINX_CONFIG" -b "$SPHINX_BUILDER" doc/manual $WEBSITE_DIR/manual
diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp
index 81a15445e..f443ddabf 100644
--- a/src/tests/test_modes.cpp
+++ b/src/tests/test_modes.cpp
@@ -8,11 +8,8 @@
#if defined(BOTAN_HAS_MODES)
-#if defined(BOTAN_HAS_FILTERS)
-
#include <botan/hex.h>
#include <botan/cipher_mode.h>
-#include <botan/filters.h>
#include <iostream>
#include <fstream>
#include <memory>
@@ -27,21 +24,16 @@ secure_vector<byte> run_mode(const std::string& algo,
const secure_vector<byte>& nonce,
const secure_vector<byte>& key)
{
-#if 0
std::unique_ptr<Cipher_Mode> cipher(get_cipher_mode(algo, dir));
+ if(!cipher)
+ throw std::runtime_error("No cipher " + algo + " enabled in build");
cipher->set_key(key);
cipher->start(nonce);
secure_vector<byte> ct = pt;
cipher->finish(ct);
-#else
- Pipe pipe(get_cipher(algo, SymmetricKey(key), InitializationVector(nonce), dir));
-
- pipe.process_msg(pt);
-
- return pipe.read_all();
-#endif
+ return ct;
}
size_t mode_test(const std::string& algo,
@@ -102,12 +94,6 @@ size_t test_modes()
#else
-UNTESTED_WARNING(modes);
-
-#endif // BOTAN_HAS_FILTERS
-
-#else
-
SKIP_TEST(modes);
#endif // BOTAN_HAS_MODES
diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp
index f5528af12..09f3843bb 100644
--- a/src/tests/test_pubkey.cpp
+++ b/src/tests/test_pubkey.cpp
@@ -22,6 +22,7 @@
#include <botan/x509_key.h>
#include <botan/pkcs8.h>
#include <botan/pubkey.h>
+#include <botan/hex.h>
#if defined(BOTAN_HAS_RSA)
#include <botan/rsa.h>
@@ -64,8 +65,8 @@
#include <botan/kdf.h>
#endif
-#include <botan/filters.h>
#include <botan/numthry.h>
+
using namespace Botan;
namespace {
@@ -73,12 +74,8 @@ namespace {
void dump_data(const std::vector<byte>& out,
const std::vector<byte>& expected)
{
- Pipe pipe(new Hex_Encoder);
-
- pipe.process_msg(out);
- pipe.process_msg(expected);
- std::cout << "Got: " << pipe.read_all_as_string(0) << std::endl;
- std::cout << "Exp: " << pipe.read_all_as_string(1) << std::endl;
+ std::cout << "Got: " << hex_encode(out) << std::endl;
+ std::cout << "Exp: " << hex_encode(expected) << std::endl;
}
size_t validate_save_and_load(const Private_Key* priv_key,
diff --git a/src/tests/test_rsa.cpp b/src/tests/test_rsa.cpp
index 940525574..dcc741bd2 100644
--- a/src/tests/test_rsa.cpp
+++ b/src/tests/test_rsa.cpp
@@ -37,7 +37,7 @@ size_t rsaes_kat(const std::string& e,
if(padding == "")
padding = "Raw";
- PK_Encryptor_EME enc(pubkey, padding);
+ PK_Encryptor_EME enc(pubkey, padding, "base");
PK_Decryptor_EME dec(privkey, padding);
return validate_encryption(enc, dec, "RSAES/" + padding, msg, nonce, output);
@@ -61,7 +61,7 @@ size_t rsa_sig_kat(const std::string& e,
padding = "Raw";
PK_Verifier verify(pubkey, padding);
- PK_Signer sign(privkey, padding);
+ PK_Signer sign(privkey, padding, IEEE_1363, "base");
return validate_signature(verify, sign, "RSA/" + padding, msg, rng, nonce, output);
}
diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp
index f77be1992..0d3946012 100644
--- a/src/tests/unit_x509.cpp
+++ b/src/tests/unit_x509.cpp
@@ -11,8 +11,8 @@
#if defined(BOTAN_HAS_RSA) && defined(BOTAN_HAS_DSA)
#include <botan/calendar.h>
-#include <botan/filters.h>
#include <botan/pkcs8.h>
+#include <botan/hash.h>
#include <botan/pkcs10.h>
#include <botan/x509self.h>
#include <botan/x509path.h>
@@ -45,22 +45,12 @@ X509_Time from_date(const int y, const int m, const int d)
u64bit key_id(const Public_Key* key)
{
- Pipe pipe(new Hash_Filter("SHA-1", 8));
- pipe.start_msg();
- pipe.write(key->algo_name());
- pipe.write(key->algorithm_identifier().parameters);
- pipe.write(key->x509_subject_public_key());
- pipe.end_msg();
-
- secure_vector<byte> output = pipe.read_all();
-
- if(output.size() != 8)
- throw Internal_Error("Public_Key::key_id: Incorrect output size");
-
- u64bit id = 0;
- for(u32bit j = 0; j != 8; ++j)
- id = (id << 8) | output[j];
- return id;
+ std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-1"));
+ hash->update(key->algo_name());
+ hash->update(key->algorithm_identifier().parameters);
+ hash->update(key->x509_subject_public_key());
+ secure_vector<byte> output = hash->final();
+ return load_be<u64bit>(output.data(), 0);
}