aboutsummaryrefslogtreecommitdiffstats
path: root/checks/pk.cpp
diff options
context:
space:
mode:
authorlloyd <lloyd@randombit.net>2006-05-18 18:33:19 +0000
committerlloyd <lloyd@randombit.net>2006-05-18 18:33:19 +0000
commita2c99d3270eb73ef2db5704fc54356c6b75096f8 (patch)
treead3d6c4fcc8dd0f403f8105598943616246fe172 /checks/pk.cpp
Initial checkin1.5.6
Diffstat (limited to 'checks/pk.cpp')
-rw-r--r--checks/pk.cpp747
1 files changed, 747 insertions, 0 deletions
diff --git a/checks/pk.cpp b/checks/pk.cpp
new file mode 100644
index 000000000..b6406b4f2
--- /dev/null
+++ b/checks/pk.cpp
@@ -0,0 +1,747 @@
+/* This file is in the public domain */
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <cstdlib>
+#include <memory>
+
+#include <botan/botan.h>
+#include <botan/libstate.h>
+#include <botan/rsa.h>
+#include <botan/dsa.h>
+#include <botan/dh.h>
+
+#if !defined(BOTAN_NO_NR)
+ #include <botan/nr.h>
+#endif
+
+#if !defined(BOTAN_NO_RW)
+ #include <botan/rw.h>
+#endif
+
+#if !defined(BOTAN_NO_ELG)
+ #include <botan/elgamal.h>
+#endif
+
+#if !defined(BOTAN_NO_DLIES)
+ #include <botan/dlies.h>
+#endif
+
+#include <botan/filters.h>
+#include <botan/look_pk.h>
+#include <botan/numthry.h>
+
+#include <botan/x931_rng.h>
+#include <botan/rng.h>
+using namespace Botan;
+
+#include "common.h"
+
+static BigInt to_bigint(const std::string& h)
+ {
+ return BigInt::decode((const byte*)h.data(),
+ h.length(), BigInt::Hexadecimal);
+ }
+
+#define DEBUG 0
+
+class Fixed_Output_RNG : public RandomNumberGenerator
+ {
+ public:
+ byte random()
+ {
+ if(position < output.size())
+ return output[position++];
+ std::cout << "Fixed_Output_RNG: Ran out of bits" << std::endl;
+ std::exit(1);
+ // Annoying: some compilers warn if a return is here (unreachable
+ // code), others warn if it's not (no return from function).
+ /* return 0; */
+ }
+ void randomize(byte out[], u32bit len) throw()
+ {
+ for(u32bit j = 0; j != len; j++)
+ out[j] = random();
+ }
+ std::string name() const { return "Fixed_Output_RNG"; }
+ void clear() throw() {}
+ void add_randomness(const byte[], u32bit) throw() {}
+ Fixed_Output_RNG(const SecureVector<byte>& x)
+ {
+ output = x;
+ position = 0;
+ }
+ private:
+ SecureVector<byte> output;
+ u32bit position;
+ };
+
+void do_pk_keygen_tests();
+extern void do_x509_tests();
+
+u32bit validate_dsa_sig(const std::string&, const std::vector<std::string>&);
+u32bit validate_dsa_ver(const std::string&, const std::vector<std::string>&);
+
+u32bit validate_rsa_enc(const std::string&, const std::vector<std::string>&);
+u32bit validate_rsa_enc_pkcs8(const std::string&,
+ const std::vector<std::string>&);
+u32bit validate_rsa_sig(const std::string&, const std::vector<std::string>&);
+u32bit validate_rsa_ver(const std::string&, const std::vector<std::string>&);
+u32bit validate_rsa_ver_x509(const std::string&,
+ const std::vector<std::string>&);
+u32bit validate_rw_ver(const std::string&, const std::vector<std::string>&);
+u32bit validate_rw_sig(const std::string&, const std::vector<std::string>&);
+u32bit validate_nr_sig(const std::string&, const std::vector<std::string>&);
+u32bit validate_elg_enc(const std::string&, const std::vector<std::string>&);
+u32bit validate_dh(const std::string&, const std::vector<std::string>&);
+u32bit validate_dlies(const std::string&, const std::vector<std::string>&);
+
+u32bit do_pk_validation_tests(const std::string& filename)
+ {
+ std::ifstream test_data(filename.c_str());
+
+ if(!test_data)
+ {
+ std::cout << "Couldn't open test file " << filename << std::endl;
+ std::exit(1);
+ }
+
+ u32bit errors = 0, alg_count = 0;
+ std::string algorithm, print_algorithm;
+
+ while(!test_data.eof())
+ {
+ if(test_data.bad() || test_data.fail())
+ {
+ std::cout << "File I/O error." << std::endl;
+ std::exit(1);
+ }
+
+ std::string line;
+ std::getline(test_data, line);
+
+ strip_comments(line);
+ if(line.size() == 0) continue;
+
+ // Do line continuation
+ while(line[line.size()-1] == '\\' && !test_data.eof())
+ {
+ line.replace(line.size()-1, 1, "");
+ std::string nextline;
+ std::getline(test_data, nextline);
+ strip_comments(nextline);
+ if(nextline.size() == 0) continue;
+ line.push_back('\n');
+ line += nextline;
+ }
+
+ if(line[0] == '[' && line[line.size() - 1] == ']')
+ {
+ std::string old_algo = print_algorithm;
+ algorithm = line.substr(1, line.size() - 2);
+ print_algorithm = algorithm;
+ if(print_algorithm.find("_PKCS8") != std::string::npos)
+ print_algorithm.replace(print_algorithm.find("_PKCS8"), 6, "");
+ if(print_algorithm.find("_X509") != std::string::npos)
+ print_algorithm.replace(print_algorithm.find("_X509"), 5, "");
+ if(print_algorithm.find("_VA") != std::string::npos)
+ print_algorithm.replace(print_algorithm.find("_VA"), 3, "");
+
+ if(old_algo != print_algorithm && old_algo != "")
+ {
+ std::cout << std::endl;
+ alg_count = 0;
+ }
+
+ if(old_algo != print_algorithm)
+ std::cout << "Testing " << print_algorithm << ": ";
+ continue;
+ }
+
+ std::cout << '.';
+ std::cout.flush();
+
+ std::vector<std::string> substr = parse(line);
+
+#if DEBUG
+ std::cout << "Testing: " << print_algorithm << std::endl;
+#endif
+
+ u32bit new_errors = 0;
+
+ if(algorithm.find("DSA/") != std::string::npos)
+ new_errors = validate_dsa_sig(algorithm, substr);
+ else if(algorithm.find("DSA_VA/") != std::string::npos)
+ new_errors = validate_dsa_ver(algorithm, substr);
+
+ else if(algorithm.find("RSAES_PKCS8/") != std::string::npos)
+ new_errors = validate_rsa_enc_pkcs8(algorithm, substr);
+ else if(algorithm.find("RSAVA_X509/") != std::string::npos)
+ new_errors = validate_rsa_ver_x509(algorithm, substr);
+
+ else if(algorithm.find("RSAES/") != std::string::npos)
+ new_errors = validate_rsa_enc(algorithm, substr);
+ else if(algorithm.find("RSASSA/") != std::string::npos)
+ new_errors = validate_rsa_sig(algorithm, substr);
+ else if(algorithm.find("RSAVA/") != std::string::npos)
+ new_errors = validate_rsa_ver(algorithm, substr);
+ else if(algorithm.find("RWVA/") != std::string::npos)
+ new_errors = validate_rw_ver(algorithm, substr);
+ else if(algorithm.find("RW/") != std::string::npos)
+ new_errors = validate_rw_sig(algorithm, substr);
+ else if(algorithm.find("NR/") != std::string::npos)
+ new_errors = validate_nr_sig(algorithm, substr);
+ else if(algorithm.find("ElGamal/") != std::string::npos)
+ new_errors = validate_elg_enc(algorithm, substr);
+ else if(algorithm.find("DH/") != std::string::npos)
+ new_errors = validate_dh(algorithm, substr);
+ else if(algorithm.find("DLIES/") != std::string::npos)
+ new_errors = validate_dlies(algorithm, substr);
+ else
+ std::cout << "WARNING: Unknown PK algorithm "
+ << algorithm << std::endl;
+
+ alg_count++;
+ errors += new_errors;
+
+ if(new_errors)
+ std::cout << "ERROR: \"" << algorithm << "\" failed test #"
+ << std::dec << alg_count << std::endl;
+ }
+
+ std::cout << std::endl;
+
+ global_state().set_prng(new ANSI_X931_RNG);
+ for(u32bit j = 0; j != 2; j++)
+ Global_RNG::seed(true, 384);
+
+ do_pk_keygen_tests();
+ do_x509_tests();
+
+ return errors;
+ }
+
+void dump_data(const SecureVector<byte>& out,
+ const SecureVector<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;
+ }
+
+void validate_decryption(PK_Decryptor* d, const std::string& algo,
+ const SecureVector<byte> ctext,
+ const SecureVector<byte> ptext,
+ bool& failure)
+ {
+ SecureVector<byte> decrypted = d->decrypt(ctext);
+ if(decrypted != ptext)
+ {
+ std::cout << "FAILED (decrypt): " << algo << std::endl;
+ dump_data(decrypted, ptext);
+ failure = true;
+ }
+ delete d;
+ }
+
+void validate_encryption(PK_Encryptor* e, PK_Decryptor* d,
+ const std::string& algo, const std::string& input,
+ const std::string& random, const std::string& exp,
+ bool& failure)
+ {
+ SecureVector<byte> message = decode_hex(input);
+
+ global_state().set_prng(new Fixed_Output_RNG(decode_hex(random)));
+
+ SecureVector<byte> expected = decode_hex(exp);
+
+ SecureVector<byte> out = e->encrypt(message);
+ if(out != expected)
+ {
+ std::cout << "FAILED (encrypt): " << algo << std::endl;
+ dump_data(out, expected);
+ failure = true;
+ }
+
+ global_state().set_prng(new ANSI_X931_RNG);
+ for(u32bit j = 0; j != 2; j++)
+ Global_RNG::seed(true, 384);
+
+ validate_decryption(d, algo, out, message, failure);
+ delete e;
+ }
+
+void validate_signature(PK_Verifier* v, PK_Signer* s, const std::string& algo,
+ const std::string& input, const std::string& random,
+ const std::string& exp, bool& failure)
+ {
+ SecureVector<byte> message = decode_hex(input);
+ global_state().set_prng(new Fixed_Output_RNG(decode_hex(random)));
+
+ SecureVector<byte> expected = decode_hex(exp);
+
+ SecureVector<byte> sig = s->sign_message(message, message.size());
+
+ if(sig != expected)
+ {
+ std::cout << "FAILED (sign): " << algo << std::endl;
+ dump_data(sig, expected);
+ failure = true;
+ }
+
+ if(!v->verify_message(message, message.size(), sig, sig.size()))
+ {
+ std::cout << "FAILED (verify): " << algo << std::endl;
+ failure = true;
+ }
+
+ /* This isn't a very thorough testing method, but it will hopefully
+ catch any really horrible errors */
+ sig[0]++;
+ if(v->verify_message(message, message.size(), sig, sig.size()))
+ {
+ std::cout << "FAILED (accepted bad sig): " << algo << std::endl;
+ failure = true;
+ }
+
+ global_state().set_prng(new ANSI_X931_RNG);
+ for(u32bit j = 0; j != 2; j++)
+ Global_RNG::seed(true, 384);
+
+ delete v;
+ delete s;
+ }
+
+void validate_kas(PK_Key_Agreement* kas, const std::string& algo,
+ const SecureVector<byte>& pubkey, const std::string& output,
+ u32bit keylen, bool& failure)
+ {
+ SecureVector<byte> expected = decode_hex(output);
+
+ SecureVector<byte> got = kas->derive_key(keylen,
+ pubkey, pubkey.size()).bits_of();
+
+ if(got != expected)
+ {
+ std::cout << "FAILED: " << algo << std::endl;
+ dump_data(got, expected);
+ failure = true;
+ }
+
+ delete kas;
+ }
+
+u32bit validate_rsa_enc_pkcs8(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 4 && str.size() != 5)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ std::string pass;
+ if(str.size() == 5) pass = str[4];
+ strip_newlines(pass); /* it will have a newline thanks to the messy
+ decoding method we use */
+
+ DataSource_Memory keysource((const byte*)str[0].c_str(), str[0].length());
+ PKCS8_PrivateKey* privkey = PKCS8::load_key(keysource, pass);
+
+ RSA_PrivateKey* rsapriv = dynamic_cast<RSA_PrivateKey*>(privkey);
+ if(!rsapriv)
+ throw Invalid_Argument("Bad key load for RSA key");
+
+ RSA_PublicKey* rsapub = dynamic_cast<RSA_PublicKey*>(rsapriv);
+
+ std::string eme = algo.substr(12, std::string::npos);
+
+ PK_Encryptor* e = get_pk_encryptor(*rsapub, eme);
+ PK_Decryptor* d = get_pk_decryptor(*rsapriv, eme);
+
+ bool failure = false;
+ validate_encryption(e, d, algo, str[1], str[2], str[3], failure);
+ delete privkey;
+ return (failure ? 1 : 0);
+ }
+
+u32bit validate_rsa_enc(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 6)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ RSA_PrivateKey privkey(to_bigint(str[1]), to_bigint(str[2]),
+ to_bigint(str[0]));
+ RSA_PublicKey pubkey = privkey;
+
+ std::string eme = algo.substr(6, std::string::npos);
+
+ PK_Encryptor* e = get_pk_encryptor(pubkey, eme);
+ PK_Decryptor* d = get_pk_decryptor(privkey, eme);
+
+ bool failure = false;
+ validate_encryption(e, d, algo, str[3], str[4], str[5], failure);
+ return (failure ? 1 : 0);
+ }
+
+u32bit validate_elg_enc(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+#if defined(BOTAN_NO_ELG)
+ return 0;
+#else
+ if(str.size() != 6 && str.size() != 7)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ DL_Group domain(to_bigint(str[0]), to_bigint(str[1]));
+ ElGamal_PrivateKey privkey(domain, to_bigint(str[2]), to_bigint(str[3]));
+ ElGamal_PublicKey pubkey = privkey;
+
+ std::string eme = algo.substr(8, std::string::npos);
+
+ PK_Decryptor* d = get_pk_decryptor(privkey, eme);
+ bool failure = false;
+
+ if(str.size() == 7)
+ {
+ PK_Encryptor* e = get_pk_encryptor(pubkey, eme);
+ validate_encryption(e, d, algo, str[4], str[5], str[6], failure);
+ }
+ else
+ validate_decryption(d, algo, decode_hex(str[5]),
+ decode_hex(str[4]), failure);
+
+ return (failure ? 1 : 0);
+#endif
+ }
+
+u32bit validate_rsa_sig(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 6)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ RSA_PrivateKey privkey(to_bigint(str[1]), to_bigint(str[2]),
+ to_bigint(str[0]));
+ RSA_PublicKey pubkey = privkey;
+
+ std::string emsa = algo.substr(7, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(pubkey, emsa);
+ PK_Signer* s = get_pk_signer(privkey, emsa);
+
+ bool failure = false;
+ validate_signature(v, s, algo, str[3], str[4], str[5], failure);
+ return (failure ? 1 : 0);
+ }
+
+u32bit validate_rsa_ver(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 5) /* is actually 4, parse() adds an extra empty one */
+ throw Exception("Invalid input from pk_valid.dat");
+
+ RSA_PublicKey key(to_bigint(str[1]), to_bigint(str[0]));
+
+ std::string emsa = algo.substr(6, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(key, emsa);
+
+ SecureVector<byte> msg = decode_hex(str[2]);
+ SecureVector<byte> sig = decode_hex(str[3]);
+
+ bool passed = v->verify_message(msg, msg.size(), sig, sig.size());
+
+ delete v;
+
+ return (passed ? 0 : 1);
+ }
+
+u32bit validate_rsa_ver_x509(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 5) /* is actually 3, parse() adds extra empty ones */
+ throw Exception("Invalid input from pk_valid.dat");
+
+ DataSource_Memory keysource((const byte*)str[0].c_str(), str[0].length());
+
+ X509_PublicKey* key = X509::load_key(keysource);
+
+ RSA_PublicKey* rsakey = dynamic_cast<RSA_PublicKey*>(key);
+
+ if(!rsakey)
+ throw Invalid_Argument("Bad key load for RSA public key");
+
+ std::string emsa = algo.substr(11, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(*rsakey, emsa);
+
+ SecureVector<byte> msg = decode_hex(str[1]);
+ SecureVector<byte> sig = decode_hex(str[2]);
+
+ bool passed = v->verify_message(msg, msg.size(), sig, sig.size());
+
+ delete v;
+ delete key;
+
+ return (passed ? 0 : 1);
+ }
+
+u32bit validate_rw_ver(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+#if defined(BOTAN_NO_RW)
+ return 0;
+#else
+ if(str.size() != 5)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ RW_PublicKey key(to_bigint(str[1]), to_bigint(str[0]));
+
+ std::string emsa = algo.substr(5, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(key, emsa);
+
+ SecureVector<byte> msg = decode_hex(str[2]);
+ SecureVector<byte> sig = decode_hex(str[3]);
+
+ bool passed = v->verify_message(msg, msg.size(), sig, sig.size());
+
+ delete v;
+
+ return (passed ? 0 : 1);
+#endif
+ }
+
+u32bit validate_rw_sig(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+#if defined(BOTAN_NO_RW)
+ return 0;
+#else
+ if(str.size() != 6)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ RW_PrivateKey privkey(to_bigint(str[1]), to_bigint(str[2]),
+ to_bigint(str[0]));
+ RW_PublicKey pubkey = privkey;
+
+ std::string emsa = algo.substr(3, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(pubkey, emsa);
+ PK_Signer* s = get_pk_signer(privkey, emsa);
+
+ bool failure = false;
+ validate_signature(v, s, algo, str[3], str[4], str[5], failure);
+ return (failure ? 1 : 0);
+#endif
+ }
+
+u32bit validate_dsa_sig(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 4 && str.size() != 5)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ std::string pass;
+ if(str.size() == 5) pass = str[4];
+ strip_newlines(pass); /* it will have a newline thanks to the messy
+ decoding method we use */
+
+ DataSource_Memory keysource((const byte*)str[0].c_str(), str[0].length());
+ PKCS8_PrivateKey* privkey = PKCS8::load_key(keysource, pass);
+
+ DSA_PrivateKey* dsapriv = dynamic_cast<DSA_PrivateKey*>(privkey);
+ if(!dsapriv)
+ throw Invalid_Argument("Bad key load for DSA private key");
+
+ DSA_PublicKey* dsapub = dynamic_cast<DSA_PublicKey*>(dsapriv);
+
+ std::string emsa = algo.substr(4, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(*dsapub, emsa);
+ PK_Signer* s = get_pk_signer(*dsapriv, emsa);
+
+ bool failure = false;
+ validate_signature(v, s, algo, str[1], str[2], str[3], failure);
+ delete privkey;
+
+ return (failure ? 1 : 0);
+ }
+
+u32bit validate_dsa_ver(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 5) /* is actually 3, parse() adds extra empty ones */
+ throw Exception("Invalid input from pk_valid.dat");
+
+ DataSource_Memory keysource((const byte*)str[0].c_str(), str[0].length());
+ X509_PublicKey* key = X509::load_key(keysource);
+
+ DSA_PublicKey* dsakey = dynamic_cast<DSA_PublicKey*>(key);
+
+ if(!dsakey)
+ throw Invalid_Argument("Bad key load for DSA public key");
+
+ std::string emsa = algo.substr(7, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(*dsakey, emsa);
+
+ SecureVector<byte> msg = decode_hex(str[1]);
+ SecureVector<byte> sig = decode_hex(str[2]);
+
+ v->set_input_format(DER_SEQUENCE);
+ bool passed = v->verify_message(msg, msg.size(), sig, sig.size());
+ delete v;
+ delete key;
+
+ return (passed ? 0 : 1);
+ }
+
+u32bit validate_nr_sig(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+#if defined(BOTAN_NO_NR)
+ return 0;
+#else
+ if(str.size() != 8)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ DL_Group domain(to_bigint(str[0]), to_bigint(str[1]), to_bigint(str[2]));
+ NR_PrivateKey privkey(domain, to_bigint(str[4]), to_bigint(str[3]));
+ NR_PublicKey pubkey = privkey;
+
+ std::string emsa = algo.substr(3, std::string::npos);
+
+ PK_Verifier* v = get_pk_verifier(pubkey, emsa);
+ PK_Signer* s = get_pk_signer(privkey, emsa);
+
+ bool failure = false;
+ validate_signature(v, s, algo, str[5], str[6], str[7], failure);
+ return (failure ? 1 : 0);
+#endif
+ }
+
+u32bit validate_dh(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+ if(str.size() != 5 && str.size() != 6)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ DL_Group domain(to_bigint(str[0]), to_bigint(str[1]));
+
+ DH_PrivateKey mykey(domain, to_bigint(str[2]), 0);
+ DH_PublicKey otherkey(domain, to_bigint(str[3]));
+
+ std::string kdf = algo.substr(3, std::string::npos);
+
+ u32bit keylen = 0;
+ if(str.size() == 6)
+ keylen = to_u32bit(str[5]);
+
+ PK_Key_Agreement* kas = get_pk_kas(mykey, kdf);
+
+ bool failure = false;
+ validate_kas(kas, algo, otherkey.public_value(),
+ str[4], keylen, failure);
+ return (failure ? 1 : 0);
+ }
+
+u32bit validate_dlies(const std::string& algo,
+ const std::vector<std::string>& str)
+ {
+#if defined(BOTAN_NO_DLIES)
+ return 0;
+#else
+ if(str.size() != 6)
+ throw Exception("Invalid input from pk_valid.dat");
+
+ DL_Group domain(to_bigint(str[0]), to_bigint(str[1]));
+
+ DH_PrivateKey from(domain, to_bigint(str[2]), 0);
+ DH_PrivateKey to(domain, to_bigint(str[3]), 0);
+
+ const std::string opt_str = algo.substr(6, std::string::npos);
+
+ std::vector<std::string> options = split_on(opt_str, '/');
+
+ if(options.size() != 3)
+ throw Exception("DLIES needs three options: " + opt_str);
+
+ std::string kdf = options[0];
+ std::string mac = options[1];
+ u32bit mac_key_len = to_u32bit(options[2]);
+
+ PK_Decryptor* d = new DLIES_Decryptor(to, kdf, mac, mac_key_len);
+ DLIES_Encryptor* e = new DLIES_Encryptor(from, kdf, mac, mac_key_len);
+ e->set_other_key(to.public_value());
+
+ std::string empty = "";
+ bool failure = false;
+ validate_encryption(e, d, algo, str[4], empty, str[5], failure);
+ return (failure ? 1 : 0);
+#endif
+ }
+
+void do_pk_keygen_tests()
+ {
+ std::cout << "Testing PK key generation: " << std::flush;
+
+ /* Putting each key in a block reduces memory pressure, speeds it up */
+#define IF_SIG_KEY(TYPE, BITS) \
+ { \
+ TYPE key(BITS); \
+ key.check_key(true); \
+ std::cout << '.' << std::flush; \
+ }
+
+#define DL_SIG_KEY(TYPE, GROUP) \
+ { \
+ TYPE key(DL_Group(GROUP)); \
+ key.check_key(true); \
+ std::cout << '.' << std::flush; \
+ }
+
+#define DL_ENC_KEY(TYPE, GROUP) \
+ { \
+ TYPE key(DL_Group(GROUP)); \
+ key.check_key(true); \
+ std::cout << '.' << std::flush; \
+ }
+
+#define DL_KEY(TYPE, GROUP) \
+ { \
+ TYPE key(DL_Group(GROUP)); \
+ key.check_key(true); \
+ std::cout << '.' << std::flush; \
+ }
+
+ IF_SIG_KEY(RSA_PrivateKey, 512);
+#if !defined(BOTAN_NO_RW)
+ IF_SIG_KEY(RW_PrivateKey, 512);
+#endif
+
+ DL_SIG_KEY(DSA_PrivateKey, "dsa/jce/512");
+ DL_SIG_KEY(DSA_PrivateKey, "dsa/jce/768");
+ DL_SIG_KEY(DSA_PrivateKey, "dsa/jce/1024");
+
+ DL_KEY(DH_PrivateKey, "modp/ietf/768");
+ DL_KEY(DH_PrivateKey, "modp/ietf/2048");
+ DL_KEY(DH_PrivateKey, "dsa/jce/1024");
+
+#if !defined(BOTAN_NO_NR)
+ DL_SIG_KEY(NR_PrivateKey, "dsa/jce/512");
+ DL_SIG_KEY(NR_PrivateKey, "dsa/jce/768");
+ DL_SIG_KEY(NR_PrivateKey, "dsa/jce/1024");
+#endif
+
+#if !defined(BOTAN_NO_ELG)
+ DL_ENC_KEY(ElGamal_PrivateKey, "modp/ietf/768");
+ DL_ENC_KEY(ElGamal_PrivateKey, "modp/ietf/1024");
+ DL_ENC_KEY(ElGamal_PrivateKey, "dsa/jce/1024");
+#endif
+
+ std::cout << std::endl;
+ }