bool CAlert::CheckSignature() const
{
- CKey key;
- if (!key.SetPubKey(ParseHex(fTestNet ? pszTestKey : pszMainKey)))
- return error("CAlert::CheckSignature() : SetPubKey failed");
+ CPubKey key;
+ key.Set(ParseHex(fTestNet ? pszTestKey : pszMainKey));
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
return error("CAlert::CheckSignature() : verify signature failed");
{ "submitblock", &submitblock, false, false },
{ "listsinceblock", &listsinceblock, false, false },
{ "dumpprivkey", &dumpprivkey, false, false },
+ { "dumppem", &dumppem, true, false },
{ "dumpwallet", &dumpwallet, true, false },
{ "importwallet", &importwallet, false, false },
{ "importprivkey", &importprivkey, false, false },
extern json_spirit::Value listmalleableviews(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value dumpmalleablekey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value importmalleablekey(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value dumppem(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value encryptdata(const json_spirit::Array& params, bool fHelp); // in rpccrypt.cpp
extern json_spirit::Value decryptdata(const json_spirit::Array& params, bool fHelp);
// ppcoin: verify signature of sync-checkpoint message
bool CSyncCheckpoint::CheckSignature()
{
- CKey key;
- if (!key.SetPubKey(ParseHex(CSyncCheckpoint::strMasterPubKey)))
- return error("CSyncCheckpoint::CheckSignature() : SetPubKey failed");
+ CPubKey key(ParseHex(CSyncCheckpoint::strMasterPubKey));
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
return error("CSyncCheckpoint::CheckSignature() : verify signature failed");
#include <map>
#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
#include <openssl/obj_mac.h>
#include "key.h"
const unsigned char *vchZero = NULL;
-
-
void CKey::SetCompressedPubKey()
{
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
void CKey::Reset()
{
- fCompressedPubKey = false;
+ fCompressedPubKey = fSet = false;
if (pkey != NULL)
EC_KEY_free(pkey);
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (pkey == NULL)
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
- fSet = false;
}
CKey::CKey()
CKey::~CKey()
{
- EC_KEY_free(pkey);
+ if (pkey != NULL)
+ EC_KEY_free(pkey);
}
bool CKey::IsNull() const
CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0;
}
-bool CKey::ReserealizeSignature(std::vector<unsigned char>& vchSig)
+bool CPubKey::ReserealizeSignature(std::vector<unsigned char>& vchSig)
{
if (vchSig.empty())
return false;
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (pkey == NULL)
throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
+
if (vchSecret.size() != 32)
throw key_error("CKey::SetSecret() : secret must be 32 bytes");
BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
return vchRet;
}
+bool CKey::WritePEM(BIO *streamObj, const SecureString &strPassKey) const // dumppem 4KJLA99FyqMMhjjDe7KnRXK4sjtv9cCtNS /tmp/test.pem 123
+{
+ EVP_PKEY *evpKey = EVP_PKEY_new();
+ bool result = true;
+
+ do
+ {
+ if (!EVP_PKEY_assign_EC_KEY(evpKey, pkey))
+ {
+ result = error("CKey::WritePEM() : Error initializing EVP_PKEY instance.");
+ break;
+ }
+
+ if(!PEM_write_bio_PKCS8PrivateKey(streamObj, evpKey, EVP_aes_256_cbc(), (char *)&strPassKey[0], strPassKey.size(), NULL, NULL))
+ {
+ result = error("CKey::WritePEM() : Error writing private key data to stream object");
+ break;
+ }
+
+ if(!PEM_write_bio_PUBKEY(streamObj, evpKey))
+ {
+ result = error("CKey::WritePEM() : Error writing public key data to stream object");
+ break;
+ }
+ }
+ while(false);
+
+ EVP_PKEY_free(evpKey);
+ return result;
+}
+
CSecret CKey::GetSecret() const
{
bool fCompressed;
return vchPrivKey;
}
-bool CKey::SetPubKey(const CPubKey& vchPubKey)
-{
- const unsigned char* pbegin = &vchPubKey.vchPubKey[0];
- if (o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size()))
- {
- fSet = true;
- if (vchPubKey.vchPubKey.size() == 33)
- SetCompressedPubKey();
- return true;
- }
- pkey = NULL;
- Reset();
- return false;
-}
-
CPubKey CKey::GetPubKey() const
{
int nSize = i2o_ECPublicKey(pkey, NULL);
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
-bool CKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
+bool CPubKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
{
if (vchSig.size() != 65)
return false;
BN_bin2bn(&vchSig[1],32,sig->r);
BN_bin2bn(&vchSig[33],32,sig->s);
- EC_KEY_free(pkey);
- pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
+ EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (nV >= 31)
{
- SetCompressedPubKey();
nV -= 4;
+ EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
}
- if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
+
+ do
{
- fSet = true;
+ if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) != 1)
+ break;
ECDSA_SIG_free(sig);
- return true;
- }
+
+ int nSize = i2o_ECPublicKey(pkey, NULL);
+ if (!nSize)
+ break;
+ std::vector<unsigned char> vchPubKey(nSize, 0);
+ unsigned char* pbegin = &vchPubKey[0];
+ if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
+ break;
+ Set(vchPubKey.begin(), vchPubKey.end());
+ return IsValid();
+
+ } while (false);
+
ECDSA_SIG_free(sig);
+ Invalidate();
return false;
}
-bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
+bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const
{
- if (vchSig.empty())
+ if (vchSig.empty() || !IsValid())
return false;
+ const unsigned char* pbegin = &vbytes[0];
+ EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
+ if (!o2i_ECPublicKey(&pkey, &pbegin, size()))
+ return false; // Unable to parse public key
+
// New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
unsigned char *norm_der = NULL;
ECDSA_SIG *norm_sig = ECDSA_SIG_new();
return ret;
}
-bool CKey::VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
+bool CPubKey::VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
{
- CKey key;
+ CPubKey key;
if (!key.SetCompactSignature(hash, vchSig))
return false;
- if (GetPubKey() != key.GetPubKey())
+ if ((*this) != key)
return false;
-
return true;
}
CSecret secret = GetSecret(fCompr);
CKey key2;
key2.SetSecret(secret, fCompr);
+
return GetPubKey() == key2.GetPubKey();
}
}
// Initialize from octets stream
-bool CPoint::setPubKey(const CPubKey &vchPubKey)
+bool CPoint::setPubKey(const CPubKey &key)
{
- return setBytes(vchPubKey.Raw());
+ std::vector<uint8_t> vchPubKey(key.begin(), key.end());
+ return setBytes(vchPubKey);
}
// Serialize to octets stream
CMalleablePubKey CMalleableKey::GetMalleablePubKey() const
{
CKey L(vchSecretL), H(vchSecretH);
- return CMalleablePubKey(L.GetPubKey().Raw(), H.GetPubKey().Raw());
+ return CMalleablePubKey(L.GetPubKey(), H.GetPubKey());
}
// Check ownership
}
CKey H(vchSecretH);
- std::vector<unsigned char> vchPubKeyH = H.GetPubKey().Raw();
+ CPubKey vchPubKeyH = H.GetPubKey();
CPoint point_H;
if (!point_H.setPubKey(vchPubKeyH)) {
}
CKey H(vchSecretH);
- std::vector<unsigned char> vchPubKeyH = H.GetPubKey().Raw();
+ CPubKey vchPubKeyH = H.GetPubKey();
CPoint point_H;
if (!point_H.setPubKey(vchPubKeyH)) {
vchSecretL = b.vchSecretL;
CKey H(b.vchSecretH);
- vchPubKeyH = H.GetPubKey().Raw();
+ vchPubKeyH = H.GetPubKey();
}
CMalleableKeyView::CMalleableKeyView(const CMalleableKeyView &b)
vchSecretL = b.vchSecretL;
CKey H(b.vchSecretH);
- vchPubKeyH = H.GetPubKey().Raw();
+ vchPubKeyH = H.GetPubKey();
return (*this);
}
void CPubKey::EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted)
{
- CKey key;
- key.SetPubKey(*this);
-
- key.EncryptData(data, encrypted);
-}
-
-void CKey::EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted)
-{
ies_ctx_t *ctx;
char error[1024] = "Unknown error";
cryptogram_t *cryptogram;
+ const unsigned char* pbegin = &vbytes[0];
+ EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
+ if (!o2i_ECPublicKey(&pkey, &pbegin, size()))
+ throw key_error("Unable to parse EC key");
+
ctx = create_context(pkey);
if (!EC_KEY_get0_public_key(ctx->user_key))
throw key_error("Given EC key is not public key");
CScriptID(const uint160 &in) : uint160(in) { }
};
-/** An encapsulated public key. */
-class CPubKey {
+/** An encapsulated OpenSSL Elliptic Curve key (public) */
+class CPubKey
+{
private:
- std::vector<unsigned char> vchPubKey;
- friend class CKey;
+
+ /**
+ * Just store the serialized data.
+ * Its length can very cheaply be computed from the first byte.
+ */
+ unsigned char vbytes[65];
+
+ //! Compute the length of a pubkey with a given first byte.
+ unsigned int static GetLen(unsigned char chHeader)
+ {
+ if (chHeader == 2 || chHeader == 3)
+ return 33;
+ if (chHeader == 4 || chHeader == 6 || chHeader == 7)
+ return 65;
+ return 0;
+ }
+
+ // Set this key data to be invalid
+ void Invalidate()
+ {
+ vbytes[0] = 0xFF;
+ }
public:
- CPubKey() { }
- CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
- friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
- friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
- friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
+ // Construct an invalid public key.
+ CPubKey()
+ {
+ Invalidate();
+ }
- IMPLEMENT_SERIALIZE(
- READWRITE(vchPubKey);
- )
+ // Initialize a public key using begin/end iterators to byte data.
+ template <typename T>
+ void Set(const T pbegin, const T pend)
+ {
+ int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
+ if (len && len == (pend - pbegin))
+ memcpy(vbytes, (unsigned char*)&pbegin[0], len);
+ else
+ Invalidate();
+ }
- CKeyID GetID() const {
- return CKeyID(Hash160(vchPubKey));
+ void Set(const std::vector<unsigned char>& vch)
+ {
+ Set(vch.begin(), vch.end());
}
- uint256 GetHash() const {
- return Hash(vchPubKey.begin(), vchPubKey.end());
+ template <typename T>
+ CPubKey(const T pbegin, const T pend)
+ {
+ Set(pbegin, pend);
}
- bool IsValid() const {
- return vchPubKey.size() == 33 || vchPubKey.size() == 65;
+ CPubKey(const std::vector<unsigned char>& vch)
+ {
+ Set(vch.begin(), vch.end());
}
- bool IsCompressed() const {
- return vchPubKey.size() == 33;
+ // Read-only vector-like interface to the data.
+ unsigned int size() const { return GetLen(vbytes[0]); }
+ const unsigned char* begin() const { return vbytes; }
+ const unsigned char* end() const { return vbytes + size(); }
+ const unsigned char& operator[](unsigned int pos) const { return vbytes[pos]; }
+
+ friend bool operator==(const CPubKey& a, const CPubKey& b) { return a.vbytes[0] == b.vbytes[0] && memcmp(a.vbytes, b.vbytes, a.size()) == 0; }
+ friend bool operator!=(const CPubKey& a, const CPubKey& b) { return !(a == b); }
+ friend bool operator<(const CPubKey& a, const CPubKey& b) { return a.vbytes[0] < b.vbytes[0] || (a.vbytes[0] == b.vbytes[0] && memcmp(a.vbytes, b.vbytes, a.size()) < 0); }
+
+ //! Implement serialization, as if this was a byte vector.
+ unsigned int GetSerializeSize(int nType, int nVersion) const
+ {
+ return size() + 1;
+ }
+ template <typename Stream>
+ void Serialize(Stream& s, int nType, int nVersion) const
+ {
+ unsigned int len = size();
+ ::WriteCompactSize(s, len);
+ s.write((char*)vbytes, len);
+ }
+ template <typename Stream>
+ void Unserialize(Stream& s, int nType, int nVersion)
+ {
+ unsigned int len = ::ReadCompactSize(s);
+ if (len <= 65) {
+ s.read((char*)vbytes, len);
+ } else {
+ // invalid pubkey, skip available data
+ char dummy;
+ while (len--)
+ s.read(&dummy, 1);
+ Invalidate();
+ }
}
- std::vector<unsigned char> Raw() const {
- return vchPubKey;
+ CKeyID GetID() const
+ {
+ return CKeyID(Hash160(vbytes, vbytes + size()));
}
+ uint256 GetHash() const
+ {
+ return Hash(vbytes, vbytes + size());
+ }
+
+ /*
+ * Check syntactic correctness.
+ *
+ * Note that this is consensus critical as CheckSig() calls it!
+ */
+ bool IsValid() const
+ {
+ return size() > 0;
+ }
+
+ //! fully validate whether this is a valid public key (more expensive than IsValid())
+ bool IsFullyValid() const
+ {
+ const unsigned char* pbegin = &vbytes[0];
+ EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
+ if (o2i_ECPublicKey(&pkey, &pbegin, size()))
+ {
+ EC_KEY_free(pkey);
+ return true;
+ }
+ return false;
+ }
+
+ //! Check whether this is a compressed public key.
+ bool IsCompressed() const
+ {
+ return size() == 33;
+ }
+
+ bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
+ bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
+
+ bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);
+
+ // Reserialize to DER
+ static bool ReserealizeSignature(std::vector<unsigned char>& vchSig);
+
// Encrypt data
void EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted);
};
-
// secure_allocator is defined in allocators.h
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
// CSecret is a serialization of just the secret parameter (32 bytes)
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
-/** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */
+/** An encapsulated OpenSSL Elliptic Curve key (private) */
class CKey
{
protected:
bool fSet;
bool fCompressedPubKey;
- void SetCompressedPubKey();
-
public:
void Reset();
bool IsNull() const;
bool IsCompressed() const;
+ void SetCompressedPubKey();
void MakeNewKey(bool fCompressed=true);
bool SetPrivKey(const CPrivKey& vchPrivKey);
bool SetSecret(const CSecret& vchSecret, bool fCompressed = true);
CSecret GetSecret(bool &fCompressed) const;
CSecret GetSecret() const;
CPrivKey GetPrivKey() const;
- bool SetPubKey(const CPubKey& vchPubKey);
CPubKey GetPubKey() const;
+ bool WritePEM(BIO *streamObj, const SecureString &strPassKey) const;
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
// 0x1D = second key with even y, 0x1E = second key with odd y
bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig);
- // reconstruct public key from a compact signature
- // This is only slightly more CPU intensive than just verifying it.
- // If this function succeeds, the recovered public key is guaranteed to be valid
- // (the signature is a valid signature of the given data for that key)
- bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);
-
- bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig);
-
- // Verify a compact signature
- bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
-
bool IsValid();
// Check whether an element of a signature (r or s) is valid.
static bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
- // Reserialize to DER
- static bool ReserealizeSignature(std::vector<unsigned char>& vchSig);
-
- // Encrypt data
- void EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted);
-
// Decrypt data
void DecryptData(const std::vector<unsigned char>& encrypted, std::vector<unsigned char>& data);
};
if (vchSecret.size() != 32)
return false;
CKey key;
- key.SetPubKey(vchPubKey);
key.SetSecret(vchSecret);
+ if (vchPubKey.size() == 33)
+ key.SetCompressedPubKey();
if (key.GetPubKey() == vchPubKey)
break;
return false;
return false;
if (vchSecret.size() != 32)
return false;
- keyOut.SetPubKey(vchPubKey);
keyOut.SetSecret(vchSecret);
+ if (vchPubKey.size() == 33)
+ keyOut.SetCompressedPubKey();
return true;
}
}
if (vchSecret.size() != 32)
return false;
CKey key;
- key.SetPubKey(vchPubKey);
key.SetSecret(vchSecret);
+ if (vchPubKey.size() == 33)
+ key.SetCompressedPubKey();
if (!CBasicKeyStore::AddKey(key))
return false;
}
KeyMap::const_iterator mi = mapKeys.find(address);
if (mi != mapKeys.end())
{
- keyOut.Reset();
keyOut.SetSecret((*mi).second.first, (*mi).second.second);
return true;
}
return true;
}
- return CKey::ReserealizeSignature(pblock->vchBlockSig);
+ return CPubKey::ReserealizeSignature(pblock->vchBlockSig);
}
bool static IsCanonicalBlockSignature(CBlock* pblock)
if (whichType == TX_PUBKEY)
{
valtype& vchPubKey = vSolutions[0];
- CKey key;
- if (!key.SetPubKey(vchPubKey))
+ CPubKey key(vchPubKey);
+ if (!key.IsValid())
return false;
return key.Verify(GetHash(), vchBlockSig);
}
{
CPubKey vchPubKey;
model->getPubKey(keyID, vchPubKey);
- std::string pubkey = HexStr(vchPubKey.Raw());
+ std::string pubkey = HexStr(vchPubKey.begin(), vchPubKey.end());
if(!pubkey.empty())
ui->pubkey->setText(pubkey.c_str());
}
if(!model)
return;
- std::vector<CKey> pubkeys;
+ std::vector<CPubKey> pubkeys;
pubkeys.resize(ui->pubkeyEntries->count());
unsigned int required = ui->requiredSignatures->text().toUInt();
CPubKey vchPubKey(ParseHex(str.toStdString().c_str()));
if(!vchPubKey.IsValid())
return;
- pubkeys[i].SetPubKey(vchPubKey);
+ pubkeys[i] = vchPubKey;
}
if(pubkeys.size() > 16)
ss << strMessageMagic;
ss << ui->messageIn_VM->document()->toPlainText().toStdString();
- CKey key;
+ CPubKey key;
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
{
ui->signatureIn_VM->setValid(false);
return;
}
- if (!(CBitcoinAddress(key.GetPubKey().GetID()) == addr))
+ if (!(CBitcoinAddress(key.GetID()) == addr))
{
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
CBitcoinAddress address;
if (!address.SetString(strAddress))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
- if (fWalletUnlockMintOnly) // ppcoin: no dumpprivkey in mint-only mode
+ if (fWalletUnlockMintOnly)
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only.");
CKeyID keyID;
if (!address.GetKeyID(keyID))
return CBitcoinSecret(vchSecret, fCompressed).ToString();
}
+Value dumppem(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 3)
+ throw runtime_error(
+ "dumppem <novacoinaddress> <filename> <passphrase>\n"
+ "Dump the key pair corresponding to <novacoinaddress> and store it as encrypted PEM file."
+ + HelpRequiringPassphrase());
+
+ EnsureWalletIsUnlocked();
+
+ string strAddress = params[0].get_str();
+ SecureString strPassKey;
+ strPassKey.reserve(100);
+ strPassKey = params[2].get_str().c_str();
+
+ CBitcoinAddress address;
+ if (!address.SetString(strAddress))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+ if (fWalletUnlockMintOnly)
+ throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only.");
+ CKeyID keyID;
+ if (!address.GetKeyID(keyID))
+ throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
+ if (!pwalletMain->GetPEM(keyID, params[1].get_str(), strPassKey))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error dumping key pair to file");
+
+ return Value::null;
+}
+
Value dumpwallet(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
"(got %" PRIszu " keys, but need at least %d to redeem)", keys.size(), nRequired));
if (keys.size() > 16)
throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
- std::vector<CKey> pubkeys;
+ std::vector<CPubKey> pubkeys;
pubkeys.resize(keys.size());
for (unsigned int i = 0; i < keys.size(); i++)
{
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
throw runtime_error(
strprintf("no full public key for address %s",ks.c_str()));
- if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
+ if (!vchPubKey.IsFullyValid())
throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
}
// Case 2: hex public key
else if (IsHex(ks))
{
CPubKey vchPubKey(ParseHex(ks));
- if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
+ if (!vchPubKey.IsFullyValid())
throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
}
else
{
ss << strMessageMagic;
ss << strMessage;
- CKey key;
+ CPubKey key;
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
return false;
- return (key.GetPubKey().GetID() == keyID);
+ return (key.GetID() == keyID);
}
"(got %" PRIszu " keys, but need at least %d to redeem)", keys.size(), nRequired));
if (keys.size() > 16)
throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
- std::vector<CKey> pubkeys;
+ std::vector<CPubKey> pubkeys;
pubkeys.resize(keys.size());
for (unsigned int i = 0; i < keys.size(); i++)
{
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
throw runtime_error(
strprintf("no full public key for address %s",ks.c_str()));
- if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
+ if (!vchPubKey.IsValid())
throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
}
// Case 2: hex public key
else if (IsHex(ks))
{
CPubKey vchPubKey(ParseHex(ks));
- if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
+ if (!vchPubKey.IsValid())
throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
}
else
{
obj.push_back(Pair("isscript", false));
if (mine == MINE_SPENDABLE) {
pwalletMain->GetPubKey(keyID, vchPubKey);
- obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
+ obj.push_back(Pair("pubkey", HexStr(vchPubKey.begin(), vchPubKey.end())));
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
}
return obj;
bool fCompressed;
CSecret vchSecret = key.GetSecret(fCompressed);
+ CPubKey vchPubKey = key.GetPubKey();
result.push_back(Pair("Secret", HexStr<CSecret::iterator>(vchSecret.begin(), vchSecret.end())));
- result.push_back(Pair("PublicKey", HexStr(key.GetPubKey().Raw())));
+ result.push_back(Pair("PublicKey", HexStr(vchPubKey.begin(), vchPubKey.end())));
return result;
}
malleablePubKey.GetVariant(R, vchPubKeyVariant);
Object result;
- result.push_back(Pair("R", HexStr(R.Raw())));
- result.push_back(Pair("PubkeyVariant", HexStr(vchPubKeyVariant.Raw())));
+ result.push_back(Pair("R", HexStr(R.begin(), R.end())));
+ result.push_back(Pair("PubkeyVariant", HexStr(vchPubKeyVariant.begin(), vchPubKeyVariant.end())));
result.push_back(Pair("KeyVariantID", CBitcoinAddress(vchPubKeyVariant.GetID()).ToString()));
return result;
{
static CSignatureCache signatureCache;
- CKey key;
- if (!key.SetPubKey(vchPubKey))
- return false;
- CPubKey pubkey = key.GetPubKey();
+ CPubKey pubkey(vchPubKey);
if (!pubkey.IsValid())
return false;
if (signatureCache.Get(sighash, vchSig, pubkey))
return true;
- if (!key.Verify(sighash, vchSig))
+ if (!pubkey.Verify(sighash, vchSig))
return false;
if (!(flags & SCRIPT_VERIFY_NOCACHE))
}
-
-
-
-
-
-
//
// Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
//
}
}
-void CScript::SetMultisig(int nRequired, const std::vector<CKey>& keys)
+void CScript::SetMultisig(int nRequired, const std::vector<CPubKey>& keys)
{
this->clear();
*this << EncodeOP_N(nRequired);
- BOOST_FOREACH(const CKey& key, keys)
- *this << key.GetPubKey();
+ BOOST_FOREACH(const CPubKey& key, keys)
+ *this << key;
*this << EncodeOP_N((int)(keys.size())) << OP_CHECKMULTISIG;
}
CScript& operator<<(const CPubKey& key)
{
- std::vector<uint8_t> vchKey = key.Raw();
+ std::vector<uint8_t> vchKey(key.begin(), key.end());
return (*this) << vchKey;
}
void SetDestination(const CTxDestination& address);
void SetAddress(const CBitcoinAddress& dest);
- void SetMultisig(int nRequired, const std::vector<CKey>& keys);
+ void SetMultisig(int nRequired, const std::vector<CPubKey>& keys);
void PrintHex() const
#include "kernel.h"
#include "coincontrol.h"
#include <boost/algorithm/string/replace.hpp>
+#include <openssl/bio.h>
#include "main.h"
return true;
}
+bool CWallet::GetPEM(const CKeyID &keyID, const std::string &fileName, const SecureString &strPassKey) const
+{
+ BIO *pemOut = BIO_new_file(fileName.c_str(), "w");
+ if (pemOut == NULL)
+ return error("GetPEM() : failed to create file %s\n", fileName.c_str());
+ CKey key;
+ if (!GetKey(keyID, key))
+ return error("GetPEM() : failed to get key for address=%s\n", CBitcoinAddress(keyID).ToString().c_str());
+ bool result = key.WritePEM(pemOut, strPassKey);
+ BIO_free(pemOut);
+ return result;
+}
+
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
{
int64_t nRet = nOrderPosNext++;
bool DecryptWallet(const SecureString& strWalletPassphrase);
void GetAddresses(std::map<CBitcoinAddress, int64_t> &mapAddresses) const;
+ bool GetPEM(const CKeyID &keyID, const std::string &fileName, const SecureString &strPassPhrase) const;
/** Increment the next transaction order id
}
else if (strType == "key" || strType == "wkey")
{
- vector<unsigned char> vchPubKey;
- ssKey >> vchPubKey;
CKey key;
+ CPubKey vchPubKey;
+ ssKey >> vchPubKey;
if (strType == "key")
{
wss.nKeys++;
CPrivKey pkey;
ssValue >> pkey;
- key.SetPubKey(vchPubKey);
if (!key.SetPrivKey(pkey))
{
strErr = "Error reading wallet database: CPrivKey corrupt";
strErr = "Error reading wallet database: CPrivKey pubkey inconsistency";
return false;
}
+ if (vchPubKey.size() == 33) {
+ key.SetCompressedPubKey();
+ }
if (!key.IsValid())
{
strErr = "Error reading wallet database: invalid CPrivKey";
{
CWalletKey wkey;
ssValue >> wkey;
- key.SetPubKey(vchPubKey);
if (!key.SetPrivKey(wkey.vchPrivKey))
{
strErr = "Error reading wallet database: CPrivKey corrupt";
strErr = "Error reading wallet database: CWalletKey pubkey inconsistency";
return false;
}
+ if (vchPubKey.size() == 33) {
+ key.SetCompressedPubKey();
+ }
if (!key.IsValid())
{
strErr = "Error reading wallet database: invalid CWalletKey";
else if (strType == "ckey")
{
wss.nCKeys++;
- vector<unsigned char> vchPubKey;
+ CPubKey vchPubKey;
ssKey >> vchPubKey;
vector<unsigned char> vchPrivKey;
ssValue >> vchPrivKey;
return Erase(std::make_pair(std::string("tx"), hash));
}
- bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta)
+ bool WriteKey(const CPubKey& key, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta)
{
nWalletDBUpdated++;
- if(!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta))
+ if(!Write(std::make_pair(std::string("keymeta"), key), keyMeta))
return false;
- if(!Write(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey, false))
+ if(!Write(std::make_pair(std::string("key"), key), vchPrivKey, false))
return false;
return true;
}
- bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta)
+ bool WriteCryptedKey(const CPubKey& key, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta)
{
nWalletDBUpdated++;
bool fEraseUnencryptedKey = true;
- if(!Write(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta))
+ if(!Write(std::make_pair(std::string("keymeta"), key), keyMeta))
return false;
- if (!Write(std::make_pair(std::string("ckey"), vchPubKey.Raw()), vchCryptedSecret, false))
+ if (!Write(std::make_pair(std::string("ckey"), key), vchCryptedSecret, false))
return false;
if (fEraseUnencryptedKey)
{
- Erase(std::make_pair(std::string("key"), vchPubKey.Raw()));
- Erase(std::make_pair(std::string("wkey"), vchPubKey.Raw()));
+ Erase(std::make_pair(std::string("key"), key));
+ Erase(std::make_pair(std::string("wkey"), key));
}
return true;
}
return Erase(std::make_pair(std::string("mkey"), nID));
}
- bool EraseCryptedKey(const CPubKey& vchPubKey)
+ bool EraseCryptedKey(const CPubKey& key)
{
- return Erase(std::make_pair(std::string("ckey"), vchPubKey.Raw()));
+ return Erase(std::make_pair(std::string("ckey"), key));
}
bool EraseCryptedMalleableKey(const CMalleableKeyView& keyView)
return Write(std::string("orderposnext"), nOrderPosNext);
}
- bool WriteDefaultKey(const CPubKey& vchPubKey)
+ bool WriteDefaultKey(const CPubKey& key)
{
nWalletDBUpdated++;
- return Write(std::string("defaultkey"), vchPubKey.Raw());
+ return Write(std::string("defaultkey"), key);
}
bool ReadPool(int64_t nPool, CKeyPool& keypool)