Clean up CKey and RippleAddress (RIPD-672)

* Remove CKey dependency on RippleAddress
* Create RAII ec_key wrapper that hides EC_KEY and other OpenSSL details
* Move CKey member logic into free functions
* Delete CKey class
* Rename units that are no longer CKey-related
* Delete code that was unused
This commit is contained in:
Josh Juran
2014-11-14 00:34:35 -08:00
committed by Vinnie Falco
parent 9aa040d917
commit b2eeb49a45
15 changed files with 638 additions and 535 deletions

View File

@@ -1,69 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/crypto/CKey.h>
#include <ripple/types/base_uint.h>
#include <beast/unit_test/suite.h>
namespace ripple {
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
// VFALCO TODO move inlined stuff from CKey into here
class CKey_test : public beast::unit_test::suite
{
public:
void
run ()
{
uint128 seed1, seed2;
seed1.SetHex ("71ED064155FFADFA38782C5E0158CB26");
seed2.SetHex ("CF0C3BE4485961858C4198515AE5B965");
CKey root1 (seed1), root2 (seed2);
uint256 priv1, priv2;
root1.GetPrivateKeyU (priv1);
root2.GetPrivateKeyU (priv2);
unexpected (to_string (priv1) != "7CFBA64F771E93E817E15039215430B53F7401C34931D111EAB3510B22DBB0D8",
"Incorrect private key for generator");
unexpected (to_string (priv2) != "98BC2EACB26EB021D1A6293C044D88BA2F0B6729A2772DEEBF2E21A263C1740B",
"Incorrect private key for generator");
RippleAddress nSeed;
nSeed.setSeed (seed1);
unexpected (nSeed.humanSeed () != "shHM53KPZ87Gwdqarm1bAmPeXg8Tn",
"Incorrect human seed");
unexpected (nSeed.humanSeed1751 () != "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH",
"Incorrect 1751 seed");
}
};
BEAST_DEFINE_TESTSUITE(CKey,ripple_data,ripple);
} // ripple

View File

@@ -0,0 +1,124 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include <ripple/crypto/ECDSA.h>
#include <ripple/crypto/ECDSACanonical.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/hmac.h>
namespace ripple {
using openssl::ec_key;
static EC_KEY* new_initialized_EC_KEY()
{
EC_KEY* key = EC_KEY_new_by_curve_name (NID_secp256k1);
if (key == nullptr)
{
throw std::runtime_error ("new_initialized_EC_KEY() : EC_KEY_new_by_curve_name failed");
}
EC_KEY_set_conv_form (key, POINT_CONVERSION_COMPRESSED);
return key;
}
ec_key ECDSAPrivateKey (uint256 const& serialized)
{
EC_KEY* key = new_initialized_EC_KEY();
BIGNUM* bn = BN_bin2bn (serialized.begin(), serialized.size(), nullptr);
if (bn == nullptr)
{
// leaks key
throw std::runtime_error ("ec_key::ec_key: BN_bin2bn failed");
}
const bool ok = EC_KEY_set_private_key (key, bn);
BN_clear_free (bn);
if (! ok)
{
EC_KEY_free (key);
}
return ec_key::acquire ((ec_key::pointer_t) key);
}
ec_key ECDSAPublicKey (Blob const& serialized)
{
EC_KEY* key = new_initialized_EC_KEY();
uint8_t const* begin = &serialized[0];
if (o2i_ECPublicKey (&key, &begin, serialized.size()) != nullptr)
{
EC_KEY_set_conv_form (key, POINT_CONVERSION_COMPRESSED);
}
else
{
EC_KEY_free (key);
}
return ec_key::acquire ((ec_key::pointer_t) key);
}
Blob ECDSASign (uint256 const& hash, const openssl::ec_key& key)
{
Blob result;
unsigned char sig[128];
unsigned int siglen = sizeof sig - 1;
const unsigned char* p = hash.begin();
if (ECDSA_sign (0, p, hash.size(), sig, &siglen, (EC_KEY*) key.get()))
{
size_t newlen = siglen;
makeCanonicalECDSASig (sig, newlen);
result.resize (newlen);
memcpy (&result[0], sig, newlen);
}
return result;
}
static bool ECDSAVerify (uint256 const& hash, uint8 const* sig, size_t sigLen, EC_KEY* key)
{
// -1 = error, 0 = bad sig, 1 = good
return ECDSA_verify (0, hash.begin(), hash.size(), sig, sigLen, key) > 0;
}
bool ECDSAVerify (uint256 const& hash, Blob const& sig, const openssl::ec_key& key)
{
return ECDSAVerify (hash, sig.data(), sig.size(), (EC_KEY*) key.get());
}
} // ripple

