diff options
-rw-r--r-- | include/dl_algo.h | 10 | ||||
-rw-r--r-- | include/if_algo.h | 8 | ||||
-rw-r--r-- | include/pkcs8.h | 2 | ||||
-rw-r--r-- | include/x509_key.h | 30 | ||||
-rw-r--r-- | src/dl_algo.cpp | 73 | ||||
-rw-r--r-- | src/if_algo.cpp | 84 | ||||
-rw-r--r-- | src/x509_key.cpp | 113 |
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(); } |