aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2006-09-06 06:27:20 +0000
committerlloyd <[email protected]>2006-09-06 06:27:20 +0000
commit0df4cf5008f0a4f6c259dc7bcd64079e5810eb80 (patch)
tree8475c9f40e1f9b2f23053e8ffa93502a688c3f89 /src
parent219aa8f6b449f7dc81ddae48c4b01328ffe69cd3 (diff)
First step in a major rewrite of the high level public key code. The
X509_PublicKey object now offers interfaces that return encoder and decoder objects. Eventually these changes will make it much easier to support alternate key formats like OpenPGP.
Diffstat (limited to 'src')
-rw-r--r--src/dl_algo.cpp73
-rw-r--r--src/if_algo.cpp84
-rw-r--r--src/x509_key.cpp113
3 files changed, 205 insertions, 65 deletions
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();
}