aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-03-04 03:22:35 +0000
committerlloyd <[email protected]>2010-03-04 03:22:35 +0000
commit76f39cc9fe4b2a3354db22f8beaf0c3788578b79 (patch)
treec25ddaf29f22dc29786487d606d68c2344c46f22
parentda09382f398dcf27a3ffdb82dd9f916ba96567ac (diff)
Add a new constructor to each public key algorithm (only the public
keys so far, private keys not changed) that takes an AlgorithmIdentifier and a MemoryRegion<byte>&. This performs the X.509 decoding. It is not possible anymore to create uninitialized PK objects.
-rw-r--r--checks/ecdh.cpp58
-rw-r--r--checks/ecdsa.cpp41
-rw-r--r--src/pubkey/dh/dh.h11
-rw-r--r--src/pubkey/dl_algo/dl_algo.cpp10
-rw-r--r--src/pubkey/dl_algo/dl_algo.h6
-rw-r--r--src/pubkey/dsa/dsa.h7
-rw-r--r--src/pubkey/ecc_key/ecc_key.cpp17
-rw-r--r--src/pubkey/ecc_key/ecc_key.h3
-rw-r--r--src/pubkey/ecdh/ecdh.h11
-rw-r--r--src/pubkey/ecdsa/ecdsa.h28
-rw-r--r--src/pubkey/elgamal/elgamal.h7
-rw-r--r--src/pubkey/gost_3410/gost_3410.h34
-rw-r--r--src/pubkey/if_algo/if_algo.cpp13
-rw-r--r--src/pubkey/if_algo/if_algo.h5
-rw-r--r--src/pubkey/nr/nr.h7
-rw-r--r--src/pubkey/pk_algs.cpp77
-rw-r--r--src/pubkey/pk_algs.h19
-rw-r--r--src/pubkey/pkcs8.cpp18
-rw-r--r--src/pubkey/rsa/rsa.h5
-rw-r--r--src/pubkey/rw/rw.h8
-rw-r--r--src/pubkey/x509_key.cpp21
21 files changed, 195 insertions, 211 deletions
diff --git a/checks/ecdh.cpp b/checks/ecdh.cpp
index 9341f8432..cb3246ace 100644
--- a/checks/ecdh.cpp
+++ b/checks/ecdh.cpp
@@ -181,8 +181,7 @@ void test_ecdh_cp_ctor_as_op(RandomNumberGenerator& rng)
Botan::ECDH_PublicKey public_a = private_a; // Bob gets this
Botan::ECDH_PublicKey public_a2(public_a);
- Botan::ECDH_PublicKey public_a3;
- public_a3 = public_a;
+ Botan::ECDH_PublicKey public_a3 = public_a;
// Bob creates a key with a matching group
Botan::ECDH_PrivateKey private_b(rng, dom_pars); //public_a.getCurve()
@@ -206,60 +205,6 @@ void test_ecdh_cp_ctor_as_op(RandomNumberGenerator& rng)
CHECK_MESSAGE(alice_key_2 == bob_key_3, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string());
}
-/**
-* The following test tests whether ECDH keys exhibit correct behaviour when it is
-* attempted to use them in an uninitialized state
-*/
-void test_non_init_ecdh_keys(RandomNumberGenerator& rng)
- {
- std::cout << "." << std::flush;
-
- // set up dom pars
- std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82");
- Botan::SecureVector<Botan::byte> sv_g_secp = decode_hex(g_secp);
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- BigInt cofactor = BigInt(1);
- PointGFp p_G = OS2ECP ( sv_g_secp, curve );
- Botan::EC_Domain_Params dom_pars = Botan::EC_Domain_Params(curve, p_G, order, cofactor);
-
- // alices key (a key constructed by domain parameters IS an emphemeral key!)
- Botan::ECDH_PrivateKey private_a(rng, dom_pars);
- Botan::ECDH_PrivateKey private_b(rng, dom_pars);
-
- Botan::ECDH_PublicKey public_b;
-
- Botan::ECDH_PrivateKey private_empty;
- Botan::ECDH_PublicKey public_empty;
-
- bool exc1 = false;
- try
- {
- Botan::SymmetricKey void_key = private_empty.derive_key(public_b);
- }
- catch (Botan::Exception e)
- {
- exc1 = true;
- }
-
- CHECK_MESSAGE(exc1, "there was no exception thrown when attempting to use an uninitialized ECDH key");
-
- bool exc2 = false;
- try
- {
- Botan::SymmetricKey void_key = private_a.derive_key(public_empty);
- }
- catch (Botan::Exception e)
- {
- exc2 = true;
- }
-
- CHECK_MESSAGE(exc2, "there was no exception thrown when attempting to use an uninitialized ECDH key");
- }
-
}
u32bit do_ecdh_tests(Botan::RandomNumberGenerator& rng)
@@ -270,7 +215,6 @@ u32bit do_ecdh_tests(Botan::RandomNumberGenerator& rng)
test_ecdh_some_dp(rng);
test_ecdh_der_derivation(rng);
test_ecdh_cp_ctor_as_op(rng);
- test_non_init_ecdh_keys(rng);
std::cout << std::endl;
diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp
index 5dcd90efd..64ac4be6b 100644
--- a/checks/ecdsa.cpp
+++ b/checks/ecdsa.cpp
@@ -470,8 +470,7 @@ void test_cp_and_as_ctors(RandomNumberGenerator& rng)
ECDSA_PublicKey pk_1 = cp_priv_key; // pub-key, as-op
ECDSA_PublicKey pk_2(pk_1); // pub-key, cp-ctor
- ECDSA_PublicKey pk_3;
- pk_3 = pk_2; // pub-key, as-op
+ ECDSA_PublicKey pk_3 = pk_2;
bool ver_success_1 = pk_1.verify(sv_message.begin(), sv_message.size(), signature_1.begin(), signature_1.size());
@@ -482,43 +481,6 @@ void test_cp_and_as_ctors(RandomNumberGenerator& rng)
CHECK_MESSAGE((ver_success_1 && ver_success_2 && ver_success_3), "different results for copied keys");
}
-/**
-* The following test tests whether ECDSA keys exhibit correct behaviour when it is
-* attempted to use them in an uninitialized state
-*/
-void test_non_init_ecdsa_keys(RandomNumberGenerator& rng)
- {
- std::cout << "." << std::flush;
-
- std::auto_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
-
- std::string str_message = ("12345678901234567890abcdef12");
- ECDSA_PrivateKey empty_priv;
- ECDSA_PublicKey empty_pub;
- SecureVector<byte> sv_message = decode_hex(str_message);
- bool exc1 = false;
- try
- {
- SecureVector<byte> signature_1 = empty_priv.sign(sv_message.begin(), sv_message.size(), rng);
- }
- catch (std::exception e)
- {
- exc1 = true;
- }
- CHECK_MESSAGE(exc1, "there was no exception thrown when attempting to use an uninitialized ECDSA key");
-
- bool exc2 = false;
- try
- {
- empty_pub.verify(sv_message.begin(), sv_message.size(), sv_message.begin(), sv_message.size());
- }
- catch (std::exception e)
- {
- exc2 = true;
- }
- CHECK_MESSAGE(exc2, "there was no exception thrown when attempting to use an uninitialized ECDSA key");
- }
-
}
u32bit do_ecdsa_tests(Botan::RandomNumberGenerator& rng)
@@ -537,7 +499,6 @@ u32bit do_ecdsa_tests(Botan::RandomNumberGenerator& rng)
test_curve_registry(rng);
test_read_pkcs8(rng);
test_cp_and_as_ctors(rng);
- test_non_init_ecdsa_keys(rng);
std::cout << std::endl;
diff --git a/src/pubkey/dh/dh.h b/src/pubkey/dh/dh.h
index fa558bce2..7b81008a3 100644
--- a/src/pubkey/dh/dh.h
+++ b/src/pubkey/dh/dh.h
@@ -26,11 +26,10 @@ class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey
DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; }
- /**
- * Construct an uninitialized key. Use this constructor if you wish
- * to decode an encoded key into the new instance.
- */
- DH_PublicKey() {}
+ DH_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42)
+ { X509_load_hook(); }
/**
* Construct a public key with the specified parameters.
@@ -38,6 +37,8 @@ class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey
* @param y the public value y
*/
DH_PublicKey(const DL_Group& grp, const BigInt& y);
+ protected:
+ DH_PublicKey() {}
private:
void X509_load_hook();
};
diff --git a/src/pubkey/dl_algo/dl_algo.cpp b/src/pubkey/dl_algo/dl_algo.cpp
index f035f852f..bf7ab0a6a 100644
--- a/src/pubkey/dl_algo/dl_algo.cpp
+++ b/src/pubkey/dl_algo/dl_algo.cpp
@@ -23,6 +23,16 @@ MemoryVector<byte> DL_Scheme_PublicKey::x509_subject_public_key() const
return DER_Encoder().encode(y).get_contents();
}
+DL_Scheme_PublicKey::DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits,
+ DL_Group::Format format)
+ {
+ DataSource_Memory source(alg_id.parameters);
+ group.BER_decode(source, format);
+
+ BER_Decoder(key_bits).decode(y);
+ }
+
/*
* Return the X.509 public key decoder
*/
diff --git a/src/pubkey/dl_algo/dl_algo.h b/src/pubkey/dl_algo/dl_algo.h
index 9e5e46e2a..7492dc3bd 100644
--- a/src/pubkey/dl_algo/dl_algo.h
+++ b/src/pubkey/dl_algo/dl_algo.h
@@ -68,7 +68,13 @@ class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key
* values in this instance.
*/
X509_Decoder* x509_decoder();
+
+ DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits,
+ DL_Group::Format group_format);
+
protected:
+ DL_Scheme_PublicKey() {}
BigInt y;
DL_Group group;
private:
diff --git a/src/pubkey/dsa/dsa.h b/src/pubkey/dsa/dsa.h
index 4c9b708f4..302715222 100644
--- a/src/pubkey/dsa/dsa.h
+++ b/src/pubkey/dsa/dsa.h
@@ -29,8 +29,13 @@ class BOTAN_DLL DSA_PublicKey : public PK_Verifying_wo_MR_Key,
bool verify(const byte[], u32bit, const byte[], u32bit) const;
u32bit max_input_bits() const;
+ DSA_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_57)
+ { X509_load_hook(); }
+
+ DSA_PublicKey(const DL_Group& group, const BigInt& y);
DSA_PublicKey() {}
- DSA_PublicKey(const DL_Group&, const BigInt&);
protected:
DSA_Core core;
private:
diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp
index 2f98eb691..8e1f40665 100644
--- a/src/pubkey/ecc_key/ecc_key.cpp
+++ b/src/pubkey/ecc_key/ecc_key.cpp
@@ -57,6 +57,23 @@ void EC_PublicKey::X509_load_hook()
}
}
+EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits)
+ {
+ domain_params = EC_Domain_Params(alg_id.parameters);
+
+ public_key = PointGFp(OS2ECP(key_bits, domain().get_curve()));
+
+ try
+ {
+ public_point().check_invariants();
+ }
+ catch(Illegal_Point)
+ {
+ throw Decoding_Error("Invalid public point; not on curve");
+ }
+ }
+
X509_Decoder* EC_PublicKey::x509_decoder()
{
class EC_Key_Decoder : public X509_Decoder
diff --git a/src/pubkey/ecc_key/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h
index 6f3ab6a01..52aad4f03 100644
--- a/src/pubkey/ecc_key/ecc_key.h
+++ b/src/pubkey/ecc_key/ecc_key.h
@@ -84,6 +84,9 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key
EC_PublicKey(const EC_Domain_Params& dom_par,
const PointGFp& pub_point);
+ EC_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits);
+
virtual ~EC_PublicKey() {}
protected:
virtual void X509_load_hook();
diff --git a/src/pubkey/ecdh/ecdh.h b/src/pubkey/ecdh/ecdh.h
index 630237edf..10cf75de0 100644
--- a/src/pubkey/ecdh/ecdh.h
+++ b/src/pubkey/ecdh/ecdh.h
@@ -21,11 +21,10 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey
{
public:
- /**
- * Default constructor. Use this one if you want to later fill
- * this object with data from an encoded key.
- */
- ECDH_PublicKey() {}
+
+ ECDH_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ EC_PublicKey(alg_id, key_bits) {}
/**
* Construct a public key from a given public point.
@@ -49,6 +48,8 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey
* @result the maximum number of input bits
*/
u32bit max_input_bits() const { return domain().get_order().bits(); }
+ protected:
+ ECDH_PublicKey() {}
};
/**
diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h
index e7f29b600..4beb531b0 100644
--- a/src/pubkey/ecdsa/ecdsa.h
+++ b/src/pubkey/ecdsa/ecdsa.h
@@ -23,6 +23,19 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey,
public:
/**
+ * Construct a public key from a given public point.
+ * @param dom_par the domain parameters associated with this key
+ * @param public_point the public point defining this key
+ */
+ ECDSA_PublicKey(const EC_Domain_Params& dom_par,
+ const PointGFp& public_point) :
+ EC_PublicKey(dom_par, public_point) {}
+
+ ECDSA_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ EC_PublicKey(alg_id, key_bits) {}
+
+ /**
* Get this keys algorithm name.
* @result this keys algorithm name ("ECDSA")
*/
@@ -50,21 +63,8 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey,
bool verify(const byte message[], u32bit mess_len,
const byte signature[], u32bit sig_len) const;
- /**
- * Default constructor. Use this one if you want to later fill
- * this object with data from an encoded key.
- */
+ protected:
ECDSA_PublicKey() {}
-
- /**
- * Construct a public key from a given public point.
- * @param dom_par the domain parameters associated with this key
- * @param public_point the public point defining this key
- */
- ECDSA_PublicKey(const EC_Domain_Params& dom_par,
- const PointGFp& public_point) :
- EC_PublicKey(dom_par, public_point) {}
-
};
/**
diff --git a/src/pubkey/elgamal/elgamal.h b/src/pubkey/elgamal/elgamal.h
index 93e640f09..305587d93 100644
--- a/src/pubkey/elgamal/elgamal.h
+++ b/src/pubkey/elgamal/elgamal.h
@@ -27,9 +27,14 @@ class BOTAN_DLL ElGamal_PublicKey : public PK_Encrypting_Key,
RandomNumberGenerator& rng) const;
u32bit max_input_bits() const;
- ElGamal_PublicKey() {}
+ ElGamal_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42)
+ { X509_load_hook(); }
+
ElGamal_PublicKey(const DL_Group&, const BigInt&);
protected:
+ ElGamal_PublicKey() {}
ELG_Core core;
private:
void X509_load_hook();
diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h
index c1cd0d293..345833ede 100644
--- a/src/pubkey/gost_3410/gost_3410.h
+++ b/src/pubkey/gost_3410/gost_3410.h
@@ -23,6 +23,22 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey,
public:
/**
+ * Construct a public key from a given public point.
+ * @param dom_par the domain parameters associated with this key
+ * @param public_point the public point defining this key
+ */
+ GOST_3410_PublicKey(const EC_Domain_Params& dom_par,
+ const PointGFp& public_point) :
+ EC_PublicKey(dom_par, public_point) {}
+
+ /**
+ * Construct from X.509 algorithm id and subject public key bits
+ */
+ GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ EC_PublicKey(alg_id, key_bits) {}
+
+ /**
* Get this keys algorithm name.
* @result this keys algorithm name
*/
@@ -54,26 +70,14 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey,
const byte signature[], u32bit sig_len) const;
/**
- * Default constructor. Use this one if you want to later fill
- * this object with data from an encoded key.
- */
- GOST_3410_PublicKey() {}
-
- /**
- * Construct a public key from a given public point.
- * @param dom_par the domain parameters associated with this key
- * @param public_point the public point defining this key
- */
- GOST_3410_PublicKey(const EC_Domain_Params& dom_par,
- const PointGFp& public_point) :
- EC_PublicKey(dom_par, public_point) {}
-
- /**
* Get an x509_decoder that can be used to decode a stored key into
* this key.
* @result an x509_decoder for this key
*/
X509_Decoder* x509_decoder();
+
+ protected:
+ GOST_3410_PublicKey() {}
};
/**
diff --git a/src/pubkey/if_algo/if_algo.cpp b/src/pubkey/if_algo/if_algo.cpp
index 201d7aa53..8260d56e0 100644
--- a/src/pubkey/if_algo/if_algo.cpp
+++ b/src/pubkey/if_algo/if_algo.cpp
@@ -28,6 +28,17 @@ MemoryVector<byte> IF_Scheme_PublicKey::x509_subject_public_key() const
.get_contents();
}
+IF_Scheme_PublicKey::IF_Scheme_PublicKey(const AlgorithmIdentifier&,
+ const MemoryRegion<byte>& key_bits)
+ {
+ BER_Decoder(key_bits)
+ .start_cons(SEQUENCE)
+ .decode(n)
+ .decode(e)
+ .verify_end()
+ .end_cons();
+ }
+
/*
* Return the X.509 public key decoder
*/
@@ -41,7 +52,7 @@ X509_Decoder* IF_Scheme_PublicKey::x509_decoder()
void key_bits(const MemoryRegion<byte>& bits)
{
BER_Decoder(bits)
- .start_cons(SEQUENCE)
+ .start_cons(SEQUENCE)
.decode(key->n)
.decode(key->e)
.verify_end()
diff --git a/src/pubkey/if_algo/if_algo.h b/src/pubkey/if_algo/if_algo.h
index c58b693be..fc09f2881 100644
--- a/src/pubkey/if_algo/if_algo.h
+++ b/src/pubkey/if_algo/if_algo.h
@@ -42,7 +42,12 @@ class BOTAN_DLL IF_Scheme_PublicKey : public virtual Public_Key
u32bit max_input_bits() const { return (n.bits() - 1); }
X509_Decoder* x509_decoder();
+
+ IF_Scheme_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits);
protected:
+ IF_Scheme_PublicKey() {}
+
virtual void X509_load_hook();
BigInt n, e;
IF_Core core;
diff --git a/src/pubkey/nr/nr.h b/src/pubkey/nr/nr.h
index 144c5ec2a..64b50fc7f 100644
--- a/src/pubkey/nr/nr.h
+++ b/src/pubkey/nr/nr.h
@@ -29,9 +29,14 @@ class BOTAN_DLL NR_PublicKey : public PK_Verifying_with_MR_Key,
u32bit message_parts() const { return 2; }
u32bit message_part_size() const;
- NR_PublicKey() {}
+ NR_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_57)
+ { X509_load_hook(); }
+
NR_PublicKey(const DL_Group&, const BigInt&);
protected:
+ NR_PublicKey() {}
NR_Core core;
private:
void X509_load_hook();
diff --git a/src/pubkey/pk_algs.cpp b/src/pubkey/pk_algs.cpp
index dd62eb5ac..d65913a06 100644
--- a/src/pubkey/pk_algs.cpp
+++ b/src/pubkey/pk_algs.cpp
@@ -1,11 +1,14 @@
/*
* PK Key
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
#include <botan/internal/pk_algs.h>
+#include <botan/oids.h>
+
+#include <stdio.h>
#if defined(BOTAN_HAS_RSA)
#include <botan/rsa.h>
@@ -41,49 +44,58 @@
namespace Botan {
-/*
-* Get an PK public key object
-*/
-Public_Key* get_public_key(const std::string& alg_name)
+BOTAN_DLL Public_Key* make_public_key(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits)
{
+ const std::string alg_name = OIDS::lookup(alg_id.oid);
+ if(alg_name == "")
+ throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());
+
#if defined(BOTAN_HAS_RSA)
- if(alg_name == "RSA") return new RSA_PublicKey;
+ if(alg_name == "RSA")
+ return new RSA_PublicKey(alg_id, key_bits);
+#endif
+
+#if defined(BOTAN_HAS_RW)
+ if(alg_name == "RW")
+ return new RW_PublicKey(alg_id, key_bits);
#endif
#if defined(BOTAN_HAS_DSA)
- if(alg_name == "DSA") return new DSA_PublicKey;
+ if(alg_name == "DSA")
+ return new DSA_PublicKey(alg_id, key_bits);
#endif
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
- if(alg_name == "DH") return new DH_PublicKey;
+ if(alg_name == "DH")
+ return new DH_PublicKey(alg_id, key_bits);
#endif
#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- if(alg_name == "NR") return new NR_PublicKey;
-#endif
-
-#if defined(BOTAN_HAS_RW)
- if(alg_name == "RW") return new RW_PublicKey;
+ if(alg_name == "NR")
+ return new NR_PublicKey(alg_id, key_bits);
#endif
#if defined(BOTAN_HAS_ELG)
- if(alg_name == "ELG") return new ElGamal_PublicKey;
+ if(alg_name == "ELG")
+ return new ElGamal_PublicKey(alg_id, key_bits);
#endif
#if defined(BOTAN_HAS_ECDSA)
- if(alg_name == "ECDSA") return new ECDSA_PublicKey;
+ if(alg_name == "ECDSA")
+ return new ECDSA_PublicKey(alg_id, key_bits);
#endif
#if defined(BOTAN_HAS_GOST_34_10_2001)
- if(alg_name == "GOST-34.10") return new GOST_3410_PublicKey;
+ if(alg_name == "GOST-34.10")
+ return new GOST_3410_PublicKey(alg_id, key_bits);
#endif
return 0;
}
-/*
-* Get an PK private key object
-*/
+namespace {
+
Private_Key* get_private_key(const std::string& alg_name)
{
#if defined(BOTAN_HAS_RSA)
@@ -122,3 +134,30 @@ Private_Key* get_private_key(const std::string& alg_name)
}
}
+
+BOTAN_DLL Private_Key* make_private_key(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits,
+ RandomNumberGenerator& rng)
+ {
+ const std::string alg_name = OIDS::lookup(alg_id.oid);
+ if(alg_name == "")
+ throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());
+
+ std::auto_ptr<Private_Key> key(get_private_key(alg_name));
+
+ if(!key.get())
+ throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " +
+ alg_id.oid.as_string());
+
+ std::auto_ptr<PKCS8_Decoder> decoder(key->pkcs8_decoder(rng));
+
+ if(!decoder.get())
+ throw Decoding_Error("Key does not support PKCS #8 decoding");
+
+ decoder->alg_id(alg_id);
+ decoder->key_bits(key_bits);
+
+ return key.release();
+ }
+
+}
diff --git a/src/pubkey/pk_algs.h b/src/pubkey/pk_algs.h
index c41bf1a63..3fbaed234 100644
--- a/src/pubkey/pk_algs.h
+++ b/src/pubkey/pk_algs.h
@@ -1,6 +1,6 @@
/*
* PK Key Factory
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -12,19 +12,12 @@
namespace Botan {
-/**
-* Get an empty public key object.
-* @param name the name of the desired public key algorithm
-* @return the public key object
-*/
-BOTAN_DLL Public_Key* get_public_key(const std::string&);
+BOTAN_DLL Public_Key* make_public_key(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits);
-/**
-* Get an empty private key object.
-* @param name the name of the desired public key algorithm
-* @return the private key object
-*/
-BOTAN_DLL Private_Key* get_private_key(const std::string&);
+BOTAN_DLL Private_Key* make_private_key(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits,
+ RandomNumberGenerator& rng);
}
diff --git a/src/pubkey/pkcs8.cpp b/src/pubkey/pkcs8.cpp
index 099d52ffa..c89431fca 100644
--- a/src/pubkey/pkcs8.cpp
+++ b/src/pubkey/pkcs8.cpp
@@ -1,6 +1,6 @@
/*
* PKCS #8
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -240,21 +240,7 @@ Private_Key* load_key(DataSource& source,
throw PKCS8_Exception("Unknown algorithm OID: " +
alg_id.oid.as_string());
- std::auto_ptr<Private_Key> key(get_private_key(alg_name));
-
- if(!key.get())
- throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " +
- alg_id.oid.as_string());
-
- std::auto_ptr<PKCS8_Decoder> decoder(key->pkcs8_decoder(rng));
-
- if(!decoder.get())
- throw Decoding_Error("Key does not support PKCS #8 decoding");
-
- decoder->alg_id(alg_id);
- decoder->key_bits(pkcs8_key);
-
- return key.release();
+ return make_private_key(alg_id, pkcs8_key, rng);
}
/*
diff --git a/src/pubkey/rsa/rsa.h b/src/pubkey/rsa/rsa.h
index 0580fe8eb..c24dc7d0c 100644
--- a/src/pubkey/rsa/rsa.h
+++ b/src/pubkey/rsa/rsa.h
@@ -27,7 +27,9 @@ class BOTAN_DLL RSA_PublicKey : public PK_Encrypting_Key,
SecureVector<byte> verify(const byte[], u32bit) const;
- RSA_PublicKey() {}
+ RSA_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ IF_Scheme_PublicKey(alg_id, key_bits) { X509_load_hook(); }
/**
* Create a RSA_PublicKey
@@ -36,6 +38,7 @@ class BOTAN_DLL RSA_PublicKey : public PK_Encrypting_Key,
*/
RSA_PublicKey(const BigInt& n, const BigInt& e);
protected:
+ RSA_PublicKey() {}
BigInt public_op(const BigInt&) const;
};
diff --git a/src/pubkey/rw/rw.h b/src/pubkey/rw/rw.h
index 900e5ebda..ecc29ed6c 100644
--- a/src/pubkey/rw/rw.h
+++ b/src/pubkey/rw/rw.h
@@ -23,9 +23,13 @@ class BOTAN_DLL RW_PublicKey : public PK_Verifying_with_MR_Key,
SecureVector<byte> verify(const byte[], u32bit) const;
- RW_PublicKey() {}
- RW_PublicKey(const BigInt&, const BigInt&);
+ RW_PublicKey(const AlgorithmIdentifier& alg_id,
+ const MemoryRegion<byte>& key_bits) :
+ IF_Scheme_PublicKey(alg_id, key_bits) { X509_load_hook(); }
+
+ RW_PublicKey(const BigInt& mod, const BigInt& exponent);
protected:
+ RW_PublicKey() {}
BigInt public_op(const BigInt&) const;
};
diff --git a/src/pubkey/x509_key.cpp b/src/pubkey/x509_key.cpp
index fdcfccf87..aaea8c943 100644
--- a/src/pubkey/x509_key.cpp
+++ b/src/pubkey/x509_key.cpp
@@ -10,7 +10,6 @@
#include <botan/asn1_obj.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
-#include <botan/oids.h>
#include <botan/pem.h>
#include <botan/internal/pk_algs.h>
#include <memory>
@@ -85,25 +84,7 @@ Public_Key* load_key(DataSource& source)
if(key_bits.empty())
throw Decoding_Error("X.509 public key decoding failed");
- const std::string alg_name = OIDS::lookup(alg_id.oid);
- if(alg_name == "")
- throw Decoding_Error("Unknown algorithm OID: " +
- alg_id.oid.as_string());
-
- std::auto_ptr<Public_Key> key_obj(get_public_key(alg_name));
- if(!key_obj.get())
- throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " +
- alg_id.oid.as_string());
-
- std::auto_ptr<X509_Decoder> decoder(key_obj->x509_decoder());
-
- if(!decoder.get())
- throw Decoding_Error("Key does not support X.509 decoding");
-
- decoder->alg_id(alg_id);
- decoder->key_bits(key_bits);
-
- return key_obj.release();
+ return make_public_key(alg_id, key_bits);
}
catch(Decoding_Error)
{