View File

@@ -18,8 +18,10 @@
//==============================================================================
#include <ripple/crypto/CKey.h>
#include <ripple/crypto/ECIES.h>
#include <ripple/crypto/RandomNumbers.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/pem.h>
namespace ripple {
@@ -63,25 +65,20 @@ namespace ripple {
#define ECIES_HMAC_TYPE uint256 // Type used to hold HMAC value
#define ECIES_HMAC_SIZE (256/8) // Size of HMAC value
void CKey::getECIESSecret (CKey& otherKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key)
// returns a 32-byte secret unique to these two keys. At least one private key must be known.
static void getECIESSecret (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key)
{
EC_KEY* privkey = (EC_KEY*) secretKey.get();
EC_KEY* pubkey = (EC_KEY*) publicKey.get();
// Retrieve a secret generated from an EC key pair. At least one private key must be known.
if (!pkey || !otherKey.pkey)
if (privkey == nullptr || pubkey == nullptr)
throw std::runtime_error ("missing key");
EC_KEY* pubkey, *privkey;
if (EC_KEY_get0_private_key (pkey))
if (! EC_KEY_get0_private_key (privkey))
{
privkey = pkey;
pubkey = otherKey.pkey;
throw std::runtime_error ("not a private key");
}
else if (EC_KEY_get0_private_key (otherKey.pkey))
{
privkey = otherKey.pkey;
pubkey = pkey;
}
else throw std::runtime_error ("no private key");
unsigned char rawbuf[512];
int buflen = ECDH_compute_key (rawbuf, 512, EC_KEY_get0_public_key (pubkey), privkey, nullptr);
@@ -131,7 +128,7 @@ static ECIES_HMAC_TYPE makeHMAC (const ECIES_HMAC_KEY_TYPE& secret, Blob const&
return ret;
}
Blob CKey::encryptECIES (CKey& otherKey, Blob const& plaintext)
Blob encryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& plaintext)
{
ECIES_ENC_IV_TYPE iv;
@@ -140,7 +137,7 @@ Blob CKey::encryptECIES (CKey& otherKey, Blob const& plaintext)
ECIES_ENC_KEY_TYPE secret;
ECIES_HMAC_KEY_TYPE hmacKey;
getECIESSecret (otherKey, secret, hmacKey);
getECIESSecret (secretKey, publicKey, secret, hmacKey);
ECIES_HMAC_TYPE hmac = makeHMAC (hmacKey, plaintext);
hmacKey.zero ();
@@ -206,7 +203,7 @@ Blob CKey::encryptECIES (CKey& otherKey, Blob const& plaintext)
return out;
}
Blob CKey::decryptECIES (CKey& otherKey, Blob const& ciphertext)
Blob decryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& ciphertext)
{
// minimum ciphertext = IV + HMAC + 1 block
if (ciphertext.size () < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) )
@@ -222,7 +219,7 @@ Blob CKey::decryptECIES (CKey& otherKey, Blob const& ciphertext)
ECIES_ENC_KEY_TYPE secret;
ECIES_HMAC_KEY_TYPE hmacKey;
getECIESSecret (otherKey, secret, hmacKey);
getECIESSecret (secretKey, publicKey, secret, hmacKey);
if (EVP_DecryptInit_ex (&ctx, ECIES_ENC_ALGO, nullptr, secret.begin (), iv.begin ()) != 1)
{
@@ -288,46 +285,4 @@ Blob CKey::decryptECIES (CKey& otherKey, Blob const& ciphertext)
return plaintext;
}
bool checkECIES (void)
{
CKey senderPriv, recipientPriv, senderPub, recipientPub;
for (int i = 0; i < 30000; ++i)
{
if ((i % 100) == 0)
{
// generate new keys every 100 times
senderPriv.MakeNewKey ();
recipientPriv.MakeNewKey ();
if (!senderPub.SetPubKey (senderPriv.GetPubKey ()))
throw std::runtime_error ("key error");
if (!recipientPub.SetPubKey (recipientPriv.GetPubKey ()))
throw std::runtime_error ("key error");
}
// generate message
Blob message (4096);
int msglen = i % 3000;
RandomNumbers::getInstance ().fillBytes (&message.front (), msglen);
message.resize (msglen);
// encrypt message with sender's private key and recipient's public key
Blob ciphertext = senderPriv.encryptECIES (recipientPub, message);
// decrypt message with recipient's private key and sender's public key
Blob decrypt = recipientPriv.decryptECIES (senderPub, ciphertext);
if (decrypt != message)
{
assert (false);
return false;
}
}
return true;
}
} // ripple

