diff options
author | lloyd <[email protected]> | 2006-09-06 06:27:20 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2006-09-06 06:27:20 +0000 |
commit | 0df4cf5008f0a4f6c259dc7bcd64079e5810eb80 (patch) | |
tree | 8475c9f40e1f9b2f23053e8ffa93502a688c3f89 /src | |
parent | 219aa8f6b449f7dc81ddae48c4b01328ffe69cd3 (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.cpp | 73 | ||||
-rw-r--r-- | src/if_algo.cpp | 84 | ||||
-rw-r--r-- | src/x509_key.cpp | 113 |
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(); } |