aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cert/cvc/cvc_ado.cpp43
-rw-r--r--src/cert/cvc/cvc_ado.h4
-rw-r--r--src/cert/cvc/cvc_ca.cpp3
-rw-r--r--src/cert/cvc/cvc_cert.cpp6
-rw-r--r--src/cert/cvc/cvc_cert.h2
-rw-r--r--src/cert/cvc/cvc_gen_cert.h9
-rw-r--r--src/cert/cvc/cvc_req.cpp15
-rw-r--r--src/cert/cvc/cvc_req.h2
-rw-r--r--src/cert/cvc/cvc_self.cpp10
-rw-r--r--src/cert/cvc/eac_obj.h8
-rw-r--r--src/cert/cvc/freestore.h84
-rw-r--r--src/cert/cvc/info.txt3
-rw-r--r--src/libstate/policy.cpp3
-rw-r--r--src/math/gfpmath/curve_gfp.cpp2
-rw-r--r--src/math/gfpmath/gfp_element.cpp2
-rw-r--r--src/math/gfpmath/gfp_element.h6
-rw-r--r--src/math/gfpmath/point_gfp.cpp4
-rw-r--r--src/pubkey/ec_dompar/ec_dompar.cpp12
-rw-r--r--src/pubkey/gost_3410/gost_3410.cpp351
-rw-r--r--src/pubkey/gost_3410/gost_3410.h164
-rw-r--r--src/pubkey/gost_3410/info.txt14
-rw-r--r--src/pubkey/pk_algs.cpp12
-rw-r--r--src/s2k/s2k.h4
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;