143 #if defined(OT_CRYPTO_USING_OPENSSL)
151 #if defined(OT_CRYPTO_USING_OPENSSL)
159 dp->m_pX509 =
nullptr;
160 dp->m_pKey =
nullptr;
173 X509_free(
dp->m_pX509);
176 dp->m_pX509 =
nullptr;
216 if (
nullptr !=
dp->m_pKey) EVP_PKEY_free(
dp->m_pKey);
217 dp->m_pKey =
nullptr;
237 otErr << __FUNCTION__ <<
": Error: Cert input is nonexistent!\n";
244 otLog3 << __FUNCTION__ <<
": FYI, Reading private key from x509 stored in "
245 "bookended string...\n";
257 const_cast<OTString&>(strCert),
259 "-----BEGIN ENCRYPTED PRIVATE"))
261 strWithBookends.
Format(
"-----BEGIN ENCRYPTED PRIVATE "
262 "KEY-----\n%s-----END ENCRYPTED PRIVATE "
268 <<
": Error extracting ASCII-Armored text from Cert String.\n";
275 strWithBookends = strCert;
285 static_cast<void*>(const_cast<char*>(strWithBookends.
Get())), -1);
287 "OTAsymmetricKey_OpenSSL::"
288 "LoadPrivateKeyFromCertString: Assert: nullptr != "
305 (
nullptr == pstrReason)
306 ? (
nullptr == pImportPassword
307 ?
"Enter the master passphrase. "
308 "(LoadPrivateKeyFromCertString)"
309 :
"Enter the passphrase for this exported nym.")
310 : pstrReason->
Get());
312 EVP_PKEY* pkey =
nullptr;
314 if (!pImportPassword)
316 pkey = PEM_read_bio_PrivateKey(
323 pkey = PEM_read_bio_PrivateKey(
325 const_cast<void*>(reinterpret_cast<const void*>(
329 if (
nullptr == pkey) {
330 otErr << __FUNCTION__ <<
": (pImportPassword size: "
331 << (
nullptr == pImportPassword
334 <<
") Error reading private key from string.\n\n";
341 dp->SetKeyAsCopyOf(*pkey,
true, &thePWData,
348 <<
": Successfully loaded private key, FYI.\n";
370 bool bReturnValue =
false;
374 <<
": Reading public key from x509 stored in bookended string...\n";
389 const_cast<OTString&>(strCert),
391 "-----BEGIN CERTIFICATE"))
393 "-----BEGIN CERTIFICATE-----\n%s-----END CERTIFICATE-----\n",
398 <<
": Error extracting ASCII-Armored text from Cert String.\n";
405 strWithBookends = strCert;
412 static_cast<void*>(const_cast<char*>(strWithBookends.
Get())), -1);
421 nullptr == pImportPassword ?
"Enter your wallet master passphrase. "
422 "(LoadPublicKeyFromCertString)"
425 (
nullptr == pstrReason
426 ?
"Enter the passphrase for your exported Nym. "
427 "(LoadPublicKeyFromCertString)"
428 : pstrReason->
Get()));
430 X509* x509 =
nullptr;
432 if (
nullptr == pImportPassword)
433 x509 = PEM_read_bio_X509(keyBio,
nullptr,
437 x509 = PEM_read_bio_X509(
438 keyBio,
nullptr, 0, const_cast<void*>(reinterpret_cast<const void*>(
448 if (
nullptr != x509) {
449 EVP_PKEY* pkey = X509_get_pubkey(x509);
451 if (pkey ==
nullptr) {
452 otErr << __FUNCTION__ <<
": Error reading public key from x509.\n";
455 dp->SetKeyAsCopyOf(*pkey,
false,
456 &thePWData, pImportPassword);
462 otLog3 << __FUNCTION__ <<
": Successfully extracted a public key "
463 "from an x509 certificate.\n";
468 otErr << __FUNCTION__ <<
": Error reading x509 out of certificate.\n";
480 if (
nullptr != x509) X509_free(x509);
482 dp->SetX509(
nullptr);
491 const OTPassword& theExportPassword,
bool bImporting)
const
496 bool bReturnVal =
false;
498 const EVP_CIPHER* pCipher =
512 EVP_PKEY* pClearKey =
nullptr;
521 "OTAsymmetricKey_OpenSSL::"
522 "ReEncryptPrivateKey: Assert: nullptr != "
528 bImporting ?
"(Importing) Enter the exported Nym's passphrase."
529 :
"(Exporting) Enter your wallet's master passphrase.");
538 pClearKey = PEM_read_bio_PrivateKey(
540 const_cast<void*>(reinterpret_cast<const void*>(
551 pClearKey = PEM_read_bio_PrivateKey(
556 if (
nullptr != pClearKey) {
562 <<
": Success reading private key from ASCII-armored data.\n";
573 int32_t nWriteBio = 0;
584 nWriteBio = PEM_write_bio_PrivateKey(
585 bmem, pClearKey, pCipher,
nullptr, 0,
600 nWriteBio = PEM_write_bio_PrivateKey(
601 bmem, pClearKey, pCipher,
nullptr, 0, 0,
602 const_cast<void*>(reinterpret_cast<const void*>(
606 EVP_PKEY_free(pClearKey);
609 otErr << __FUNCTION__
610 <<
": Failed writing EVP_PKEY to memory buffer.\n";
614 <<
": Success writing EVP_PKEY to memory buffer.\n";
617 char* pChar =
nullptr;
623 int64_t lSize = BIO_get_mem_data(bmem, &pChar);
624 uint32_t nSize =
static_cast<uint32_t
>(lSize);
632 (static_cast<char*>(const_cast<void*>(
647 otErr << __FUNCTION__
648 <<
": Failed copying private key into memory.\n";
653 otErr << __FUNCTION__ <<
": Failed loading actual private key from "
654 "BIO containing ASCII-armored data:\n\n"
658 otErr << __FUNCTION__
659 <<
": Failed reading private key from ASCII-armored data.\n\n";
672 X509* x509 =
dp->GetX509();
674 if (
nullptr == x509) {
675 otErr << __FUNCTION__
676 <<
": Error: Unexpected nullptr x509. (Returning false.)\n";
682 PEM_write_bio_X509(bio_out_x509, x509);
684 bool bSuccess =
false;
686 uint8_t buffer_x509[8192] =
"";
692 if (0 < (len = BIO_read(bio_out_x509, buffer_x509, 8100)))
697 buffer_x509[len] =
'\0';
698 strx509.
Set((
const char*)buffer_x509);
700 EVP_PKEY* pPublicKey = X509_get_pubkey(x509);
701 if (
nullptr != pPublicKey) {
703 nullptr == pstrReason
704 ?
"OTAsymmetricKey_OpenSSL::SaveCertToString"
705 : pstrReason->
Get());
707 dp->SetKeyAsCopyOf(*pPublicKey,
false, &thePWData, pImportPassword);
708 EVP_PKEY_free(pPublicKey);
709 pPublicKey =
nullptr;
715 if (bSuccess) strOutput = strx509;
725 const EVP_CIPHER* pCipher =
729 otErr << __FUNCTION__ <<
": Error: !IsPrivate() (This function should "
730 "only be called on a private key.)\n";
734 EVP_PKEY* pPrivateKey =
dp->GetKeyLowLevel();
735 if (
nullptr == pPrivateKey) {
738 <<
": Error: Unexpected nullptr pPrivateKey. (Returning false.)\n";
747 :
"OTAsymmetricKey_OpenSSL::"
748 "SavePrivateKeyToString is calling "
749 "PEM_write_bio_PrivateKey...");
751 if (
nullptr == pImportPassword)
752 PEM_write_bio_PrivateKey(bio_out_pri, pPrivateKey, pCipher,
nullptr, 0,
756 PEM_write_bio_PrivateKey(
757 bio_out_pri, pPrivateKey, pCipher,
nullptr, 0, 0,
759 reinterpret_cast<const void*>(pImportPassword->
getPassword())));
761 bool bSuccess =
false;
764 uint8_t buffer_pri[4096] =
"";
767 if (0 < (len = BIO_read(bio_out_pri, buffer_pri, 4080)))
772 buffer_pri[len] =
'\0';
773 strOutput.
Set((
const char*)buffer_pri);
778 otErr << __FUNCTION__ <<
": Error : key length is not 1 or more!";
820 memset(&pgpKeys, 0,
sizeof(pgpKeys));
821 for (i = 0; i < dataLength;) {
822 int32_t packetLength;
823 uint8_t packetTag = pbData[i++];
824 if ((packetTag & 0x80) == 0)
break;
825 if ((packetTag & 0x40)) {
827 packetLength = pbData[i++];
828 if ((packetLength > 191) && (packetLength < 224))
829 packetLength = ((packetLength - 192) << 8) + pbData[i++];
830 else if ((packetLength > 223) && (packetLength < 255))
831 packetLength = (1 << (packetLength & 0x1f));
832 else if (packetLength == 255) {
833 packetLength = (pbData[i] << 24) + (pbData[i + 1] << 16) +
834 (pbData[i + 2] << 8) + pbData[i + 3];
839 packetLength = packetTag & 3;
840 packetTag = (packetTag >> 2) & 15;
841 if (packetLength == 0)
842 packetLength = pbData[i++];
843 else if (packetLength == 1) {
844 packetLength = (pbData[i] << 8) + pbData[i + 1];
847 else if (packetLength == 2) {
848 packetLength = (pbData[i] << 24) + (pbData[i + 1] << 16) +
849 (pbData[i + 2] << 8) + pbData[i + 3];
853 packetLength = dataLength - 1;
856 if ((packetTag == 6) || (packetTag == 14))
859 int32_t version = pbData[i++];
864 if ((version == 2) || (version == 3)) {
869 algorithm = pbData[i++];
871 if ((algorithm == 1) || (algorithm == 2) ||
874 int32_t modulusLength, exponentLength;
875 RSA* pKey = RSA_new();
878 modulusLength = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
879 pKey->n = BN_bin2bn(pbData + i + 2, modulusLength,
nullptr);
880 i += modulusLength + 2;
883 exponentLength = (pbData[i] * 256 + pbData[i + 1] + 7) / 8;
884 pKey->e = BN_bin2bn(pbData + i + 2, exponentLength,
nullptr);
885 i += exponentLength + 2;
891 else if (algorithm == 17)
893 int32_t pLen, qLen, gLen, yLen;
894 DSA* pKey = DSA_new();
897 pLen = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
898 pKey->p = BN_bin2bn(pbData + i + 2, pLen,
nullptr);
902 qLen = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
903 pKey->q = BN_bin2bn(pbData + i + 2, qLen,
nullptr);
907 gLen = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
908 pKey->g = BN_bin2bn(pbData + i + 2, gLen,
nullptr);
912 yLen = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
913 pKey->pub_key = BN_bin2bn(pbData + i + 2, yLen,
nullptr);
920 else if ((algorithm == 16) || (algorithm == 20))
924 int32_t pLen, gLen, yLen;
926 if (
nullptr == pKey) {
927 otErr << __FUNCTION__ <<
": Error: pKey is nullptr!";
932 pLen = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
934 pKey->
p = BN_bin2bn(pbData + i + 2, pLen,
nullptr);
939 gLen = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
940 pKey->
g = BN_bin2bn(pbData + i + 2, gLen,
nullptr);
944 yLen = ((pbData[i] * 256 + pbData[i + 1] + 7) / 8);
945 pKey->
pub_key = BN_bin2bn(pbData + i + 2, yLen,
nullptr);
954 if (version == 2 || version == 3) i -= 2;
1003 while ((len = BIO_read(bioJoin, buffer, 512)) > 0)
1004 BIO_write(bio_out, buffer, len);
1006 BIO_get_mem_ptr(bio_out, &bptr);
1007 bio_out.setFreeOnly();
1010 ExportRsaKey((uint8_t*)bptr->data, static_cast<int32_t>(bptr->length));
1012 if (!pgpKeys.
pRsa) {
1013 otLog5 <<
"\nNo RSA public key found.\n\n";
1016 char* szModulusHex = BN_bn2hex(pgpKeys.
pRsa->n);
1017 char* szExponentHex = BN_bn2hex(pgpKeys.
pRsa->e);
1018 otLog5 <<
"RSA public key found : \n Modulus ("
1019 << BN_num_bits(pgpKeys.
pRsa->n) <<
" bits)\n";
1020 otLog5 <<
" Exponent : 0x" << szExponentHex <<
"\n\n";
1021 otLog5 <<
"RSA public key found : \nModulus ("
1022 << BN_num_bits(pgpKeys.
pRsa->n) <<
" bits) : 0x" << szModulusHex
1024 otLog5 <<
"Exponent : 0x" << szExponentHex <<
"\n\n";
1026 CRYPTO_free(szModulusHex);
1027 CRYPTO_free(szExponentHex);
1030 if (!pgpKeys.
pDsa) {
1031 otLog5 <<
"No DSA public key found.\n\n";
1034 char* szPHex = BN_bn2hex(pgpKeys.
pDsa->p);
1035 char* szQHex = BN_bn2hex(pgpKeys.
pDsa->q);
1036 char* szGHex = BN_bn2hex(pgpKeys.
pDsa->g);
1037 char* szYHex = BN_bn2hex(pgpKeys.
pDsa->pub_key);
1038 otLog5 <<
"DSA public key found : \n p ("
1039 << BN_num_bits(pgpKeys.
pDsa->p) <<
" bits)\n";
1040 otLog5 <<
" q (" << BN_num_bits(pgpKeys.
pDsa->q) <<
" bits)\n";
1041 otLog5 <<
" g (" << BN_num_bits(pgpKeys.
pDsa->g) <<
" bits)\n";
1042 otLog5 <<
"public key (" << BN_num_bits(pgpKeys.
pDsa->pub_key)
1044 otLog5 <<
"DSA public key found : \np (" << BN_num_bits(pgpKeys.
pDsa->p)
1045 <<
" bits) : 0x" << szPHex <<
"\n";
1046 otLog5 <<
"q (" << BN_num_bits(pgpKeys.
pDsa->q) <<
" bits) : 0x"
1048 otLog5 <<
"g (" << BN_num_bits(pgpKeys.
pDsa->g) <<
" bits) : 0x"
1050 otLog5 <<
"public key (" << BN_num_bits(pgpKeys.
pDsa->pub_key)
1051 <<
" bits) : 0x" << szYHex <<
"\n\n";
1053 CRYPTO_free(szPHex);
1054 CRYPTO_free(szQHex);
1055 CRYPTO_free(szGHex);
1056 CRYPTO_free(szYHex);
1060 otLog5 <<
"No Elgamal public key found.\n\n";
1063 char* szPHex = BN_bn2hex(pgpKeys.
pElgamal->
p);
1064 char* szGHex = BN_bn2hex(pgpKeys.
pElgamal->
g);
1066 otLog5 <<
"Elgamal public key found : \n p ("
1067 << BN_num_bits(pgpKeys.
pElgamal->
p) <<
" bits) : 0x" << szPHex
1072 <<
" bits) : 0x" << szYHex <<
"\n\n";
1074 CRYPTO_free(szPHex);
1075 CRYPTO_free(szGHex);
1076 CRYPTO_free(szYHex);
1079 bool bReturnValue =
false;
1080 EVP_PKEY* pkey = EVP_PKEY_new();
1084 if (EVP_PKEY_assign_RSA(pkey, pgpKeys.
pRsa)) {
1085 bReturnValue =
true;
1087 otLog4 <<
"Successfully extracted RSA public key from PGP public "
1091 RSA_free(pgpKeys.
pRsa);
1092 otOut <<
"Extracted RSA public key from PGP public key block, but "
1093 "unable to convert to EVP_PKEY.\n";
1096 pgpKeys.
pRsa =
nullptr;
1098 else if (pgpKeys.
pDsa) {
1099 if (EVP_PKEY_assign_DSA(pkey, pgpKeys.
pDsa)) {
1100 bReturnValue =
true;
1102 otLog4 <<
"Successfully extracted DSA public key from PGP public "
1106 DSA_free(pgpKeys.
pDsa);
1107 otOut <<
"Extracted DSA public key from PGP public key block, but "
1108 "unable to convert to EVP_PKEY.\n";
1111 pgpKeys.
pDsa =
nullptr;
1114 otOut <<
"Extracted ElGamal Key from PGP public key block, but "
1115 "currently do not support it (sorry))\n";
1129 dp->SetKeyAsCopyOf(*pkey,
false);
1130 EVP_PKEY_free(pkey);
1136 EVP_PKEY_free(pkey);
1142 return bReturnValue;
1145 #elif defined(OT_CRYPTO_USING_GPG)
OTLOG_IMPORT OTLogStream otLog4
virtual bool SaveCertToString(OTString &strOutput, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr) const
virtual bool SavePrivateKeyToString(OTString &strOutput, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr) const
virtual bool LoadPublicKeyFromPGPKey(const OTASCIIArmor &strKey)
OTASCIIArmor * m_p_ascKey
virtual void ReleaseKeyLowLevel_Hook() const
virtual bool ReEncryptPrivateKey(const OTPassword &theExportPassword, bool bImporting) const
virtual bool LoadPublicKeyFromCertString(const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
OTLOG_IMPORT OTLogStream otOut
OTAsymmetricKey_OpenSSL()
OTLOG_IMPORT OTLogStream otLog3
virtual bool LoadPrivateKeyFromCertString(const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
PgpKeys ExportRsaKey(uint8_t *pbData, int32_t dataLength)
EXPORT bool Exists() const
void Release_AsymmetricKey_OpenSSL()
static EXPORT bool LoadFromString(OTASCIIArmor &ascArmor, const OTString &strInput, std::string str_bookend="-----BEGIN")
EXPORT void Format(const char *fmt,...)
virtual ~OTAsymmetricKey_OpenSSL()
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
#define OT_ASSERT_MSG(x, s)
EXPORT void SetPayloadSize(uint32_t lNewSize)
EXPORT uint32_t getPasswordSize() const
EXPORT bool GetData(OTData &theData, bool bLineBreaks=true) const
EXPORT void setFreeOnly()
EXPORT const char * getPassword() const
EXPORT const char * Get() const
EXPORT const void * GetPayloadPointer() const
OTLOG_IMPORT OTLogStream otErr
OTAsymmetricKey_OpenSSLPrivdp * dp
static EXPORT OT_OPENSSL_CALLBACK * GetPasswordCallback()
EXPORT bool SetData(const OTData &theData, bool bLineBreaks=true)
static EXPORT void * safe_memcpy(void *dest, uint32_t dsize, const void *src, uint32_t ssize, bool zeroSource=false)
OTAsymmetricKey_OpenSSL * backlink
OTLOG_IMPORT OTLogStream otLog5