aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/dl_algo.h7
-rw-r--r--include/if_algo.h6
-rw-r--r--include/pkcs8.h28
-rw-r--r--src/dl_algo.cpp98
-rw-r--r--src/if_algo.cpp148
-rw-r--r--src/pkcs8.cpp23
-rw-r--r--src/x509_ca.cpp8
-rw-r--r--src/x509_key.cpp3
8 files changed, 183 insertions, 138 deletions
diff --git a/include/dl_algo.h b/include/dl_algo.h
index 8bcd704df..b72b3df42 100644
--- a/include/dl_algo.h
+++ b/include/dl_algo.h
@@ -54,11 +54,8 @@ class DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey,
protected:
BigInt x;
private:
- SecureVector<byte> DER_encode_priv() const;
- void BER_decode_priv(DataSource&);
- MemoryVector<byte> DER_encode_params() const;
- void BER_decode_params(DataSource&);
-
+ PKCS8_Encoder* pkcs8_encoder() const;
+ PKCS8_Decoder* pkcs8_decoder();
virtual void PKCS8_load_hook() {}
};
diff --git a/include/if_algo.h b/include/if_algo.h
index d8a0229fa..02f8763d8 100644
--- a/include/if_algo.h
+++ b/include/if_algo.h
@@ -53,10 +53,8 @@ class IF_Scheme_PrivateKey : public virtual IF_Scheme_PublicKey,
virtual void PKCS8_load_hook();
BigInt d, p, q, d1, d2, c;
private:
- SecureVector<byte> DER_encode_priv() const;
- void BER_decode_priv(DataSource&);
- MemoryVector<byte> DER_encode_params() const;
- void BER_decode_params(DataSource&);
+ PKCS8_Encoder* pkcs8_encoder() const;
+ PKCS8_Decoder* pkcs8_decoder();
};
}
diff --git a/include/pkcs8.h b/include/pkcs8.h
index b7ad9f344..5e3e1c097 100644
--- a/include/pkcs8.h
+++ b/include/pkcs8.h
@@ -12,15 +12,35 @@
namespace Botan {
/*************************************************
+* PKCS #8 Private Key Encoder *
+*************************************************/
+class PKCS8_Encoder
+ {
+ public:
+ virtual AlgorithmIdentifier alg_id() const = 0;
+ virtual MemoryVector<byte> key_bits() const = 0;
+ virtual ~PKCS8_Encoder() {}
+ };
+
+/*************************************************
+* PKCS #8 Private Key Decoder *
+*************************************************/
+class PKCS8_Decoder
+ {
+ public:
+ virtual void alg_id(const AlgorithmIdentifier&) = 0;
+ virtual void key_bits(const MemoryRegion<byte>&) = 0;
+ virtual ~PKCS8_Decoder() {}
+ };
+
+/*************************************************
* PKCS #8 Private Key *
*************************************************/
class PKCS8_PrivateKey : public virtual X509_PublicKey
{
public:
- virtual SecureVector<byte> DER_encode_priv() const = 0;
- virtual void BER_decode_priv(DataSource&) = 0;
- virtual MemoryVector<byte> DER_encode_params() const = 0;
- virtual void BER_decode_params(DataSource&) = 0;
+ virtual PKCS8_Encoder* pkcs8_encoder() const = 0;
+ virtual PKCS8_Decoder* pkcs8_decoder() = 0;
virtual ~PKCS8_PrivateKey() {}
};
diff --git a/src/dl_algo.cpp b/src/dl_algo.cpp
index 731a652d2..46ae5b310 100644
--- a/src/dl_algo.cpp
+++ b/src/dl_algo.cpp
@@ -15,36 +15,28 @@ namespace Botan {
*************************************************/
X509_Encoder* DL_Scheme_PublicKey::x509_encoder() const
{
- class DL_Algo_Encoder : public X509_Encoder
+ class DL_Scheme_Encoder : public X509_Encoder
{
public:
AlgorithmIdentifier alg_id() const
{
- return AlgorithmIdentifier(oid, group.DER_encode(group_format));
+ MemoryVector<byte> group =
+ key->group.DER_encode(key->group_format());
+
+ return AlgorithmIdentifier(key->get_oid(), group);
}
MemoryVector<byte> key_bits() const
{
- return DER_Encoder().encode(y).get_contents();
+ return DER_Encoder().encode(key->y).get_contents();
}
- DL_Algo_Encoder(const OID& oid, const BigInt& y,
- const DL_Group& group,
- const DL_Group::Format group_format)
- {
- this->oid = oid;
- this->y = y;
- this->group = group;
- this->group_format = group_format;
- }
+ DL_Scheme_Encoder(const DL_Scheme_PublicKey* k) : key(k) {}
private:
- OID oid;
- BigInt y;
- DL_Group group;
- DL_Group::Format group_format;
+ const DL_Scheme_PublicKey* key;
};
- return new DL_Algo_Encoder(get_oid(), y, group, group_format());
+ return new DL_Scheme_Encoder(this);
}
/*************************************************
@@ -52,7 +44,7 @@ X509_Encoder* DL_Scheme_PublicKey::x509_encoder() const
*************************************************/
X509_Decoder* DL_Scheme_PublicKey::x509_decoder()
{
- class DL_Algo_Decoder : public X509_Decoder
+ class DL_Scheme_Decoder : public X509_Decoder
{
public:
void alg_id(const AlgorithmIdentifier& alg_id)
@@ -67,47 +59,69 @@ X509_Decoder* DL_Scheme_PublicKey::x509_decoder()
key->X509_load_hook();
}
- DL_Algo_Decoder(DL_Scheme_PublicKey* k) : key(k) {}
+ DL_Scheme_Decoder(DL_Scheme_PublicKey* k) : key(k) {}
private:
DL_Scheme_PublicKey* key;
};
- return new DL_Algo_Decoder(this);
+ return new DL_Scheme_Decoder(this);
}
/*************************************************
-* Return the X.509 parameters encoding *
+* Return the PKCS #8 private key encoder *
*************************************************/
-MemoryVector<byte> DL_Scheme_PrivateKey::DER_encode_params() const
+PKCS8_Encoder* DL_Scheme_PrivateKey::pkcs8_encoder() const
{
- return group.DER_encode(group_format());
- }
+ class DL_Scheme_Encoder : public PKCS8_Encoder
+ {
+ public:
+ AlgorithmIdentifier alg_id() const
+ {
+ MemoryVector<byte> group =
+ key->group.DER_encode(key->group_format());
-/*************************************************
-* Decode X.509 algorithm parameters *
-*************************************************/
-void DL_Scheme_PrivateKey::BER_decode_params(DataSource& source)
- {
- group.BER_decode(source, group_format());
- }
+ return AlgorithmIdentifier(key->get_oid(), group);
+ }
-/*************************************************
-* Return the PKCS #8 private key encoding *
-*************************************************/
-SecureVector<byte> DL_Scheme_PrivateKey::DER_encode_priv() const
- {
- return DER_Encoder().encode(x).get_contents();
+ MemoryVector<byte> key_bits() const
+ {
+ return DER_Encoder().encode(key->x).get_contents();
+ }
+
+ DL_Scheme_Encoder(const DL_Scheme_PrivateKey* k) : key(k) {}
+ private:
+ const DL_Scheme_PrivateKey* key;
+ };
+
+ return new DL_Scheme_Encoder(this);
}
/*************************************************
-* Decode a PKCS #8 private key encoding *
+* Return the PKCS #8 private key decoder *
*************************************************/
-void DL_Scheme_PrivateKey::BER_decode_priv(DataSource& source)
+PKCS8_Decoder* DL_Scheme_PrivateKey::pkcs8_decoder()
{
- BER_Decoder(source).decode(x);
+ class DL_Scheme_Decoder : public PKCS8_Decoder
+ {
+ public:
+ void alg_id(const AlgorithmIdentifier& alg_id)
+ {
+ DataSource_Memory source(alg_id.parameters);
+ key->group.BER_decode(source, key->group_format());
+ }
+
+ void key_bits(const MemoryRegion<byte>& bits)
+ {
+ BER_Decoder(bits).decode(key->x);
+ key->PKCS8_load_hook();
+ }
+
+ DL_Scheme_Decoder(DL_Scheme_PrivateKey* k) : key(k) {}
+ private:
+ DL_Scheme_PrivateKey* key;
+ };
- PKCS8_load_hook();
- check_loaded_private();
+ return new DL_Scheme_Decoder(this);
}
/*************************************************
diff --git a/src/if_algo.cpp b/src/if_algo.cpp
index 3668580b3..97d0d0510 100644
--- a/src/if_algo.cpp
+++ b/src/if_algo.cpp
@@ -15,12 +15,12 @@ namespace Botan {
*************************************************/
X509_Encoder* IF_Scheme_PublicKey::x509_encoder() const
{
- class IF_Algo_Encoder : public X509_Encoder
+ class IF_Scheme_Encoder : public X509_Encoder
{
public:
AlgorithmIdentifier alg_id() const
{
- return AlgorithmIdentifier(oid,
+ return AlgorithmIdentifier(key->get_oid(),
AlgorithmIdentifier::USE_NULL_PARAM);
}
@@ -28,24 +28,18 @@ X509_Encoder* IF_Scheme_PublicKey::x509_encoder() const
{
return DER_Encoder()
.start_cons(SEQUENCE)
- .encode(n)
- .encode(e)
+ .encode(key->n)
+ .encode(key->e)
.end_cons()
.get_contents();
}
- IF_Algo_Encoder(const OID& oid, const BigInt& n, const BigInt& e)
- {
- this->oid = oid;
- this->n = n;
- this->e = e;
- }
+ IF_Scheme_Encoder(const IF_Scheme_PublicKey* k) : key(k) {}
private:
- OID oid;
- BigInt n, e;
+ const IF_Scheme_PublicKey* key;
};
- return new IF_Algo_Encoder(get_oid(), n, e);
+ return new IF_Scheme_Encoder(this);
}
/*************************************************
@@ -53,7 +47,7 @@ X509_Encoder* IF_Scheme_PublicKey::x509_encoder() const
*************************************************/
X509_Decoder* IF_Scheme_PublicKey::x509_decoder()
{
- class IF_Algo_Decoder : public X509_Decoder
+ class IF_Scheme_Decoder : public X509_Decoder
{
public:
void alg_id(const AlgorithmIdentifier&) {}
@@ -70,77 +64,93 @@ X509_Decoder* IF_Scheme_PublicKey::x509_decoder()
key->X509_load_hook();
}
- IF_Algo_Decoder(IF_Scheme_PublicKey* k) : key(k) {}
+ IF_Scheme_Decoder(IF_Scheme_PublicKey* k) : key(k) {}
private:
IF_Scheme_PublicKey* key;
};
- return new IF_Algo_Decoder(this);
+ return new IF_Scheme_Decoder(this);
}
/*************************************************
-* Return the X.509 parameters encoding *
+* Return the PKCS #8 public key encoder *
*************************************************/
-MemoryVector<byte> IF_Scheme_PrivateKey::DER_encode_params() const
+PKCS8_Encoder* IF_Scheme_PrivateKey::pkcs8_encoder() const
{
- return DER_Encoder().encode_null().get_contents();
- }
+ class IF_Scheme_Encoder : public PKCS8_Encoder
+ {
+ public:
+ AlgorithmIdentifier alg_id() const
+ {
+ return AlgorithmIdentifier(key->get_oid(),
+ AlgorithmIdentifier::USE_NULL_PARAM);
+ }
-/*************************************************
-* Decode X.509 algorithm parameters *
-*************************************************/
-void IF_Scheme_PrivateKey::BER_decode_params(DataSource& source)
- {
- byte dummy = 0;
- while(!source.end_of_data())
- source.read_byte(dummy);
- }
+ MemoryVector<byte> key_bits() const
+ {
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode((u32bit)0)
+ .encode(key->n)
+ .encode(key->e)
+ .encode(key->d)
+ .encode(key->p)
+ .encode(key->q)
+ .encode(key->d1)
+ .encode(key->d2)
+ .encode(key->c)
+ .end_cons()
+ .get_contents();
+ }
-/*************************************************
-* Return the PKCS #1 private key encoding *
-*************************************************/
-SecureVector<byte> IF_Scheme_PrivateKey::DER_encode_priv() const
- {
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode((u32bit)0)
- .encode(n)
- .encode(e)
- .encode(d)
- .encode(p)
- .encode(q)
- .encode(d1)
- .encode(d2)
- .encode(c)
- .end_cons()
- .get_contents();
+ IF_Scheme_Encoder(const IF_Scheme_PrivateKey* k) : key(k) {}
+ private:
+ const IF_Scheme_PrivateKey* key;
+ };
+
+ return new IF_Scheme_Encoder(this);
}
/*************************************************
-* Decode a PKCS #1 private key encoding *
+* Return the PKCS #8 public key decoder *
*************************************************/
-void IF_Scheme_PrivateKey::BER_decode_priv(DataSource& source)
+PKCS8_Decoder* IF_Scheme_PrivateKey::pkcs8_decoder()
{
- u32bit version;
-
- BER_Decoder(source)
- .start_cons(SEQUENCE)
- .decode(version)
- .decode(n)
- .decode(e)
- .decode(d)
- .decode(p)
- .decode(q)
- .decode(d1)
- .decode(d2)
- .decode(c)
- .end_cons();
-
- if(version != 0)
- throw Decoding_Error(algo_name() + ": Unknown PKCS #1 key version");
-
- PKCS8_load_hook();
- check_loaded_private();
+ class IF_Scheme_Decoder : public PKCS8_Decoder
+ {
+ public:
+ void alg_id(const AlgorithmIdentifier&) {}
+
+ void key_bits(const MemoryRegion<byte>& bits)
+ {
+ u32bit version;
+
+ BER_Decoder(bits)
+ .start_cons(SEQUENCE)
+ .decode(version)
+ .decode(key->n)
+ .decode(key->e)
+ .decode(key->d)
+ .decode(key->p)
+ .decode(key->q)
+ .decode(key->d1)
+ .decode(key->d2)
+ .decode(key->c)
+ .end_cons();
+
+ if(version != 0)
+ throw Decoding_Error(key->algo_name() +
+ ": Unknown PKCS #1 key version");
+
+ key->PKCS8_load_hook();
+ }
+
+ IF_Scheme_Decoder(IF_Scheme_PrivateKey* k) : key(k) {}
+ private:
+ IF_Scheme_PrivateKey* key;
+ };
+
+ return new IF_Scheme_Decoder(this);
}
/*************************************************
diff --git a/src/pkcs8.cpp b/src/pkcs8.cpp
index 930cc9163..c4fc97031 100644
--- a/src/pkcs8.cpp
+++ b/src/pkcs8.cpp
@@ -143,16 +143,18 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui,
*************************************************/
void encode(const PKCS8_PrivateKey& key, Pipe& pipe, X509_Encoding encoding)
{
- const u32bit PKCS8_VERSION = 0;
+ std::auto_ptr<PKCS8_Encoder> encoder(key.pkcs8_encoder());
+ if(!encoder.get())
+ throw Encoding_Error("PKCS8::encode: Key does not support encoding");
- AlgorithmIdentifier alg_id(key.get_oid(), key.DER_encode_params());
+ const u32bit PKCS8_VERSION = 0;
SecureVector<byte> contents =
DER_Encoder()
.start_cons(SEQUENCE)
.encode(PKCS8_VERSION)
- .encode(alg_id)
- .encode(key.DER_encode_priv(), OCTET_STRING)
+ .encode(encoder->alg_id())
+ .encode(encoder->key_bits(), OCTET_STRING)
.end_cons()
.get_contents();
@@ -230,7 +232,6 @@ std::string PEM_encode(const PKCS8_PrivateKey& key, const std::string& pass,
PKCS8_PrivateKey* load_key(DataSource& source, const User_Interface& ui)
{
AlgorithmIdentifier alg_id;
-
SecureVector<byte> pkcs8_key = PKCS8_decode(source, ui, alg_id);
const std::string alg_name = OIDS::lookup(alg_id.oid);
@@ -244,12 +245,12 @@ PKCS8_PrivateKey* load_key(DataSource& source, const User_Interface& ui)
throw PKCS8_Exception("Unknown PK algorithm/OID: " + alg_name + ", " +
alg_id.oid.as_string());
- Pipe output;
- output.process_msg(alg_id.parameters);
- output.process_msg(pkcs8_key);
- key->BER_decode_params(output);
- output.set_default_msg(1);
- key->BER_decode_priv(output);
+ std::auto_ptr<PKCS8_Decoder> decoder(key->pkcs8_decoder());
+ 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();
}
diff --git a/src/x509_ca.cpp b/src/x509_ca.cpp
index e7a463e18..d074afbe2 100644
--- a/src/x509_ca.cpp
+++ b/src/x509_ca.cpp
@@ -251,7 +251,13 @@ PK_Signer* choose_sig_format(const PKCS8_PrivateKey& key,
Config::choose_sig_format(key.algo_name(), padding, format);
sig_algo.oid = OIDS::lookup(key.algo_name() + "/" + padding);
- sig_algo.parameters = key.DER_encode_params();
+
+ std::auto_ptr<X509_Encoder> encoding(key.x509_encoder());
+ if(!encoding.get())
+ throw Encoding_Error("Key " + key.algo_name() + " does not support "
+ "X.509 encoding");
+
+ sig_algo.parameters = encoding->alg_id().parameters;
const PK_Signing_Key& sig_key = dynamic_cast<const PK_Signing_Key&>(key);
diff --git a/src/x509_key.cpp b/src/x509_key.cpp
index 00b565df1..2825cf836 100644
--- a/src/x509_key.cpp
+++ b/src/x509_key.cpp
@@ -20,12 +20,11 @@ namespace Botan {
*************************************************/
u64bit X509_PublicKey::key_id() const
{
- Pipe pipe(new Hash_Filter("SHA-1", 8));
-
std::auto_ptr<X509_Encoder> encoder(x509_encoder());
if(!encoder.get())
throw Internal_Error("X509_PublicKey:key_id: No encoder found");
+ Pipe pipe(new Hash_Filter("SHA-1", 8));
pipe.start_msg();
pipe.write(algo_name());
pipe.write(encoder->alg_id().parameters);