View File

@@ -17,47 +17,34 @@
*/
//==============================================================================
#include <ripple/crypto/GenerateDeterministicKey.h>
#include <ripple/crypto/CBigNum.h>
#include <ripple/crypto/CKey.h>
#include <ripple/protocol/Serializer.h>
#include <string>
namespace ripple {
using openssl::ec_key;
// #define EC_DEBUG
// Functions to add CKey support for deterministic EC keys
// <-- seed
uint128 CKey::PassPhraseToKey (std::string const& passPhrase)
{
// VFALCO NOTE This is a bad dependency, CKey shouldn't need it
Serializer s;
s.addRaw (passPhrase);
// NIKB TODO this caling sequence is a bit ugly; this should be improved.
uint256 hash256 = s.getSHA512Half ();
uint128 ret (uint128::fromVoid (hash256.data()));
s.secureErase ();
return ret;
}
// Functions to add support for deterministic EC keys
// --> seed
// <-- private root generator + public root generator
EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
ec_key GenerateRootDeterministicKey (uint128 const& seed)
{
BN_CTX* ctx = BN_CTX_new ();
if (!ctx) return nullptr;
if (!ctx) return ec_key::invalid;
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
if (!pkey)
{
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
@@ -68,7 +55,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
{
BN_CTX_free (ctx);
EC_KEY_free (pkey);
return nullptr;
return ec_key::invalid;
}
if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
@@ -77,7 +64,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
BN_free (order);
EC_KEY_free (pkey);
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
BIGNUM* privKey = nullptr;
@@ -98,7 +85,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
EC_KEY_free (pkey);
BN_free (order);
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
root.zero ();
@@ -114,7 +101,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
EC_KEY_free (pkey);
BN_clear_free (privKey);
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
EC_POINT* pubKey = EC_POINT_new (EC_KEY_get0_group (pkey));
@@ -127,7 +114,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
EC_POINT_free (pubKey);
EC_KEY_free (pkey);
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
BN_clear_free (privKey);
@@ -138,7 +125,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
EC_POINT_free (pubKey);
EC_KEY_free (pkey);
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
EC_POINT_free (pubKey);
@@ -148,13 +135,13 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed)
#ifdef EC_DEBUG
assert (EC_KEY_check_key (pkey) == 1); // CAUTION: This check is *very* expensive
#endif
return pkey;
return ec_key::acquire ((ec_key::pointer_t) pkey);
}
// Take ripple address.
// --> root public generator (consumes)
// <-- root public generator in EC format
EC_KEY* CKey::GenerateRootPubKey (BIGNUM* pubGenerator)
static EC_KEY* GenerateRootPubKey (BIGNUM* pubGenerator)
{
if (pubGenerator == nullptr)
{
@@ -196,7 +183,7 @@ EC_KEY* CKey::GenerateRootPubKey (BIGNUM* pubGenerator)
}
// --> public generator
static BIGNUM* makeHash (RippleAddress const& pubGen, int seq, BIGNUM const* order)
static BIGNUM* makeHash (Blob const& pubGen, int seq, BIGNUM const* order)
{
int subSeq = 0;
BIGNUM* ret = nullptr;
@@ -204,7 +191,7 @@ static BIGNUM* makeHash (RippleAddress const& pubGen, int seq, BIGNUM const* ord
do
{
Serializer s ((33 * 8 + 32 + 32) / 8);
s.addRaw (pubGen.getGenerator ());
s.addRaw (pubGen);
s.add32 (seq);
s.add32 (subSeq++);
uint256 root = s.getSHA512Half ();
@@ -219,18 +206,18 @@ static BIGNUM* makeHash (RippleAddress const& pubGen, int seq, BIGNUM const* ord
}
// --> public generator
EC_KEY* CKey::GeneratePublicDeterministicKey (RippleAddress const& pubGen, int seq)
ec_key GeneratePublicDeterministicKey (Blob const& pubGen, int seq)
{
// publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point
BIGNUM* generator = BN_bin2bn (
pubGen.getGenerator ().data (),
pubGen.getGenerator ().size (),
pubGen.data(),
pubGen.size(),
nullptr);
if (generator == nullptr)
return nullptr;
return ec_key::invalid;
EC_KEY* rootKey = CKey::GenerateRootPubKey (generator);
EC_KEY* rootKey = GenerateRootPubKey (generator);
const EC_POINT* rootPubKey = EC_KEY_get0_public_key (rootKey);
BN_CTX* ctx = BN_CTX_new ();
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
@@ -289,29 +276,23 @@ EC_KEY* CKey::GeneratePublicDeterministicKey (RippleAddress const& pubGen, int s
if (pkey && !success) EC_KEY_free (pkey);
return success ? pkey : nullptr;
}
EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, uint256 const& u, int seq)
{
CBigNum bn (u);
return GeneratePrivateDeterministicKey (pubGen, static_cast<BIGNUM*> (&bn), seq);
return success ? ec_key::acquire ((ec_key::pointer_t) pkey) : ec_key::invalid;
}
// --> root private key
EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, const BIGNUM* rootPrivKey, int seq)
ec_key GeneratePrivateDeterministicKey (Blob const& pubGen, const BIGNUM* rootPrivKey, int seq)
{
// privateKey(n) = (rootPrivateKey + Hash(pubHash|seq)) % order
BN_CTX* ctx = BN_CTX_new ();
if (ctx == nullptr) return nullptr;
if (ctx == nullptr) return ec_key::invalid;
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
if (pkey == nullptr)
{
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
@@ -322,7 +303,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons
{
BN_CTX_free (ctx);
EC_KEY_free (pkey);
return nullptr;
return ec_key::invalid;
}
if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
@@ -330,7 +311,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons
BN_free (order);
BN_CTX_free (ctx);
EC_KEY_free (pkey);
return nullptr;
return ec_key::invalid;
}
// calculate the private additional key
@@ -341,7 +322,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons
BN_free (order);
BN_CTX_free (ctx);
EC_KEY_free (pkey);
return nullptr;
return ec_key::invalid;
}
// calculate the final private key
@@ -357,7 +338,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons
BN_clear_free (privKey);
BN_CTX_free (ctx);
EC_KEY_free (pkey);
return nullptr;
return ec_key::invalid;
}
if (EC_POINT_mul (EC_KEY_get0_group (pkey), pubKey, privKey, nullptr, nullptr, ctx) == 0)
@@ -366,7 +347,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons
EC_POINT_free (pubKey);
EC_KEY_free (pkey);
BN_CTX_free (ctx);
return nullptr;
return ec_key::invalid;
}
BN_clear_free (privKey);
@@ -375,7 +356,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons
EC_POINT_free (pubKey);
BN_CTX_free (ctx);
return pkey;
return ec_key::acquire ((ec_key::pointer_t) pkey);
}
} // ripple

