bool Base58::raw_decode (char const* first, char const* last, void* dest, std::size_t size, bool checked, Alphabet const& alphabet) { CAutoBN_CTX pctx; CBigNum bn58 = 58; CBigNum bn = 0; CBigNum bnChar; // Convert big endian string to bignum for (char const* p = first; p != last; ++p) { int i (alphabet.from_char (*p)); if (i == -1) return false; bnChar.setuint ((unsigned int) i); int const success (BN_mul (&bn, &bn, &bn58, pctx)); assert (success); (void) success; bn += bnChar; } // Get bignum as little endian data Blob vchTmp = bn.getvch (); // Trim off sign byte if present if (vchTmp.size () >= 2 && vchTmp.end ()[-1] == 0 && vchTmp.end ()[-2] >= 0x80) vchTmp.erase (vchTmp.end () - 1); char* const out (static_cast <char*> (dest)); // Count leading zeros int nLeadingZeros = 0; for (char const* p = first; p!=last && *p==alphabet[0]; p++) nLeadingZeros++; // Verify that the size is correct if (vchTmp.size() + nLeadingZeros != size) return false; // Fill the leading zeros memset (out, 0, nLeadingZeros); // Copy little endian data to big endian std::reverse_copy (vchTmp.begin (), vchTmp.end (), out + nLeadingZeros); if (checked) { char hash4 [4]; fourbyte_hash256 (hash4, out, size - 4); if (memcmp (hash4, out + size - 4, 4) != 0) return false; } return true; }
bool Base58::decode (const char* psz, Blob& vchRet, Alphabet const& alphabet) { CAutoBN_CTX pctx; vchRet.clear (); CBigNum bn58 = 58; CBigNum bn = 0; CBigNum bnChar; while (isspace (*psz)) psz++; // Convert big endian string to bignum for (const char* p = psz; *p; p++) { // VFALCO TODO Make this use the inverse table! // Or better yet ditch this and call raw_decode // const char* p1 = strchr (alphabet.chars(), *p); if (p1 == nullptr) { while (isspace (*p)) p++; if (*p != '\0') return false; break; } bnChar.setuint (p1 - alphabet.chars()); if (!BN_mul (&bn, &bn, &bn58, pctx)) throw bignum_error ("DecodeBase58 : BN_mul failed"); bn += bnChar; } // Get bignum as little endian data Blob vchTmp = bn.getvch (); // Trim off sign byte if present if (vchTmp.size () >= 2 && vchTmp.end ()[-1] == 0 && vchTmp.end ()[-2] >= 0x80) vchTmp.erase (vchTmp.end () - 1); // Restore leading zeros int nLeadingZeros = 0; for (const char* p = psz; *p == alphabet.chars()[0]; p++) nLeadingZeros++; vchRet.assign (nLeadingZeros + vchTmp.size (), 0); // Convert little endian data to big endian std::reverse_copy (vchTmp.begin (), vchTmp.end (), vchRet.end () - vchTmp.size ()); return true; }
void convertNonCanonical(std::string const& hex, std::string const& canonHex) { Blob b (loadSignature(hex)); // The signature ought to at least be valid before we begin. expect (isValid (hex), "invalid signature"); size_t len = b.size (); expect (!makeCanonicalECDSASig (&b[0], len), "non-canonical signature was already canonical"); expect (b.size () >= len, "canonicalized signature length longer than non-canonical"); b.resize (len); expect (isCanonicalECDSASig (&b[0], len, ECDSA::strict), "canonicalized signature is not strictly canonical"); Blob canonicalForm (loadSignature (canonHex)); expect (b.size () == canonicalForm.size (), "canonicalized signature doesn't have the expected length"); expect (std::equal (b.begin (), b.end (), canonicalForm.begin ()), "canonicalized signature isn't what we expected"); }
Blob PrivateKey::decrypt(const Blob& cipher) const { if (!key) throw CryptoException("Can't decrypt data without private key !"); unsigned key_len = 0; int err = gnutls_privkey_get_pk_algorithm(key, &key_len); if (err < 0) throw CryptoException("Can't read public key length !"); if (err != GNUTLS_PK_RSA) throw CryptoException("Must be an RSA key"); unsigned cypher_block_sz = key_len / 8; if (cipher.size() % cypher_block_sz) throw CryptoException("Unexpected cipher length"); Blob ret; for (auto cb = cipher.cbegin(), ce = cipher.cend(); cb < ce; cb += cypher_block_sz) { const gnutls_datum_t dat {(uint8_t*)(&(*cb)), cypher_block_sz}; gnutls_datum_t out; int err = gnutls_privkey_decrypt_data(key, 0, &dat, &out); if (err != GNUTLS_E_SUCCESS) throw DhtException(std::string("Can't decrypt data: ") + gnutls_strerror(err)); ret.insert(ret.end(), out.data, out.data+out.size); gnutls_free(out.data); } return ret; }
void ConsensusTransSetSF::gotNode (bool fromFilter, const SHAMapNode& id, uint256 const& nodeHash, Blob& nodeData, SHAMapTreeNode::TNType type) { if (fromFilter) return; m_nodeCache.insert (nodeHash, nodeData); if ((type == SHAMapTreeNode::tnTRANSACTION_NM) && (nodeData.size () > 16)) { // this is a transaction, and we didn't have it WriteLog (lsDEBUG, TransactionAcquire) << "Node on our acquiring TX set is TXN we may not have"; try { Serializer s (nodeData.begin () + 4, nodeData.end ()); // skip prefix SerializerIterator sit (s); SerializedTransaction::pointer stx = boost::make_shared<SerializedTransaction> (boost::ref (sit)); assert (stx->getTransactionID () == nodeHash); getApp().getJobQueue ().addJob (jtTRANSACTION, "TXS->TXN", BIND_TYPE (&NetworkOPs::submitTransaction, &getApp().getOPs (), P_1, stx)); } catch (...) { WriteLog (lsWARNING, TransactionAcquire) << "Fetched invalid transaction in proposed set"; } } }
std::string CBase58Data::ToString () const { Blob vch (1, nVersion); vch.insert (vch.end (), vchData.begin (), vchData.end ()); return Base58::encodeWithCheck (vch); }
std::string RippleAddress::human(Blob& blob, VersionEncoding type) { Blob vch(1, type); vch.insert(vch.end(), blob.begin(), blob.end()); return Base58::encodeWithCheck(vch); }
std::string toString (AnyPublicKey const& pk) { Blob buffer; buffer.reserve (1 + pk.size ()); buffer.push_back (VER_NODE_PUBLIC); auto const data = pk.data (); buffer.insert (buffer.end (), data, data + pk.size ()); return Base58::encodeWithCheck (buffer); }
std::string strCopy (Blob const& vucSrc) { std::string strDst; strDst.resize (vucSrc.size ()); std::copy (vucSrc.begin (), vucSrc.end (), strDst.begin ()); return strDst; }
bool Base58::decodeWithCheck (const char* psz, Blob& vchRet, Alphabet const& alphabet) { if (!decode (psz, vchRet, alphabet)) return false; if (vchRet.size () < 4) { vchRet.clear (); return false; } uint256 hash = SHA256Hash (vchRet.begin (), vchRet.end () - 4); if (memcmp (&hash, &vchRet.end ()[-4], 4) != 0) { vchRet.clear (); return false; } vchRet.resize (vchRet.size () - 4); return true; }
String ConvertToBase58(const ConstBuf& cbuf) { HashValue hash = HasherEng::GetCurrent()->HashForAddress(cbuf); Blob v = cbuf + Blob(hash.data(), 4); vector<char> r; vector<byte> tmp(v.Size+1, 0); std::reverse_copy(v.begin(), v.end(), tmp.begin()); for (BigInteger n(&tmp[0], tmp.size()); Sign(n);) { pair<BigInteger, BigInteger> pp = div(n, 58); n = pp.first; r.insert(r.begin(), s_pszBase58[explicit_cast<int>(pp.second)]); } for (int i=0; i<v.Size && !v.constData()[i]; ++i) r.insert(r.begin(), s_pszBase58[0]); return String(&r[0], r.size()); }
String ConvertToBase58ShaSquare(const ConstBuf& cbuf) { SHA256 sha; HashValue hash = HashValue(sha.ComputeHash(sha.ComputeHash(cbuf))); Blob v = cbuf + Blob(hash.data(), 4); vector<char> r; vector<byte> tmp(v.Size+1, 0); std::reverse_copy(v.begin(), v.end(), tmp.begin()); for (BigInteger n(&tmp[0], tmp.size()); Sign(n);) { pair<BigInteger, BigInteger> pp = div(n, 58); n = pp.first; r.insert(r.begin(), s_pszBase58[explicit_cast<int>(pp.second)]); } for (int i=0; i<v.Size && !v.constData()[i]; ++i) r.insert(r.begin(), s_pszBase58[0]); return String(&r[0], r.size()); }
void Certificate::pack(Blob& b) const { const Certificate* crt = this; while (crt) { std::string str; size_t buf_sz = 8192; str.resize(buf_sz); if (int err = gnutls_x509_crt_export(crt->cert, GNUTLS_X509_FMT_DER, &(*str.begin()), &buf_sz)) { std::cerr << "Could not export certificate - " << gnutls_strerror(err) << std::endl; return; } str.resize(buf_sz); b.insert(b.end(), str.begin(), str.end()); crt = crt->issuer.get(); return; } }
Blob PublicKey::encrypt(const Blob& data) const { if (!pk) throw CryptoException("Can't read public key !"); unsigned key_len = 0; int err = gnutls_pubkey_get_pk_algorithm(pk, &key_len); if (err < 0) throw CryptoException("Can't read public key length !"); if (err != GNUTLS_PK_RSA) throw CryptoException("Must be an RSA key"); unsigned max_block_sz = key_len / 8 - 11; unsigned cypher_block_sz = key_len / 8; unsigned block_num = data.empty() ? 1 : 1 + (data.size() - 1) / max_block_sz; Blob ret; auto eb = data.cbegin(); auto ee = data.cend(); for (unsigned i=0; i<block_num; i++) { auto blk_sz = std::min<unsigned>(ee - eb, max_block_sz); const gnutls_datum_t dat {(uint8_t*)&(*eb), blk_sz}; gnutls_datum_t encrypted; err = gnutls_pubkey_encrypt_data(pk, 0, &dat, &encrypted); if (err != GNUTLS_E_SUCCESS) throw CryptoException(std::string("Can't encrypt data: ") + gnutls_strerror(err)); if (encrypted.size != cypher_block_sz) throw CryptoException("Unexpected cypherblock size"); ret.insert(ret.end(), encrypted.data, encrypted.data+encrypted.size); eb += blk_sz; gnutls_free(encrypted.data); } return ret; }
void ClusterImpl::addBlob(const Blob& blob) { log_debug1("addBlob(ptr, " << blob.size() << ')'); data.insert(data.end(), blob.data(), blob.end()); offsets.push_back(data.size()); }
friend bool load(Blob const& blob, SpecificMessage& msg) { msg.contents.assign(blob.begin(), blob.end()); return true; }
SHAMapTreeNode::SHAMapTreeNode (const SHAMapNode& id, Blob const& rawNode, uint32 seq, SHANodeFormat format, uint256 const& hash, bool hashValid) : SHAMapNode (id), mSeq (seq), mType (tnERROR), mIsBranch (0), mFullBelow (false) { if (format == snfWIRE) { Serializer s (rawNode); int type = s.removeLastByte (); int len = s.getLength (); if ((type < 0) || (type > 4)) { #ifdef BEAST_DEBUG Log::out() << "Invalid wire format node"; Log::out() << strHex (rawNode); assert (false); #endif throw std::runtime_error ("invalid node AW type"); } if (type == 0) { // transaction mItem = boost::make_shared<SHAMapItem> (s.getPrefixHash (HashPrefix::transactionID), s.peekData ()); mType = tnTRANSACTION_NM; } else if (type == 1) { // account state if (len < (256 / 8)) throw std::runtime_error ("short AS node"); uint256 u; s.get256 (u, len - (256 / 8)); s.chop (256 / 8); if (u.isZero ()) throw std::runtime_error ("invalid AS node"); mItem = boost::make_shared<SHAMapItem> (u, s.peekData ()); mType = tnACCOUNT_STATE; } else if (type == 2) { // full inner if (len != 512) throw std::runtime_error ("invalid FI node"); for (int i = 0; i < 16; ++i) { s.get256 (mHashes[i], i * 32); if (mHashes[i].isNonZero ()) mIsBranch |= (1 << i); } mType = tnINNER; } else if (type == 3) { // compressed inner for (int i = 0; i < (len / 33); ++i) { int pos; s.get8 (pos, 32 + (i * 33)); if ((pos < 0) || (pos >= 16)) throw std::runtime_error ("invalid CI node"); s.get256 (mHashes[pos], i * 33); if (mHashes[pos].isNonZero ()) mIsBranch |= (1 << pos); } mType = tnINNER; } else if (type == 4) { // transaction with metadata if (len < (256 / 8)) throw std::runtime_error ("short TM node"); uint256 u; s.get256 (u, len - (256 / 8)); s.chop (256 / 8); if (u.isZero ()) throw std::runtime_error ("invalid TM node"); mItem = boost::make_shared<SHAMapItem> (u, s.peekData ()); mType = tnTRANSACTION_MD; } } else if (format == snfPREFIX) { if (rawNode.size () < 4) { WriteLog (lsINFO, SHAMapNode) << "size < 4"; throw std::runtime_error ("invalid P node"); } uint32 prefix = rawNode[0]; prefix <<= 8; prefix |= rawNode[1]; prefix <<= 8; prefix |= rawNode[2]; prefix <<= 8; prefix |= rawNode[3]; Serializer s (rawNode.begin () + 4, rawNode.end ()); if (prefix == HashPrefix::transactionID) { mItem = boost::make_shared<SHAMapItem> (Serializer::getSHA512Half (rawNode), s.peekData ()); mType = tnTRANSACTION_NM; } else if (prefix == HashPrefix::leafNode) { if (s.getLength () < 32) throw std::runtime_error ("short PLN node"); uint256 u; s.get256 (u, s.getLength () - 32); s.chop (32); if (u.isZero ()) { WriteLog (lsINFO, SHAMapNode) << "invalid PLN node"; throw std::runtime_error ("invalid PLN node"); } mItem = boost::make_shared<SHAMapItem> (u, s.peekData ()); mType = tnACCOUNT_STATE; } else if (prefix == HashPrefix::innerNode) { if (s.getLength () != 512) throw std::runtime_error ("invalid PIN node"); for (int i = 0; i < 16; ++i) { s.get256 (mHashes[i], i * 32); if (mHashes[i].isNonZero ()) mIsBranch |= (1 << i); } mType = tnINNER; } else if (prefix == HashPrefix::txNode) { // transaction with metadata if (s.getLength () < 32) throw std::runtime_error ("short TXN node"); uint256 txID; s.get256 (txID, s.getLength () - 32); s.chop (32); mItem = boost::make_shared<SHAMapItem> (txID, s.peekData ()); mType = tnTRANSACTION_MD; } else { WriteLog (lsINFO, SHAMapNode) << "Unknown node prefix " << std::hex << prefix << std::dec; throw std::runtime_error ("invalid node prefix"); } } else { assert (false); throw std::runtime_error ("Unknown format"); } if (hashValid) { mHash = hash; #if RIPPLE_VERIFY_NODEOBJECT_KEYS updateHash (); assert (mHash == hash); #endif } else updateHash (); }