diff options
-rw-r--r-- | include/dl_algo.h | 7 | ||||
-rw-r--r-- | include/if_algo.h | 6 | ||||
-rw-r--r-- | include/pkcs8.h | 28 | ||||
-rw-r--r-- | src/dl_algo.cpp | 98 | ||||
-rw-r--r-- | src/if_algo.cpp | 148 | ||||
-rw-r--r-- | src/pkcs8.cpp | 23 | ||||
-rw-r--r-- | src/x509_ca.cpp | 8 | ||||
-rw-r--r-- | src/x509_key.cpp | 3 |
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); |