aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/dl_algo.h10
-rw-r--r--include/if_algo.h8
-rw-r--r--include/pkcs8.h2
-rw-r--r--include/x509_key.h30
-rw-r--r--src/dl_algo.cpp73
-rw-r--r--src/if_algo.cpp84
-rw-r--r--src/x509_key.cpp113
7 files changed, 242 insertions, 78 deletions
diff --git a/include/dl_algo.h b/include/dl_algo.h
index ccb8a05a0..8bcd704df 100644
--- a/include/dl_algo.h
+++ b/include/dl_algo.h
@@ -28,16 +28,14 @@ class DL_Scheme_PublicKey : public virtual X509_PublicKey
const BigInt& group_p() const { return group.get_p(); }
const BigInt& group_q() const { return group.get_q(); }
const BigInt& group_g() const { return group.get_g(); }
+ virtual DL_Group::Format group_format() const = 0;
BigInt y;
DL_Group group;
private:
- MemoryVector<byte> DER_encode_pub() const;
- MemoryVector<byte> DER_encode_params() const;
- void BER_decode_pub(DataSource&);
- void BER_decode_params(DataSource&);
+ X509_Encoder* x509_encoder() const;
+ X509_Decoder* x509_decoder();
- virtual DL_Group::Format group_format() const = 0;
virtual void X509_load_hook() {}
};
@@ -58,6 +56,8 @@ class DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey,
private:
SecureVector<byte> DER_encode_priv() const;
void BER_decode_priv(DataSource&);
+ MemoryVector<byte> DER_encode_params() const;
+ void BER_decode_params(DataSource&);
virtual void PKCS8_load_hook() {}
};
diff --git a/include/if_algo.h b/include/if_algo.h
index 323d58256..d8a0229fa 100644
--- a/include/if_algo.h
+++ b/include/if_algo.h
@@ -31,10 +31,8 @@ class IF_Scheme_PublicKey : public virtual X509_PublicKey
BigInt n, e;
IF_Core core;
private:
- MemoryVector<byte> DER_encode_pub() const;
- MemoryVector<byte> DER_encode_params() const;
- void BER_decode_params(DataSource&);
- void BER_decode_pub(DataSource&);
+ X509_Encoder* x509_encoder() const;
+ X509_Decoder* x509_decoder();
};
/*************************************************
@@ -57,6 +55,8 @@ class IF_Scheme_PrivateKey : public virtual IF_Scheme_PublicKey,
private:
SecureVector<byte> DER_encode_priv() const;
void BER_decode_priv(DataSource&);
+ MemoryVector<byte> DER_encode_params() const;
+ void BER_decode_params(DataSource&);
};
}
diff --git a/include/pkcs8.h b/include/pkcs8.h
index dc70acbe4..b7ad9f344 100644
--- a/include/pkcs8.h
+++ b/include/pkcs8.h
@@ -19,6 +19,8 @@ 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_PrivateKey() {}
};
diff --git a/include/x509_key.h b/include/x509_key.h
index b55ba69cc..330444097 100644
--- a/include/x509_key.h
+++ b/include/x509_key.h
@@ -8,20 +8,42 @@
#include <botan/pipe.h>
#include <botan/pk_keys.h>
+#include <botan/alg_id.h>
namespace Botan {
/*************************************************
+* X.509 Public Key Encoder *
+*************************************************/
+class X509_Encoder
+ {
+ public:
+ virtual AlgorithmIdentifier alg_id() const = 0;
+ virtual MemoryVector<byte> key_bits() const = 0;
+ virtual ~X509_Encoder() {}
+ };
+
+/*************************************************
+* X.509 Public Key Decoder *
+*************************************************/
+class X509_Decoder
+ {
+ public:
+ virtual void alg_id(const AlgorithmIdentifier&) = 0;
+ virtual void key_bits(const MemoryRegion<byte>&) = 0;
+ virtual ~X509_Decoder() {}
+ };
+
+/*************************************************
* X.509 Public Key *
*************************************************/
class X509_PublicKey : public virtual PK_Key
{
public:
u64bit key_id() const;
- virtual MemoryVector<byte> DER_encode_pub() const = 0;
- virtual MemoryVector<byte> DER_encode_params() const = 0;
- virtual void BER_decode_pub(DataSource&) = 0;
- virtual void BER_decode_params(DataSource&) = 0;
+
+ virtual X509_Encoder* x509_encoder() const = 0;
+ virtual X509_Decoder* x509_decoder() = 0;
virtual ~X509_PublicKey() {}
};
diff --git a/src/dl_algo.cpp b/src/dl_algo.cpp
index 6e61a672b..731a652d2 100644
--- a/src/dl_algo.cpp
+++ b/src/dl_algo.cpp
@@ -11,37 +11,82 @@
namespace Botan {
/*************************************************
-* Return the X.509 public key encoding *
+* Return the X.509 public key encoder *
*************************************************/
-MemoryVector<byte> DL_Scheme_PublicKey::DER_encode_pub() const
+X509_Encoder* DL_Scheme_PublicKey::x509_encoder() const
{
- return DER_Encoder().encode(y).get_contents();
+ class DL_Algo_Encoder : public X509_Encoder
+ {
+ public:
+ AlgorithmIdentifier alg_id() const
+ {
+ return AlgorithmIdentifier(oid, group.DER_encode(group_format));
+ }
+
+ MemoryVector<byte> key_bits() const
+ {
+ return DER_Encoder().encode(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;
+ }
+ private:
+ OID oid;
+ BigInt y;
+ DL_Group group;
+ DL_Group::Format group_format;
+ };
+
+ return new DL_Algo_Encoder(get_oid(), y, group, group_format());
}
/*************************************************
-* Return the X.509 parameters encoding *
+* Return the X.509 public key decoder *
*************************************************/
-MemoryVector<byte> DL_Scheme_PublicKey::DER_encode_params() const
+X509_Decoder* DL_Scheme_PublicKey::x509_decoder()
{
- return group.DER_encode(group_format());
+ class DL_Algo_Decoder : public X509_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->y);
+ key->X509_load_hook();
+ }
+
+ DL_Algo_Decoder(DL_Scheme_PublicKey* k) : key(k) {}
+ private:
+ DL_Scheme_PublicKey* key;
+ };
+
+ return new DL_Algo_Decoder(this);
}
/*************************************************
-* Decode X.509 public key encoding *
+* Return the X.509 parameters encoding *
*************************************************/
-void DL_Scheme_PublicKey::BER_decode_pub(DataSource& source)
+MemoryVector<byte> DL_Scheme_PrivateKey::DER_encode_params() const
{
- BER_Decoder(source).decode(y);
-
- if(y < 2 || y >= group_p())
- throw Invalid_Argument(algo_name() + ": Invalid public key");
- X509_load_hook();
+ return group.DER_encode(group_format());
}
/*************************************************
* Decode X.509 algorithm parameters *
*************************************************/
-void DL_Scheme_PublicKey::BER_decode_params(DataSource& source)
+void DL_Scheme_PrivateKey::BER_decode_params(DataSource& source)
{
group.BER_decode(source, group_format());
}
diff --git a/src/if_algo.cpp b/src/if_algo.cpp
index 36d859282..3668580b3 100644
--- a/src/if_algo.cpp
+++ b/src/if_algo.cpp
@@ -11,45 +11,85 @@
namespace Botan {
/*************************************************
-* Return the X.509 public key encoding *
+* Return the X.509 public key encoder *
*************************************************/
-MemoryVector<byte> IF_Scheme_PublicKey::DER_encode_pub() const
+X509_Encoder* IF_Scheme_PublicKey::x509_encoder() const
{
- return DER_Encoder()
- .start_cons(SEQUENCE)
- .encode(n)
- .encode(e)
- .end_cons()
- .get_contents();
+ class IF_Algo_Encoder : public X509_Encoder
+ {
+ public:
+ AlgorithmIdentifier alg_id() const
+ {
+ return AlgorithmIdentifier(oid,
+ AlgorithmIdentifier::USE_NULL_PARAM);
+ }
+
+ MemoryVector<byte> key_bits() const
+ {
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode(n)
+ .encode(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;
+ }
+ private:
+ OID oid;
+ BigInt n, e;
+ };
+
+ return new IF_Algo_Encoder(get_oid(), n, e);
}
/*************************************************
-* Return the X.509 parameters encoding *
+* Return the X.509 public key decoder *
*************************************************/
-MemoryVector<byte> IF_Scheme_PublicKey::DER_encode_params() const
+X509_Decoder* IF_Scheme_PublicKey::x509_decoder()
{
- return DER_Encoder().encode_null().get_contents();
+ class IF_Algo_Decoder : public X509_Decoder
+ {
+ public:
+ void alg_id(const AlgorithmIdentifier&) {}
+
+ void key_bits(const MemoryRegion<byte>& bits)
+ {
+ BER_Decoder(bits)
+ .start_cons(SEQUENCE)
+ .decode(key->n)
+ .decode(key->e)
+ .verify_end()
+ .end_cons();
+
+ key->X509_load_hook();
+ }
+
+ IF_Algo_Decoder(IF_Scheme_PublicKey* k) : key(k) {}
+ private:
+ IF_Scheme_PublicKey* key;
+ };
+
+ return new IF_Algo_Decoder(this);
}
/*************************************************
-* Decode X.509 public key encoding *
+* Return the X.509 parameters encoding *
*************************************************/
-void IF_Scheme_PublicKey::BER_decode_pub(DataSource& source)
+MemoryVector<byte> IF_Scheme_PrivateKey::DER_encode_params() const
{
- BER_Decoder(source)
- .start_cons(SEQUENCE)
- .decode(n)
- .decode(e)
- .verify_end()
- .end_cons();
-
- X509_load_hook();
+ return DER_Encoder().encode_null().get_contents();
}
/*************************************************
* Decode X.509 algorithm parameters *
*************************************************/
-void IF_Scheme_PublicKey::BER_decode_params(DataSource& source)
+void IF_Scheme_PrivateKey::BER_decode_params(DataSource& source)
{
byte dummy = 0;
while(!source.end_of_data())
diff --git a/src/x509_key.cpp b/src/x509_key.cpp
index 08b440a3d..9aeba1d92 100644
--- a/src/x509_key.cpp
+++ b/src/x509_key.cpp
@@ -22,10 +22,16 @@ 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.start_msg();
pipe.write(algo_name());
- pipe.write(DER_encode_pub());
- pipe.write(DER_encode_params());
+ pipe.write(encoder->alg_id().parameters);
+ pipe.write(encoder->key_bits());
+ //pipe.write(DER_encode_pub());
+ //pipe.write(DER_encode_params());
pipe.end_msg();
SecureVector<byte> output = pipe.read_all();
@@ -39,38 +45,74 @@ u64bit X509_PublicKey::key_id() const
return id;
}
-namespace X509 {
-
-namespace {
-
/*************************************************
-* Extract the fields of a subjectPublicKeyInfo *
+* Return an encoder for this key *
*************************************************/
-void X509_extract_info(DataSource& source, AlgorithmIdentifier& alg_id,
- MemoryVector<byte>& key)
+/*
+X509_Encoder* X509_PublicKey::x509_encoder() const
{
- BER_Decoder(source)
- .start_cons(SEQUENCE)
- .decode(alg_id)
- .decode(key, BIT_STRING)
- .verify_end()
- .end_cons();
+ class X509_Default_Encoder : public X509_Encoder
+ {
+ public:
+ AlgorithmIdentifier alg_id() const { return id; }
+ MemoryVector<byte> key_bits() const { return bits; }
+
+ X509_Default_Encoder(const X509_PublicKey* key)
+ {
+ id = AlgorithmIdentifier(key->get_oid(), key->DER_encode_params());
+ bits = key->DER_encode_pub();
+ }
+ private:
+ AlgorithmIdentifier id;
+ MemoryVector<byte> bits;
+ };
+
+ return new X509_Default_Encoder(this);
}
+*/
-}
+/*
+X509_Decoder* X509_PublicKey::x509_decoder()
+ {
+ class X509_Default_Decoder : public X509_Decoder
+ {
+ public:
+ void alg_id(const AlgorithmIdentifier& alg_id)
+ {
+ DataSource_Memory params(alg_id.parameters);
+ key->BER_decode_params(params);
+ }
+ void key_bits(const MemoryRegion<byte>& bits)
+ {
+ DataSource_Memory key_bits(bits);
+ key->BER_decode_pub(key_bits);
+ }
+
+ X509_Default_Decoder(X509_PublicKey* k) : key(k) {}
+ private:
+ X509_PublicKey* key;
+ };
+
+ return new X509_Default_Decoder(this);
+ }
+*/
+
+namespace X509 {
/*************************************************
* DER or PEM encode a X.509 public key *
*************************************************/
void encode(const X509_PublicKey& key, Pipe& pipe, X509_Encoding encoding)
{
- AlgorithmIdentifier alg_id(key.get_oid(), key.DER_encode_params());
+ std::auto_ptr<X509_Encoder> encoder(key.x509_encoder());
+ if(!encoder.get())
+ throw Encoding_Error("X509::encode: Key does not support encoding");
MemoryVector<byte> der =
DER_Encoder()
.start_cons(SEQUENCE)
- .encode(alg_id)
- .encode(key.DER_encode_pub(), BIT_STRING)
+ .encode(encoder->alg_id())
+ .encode(encoder->key_bits(), BIT_STRING)
.end_cons()
.get_contents();
@@ -99,19 +141,32 @@ X509_PublicKey* load_key(DataSource& source)
{
try {
AlgorithmIdentifier alg_id;
- MemoryVector<byte> key;
+ MemoryVector<byte> key_bits;
if(ASN1::maybe_BER(source) && !PEM_Code::matches(source))
- X509_extract_info(source, alg_id, key);
+ {
+ BER_Decoder(source)
+ .start_cons(SEQUENCE)
+ .decode(alg_id)
+ .decode(key_bits, BIT_STRING)
+ .verify_end()
+ .end_cons();
+ }
else
{
DataSource_Memory ber(
PEM_Code::decode_check_label(source, "PUBLIC KEY")
);
- X509_extract_info(ber, alg_id, key);
+
+ BER_Decoder(ber)
+ .start_cons(SEQUENCE)
+ .decode(alg_id)
+ .decode(key_bits, BIT_STRING)
+ .verify_end()
+ .end_cons();
}
- if(key.is_empty())
+ if(key_bits.is_empty())
throw Decoding_Error("X.509 public key decoding failed");
const std::string alg_name = OIDS::lookup(alg_id.oid);
@@ -124,12 +179,12 @@ X509_PublicKey* load_key(DataSource& source)
throw Decoding_Error("Unknown PK algorithm/OID: " + alg_name + ", " +
alg_id.oid.as_string());
- Pipe output;
- output.process_msg(alg_id.parameters);
- output.process_msg(key);
- key_obj->BER_decode_params(output);
- output.set_default_msg(1);
- key_obj->BER_decode_pub(output);
+ 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();
}