diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cert/cvc/cvc_ado.cpp | 43 | ||||
-rw-r--r-- | src/cert/cvc/cvc_ado.h | 4 | ||||
-rw-r--r-- | src/cert/cvc/cvc_ca.cpp | 3 | ||||
-rw-r--r-- | src/cert/cvc/cvc_cert.cpp | 6 | ||||
-rw-r--r-- | src/cert/cvc/cvc_cert.h | 2 | ||||
-rw-r--r-- | src/cert/cvc/cvc_gen_cert.h | 9 | ||||
-rw-r--r-- | src/cert/cvc/cvc_req.cpp | 15 | ||||
-rw-r--r-- | src/cert/cvc/cvc_req.h | 2 | ||||
-rw-r--r-- | src/cert/cvc/cvc_self.cpp | 10 | ||||
-rw-r--r-- | src/cert/cvc/eac_obj.h | 8 | ||||
-rw-r--r-- | src/cert/cvc/freestore.h | 84 | ||||
-rw-r--r-- | src/cert/cvc/info.txt | 3 | ||||
-rw-r--r-- | src/libstate/policy.cpp | 3 | ||||
-rw-r--r-- | src/math/gfpmath/curve_gfp.cpp | 2 | ||||
-rw-r--r-- | src/math/gfpmath/gfp_element.cpp | 2 | ||||
-rw-r--r-- | src/math/gfpmath/gfp_element.h | 6 | ||||
-rw-r--r-- | src/math/gfpmath/point_gfp.cpp | 4 | ||||
-rw-r--r-- | src/pubkey/ec_dompar/ec_dompar.cpp | 12 | ||||
-rw-r--r-- | src/pubkey/gost_3410/gost_3410.cpp | 351 | ||||
-rw-r--r-- | src/pubkey/gost_3410/gost_3410.h | 164 | ||||
-rw-r--r-- | src/pubkey/gost_3410/info.txt | 14 | ||||
-rw-r--r-- | src/pubkey/pk_algs.cpp | 12 | ||||
-rw-r--r-- | src/s2k/s2k.h | 4 |
23 files changed, 613 insertions, 150 deletions
diff --git a/src/cert/cvc/cvc_ado.cpp b/src/cert/cvc/cvc_ado.cpp index 6e1484e90..fcce0ff82 100644 --- a/src/cert/cvc/cvc_ado.cpp +++ b/src/cert/cvc/cvc_ado.cpp @@ -8,11 +8,10 @@ #include <botan/cvc_ado.h> #include <fstream> -#include <assert.h> namespace Botan { -EAC1_1_ADO::EAC1_1_ADO(std::tr1::shared_ptr<DataSource> in) +EAC1_1_ADO::EAC1_1_ADO(DataSource& in) { init(in); do_decode(); @@ -20,7 +19,7 @@ EAC1_1_ADO::EAC1_1_ADO(std::tr1::shared_ptr<DataSource> in) EAC1_1_ADO::EAC1_1_ADO(const std::string& in) { - std::tr1::shared_ptr<DataSource> stream(new DataSource_Stream(in, true)); + DataSource_Stream stream(in, true); init(stream); do_decode(); } @@ -41,7 +40,7 @@ void EAC1_1_ADO::force_decode() .end_cons() .get_contents(); - std::tr1::shared_ptr<DataSource> req_source(new DataSource_Memory(req_bits)); + DataSource_Memory req_source(req_bits); m_req = EAC1_1_Req(req_source); sig_algo = m_req.sig_algo; } @@ -53,14 +52,13 @@ MemoryVector<byte> EAC1_1_ADO::make_signed( { SecureVector<byte> concat_sig = EAC1_1_obj<EAC1_1_ADO>::make_signature(signer.get(), tbs_bits, rng); - assert(concat_sig.size() % 2 == 0); - MemoryVector<byte> result = DER_Encoder() + + return DER_Encoder() .start_cons(ASN1_Tag(7), APPLICATION) .raw_bytes(tbs_bits) .encode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION) .end_cons() .get_contents(); - return result; } ASN1_Car EAC1_1_ADO::get_car() const @@ -68,14 +66,15 @@ ASN1_Car EAC1_1_ADO::get_car() const return m_car; } -void EAC1_1_ADO::decode_info(SharedPtrConverter<DataSource> source, +void EAC1_1_ADO::decode_info(DataSource& source, SecureVector<byte> & res_tbs_bits, ECDSA_Signature & res_sig) { SecureVector<byte> concat_sig; SecureVector<byte> cert_inner_bits; ASN1_Car car; - BER_Decoder(*source.get_ptr().get()) + + BER_Decoder(source) .start_cons(ASN1_Tag(7)) .start_cons(ASN1_Tag(33)) .raw_bytes(cert_inner_bits) @@ -89,28 +88,30 @@ void EAC1_1_ADO::decode_info(SharedPtrConverter<DataSource> source, .raw_bytes(cert_inner_bits) .end_cons() .get_contents(); + SecureVector<byte> enc_car = DER_Encoder() .encode(car) .get_contents(); + res_tbs_bits = enc_cert; res_tbs_bits.append(enc_car); res_sig = decode_concatenation(concat_sig); - - } + void EAC1_1_ADO::encode(Pipe& out, X509_Encoding encoding) const { - SecureVector<byte> concat_sig(EAC1_1_obj<EAC1_1_ADO>::m_sig.get_concatenation()); - SecureVector<byte> der = DER_Encoder() - .start_cons(ASN1_Tag(7), APPLICATION) - .raw_bytes(tbs_bits) - .encode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION) - .end_cons() - .get_contents(); if(encoding == PEM) throw Invalid_Argument("EAC1_1_ADO::encode() cannot PEM encode an EAC object"); - else - out.write(der); + + SecureVector<byte> concat_sig( + EAC1_1_obj<EAC1_1_ADO>::m_sig.get_concatenation()); + + out.write(DER_Encoder() + .start_cons(ASN1_Tag(7), APPLICATION) + .raw_bytes(tbs_bits) + .encode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION) + .end_cons() + .get_contents()); } SecureVector<byte> EAC1_1_ADO::tbs_data() const @@ -120,8 +121,6 @@ SecureVector<byte> EAC1_1_ADO::tbs_data() const bool EAC1_1_ADO::operator==(EAC1_1_ADO const& rhs) const { - assert(((this->m_req == rhs.m_req) && (this->tbs_data() == rhs.tbs_data())) || - ((this->m_req != rhs.m_req) && (this->tbs_data() != rhs.tbs_data()))); return (this->get_concat_sig() == rhs.get_concat_sig() && this->tbs_data() == rhs.tbs_data() && this->get_car() == rhs.get_car()); diff --git a/src/cert/cvc/cvc_ado.h b/src/cert/cvc/cvc_ado.h index a0dbec2a6..80e6a82b7 100644 --- a/src/cert/cvc/cvc_ado.h +++ b/src/cert/cvc/cvc_ado.h @@ -38,7 +38,7 @@ class BOTAN_DLL EAC1_1_ADO : public EAC1_1_obj<EAC1_1_ADO> * Construct a CVC ADO request from a data source * @param source the data source */ - EAC1_1_ADO(std::tr1::shared_ptr<DataSource> source); + EAC1_1_ADO(DataSource& source); /** * Create a signed CVC ADO request from to be signed (TBS) data @@ -83,7 +83,7 @@ class BOTAN_DLL EAC1_1_ADO : public EAC1_1_obj<EAC1_1_ADO> EAC1_1_Req m_req; void force_decode(); - static void decode_info(SharedPtrConverter<DataSource> source, + static void decode_info(DataSource& source, SecureVector<byte> & res_tbs_bits, ECDSA_Signature & res_sig); }; diff --git a/src/cert/cvc/cvc_ca.cpp b/src/cert/cvc/cvc_ca.cpp index 8ca8db0c2..814df216b 100644 --- a/src/cert/cvc/cvc_ca.cpp +++ b/src/cert/cvc/cvc_ca.cpp @@ -37,8 +37,7 @@ EAC1_1_CVC EAC1_1_CVC_CA::make_cert(std::auto_ptr<PK_Signer> signer, EAC1_1_CVC::build_cert_body(tbs), rng); - std::tr1::shared_ptr<DataSource> source(new DataSource_Memory(signed_cert)); - + DataSource_Memory source(signed_cert); return EAC1_1_CVC(source); } diff --git a/src/cert/cvc/cvc_cert.cpp b/src/cert/cvc/cvc_cert.cpp index d2be12df8..94d80af21 100644 --- a/src/cert/cvc/cvc_cert.cpp +++ b/src/cert/cvc/cvc_cert.cpp @@ -56,7 +56,7 @@ void EAC1_1_CVC::force_decode() throw Decoding_Error("CertificateHolderAuthorizationValue was not of length 1"); if(cpi != 0) - throw Decoding_Error("EAC1_1 certificate´s cpi was not 0"); + throw Decoding_Error("EAC1_1 certificate's cpi was not 0"); // FIXME: PK algos have no notion of EAC encoder/decoder currently #if 0 @@ -78,7 +78,7 @@ void EAC1_1_CVC::force_decode() /* * CVC Certificate Constructor */ -EAC1_1_CVC::EAC1_1_CVC(std::tr1::shared_ptr<DataSource>& in) +EAC1_1_CVC::EAC1_1_CVC(DataSource& in) { init(in); self_signed = false; @@ -87,7 +87,7 @@ EAC1_1_CVC::EAC1_1_CVC(std::tr1::shared_ptr<DataSource>& in) EAC1_1_CVC::EAC1_1_CVC(const std::string& in) { - std::tr1::shared_ptr<DataSource> stream(new DataSource_Stream(in, true)); + DataSource_Stream stream(in, true); init(stream); self_signed = false; do_decode(); diff --git a/src/cert/cvc/cvc_cert.h b/src/cert/cvc/cvc_cert.h index 17671d332..ae0c21d7b 100644 --- a/src/cert/cvc/cvc_cert.h +++ b/src/cert/cvc/cvc_cert.h @@ -59,7 +59,7 @@ class BOTAN_DLL EAC1_1_CVC : public EAC1_1_gen_CVC<EAC1_1_CVC>//Signed_Object * Construct a CVC from a data source * @param source the data source */ - EAC1_1_CVC(std::tr1::shared_ptr<DataSource>& source); + EAC1_1_CVC(DataSource& source); /** * Construct a CVC from a file diff --git a/src/cert/cvc/cvc_gen_cert.h b/src/cert/cvc/cvc_gen_cert.h index 797970e29..096f7898c 100644 --- a/src/cert/cvc/cvc_gen_cert.h +++ b/src/cert/cvc/cvc_gen_cert.h @@ -16,7 +16,6 @@ #include <botan/ecdsa.h> #include <botan/ecdsa_sig.h> #include <string> -#include <assert.h> namespace Botan { @@ -87,7 +86,7 @@ class BOTAN_DLL EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation ASN1_Chr m_chr; bool self_signed; - static void decode_info(SharedPtrConverter<DataSource> source, + static void decode_info(DataSource& source, SecureVector<byte> & res_tbs_bits, ECDSA_Signature & res_sig); @@ -109,7 +108,7 @@ template<typename Derived> MemoryVector<byte> EAC1_1_gen_CVC<Derived>::make_sign RandomNumberGenerator& rng) // static { SecureVector<byte> concat_sig = EAC1_1_obj<Derived>::make_signature(signer.get(), tbs_bits, rng); - assert(concat_sig.size() % 2 == 0); + return DER_Encoder() .start_cons(ASN1_Tag(33), APPLICATION) .raw_bytes(tbs_bits) @@ -156,12 +155,12 @@ template<typename Derived> void EAC1_1_gen_CVC<Derived>::encode(Pipe& out, X509_ template<typename Derived> void EAC1_1_gen_CVC<Derived>::decode_info( - SharedPtrConverter<DataSource> source, + DataSource& source, SecureVector<byte> & res_tbs_bits, ECDSA_Signature & res_sig) { SecureVector<byte> concat_sig; - BER_Decoder(*source.get_shared().get()) + BER_Decoder(source) .start_cons(ASN1_Tag(33)) .start_cons(ASN1_Tag(78)) .raw_bytes(res_tbs_bits) diff --git a/src/cert/cvc/cvc_req.cpp b/src/cert/cvc/cvc_req.cpp index 70a44bacd..78dbdea52 100644 --- a/src/cert/cvc/cvc_req.cpp +++ b/src/cert/cvc/cvc_req.cpp @@ -10,19 +10,17 @@ #include <botan/ber_dec.h> #include <botan/pem.h> #include <botan/parsing.h> -#include <assert.h> #include <botan/cvc_key.h> #include <botan/oids.h> #include <botan/look_pk.h> #include <botan/cvc_req.h> -#include <botan/freestore.h> namespace Botan { bool EAC1_1_Req::operator==(EAC1_1_Req const& rhs) const { - return (this->tbs_data() == rhs.tbs_data() - && this->get_concat_sig() == rhs.get_concat_sig()); + return (this->tbs_data() == rhs.tbs_data() && + this->get_concat_sig() == rhs.get_concat_sig()); } void EAC1_1_Req::force_decode() @@ -36,10 +34,9 @@ void EAC1_1_Req::force_decode() .end_cons() .decode(m_chr) .verify_end(); + if(cpi != 0) - { - throw Decoding_Error("EAC1_1 request´s cpi was not 0"); - } + throw Decoding_Error("EAC1_1 requests cpi was not 0"); // FIXME: No EAC support in ECDSA #if 0 @@ -50,7 +47,7 @@ void EAC1_1_Req::force_decode() #endif } -EAC1_1_Req::EAC1_1_Req(std::tr1::shared_ptr<DataSource> in) +EAC1_1_Req::EAC1_1_Req(DataSource& in) { init(in); self_signed = true; @@ -59,7 +56,7 @@ EAC1_1_Req::EAC1_1_Req(std::tr1::shared_ptr<DataSource> in) EAC1_1_Req::EAC1_1_Req(const std::string& in) { - std::tr1::shared_ptr<DataSource> stream(new DataSource_Stream(in, true)); + DataSource_Stream stream(in, true); init(stream); self_signed = true; do_decode(); diff --git a/src/cert/cvc/cvc_req.h b/src/cert/cvc/cvc_req.h index 28f03db80..2abc72c9a 100644 --- a/src/cert/cvc/cvc_req.h +++ b/src/cert/cvc/cvc_req.h @@ -35,7 +35,7 @@ class BOTAN_DLL EAC1_1_Req : public EAC1_1_gen_CVC<EAC1_1_Req> * Construct a CVC request from a data source. * @param source the data source */ - EAC1_1_Req(std::tr1::shared_ptr<DataSource> source); + EAC1_1_Req(DataSource& source); /** * Construct a CVC request from a DER encoded CVC reqeust file. diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 06b7eb1ab..deef351b9 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -16,6 +16,7 @@ #include <botan/cvc_ado.h> #include <botan/time.h> #include <sstream> +#include <assert.h> namespace Botan { @@ -42,6 +43,7 @@ std::string padding_and_hash_from_oid(OID const& oid) padding_and_hash.erase(0, padding_and_hash.find("/",0) + 1); return padding_and_hash; } + std::string fixed_len_seqnr(u32bit seqnr, u32bit len) { std::stringstream ss; @@ -131,7 +133,8 @@ EAC1_1_Req create_cvc_req(Private_Key const& key, .get_contents(); MemoryVector<byte> signed_cert = EAC1_1_gen_CVC<EAC1_1_Req>::make_signed(signer, EAC1_1_gen_CVC<EAC1_1_Req>::build_cert_body(tbs), rng); - std::tr1::shared_ptr<DataSource> source(new DataSource_Memory(signed_cert)); + + DataSource_Memory source(signed_cert); return EAC1_1_Req(source); } @@ -151,7 +154,8 @@ EAC1_1_ADO create_ado_req(Private_Key const& key, SecureVector<byte> tbs_bits = req.BER_encode(); tbs_bits.append(DER_Encoder().encode(car).get_contents()); MemoryVector<byte> signed_cert = EAC1_1_ADO::make_signed(signer, tbs_bits, rng); - std::tr1::shared_ptr<DataSource> source(new DataSource_Memory(signed_cert)); + + DataSource_Memory source(signed_cert); return EAC1_1_ADO(source); } @@ -206,7 +210,7 @@ EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer, } if (signer.signature_algorithm() != signee.signature_algorithm()) { - throw Invalid_Argument("link_cvca(): signature algorithms of signer and signee don´t match"); + throw Invalid_Argument("link_cvca(): signature algorithms of signer and signee don't match"); } AlgorithmIdentifier sig_algo = signer.signature_algorithm(); std::string padding_and_hash = padding_and_hash_from_oid(sig_algo.oid); diff --git a/src/cert/cvc/eac_obj.h b/src/cert/cvc/eac_obj.h index 646bbeee6..e4eb895c1 100644 --- a/src/cert/cvc/eac_obj.h +++ b/src/cert/cvc/eac_obj.h @@ -18,7 +18,6 @@ #include <botan/oids.h> #include <botan/look_pk.h> #include <botan/ecdsa_sig.h> -#include <botan/freestore.h> #include <string> namespace Botan { @@ -50,7 +49,7 @@ class BOTAN_DLL EAC1_1_obj : public EAC_Signed_Object virtual bool check_signature(Public_Key& pub_key) const; protected: - void init(SharedPtrConverter<DataSource> in); + void init(DataSource& in); static SecureVector<byte> make_signature(PK_Signer* signer, const MemoryRegion<byte>& tbs_bits, @@ -78,11 +77,12 @@ EAC1_1_obj<Derived>::make_signature(PK_Signer* signer, return concat_sig; } -template<typename Derived> void EAC1_1_obj<Derived>::init(SharedPtrConverter<DataSource> in) +template<typename Derived> +void EAC1_1_obj<Derived>::init(DataSource& in) { try { - Derived::decode_info(in.get_shared(), tbs_bits, m_sig); + Derived::decode_info(in, tbs_bits, m_sig); } catch(Decoding_Error) { diff --git a/src/cert/cvc/freestore.h b/src/cert/cvc/freestore.h deleted file mode 100644 index 7f8b85388..000000000 --- a/src/cert/cvc/freestore.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* (C) 2007 Christoph Ludwig -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_FREESTORE_H__ -#define BOTAN_FREESTORE_H__ - -#include <botan/build.h> - -#if defined(BOTAN_USE_STD_TR1) - #include <tr1/memory> -#elif defined(BOTAN_USE_BOOST_TR1) - #include <boost/tr1/memory.hpp> -#else - #error "Please choose a TR1 implementation in build.h" -#endif - -namespace Botan { - -/** -* This class is intended as an function call parameter type and -* enables convenient automatic conversions between plain and smart -* pointer types. It internally stores a SharedPointer which can be -* accessed. -*/ -template<typename T> -class BOTAN_DLL SharedPtrConverter - { - public: - typedef std::tr1::shared_ptr<T> SharedPtr; - - /** - * Construct a null pointer equivalent object. - */ - SharedPtrConverter() : ptr() {} - - /** - * Copy constructor. - */ - SharedPtrConverter(SharedPtrConverter const& other) : - ptr(other.ptr) {} - - /** - * Construct a converter object from another pointer type. - * @param p the pointer which shall be set as the internally stored - * pointer value of this converter. - */ - template<typename Ptr> - SharedPtrConverter(Ptr p) - : ptr(p) {} - - /** - * Get the internally stored shared pointer. - * @return the internally stored shared pointer - */ - SharedPtr const& get_ptr() const { return this->ptr; } - - /** - * Get the internally stored shared pointer. - * @return the internally stored shared pointer - */ - SharedPtr get_ptr() { return this->ptr; } - - /** - * Get the internally stored shared pointer. - * @return the internally stored shared pointer - */ - SharedPtr const& get_shared() const { return this->ptr; } - - /** - * Get the internally stored shared pointer. - * @return the internally stored shared pointer - */ - SharedPtr get_shared() { return this->ptr; } - - private: - SharedPtr ptr; - }; - -} - -#endif diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index 2033b9576..f3cf42a0e 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -1,7 +1,5 @@ define CARD_VERIFIABLE_CERTIFICATES -uses_tr1 yes - load_on auto <header:public> @@ -15,7 +13,6 @@ cvc_self.h eac_asn_obj.h eac_obj.h ecdsa_sig.h -freestore.h signed_obj.h </header:public> diff --git a/src/libstate/policy.cpp b/src/libstate/policy.cpp index c11fc28ce..3e9c8e122 100644 --- a/src/libstate/policy.cpp +++ b/src/libstate/policy.cpp @@ -38,6 +38,7 @@ void set_default_oids(Library_State& config) add_oid(config, "1.3.6.1.4.1.25258.1.1", "RW"); add_oid(config, "1.3.6.1.4.1.25258.1.2", "NR"); add_oid(config, "1.2.840.10045.2.1", "ECDSA"); // X9.62 + add_oid(config, "1.2.643.2.2.19", "GOST-34.10"); // RFC 4491 /* Ciphers */ add_oid(config, "1.3.14.3.2.7", "DES/CBC"); @@ -103,6 +104,8 @@ void set_default_oids(Library_State& config) add_oid(config, "1.2.840.10045.4.3.3", "ECDSA/EMSA1(SHA-384)"); add_oid(config, "1.2.840.10045.4.3.4", "ECDSA/EMSA1(SHA-512)"); + add_oid(config, "1.2.643.2.2.3", "GOST-34.10/EMSA1(GOST-R-34.11-94)"); + add_oid(config, "1.3.6.1.4.1.25258.2.1.1.1", "RW/EMSA2(RIPEMD-160)"); add_oid(config, "1.3.6.1.4.1.25258.2.1.1.2", "RW/EMSA2(SHA-160)"); add_oid(config, "1.3.6.1.4.1.25258.2.1.1.3", "RW/EMSA2(SHA-224)"); diff --git a/src/math/gfpmath/curve_gfp.cpp b/src/math/gfpmath/curve_gfp.cpp index cf687b6ab..e6e69ab0f 100644 --- a/src/math/gfpmath/curve_gfp.cpp +++ b/src/math/gfpmath/curve_gfp.cpp @@ -52,7 +52,7 @@ bool operator==(const CurveGFp& lhs, const CurveGFp& rhs) std::ostream& operator<<(std::ostream& output, const CurveGFp& elem) { - return output << "y^2f = x^3 + (" << elem.get_a() << ")x + (" << elem.get_b() << ")"; + return output << "y^2 = x^3 + (" << elem.get_a() << ")x + (" << elem.get_b() << ")"; } } diff --git a/src/math/gfpmath/gfp_element.cpp b/src/math/gfpmath/gfp_element.cpp index 863135491..3bb4d0002 100644 --- a/src/math/gfpmath/gfp_element.cpp +++ b/src/math/gfpmath/gfp_element.cpp @@ -303,7 +303,7 @@ const BigInt& GFpElement::get_mres() const if(!m_use_montgm) { // does the following exception really make sense? - // wouldn´t it be better to simply turn on montg.mult. when + // wouldn't it be better to simply turn on montg.mult. when // this explicit request is made? throw Illegal_Transformation("GFpElement is not allowed to be transformed to m-residue"); } diff --git a/src/math/gfpmath/gfp_element.h b/src/math/gfpmath/gfp_element.h index 9d2523591..538d41a47 100644 --- a/src/math/gfpmath/gfp_element.h +++ b/src/math/gfpmath/gfp_element.h @@ -121,9 +121,9 @@ class BOTAN_DLL GFpElement const BigInt& get_value() const; /** - * Tells whether this GFpElement is currently transformed to it´ m-residue, + * Tells whether this GFpElement is currently transformed to an m-residue, * i.e. in the form x_bar = x * r mod m. - * @result true if it is currently transformed to it´s m-residue. + * @result true if it is currently transformed to its m-residue. */ bool is_trf_to_mres() const; @@ -148,7 +148,7 @@ class BOTAN_DLL GFpElement * in ordinary residue representation (returns false). * m-residue is prefered in case of ambiguity. * does not toggle m_use_montgm of the arguments. - * Don´t be confused about the constness of the arguments: + * Don't be confused about the constness of the arguments: * the transformation between normal residue and m-residue is * considered as leaving the object const. * @param lhs the first operand to be aligned diff --git a/src/math/gfpmath/point_gfp.cpp b/src/math/gfpmath/point_gfp.cpp index 166bb61dd..4b2de7913 100644 --- a/src/math/gfpmath/point_gfp.cpp +++ b/src/math/gfpmath/point_gfp.cpp @@ -641,10 +641,6 @@ PointGFp OS2ECP(MemoryRegion<byte> const& os, const CurveGFp& curve) bX = SecureVector<byte>(os.size() - 1); bX.copy(os.begin()+1, os.size()-1); - /* Problem wäre, wenn decode() das erste bit als Vorzeichen interpretiert. - *--------------------- - * AW(FS): decode() interpretiert das erste Bit nicht als Vorzeichen - */ bi_dec_x = BigInt::decode(bX, bX.size()); x = GFpElement(curve.get_p(), bi_dec_x); bool yMod2; diff --git a/src/pubkey/ec_dompar/ec_dompar.cpp b/src/pubkey/ec_dompar/ec_dompar.cpp index 475a1ce52..3719153f0 100644 --- a/src/pubkey/ec_dompar/ec_dompar.cpp +++ b/src/pubkey/ec_dompar/ec_dompar.cpp @@ -409,6 +409,18 @@ std::vector<std::string> get_standard_domain_parameter(const std::string& oid) return dom_par; } + if(oid == "1.2.643.2.2.35.1" || oid == "1.2.643.2.2.36.0") // GostR3410-2001-CryptoPro-A-ParamSet + { + std::vector<std::string> dom_par; + dom_par.push_back("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97"); + dom_par.push_back("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94"); + dom_par.push_back("166"); + dom_par.push_back("0400000000000000000000000000000000000000000000000000000000000000018D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"); + dom_par.push_back("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893"); + dom_par.push_back("1"); + return dom_par; + } + throw Invalid_Argument("No such ECC curve " + oid); } diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp new file mode 100644 index 000000000..c2ddabe63 --- /dev/null +++ b/src/pubkey/gost_3410/gost_3410.cpp @@ -0,0 +1,351 @@ +/* +* GOST 34.10-2001 implemenation +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* Manuel Hartl, FlexSecure GmbH +* (C) 2008-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/gost_3410.h> +#include <botan/numthry.h> +#include <botan/der_enc.h> +#include <botan/ber_dec.h> +#include <botan/secmem.h> +#include <botan/point_gfp.h> + +namespace Botan { + +GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, + const EC_Domain_Params& dom_pars) + { + mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_pars)); + generate_private_key(rng); + + try + { + mp_public_point->check_invariants(); + } + catch(Illegal_Point& e) + { + throw Invalid_State("GOST_3410 key generation failed"); + } + } + +GOST_3410_PrivateKey::GOST_3410_PrivateKey(const EC_Domain_Params& domain, + const BigInt& x) + { + mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(domain)); + + m_private_value = x; + mp_public_point = std::auto_ptr<PointGFp>(new PointGFp (mp_dom_pars->get_base_point())); + mp_public_point->mult_this_secure(m_private_value, + mp_dom_pars->get_order(), + mp_dom_pars->get_order()-1); + + try + { + mp_public_point->check_invariants(); + } + catch(Illegal_Point) + { + throw Invalid_State("GOST_3410 key generation failed"); + } + } + +X509_Encoder* GOST_3410_PublicKey::x509_encoder() const + { + class GOST_3410_Key_Encoder : public X509_Encoder + { + public: + AlgorithmIdentifier alg_id() const + { + key->affirm_init(); + + SecureVector<byte> params = + encode_der_ec_dompar(key->domain_parameters(), key->m_param_enc); + + return AlgorithmIdentifier(key->get_oid(), params); + } + + MemoryVector<byte> key_bits() const + { + key->affirm_init(); + + // Trust CryptoPro to come up with something obnoxious + const BigInt x = key->mp_public_point->get_affine_x().get_value(); + const BigInt y = key->mp_public_point->get_affine_y().get_value(); + + SecureVector<byte> bits(2*std::max(x.bytes(), y.bytes())); + + y.binary_encode(bits + (bits.size() / 2 - y.bytes())); + x.binary_encode(bits + (bits.size() - y.bytes())); + + return DER_Encoder().encode(bits, OCTET_STRING).get_contents(); + } + + GOST_3410_Key_Encoder(const GOST_3410_PublicKey* k): key(k) {} + private: + const GOST_3410_PublicKey* key; + }; + + return new GOST_3410_Key_Encoder(this); + } + +X509_Decoder* GOST_3410_PublicKey::x509_decoder() + { + class GOST_3410_Key_Decoder : public X509_Decoder + { + public: + void alg_id(const AlgorithmIdentifier& alg_id) + { + // Also includes hash and cipher OIDs... brilliant design guys + OID ecc_param_id; + + BER_Decoder ber(alg_id.parameters); + ber.start_cons(SEQUENCE).decode(ecc_param_id); + + EC_Domain_Params ecc_params = get_EC_Dom_Pars_by_oid(ecc_param_id.as_string()); + + key->mp_dom_pars.reset(new EC_Domain_Params(ecc_params)); + } + + void key_bits(const MemoryRegion<byte>& bits) + { + + SecureVector<byte> key_bits; + BER_Decoder ber(bits); + ber.decode(key_bits, OCTET_STRING); + + const u32bit part_size = key_bits.size() / 2; + + BigInt y(key_bits, part_size); + BigInt x(key_bits + part_size, part_size); + + const BigInt p = key->domain_parameters().get_curve().get_p(); + + key->mp_public_point.reset( + new PointGFp(key->domain_parameters().get_curve(), + GFpElement(x, p), + GFpElement(y, p))); + + key->X509_load_hook(); + } + + GOST_3410_Key_Decoder(GOST_3410_PublicKey* k): key(k) {} + private: + GOST_3410_PublicKey* key; + }; + + return new GOST_3410_Key_Decoder(this); + } + +/* +* GOST_3410_PublicKey +*/ +void GOST_3410_PublicKey::affirm_init() const // virtual + { + EC_PublicKey::affirm_init(); + } + +void GOST_3410_PublicKey::set_domain_parameters(const EC_Domain_Params& dom_pars) + { + if(mp_dom_pars.get()) + { + // they are already set, we must ensure that they are equal to the arg + if(dom_pars != *mp_dom_pars.get()) + throw Invalid_Argument("EC_PublicKey::set_domain_parameters - cannot reset to a new value"); + + return; + } + + if(m_enc_public_point.size() == 0) + throw Invalid_State("EC_PublicKey::set_domain_parameters(): encoded public point isn't set"); + + // now try to decode the public key ... + PointGFp tmp_pp(OS2ECP(m_enc_public_point, dom_pars.get_curve())); + try + { + tmp_pp.check_invariants(); + } + catch(Illegal_Point e) + { + throw Invalid_State("EC_PublicKey::set_domain_parameters(): point does not lie on provided curve"); + } + + std::auto_ptr<EC_Domain_Params> p_tmp_pars(new EC_Domain_Params(dom_pars)); + mp_public_point.reset(new PointGFp(tmp_pp)); + mp_dom_pars = p_tmp_pars; + } + +void GOST_3410_PublicKey::set_all_values(const GOST_3410_PublicKey& other) + { + m_param_enc = other.m_param_enc; + m_enc_public_point = other.m_enc_public_point; + if(other.mp_dom_pars.get()) + mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); + + if(other.mp_public_point.get()) + mp_public_point.reset(new PointGFp(other.public_point())); + } + +GOST_3410_PublicKey::GOST_3410_PublicKey(const GOST_3410_PublicKey& other) + : Public_Key(), + EC_PublicKey(), + PK_Verifying_wo_MR_Key() + { + set_all_values(other); + } + +const GOST_3410_PublicKey& GOST_3410_PublicKey::operator=(const GOST_3410_PublicKey& rhs) + { + set_all_values(rhs); + return *this; + } + +bool GOST_3410_PublicKey::verify(const byte msg[], u32bit msg_len, + const byte sig[], u32bit sig_len) const + { + affirm_init(); + + const BigInt& n = mp_dom_pars->get_order(); + + if(sig_len != n.bytes()*2) + return false; + + // NOTE: it is not checked whether the public point is set + if(mp_dom_pars->get_curve().get_p() == 0) + throw Internal_Error("domain parameters not set"); + + BigInt e(msg, msg_len); + + BigInt r(sig, sig_len / 2); + BigInt s(sig + sig_len / 2, sig_len / 2); + + if(r < 0 || r >= n || s < 0 || s >= n) + return false; + + e %= n; + if(e == 0) + e = 1; + + BigInt v = inverse_mod(e, n); + + BigInt z1 = (s*v) % n; + BigInt z2 = (-r*v) % n; + + PointGFp R = (z1 * mp_dom_pars->get_base_point() + z2 * *mp_public_point); + + return (R.get_affine_x().get_value() == r); + } + +GOST_3410_PublicKey::GOST_3410_PublicKey(const EC_Domain_Params& dom_par, + const PointGFp& public_point) + { + mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par)); + mp_public_point = std::auto_ptr<PointGFp>(new PointGFp(public_point)); + m_param_enc = ENC_EXPLICIT; + } + +void GOST_3410_PublicKey::X509_load_hook() + { + EC_PublicKey::X509_load_hook(); + EC_PublicKey::affirm_init(); + } + +u32bit GOST_3410_PublicKey::max_input_bits() const + { + if(!mp_dom_pars.get()) + { + throw Invalid_State("GOST_3410_PublicKey::max_input_bits(): domain parameters not set"); + } + return mp_dom_pars->get_order().bits(); + } + +/************************* +* GOST_3410_PrivateKey +*************************/ +void GOST_3410_PrivateKey::affirm_init() const // virtual + { + EC_PrivateKey::affirm_init(); + } + +void GOST_3410_PrivateKey::PKCS8_load_hook(bool generated) + { + EC_PrivateKey::PKCS8_load_hook(generated); + EC_PrivateKey::affirm_init(); + } + +void GOST_3410_PrivateKey::set_all_values(const GOST_3410_PrivateKey& other) + { + m_private_value = other.m_private_value; + m_param_enc = other.m_param_enc; + m_enc_public_point = other.m_enc_public_point; + + if(other.mp_dom_pars.get()) + mp_dom_pars.reset(new EC_Domain_Params(other.domain_parameters())); + + if(other.mp_public_point.get()) + mp_public_point.reset(new PointGFp(other.public_point())); + } + +GOST_3410_PrivateKey::GOST_3410_PrivateKey(GOST_3410_PrivateKey const& other) + : Public_Key(), + EC_PublicKey(), + Private_Key(), + GOST_3410_PublicKey(), + EC_PrivateKey(), + PK_Signing_Key() + { + set_all_values(other); + } + +const GOST_3410_PrivateKey& GOST_3410_PrivateKey::operator=(const GOST_3410_PrivateKey& rhs) + { + set_all_values(rhs); + return *this; + } + +SecureVector<byte> +GOST_3410_PrivateKey::sign(const byte msg[], + u32bit msg_len, + RandomNumberGenerator& rng) const + { + affirm_init(); + + const BigInt& n = mp_dom_pars->get_order(); + + BigInt k; + do + k.randomize(rng, n.bits()-1); + while(k >= n); + + if(m_private_value == 0) + throw Internal_Error("GOST_3410::sign(): no private key"); + + if(n == 0) + throw Internal_Error("GOST_3410::sign(): domain parameters not set"); + + BigInt e(msg, msg_len); + + e %= n; + if(e == 0) + e = 1; + + PointGFp k_times_P(mp_dom_pars->get_base_point()); + k_times_P.mult_this_secure(k, n, n-1); + k_times_P.check_invariants(); + BigInt r = k_times_P.get_affine_x().get_value() % n; + + if(r == 0) + throw Internal_Error("GOST_3410::sign: r was zero"); + + BigInt s = (r*m_private_value + k*e) % n; + + SecureVector<byte> output(2*n.bytes()); + r.binary_encode(output + (output.size() / 2 - r.bytes())); + s.binary_encode(output + (output.size() - s.bytes())); + return output; + } + +} diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h new file mode 100644 index 000000000..460aca9bf --- /dev/null +++ b/src/pubkey/gost_3410/gost_3410.h @@ -0,0 +1,164 @@ +/* +* GOST 34.10-2001 +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* Manuel Hartl, FlexSecure GmbH +* (C) 2008-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_GOST_3410_KEY_H__ +#define BOTAN_GOST_3410_KEY_H__ + +#include <botan/ecc_key.h> + +namespace Botan { + +/** +* This class represents GOST_3410 Public Keys. +*/ +class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, + public PK_Verifying_wo_MR_Key + { + public: + + /** + * Get this keys algorithm name. + * @result this keys algorithm name + */ + std::string algo_name() const { return "GOST-34.10"; } + + /** + * Get the maximum number of bits allowed to be fed to this key. + * This is the bitlength of the order of the base point. + + * @result the maximum number of input bits + */ + u32bit max_input_bits() const; + + u32bit message_parts() const { return 2; } + + u32bit message_part_size() const + { return mp_dom_pars->get_order().bytes(); } + + /** + * Verify a message with this key. + * @param message the byte array containing the message + * @param mess_len the number of bytes in the message byte array + * @param signature the byte array containing the signature + * @param sig_len the number of bytes in the signature byte array + */ + bool verify(const byte message[], u32bit mess_len, + const byte signature[], u32bit sig_len) const; + + /** + * Default constructor. Use this one if you want to later fill + * this object with data from an encoded key. + */ + GOST_3410_PublicKey() {} + + /** + * Construct a public key from a given public point. + * @param dom_par the domain parameters associated with this key + * @param public_point the public point defining this key + */ + GOST_3410_PublicKey(const EC_Domain_Params& dom_par, + const PointGFp& public_point); // sets core + + GOST_3410_PublicKey const& operator=(const GOST_3410_PublicKey& rhs); + + GOST_3410_PublicKey(const GOST_3410_PublicKey& other); + + /** + * Set the domain parameters of this key. This function has to be + * used when a key encoded without domain parameters was decoded into + * this key. Otherwise it will not be able to verify a signature. + * @param dom_pars the domain_parameters associated with this key + * @throw Invalid_Argument if the point was found not to be satisfying the + * curve equation of the provided domain parameters + * or if this key already has domain parameters set + * and these are differing from those given as the parameter + */ + void set_domain_parameters(const EC_Domain_Params& dom_pars); + + /** + * Ensure that the public point and domain parameters of this key are set. + * @throw Invalid_State if either of the two data members is not set + */ + virtual void affirm_init() const; + + /** + * Get an x509_encoder that can be used to encode this key. + * @result an x509_encoder for this key + */ + X509_Encoder* x509_encoder() const; + + /** + * Get an x509_decoder that can be used to decode a stored key into + * this key. + * @result an x509_decoder for this key + */ + X509_Decoder* x509_decoder(); + + protected: + void X509_load_hook(); + void set_all_values(const GOST_3410_PublicKey& other); + }; + +/** +* This class represents GOST_3410 Private Keys +*/ +class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, + public EC_PrivateKey, + public PK_Signing_Key + { + public: + /** + * Default constructor. Use this one if you want to later fill + * this object with data from an encoded key. + */ + GOST_3410_PrivateKey() {} + + /** + * Generate a new private key + * @param the domain parameters to used for this key + */ + GOST_3410_PrivateKey(RandomNumberGenerator& rng, + const EC_Domain_Params& domain); + + /** + * Load a private key + * @param domain parameters + * @param x the private key + */ + GOST_3410_PrivateKey(const EC_Domain_Params& domain, const BigInt& x); + + GOST_3410_PrivateKey(const GOST_3410_PrivateKey& other); + GOST_3410_PrivateKey const& operator=(const GOST_3410_PrivateKey& rhs); + + /** + * Sign a message with this key. + * @param message the byte array representing the message to be signed + * @param mess_len the length of the message byte array + * @result the signature + */ + + SecureVector<byte> sign(const byte message[], u32bit mess_len, + RandomNumberGenerator& rng) const; + + /** + * Make sure that the public key parts of this object are set + * (calls EC_PublicKey::affirm_init()) as well as the private key + * value. + * @throw Invalid_State if the above conditions are not satisfied + */ + virtual void affirm_init() const; + + private: + void set_all_values(const GOST_3410_PrivateKey& other); + void PKCS8_load_hook(bool = false); + }; + +} + +#endif diff --git a/src/pubkey/gost_3410/info.txt b/src/pubkey/gost_3410/info.txt new file mode 100644 index 000000000..1d6c1ed17 --- /dev/null +++ b/src/pubkey/gost_3410/info.txt @@ -0,0 +1,14 @@ +define GOST_34_10_2001 + +load_on auto + +<requires> +alloc +asn1 +ec_dompar +ecc_key +gfpmath +libstate +numbertheory +rng +</requires> diff --git a/src/pubkey/pk_algs.cpp b/src/pubkey/pk_algs.cpp index c040e006b..dd62eb5ac 100644 --- a/src/pubkey/pk_algs.cpp +++ b/src/pubkey/pk_algs.cpp @@ -23,6 +23,10 @@ #include <botan/ecdsa.h> #endif +#if defined(BOTAN_HAS_GOST_34_10_2001) + #include <botan/gost_3410.h> +#endif + #if defined(BOTAN_HAS_NYBERG_RUEPPEL) #include <botan/nr.h> #endif @@ -70,6 +74,10 @@ Public_Key* get_public_key(const std::string& alg_name) if(alg_name == "ECDSA") return new ECDSA_PublicKey; #endif +#if defined(BOTAN_HAS_GOST_34_10_2001) + if(alg_name == "GOST-34.10") return new GOST_3410_PublicKey; +#endif + return 0; } @@ -106,6 +114,10 @@ Private_Key* get_private_key(const std::string& alg_name) if(alg_name == "ECDSA") return new ECDSA_PrivateKey; #endif +#if defined(BOTAN_HAS_GOST_34_10_2001) + if(alg_name == "GOST-34.10") return new GOST_3410_PrivateKey; +#endif + return 0; } diff --git a/src/s2k/s2k.h b/src/s2k/s2k.h index 9ab71344e..055ef8911 100644 --- a/src/s2k/s2k.h +++ b/src/s2k/s2k.h @@ -18,9 +18,9 @@ namespace Botan { class BOTAN_DLL S2K { public: + /** - * Create a copy of this object. - * @return an auto_ptr to a copy of this object + * @return a new instance of this same algorithm */ virtual S2K* clone() const = 0; |