View File

@@ -0,0 +1,114 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include <ripple/crypto/ec_key.h>
#include <openssl/ec.h>
namespace ripple {
namespace openssl {
static inline EC_KEY* get_EC_KEY (const ec_key& that)
{
return (EC_KEY*) that.get();
}
const ec_key ec_key::invalid = ec_key::acquire (nullptr);
ec_key::ec_key (const ec_key& that)
{
if (that.ptr == nullptr)
{
ptr = nullptr;
return;
}
ptr = (pointer_t) EC_KEY_dup (get_EC_KEY (that));
if (ptr == nullptr)
{
throw std::runtime_error ("ec_key::ec_key() : EC_KEY_dup failed");
}
EC_KEY_set_conv_form (get_EC_KEY (*this), POINT_CONVERSION_COMPRESSED);
}
void ec_key::destroy()
{
if (ptr != nullptr)
{
EC_KEY_free (get_EC_KEY (*this));
ptr = nullptr;
}
}
uint256 ec_key::get_private_key() const
{
uint256 result;
result.zero();
if (valid())
{
const BIGNUM* bn = EC_KEY_get0_private_key (get_EC_KEY (*this));
if (bn == nullptr)
{
throw std::runtime_error ("ec_key::get_private_key: EC_KEY_get0_private_key failed");
}
BN_bn2bin (bn, result.end() - BN_num_bytes (bn));
}
return result;
}
std::size_t ec_key::get_public_key_size() const
{
int const size = i2o_ECPublicKey (get_EC_KEY (*this), nullptr);
if (size == 0)
{
throw std::runtime_error ("ec_key::get_public_key_size() : i2o_ECPublicKey failed");
}
if (size > get_public_key_max_size())
{
throw std::runtime_error ("ec_key::get_public_key_size() : i2o_ECPublicKey() result too big");
}
return size;
}
uint8_t ec_key::get_public_key (uint8* buffer) const
{
uint8_t* begin = buffer;
int const size = i2o_ECPublicKey (get_EC_KEY (*this), &begin);
assert (size == get_public_key_size());
return uint8_t (size);
}
} // openssl
} // ripple