Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
opentxs::OTAsymmetricKey_OpenSSL Class Reference

#include <OTAsymmetricKeyOpenSSL.hpp>

Inheritance diagram for opentxs::OTAsymmetricKey_OpenSSL:
Collaboration diagram for opentxs::OTAsymmetricKey_OpenSSL:

Classes

class  OTAsymmetricKey_OpenSSLPrivdp
 

Public Member Functions

virtual bool LoadPrivateKeyFromCertString (const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
 
virtual bool LoadPublicKeyFromCertString (const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
 
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)
 
virtual bool ReEncryptPrivateKey (const OTPassword &theExportPassword, bool bImporting) const
 
virtual ~OTAsymmetricKey_OpenSSL ()
 
virtual void Release ()
 
void Release_AsymmetricKey_OpenSSL ()
 
- Public Member Functions inherited from opentxs::OTAsymmetricKey
virtual OTAsymmetricKeyClonePubKey () const
 
virtual EXPORT ~OTAsymmetricKey ()
 
void Release_AsymmetricKey ()
 
void ReleaseKey ()
 
bool IsEmpty () const
 
bool IsPublic () const
 
bool IsPrivate () const
 
void SetAsPublic ()
 
void SetAsPrivate ()
 
virtual bool CalculateID (OTIdentifier &theOutput) const
 
bool LoadPrivateKey (const OTString &strFoldername, const OTString &strFilename, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
 
bool LoadPublicKey (const OTString &strFoldername, const OTString &strFilename)
 
bool LoadPublicKeyFromCertFile (const OTString &strFoldername, const OTString &strFilename, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
 
EXPORT bool GetPublicKey (OTASCIIArmor &strKey) const
 
EXPORT bool GetPublicKey (OTString &strKey, bool bEscaped=true) const
 
EXPORT bool SetPublicKey (const OTASCIIArmor &strKey)
 
EXPORT bool SetPublicKey (const OTString &strKey, bool bEscaped=false)
 
bool GetPrivateKey (OTString &strKey, bool bEscaped=true) const
 
bool GetPrivateKey (OTASCIIArmor &strKey) const
 
bool SetPrivateKey (const OTString &strKey, bool bEscaped=false)
 
bool SetPrivateKey (const OTASCIIArmor &strKey)
 

Public Attributes

OTAsymmetricKey_OpenSSLPrivdpdp
 
- Public Attributes inherited from opentxs::OTAsymmetricKey
OTSignatureMetadatam_pMetadata
 

Protected Member Functions

 OTAsymmetricKey_OpenSSL ()
 
virtual void ReleaseKeyLowLevel_Hook () const
 
- Protected Member Functions inherited from opentxs::OTAsymmetricKey
void ReleaseKeyLowLevel ()
 
EXPORT OTAsymmetricKey ()
 

Friends

class OTAsymmetricKey
 
class OTLowLevelKeyData
 
class OTCrypto_OpenSSL
 

Additional Inherited Members

- Static Public Member Functions inherited from opentxs::OTAsymmetricKey
static EXPORT OTAsymmetricKeyKeyFactory ()
 
static void SetPasswordCallback (OT_OPENSSL_CALLBACK *pCallback)
 
static EXPORT OT_OPENSSL_CALLBACKGetPasswordCallback ()
 
static bool IsPasswordCallbackSet ()
 
static bool SetPasswordCaller (OTCaller &theCaller)
 
static OTCallerGetPasswordCaller ()
 
- Protected Attributes inherited from opentxs::OTAsymmetricKey
OTASCIIArmorm_p_ascKey
 
bool m_bIsPublicKey
 
bool m_bIsPrivateKey
 
Timer m_timer
 
- Static Protected Attributes inherited from opentxs::OTAsymmetricKey
static OT_OPENSSL_CALLBACKs_pwCallback = nullptr
 
static OTCallers_pCaller = nullptr
 

Detailed Description

Definition at line 188 of file OTAsymmetricKeyOpenSSL.hpp.

Constructor & Destructor Documentation

opentxs::OTAsymmetricKey_OpenSSL::OTAsymmetricKey_OpenSSL ( )
protected

Definition at line 153 of file OTAsymmetricKeyOpenSSL.cpp.

154  : OTAsymmetricKey()
155  , dp(new OTAsymmetricKey_OpenSSLPrivdp())
156 {
157  dp->backlink = this;
158 
159  dp->m_pX509 = nullptr;
160  dp->m_pKey = nullptr;
161 }
OTAsymmetricKey_OpenSSLPrivdp * dp
opentxs::OTAsymmetricKey_OpenSSL::~OTAsymmetricKey_OpenSSL ( )
virtual

Definition at line 163 of file OTAsymmetricKeyOpenSSL.cpp.

164 {
166 
168 
169  if (nullptr !=
170  dp->m_pX509) // Todo: figure out if I should put a copy of this
171  // into ReleaseKeyLowLevel_Hook as we are with
172  // m_pKey.
173  X509_free(dp->m_pX509); // FYI: the reason it's not there already is
174  // because the original need was for wiping
175  // m_pKey when a private key timed out.
176  dp->m_pX509 = nullptr; // ReleaseKeyLowLevel is used all over
177  // OTAsymmetricKey.cpp for the purpose of wiping that
178  // private key. The same need didn't exist with the x509
179  // so it was never coded that way. As long as it's
180  // cleaned up here in the destructor, seems good enough?
181  // YOU MIGHT ASK... Why is m_pKey cleaned up here in the destructor, and
182  // ALSO in ReleaseKeyLowLevel_Hook ?
183  // The answer is because if we call ReleaseKeyLowLevel_Hook from
184  // OTAsymmetricKey's destructor (down that chain)
185  // then it will fail at runtime, since it is a pure virtual method. Since we
186  // still want the ABILITY to use ReleaseKeyLowLevel_Hook
187  // (For cases where the destructor is not being used) and since we still
188  // want it to ALSO work when destructing, the
189  // easiest/quickest/simplest way is to put the code into
190  // OTAsymmetricKey_OpenSSL's destructor directly, as well
191  // as OTAsymmetricKey_OpenSSL's override of ReleaseKeyLowLevel_Hook. Then go
192  // into OTAsymmetricKey's destructor and
193  // make sure the full call path through there doesn't involve any virtual
194  // functions.
195 }
OTAsymmetricKey_OpenSSLPrivdp * dp

Member Function Documentation

bool opentxs::OTAsymmetricKey_OpenSSL::LoadPrivateKeyFromCertString ( const OTString strCert,
bool  bEscaped = true,
const OTString pstrReason = nullptr,
const OTPassword pImportPassword = nullptr 
)
virtual

Implements opentxs::OTAsymmetricKey.

Definition at line 222 of file OTAsymmetricKeyOpenSSL.cpp.

230 {
231  Release();
232 
233  m_bIsPublicKey = false;
234  m_bIsPrivateKey = true;
235 
236  if (!strCert.Exists()) {
237  otErr << __FUNCTION__ << ": Error: Cert input is nonexistent!\n";
238  return false;
239  }
240 
241  // Read private key
242  //
243  OTString strWithBookends;
244  otLog3 << __FUNCTION__ << ": FYI, Reading private key from x509 stored in "
245  "bookended string...\n";
246 
247  if (bEscaped) {
248  OTASCIIArmor theArmor;
249 
250  // I only have a CERTIFICATE 'if' here, not a PUBLIC KEY 'if'.
251  // That's because this function is called
252  // "LoadPublicKeyFrom*CERT*String"
253  // If you want to load a public key from a public key string, then call
254  // the
255  // other function that does that.
256  if (theArmor.LoadFromString(
257  const_cast<OTString&>(strCert),
258  true, // passing bEscaped in as true explicitly here.
259  "-----BEGIN ENCRYPTED PRIVATE")) // It will start loading from
260  // THIS substring...
261  strWithBookends.Format("-----BEGIN ENCRYPTED PRIVATE "
262  "KEY-----\n%s-----END ENCRYPTED PRIVATE "
263  "KEY-----\n",
264  theArmor.Get());
265  else {
266  otErr
267  << __FUNCTION__
268  << ": Error extracting ASCII-Armored text from Cert String.\n";
269  return false;
270  }
271  }
272  else // It's not escaped already, so no need to remove the escaping, in
273  // this case.
274  {
275  strWithBookends = strCert;
276  }
277 
278  // Create a new memory buffer on the OpenSSL side.
279  //
280  // OpenSSL_BIO bio = BIO_new(BIO_s_mem());
281  // OpenSSL_BIO bio =
282  // BIO_new_mem_buf(static_cast<void*>(const_cast<char*>(strWithBookends.Get())),
283  // strWithBookends.GetLength() /*+1*/);
284  OpenSSL_BIO bio = BIO_new_mem_buf(
285  static_cast<void*>(const_cast<char*>(strWithBookends.Get())), -1);
286  OT_ASSERT_MSG(nullptr != bio,
287  "OTAsymmetricKey_OpenSSL::"
288  "LoadPrivateKeyFromCertString: Assert: nullptr != "
289  "bio \n");
290 
291  {
292  // TODO security: Need to replace PEM_read_bio_PrivateKey().
293  /*
294  The old PrivateKey write routines are retained for compatibility.
295  New applications should write private keys using the
296  PEM_write_bio_PKCS8PrivateKey() or PEM_write_PKCS8PrivateKey()
297  routines because they are more secure (they use an iteration count of
298  2048 whereas the traditional routines use a
299  count of 1) unless compatibility with older versions of OpenSSL is
300  important.
301  NOTE: The PrivateKey read routines can be used in all applications
302  because they handle all formats transparently.
303  */
304  OTPasswordData thePWData(
305  (nullptr == pstrReason)
306  ? (nullptr == pImportPassword
307  ? "Enter the master passphrase. "
308  "(LoadPrivateKeyFromCertString)"
309  : "Enter the passphrase for this exported nym.")
310  : pstrReason->Get());
311 
312  EVP_PKEY* pkey = nullptr;
313 
314  if (!pImportPassword) // pImportPassword is nullptr? Do it normally then
315  {
316  pkey = PEM_read_bio_PrivateKey(
317  bio, nullptr, OTAsymmetricKey::GetPasswordCallback(),
318  &thePWData);
319  }
320  else // Otherwise, use pImportPassword instead of the normal
321  // OTCachedKey system.
322  {
323  pkey = PEM_read_bio_PrivateKey(
324  bio, nullptr, 0,
325  const_cast<void*>(reinterpret_cast<const void*>(
326  pImportPassword->getPassword())));
327  }
328 
329  if (nullptr == pkey) {
330  otErr << __FUNCTION__ << ": (pImportPassword size: "
331  << (nullptr == pImportPassword
332  ? 0
333  : pImportPassword->getPasswordSize())
334  << ") Error reading private key from string.\n\n";
335  return false;
336  }
337  else {
338  // Note: no need to start m_timer here since SetKeyAsCopyOf already
339  // calls ArmorPrivateKey, which does that.
340  //
341  dp->SetKeyAsCopyOf(*pkey, true, &thePWData,
342  pImportPassword); // bIsPrivateKey=false by
343  // default, but true
344  // here.
345  EVP_PKEY_free(pkey);
346  pkey = nullptr;
347  otLog3 << __FUNCTION__
348  << ": Successfully loaded private key, FYI.\n";
349  return true;
350  }
351  }
352 }
OTLOG_IMPORT OTLogStream otLog3
#define OT_ASSERT_MSG(x, s)
Definition: Assert.hpp:155
OTLOG_IMPORT OTLogStream otErr
OTAsymmetricKey_OpenSSLPrivdp * dp
static EXPORT OT_OPENSSL_CALLBACK * GetPasswordCallback()
bool opentxs::OTAsymmetricKey_OpenSSL::LoadPublicKeyFromCertString ( const OTString strCert,
bool  bEscaped = true,
const OTString pstrReason = nullptr,
const OTPassword pImportPassword = nullptr 
)
virtual

Implements opentxs::OTAsymmetricKey.

Definition at line 361 of file OTAsymmetricKeyOpenSSL.cpp.

364 {
365  Release();
366 
367  m_bIsPublicKey = true;
368  m_bIsPrivateKey = false;
369 
370  bool bReturnValue = false;
371 
372  // Read public key
373  otLog3 << __FUNCTION__
374  << ": Reading public key from x509 stored in bookended string...\n";
375 
376  OTString strWithBookends;
377 
378  if (bEscaped) {
379  OTASCIIArmor theArmor;
380 
381  // I only have a CERTIFICATE 'if' here, not a PUBLIC KEY 'if'.
382  // That's because this function is called
383  // "LoadPublicKeyFrom*CERT*String"
384  // If you want to load a public key from a public key string, then call
385  // the
386  // other function that does that.
387  //
388  if (theArmor.LoadFromString(
389  const_cast<OTString&>(strCert),
390  true, // passing bEscaped in as true explicitly here.
391  "-----BEGIN CERTIFICATE")) // Overrides "-----BEGIN"
392  strWithBookends.Format(
393  "-----BEGIN CERTIFICATE-----\n%s-----END CERTIFICATE-----\n",
394  theArmor.Get());
395  else {
396  otErr
397  << __FUNCTION__
398  << ": Error extracting ASCII-Armored text from Cert String.\n";
399  return false;
400  }
401  }
402  else // It's not escaped already, so no need to remove the escaping, in
403  // this case.
404  {
405  strWithBookends = strCert;
406  }
407 
408  // took out the +1 on the length since null terminater only
409  // needed in string form, not binary form as OpenSSL treats it.
410  //
411  OpenSSL_BIO keyBio = BIO_new_mem_buf(
412  static_cast<void*>(const_cast<char*>(strWithBookends.Get())), -1);
413  // OpenSSL_BIO keyBio =
414  // BIO_new_mem_buf(static_cast<void*>(const_cast<char*>(strWithBookends.Get())),
415  // strWithBookends.GetLength() /*+1*/);
416  // OpenSSL_BIO keyBio = BIO_new_mem_buf((void*)strCert.Get(),
417  // strCert.GetLength() /*+1*/);
418  OT_ASSERT(nullptr != keyBio);
419 
420  OTPasswordData thePWData(
421  nullptr == pImportPassword ? "Enter your wallet master passphrase. "
422  "(LoadPublicKeyFromCertString)"
423  :
424  // pImportPassword exists:
425  (nullptr == pstrReason
426  ? "Enter the passphrase for your exported Nym. "
427  "(LoadPublicKeyFromCertString)"
428  : pstrReason->Get()));
429 
430  X509* x509 = nullptr;
431 
432  if (nullptr == pImportPassword)
433  x509 = PEM_read_bio_X509(keyBio, nullptr,
435  &thePWData);
436  else
437  x509 = PEM_read_bio_X509(
438  keyBio, nullptr, 0, const_cast<void*>(reinterpret_cast<const void*>(
439  pImportPassword->getPassword())));
440 
441  // TODO security: At some point need to switch to using X509_AUX functions.
442  // The current x509 functions will read a trust certificate but discard the
443  // trust structure.
444  // The X509_AUX functions will process the trust structure.
445  // UPDATE: Possibly the trust structure sucks. Need to consult experts. (CA
446  // system is a farce.)
447  //
448  if (nullptr != x509) {
449  EVP_PKEY* pkey = X509_get_pubkey(x509);
450 
451  if (pkey == nullptr) {
452  otErr << __FUNCTION__ << ": Error reading public key from x509.\n";
453  }
454  else {
455  dp->SetKeyAsCopyOf(*pkey, false, // bIsPrivateKey=false. PUBLIC KEY.
456  &thePWData, pImportPassword); // pImportPassword
457  // is sometimes
458  // nullptr here.
459 
460  EVP_PKEY_free(pkey);
461  pkey = nullptr;
462  otLog3 << __FUNCTION__ << ": Successfully extracted a public key "
463  "from an x509 certificate.\n";
464  bReturnValue = true;
465  }
466  }
467  else {
468  otErr << __FUNCTION__ << ": Error reading x509 out of certificate.\n";
469  }
470 
471  // For now we save the x509, and free it in the destructor, since we may
472  // need it in the meantime, to convert the Nym to the new master key and
473  // re-save. (Don't want to have to load the x509 AGAIN just to re-save
474  // it...)
475  //
476  if (bReturnValue) {
477  dp->SetX509(x509);
478  }
479  else {
480  if (nullptr != x509) X509_free(x509);
481  x509 = nullptr;
482  dp->SetX509(nullptr);
483  }
484 
485  return bReturnValue;
486 }
OTLOG_IMPORT OTLogStream otLog3
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTAsymmetricKey_OpenSSLPrivdp * dp
static EXPORT OT_OPENSSL_CALLBACK * GetPasswordCallback()
bool opentxs::OTAsymmetricKey_OpenSSL::LoadPublicKeyFromPGPKey ( const OTASCIIArmor strKey)
virtual

Implements opentxs::OTAsymmetricKey.

Definition at line 969 of file OTAsymmetricKeyOpenSSL.cpp.

971 {
972  Release();
973 
974  m_bIsPublicKey = true;
975  m_bIsPrivateKey = false;
976 
977  /*
978  * An implementation of convertion from PGP public key format to OpenSSL
979  *equivalent
980  * Support of RSA, DSA and Elgamal public keys
981  *
982  * Copyright (c) 2010 Mounir IDRASSI <[email protected]>. All rights
983  *reserved.
984  *
985  * This program is distributed in the hope that it will be useful,
986  * but WITHOUT ANY WARRANTY; without even the implied warranty of
987  *MERCHANTABILITY
988  * or FITNESS FOR A PARTICULAR PURPOSE.
989  *
990  */
991  int32_t len;
992  uint8_t buffer[520]; // Making it a bit bigger than 512 for safety reasons.
993  BUF_MEM* bptr;
994  PgpKeys pgpKeys;
995 
996  OpenSSL_BIO b64 = BIO_new(BIO_f_base64());
997  OpenSSL_BIO bio = BIO_new_mem_buf((void*)strKey.Get(), -1);
998  OpenSSL_BIO bio_out = BIO_new(BIO_s_mem());
999  OpenSSL_BIO bioJoin = BIO_push(b64, bio);
1000  b64.release();
1001  bio.release();
1002 
1003  while ((len = BIO_read(bioJoin, buffer, 512)) > 0)
1004  BIO_write(bio_out, buffer, len);
1005 
1006  BIO_get_mem_ptr(bio_out, &bptr);
1007  bio_out.setFreeOnly();
1008 
1009  pgpKeys =
1010  ExportRsaKey((uint8_t*)bptr->data, static_cast<int32_t>(bptr->length));
1011 
1012  if (!pgpKeys.pRsa) {
1013  otLog5 << "\nNo RSA public key found.\n\n";
1014  }
1015  else {
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
1023  << "\n";
1024  otLog5 << "Exponent : 0x" << szExponentHex << "\n\n";
1025 
1026  CRYPTO_free(szModulusHex);
1027  CRYPTO_free(szExponentHex);
1028  }
1029 
1030  if (!pgpKeys.pDsa) {
1031  otLog5 << "No DSA public key found.\n\n";
1032  }
1033  else {
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)
1043  << " bits)\n\n";
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"
1047  << szQHex << "\n";
1048  otLog5 << "g (" << BN_num_bits(pgpKeys.pDsa->g) << " bits) : 0x"
1049  << szGHex << "\n";
1050  otLog5 << "public key (" << BN_num_bits(pgpKeys.pDsa->pub_key)
1051  << " bits) : 0x" << szYHex << "\n\n";
1052 
1053  CRYPTO_free(szPHex);
1054  CRYPTO_free(szQHex);
1055  CRYPTO_free(szGHex);
1056  CRYPTO_free(szYHex);
1057  }
1058 
1059  if (!pgpKeys.pElgamal) {
1060  otLog5 << "No Elgamal public key found.\n\n";
1061  }
1062  else {
1063  char* szPHex = BN_bn2hex(pgpKeys.pElgamal->p);
1064  char* szGHex = BN_bn2hex(pgpKeys.pElgamal->g);
1065  char* szYHex = BN_bn2hex(pgpKeys.pElgamal->pub_key);
1066  otLog5 << "Elgamal public key found : \n p ("
1067  << BN_num_bits(pgpKeys.pElgamal->p) << " bits) : 0x" << szPHex
1068  << "\n";
1069  otLog5 << " g (" << BN_num_bits(pgpKeys.pElgamal->g) << " bits) : 0x"
1070  << szGHex << "\n";
1071  otLog5 << " public key (" << BN_num_bits(pgpKeys.pElgamal->pub_key)
1072  << " bits) : 0x" << szYHex << "\n\n";
1073 
1074  CRYPTO_free(szPHex);
1075  CRYPTO_free(szGHex);
1076  CRYPTO_free(szYHex);
1077  }
1078 
1079  bool bReturnValue = false;
1080  EVP_PKEY* pkey = EVP_PKEY_new();
1081  OT_ASSERT(nullptr != pkey);
1082 
1083  if (pgpKeys.pRsa) {
1084  if (EVP_PKEY_assign_RSA(pkey, pgpKeys.pRsa)) {
1085  bReturnValue = true;
1086  // todo: make sure the lack of RSA_free here is not a memory leak.
1087  otLog4 << "Successfully extracted RSA public key from PGP public "
1088  "key block.\n";
1089  }
1090  else {
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";
1094  }
1095 
1096  pgpKeys.pRsa = nullptr;
1097  }
1098  else if (pgpKeys.pDsa) {
1099  if (EVP_PKEY_assign_DSA(pkey, pgpKeys.pDsa)) {
1100  bReturnValue = true;
1101  // todo: make sure the lack of DSA_free here is not a memory leak.
1102  otLog4 << "Successfully extracted DSA public key from PGP public "
1103  "key block.\n";
1104  }
1105  else {
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";
1109  }
1110 
1111  pgpKeys.pDsa = nullptr;
1112  }
1113  else if (pgpKeys.pElgamal) {
1114  otOut << "Extracted ElGamal Key from PGP public key block, but "
1115  "currently do not support it (sorry))\n";
1116  //
1117  // int32_t EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, EC_KEY* key); // Here
1118  // is the assign function for El Gamal
1119  // (assuming that "EC" stands for eliptical curve... kind of hard to
1120  // tell with the OpenSSL docs...)
1121  //
1122  free(pgpKeys.pElgamal);
1123  pgpKeys.pElgamal = nullptr;
1124  }
1125 
1126  // FT: Adding some fixes here...
1127  //
1128  if (bReturnValue) {
1129  dp->SetKeyAsCopyOf(*pkey, false); // bIsPrivateKey=false. PUBLIC KEY.
1130  EVP_PKEY_free(pkey); // We have our own copy already. It's set nullptr
1131  // just below...
1132  }
1133  else if (nullptr !=
1134  pkey) // we failed, but pkey is NOT null (need to free it.)
1135  {
1136  EVP_PKEY_free(pkey); // Set nullptr just below...
1137  }
1138 
1139  pkey = nullptr; // This is either stored on m_pKey, or deleted. I'm setting
1140  // pointer to nullptr here just for completeness.
1141 
1142  return bReturnValue;
1143 }
OTLOG_IMPORT OTLogStream otLog4
OTLOG_IMPORT OTLogStream otOut
PgpKeys ExportRsaKey(uint8_t *pbData, int32_t dataLength)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTAsymmetricKey_OpenSSLPrivdp * dp
OTLOG_IMPORT OTLogStream otLog5
bool opentxs::OTAsymmetricKey_OpenSSL::ReEncryptPrivateKey ( const OTPassword theExportPassword,
bool  bImporting 
) const
virtual

Implements opentxs::OTAsymmetricKey.

Definition at line 490 of file OTAsymmetricKeyOpenSSL.cpp.

492 {
493  OT_ASSERT(m_p_ascKey != nullptr);
494  OT_ASSERT(IsPrivate());
495 
496  bool bReturnVal = false;
497 
498  const EVP_CIPHER* pCipher =
499  EVP_des_ede3_cbc(); // todo should this algorithm be hardcoded?
500 
501  OTPayload theData; // after base64-decoding the ascii-armored string, the
502  // (encrypted) binary will be stored here.
503 
504  // This line base64 decodes the ascii-armored string into binary object
505  // theData...
506  //
507  m_p_ascKey->GetData(theData); // theData now contains binary data, the
508  // encrypted private key itself, no longer in
509  // text-armoring.
510 
511  if (theData.GetSize() > 0) {
512  EVP_PKEY* pClearKey = nullptr;
513 
514  // Copy the encrypted binary private key data into an OpenSSL memory
515  // BIO...
516  //
517  OpenSSL_BIO keyBio = BIO_new_mem_buf(
518  static_cast<char*>(const_cast<void*>(theData.GetPayloadPointer())),
519  theData.GetSize()); // theData will zeroMemory upon destruction.
520  OT_ASSERT_MSG(nullptr != keyBio,
521  "OTAsymmetricKey_OpenSSL::"
522  "ReEncryptPrivateKey: Assert: nullptr != "
523  "keyBio \n");
524 
525  // Here's thePWData we use if we didn't have anything else:
526  //
527  OTPasswordData thePWData(
528  bImporting ? "(Importing) Enter the exported Nym's passphrase."
529  : "(Exporting) Enter your wallet's master passphrase.");
530 
531  // If we're importing, that means we're currently stored as an EXPORTED
532  // NYM (i.e. with its own
533  // password, independent of the wallet.) So we use theExportedPassword.
534  //
535  if (bImporting) {
536  // otOut << "RE-ENCRYPT PRIVATE KEY -- READING using
537  // special EXPORT password: %s\n", theExportPassword.getPassword());
538  pClearKey = PEM_read_bio_PrivateKey(
539  keyBio, nullptr, 0,
540  const_cast<void*>(reinterpret_cast<const void*>(
541  theExportPassword.getPassword())));
542  }
543 
544  // Else if we're exporting, that means we're currently stored in the
545  // wallet (i.e. using the wallet's
546  // cached master key.) So we use the normal password callback.
547  //
548  else {
549  // otOut << "RE-ENCRYPT PRIVATE KEY -- READING using WALLET
550  // password.\n";
551  pClearKey = PEM_read_bio_PrivateKey(
552  keyBio, nullptr, OTAsymmetricKey::GetPasswordCallback(),
553  &thePWData);
554  }
555 
556  if (nullptr != pClearKey) {
557  // otLog4 << "%s: Success reading private key from
558  // ASCII-armored data:\n\n%s\n\n",
559  // __FUNCTION__, m_p_ascKey->Get());
560  otLog4
561  << __FUNCTION__
562  << ": Success reading private key from ASCII-armored data.\n";
563 
564  // Okay, we have loaded up the private key, now let's save it back
565  // to m_p_ascKey
566  // using the new passphrase.
567  //
568  OpenSSL_BIO bmem = BIO_new(BIO_s_mem());
569  OT_ASSERT(nullptr != bmem);
570 
571  // write a private key to that buffer, from pClearKey
572  //
573  int32_t nWriteBio = 0;
574 
575  // If we're importing, that means we just loaded up the (previously)
576  // exported Nym
577  // using theExportedPassphrase, so now we need to save it back again
578  // using the
579  // normal password callback (for importing it to the wallet.)
580  //
581  if (bImporting) {
582  // otOut << "RE-ENCRYPT PRIVATE KEY -- WRITING
583  // using WALLET password.\n";
584  nWriteBio = PEM_write_bio_PrivateKey(
585  bmem, pClearKey, pCipher, nullptr, 0,
587  }
588 
589  // Else if we're exporting, that means we just loaded up the Nym
590  // from the wallet
591  // using the normal password callback, and now we need to save it
592  // back again using
593  // theExportedPassphrase (for exporting it outside of the wallet.)
594  //
595  else {
596  // otOut << "RE-ENCRYPT PRIVATE KEY -- WRITING
597  // using special EXPORT password: %s Size: %d\n",
598  // theExportPassword.getPassword(),
599  // theExportPassword.getPasswordSize());
600  nWriteBio = PEM_write_bio_PrivateKey(
601  bmem, pClearKey, pCipher, nullptr, 0, 0,
602  const_cast<void*>(reinterpret_cast<const void*>(
603  theExportPassword.getPassword())));
604  }
605 
606  EVP_PKEY_free(pClearKey);
607 
608  if (0 == nWriteBio)
609  otErr << __FUNCTION__
610  << ": Failed writing EVP_PKEY to memory buffer.\n";
611  else {
612 
613  otLog5 << __FUNCTION__
614  << ": Success writing EVP_PKEY to memory buffer.\n";
615 
616  OTPayload theNewData;
617  char* pChar = nullptr;
618 
619  // After the below call, pChar will point to the memory buffer
620  // where the private key supposedly is,
621  // and lSize will contain the size of that memory.
622  //
623  int64_t lSize = BIO_get_mem_data(bmem, &pChar);
624  uint32_t nSize = static_cast<uint32_t>(lSize);
625 
626  if (nSize > 0) {
627  // Set the buffer size in our own memory.
628  theNewData.SetPayloadSize(nSize);
629 
630  // void * pv =
632  (static_cast<char*>(const_cast<void*>(
633  theNewData.GetPayloadPointer()))), // destination
634  theNewData.GetSize(), // size of destination buffer.
635  pChar, // source
636  nSize); // length of source.
637  // bool bZeroSource=false); // if true, sets the source
638  // buffer to zero after copying is done.
639 
640  // This base64 encodes the private key data, which
641  // is already encrypted to its passphase as well.
642  //
643  m_p_ascKey->SetData(theNewData); // <======== Success!
644  bReturnVal = true;
645  }
646  else
647  otErr << __FUNCTION__
648  << ": Failed copying private key into memory.\n";
649  } // (nWriteBio != 0)
650 
651  }
652  else
653  otErr << __FUNCTION__ << ": Failed loading actual private key from "
654  "BIO containing ASCII-armored data:\n\n"
655  << m_p_ascKey->Get() << "\n\n";
656  }
657  else
658  otErr << __FUNCTION__
659  << ": Failed reading private key from ASCII-armored data.\n\n";
660  // otErr << "%s: Failed reading private key from ASCII-armored
661  // data:\n\n%s\n\n",
662  // __FUNCTION__, m_p_ascKey->Get());
663 
664  return bReturnVal;
665 }
OTLOG_IMPORT OTLogStream otLog4
#define OT_ASSERT(x)
Definition: Assert.hpp:150
#define OT_ASSERT_MSG(x, s)
Definition: Assert.hpp:155
EXPORT bool GetData(OTData &theData, bool bLineBreaks=true) const
EXPORT const char * Get() const
Definition: OTString.cpp:1045
OTLOG_IMPORT OTLogStream otErr
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)
Definition: OTPassword.cpp:357
OTLOG_IMPORT OTLogStream otLog5
void opentxs::OTAsymmetricKey_OpenSSL::Release ( )
virtual

Reimplemented from opentxs::OTAsymmetricKey.

Definition at line 198 of file OTAsymmetricKeyOpenSSL.cpp.

199 {
200  Release_AsymmetricKey_OpenSSL(); // My own cleanup is performed here.
201 
202  // Next give the base class a chance to do the same...
203  ot_super::Release(); // since I've overridden the base class, I call it
204  // now...
205 }
void opentxs::OTAsymmetricKey_OpenSSL::Release_AsymmetricKey_OpenSSL ( )

Definition at line 207 of file OTAsymmetricKeyOpenSSL.cpp.

208 {
209  // Release any dynamically allocated members here. (Normally.)
210 }
void opentxs::OTAsymmetricKey_OpenSSL::ReleaseKeyLowLevel_Hook ( ) const
protectedvirtual

Implements opentxs::OTAsymmetricKey.

Definition at line 212 of file OTAsymmetricKeyOpenSSL.cpp.

213 {
214  // Release the instantiated OpenSSL key (unsafe to store in this form.)
215  //
216  if (nullptr != dp->m_pKey) EVP_PKEY_free(dp->m_pKey);
217  dp->m_pKey = nullptr;
218 }
OTAsymmetricKey_OpenSSLPrivdp * dp
bool opentxs::OTAsymmetricKey_OpenSSL::SaveCertToString ( OTString strOutput,
const OTString pstrReason = nullptr,
const OTPassword pImportPassword = nullptr 
) const
virtual

Implements opentxs::OTAsymmetricKey.

Definition at line 668 of file OTAsymmetricKeyOpenSSL.cpp.

671 {
672  X509* x509 = dp->GetX509();
673 
674  if (nullptr == x509) {
675  otErr << __FUNCTION__
676  << ": Error: Unexpected nullptr x509. (Returning false.)\n";
677  return false;
678  }
679 
680  OpenSSL_BIO bio_out_x509 = BIO_new(BIO_s_mem()); // we now have auto-cleanup
681 
682  PEM_write_bio_X509(bio_out_x509, x509);
683 
684  bool bSuccess = false;
685 
686  uint8_t buffer_x509[8192] = ""; // todo hardcoded
687  OTString strx509;
688  int32_t len = 0;
689 
690  // todo hardcoded 4080 (see array above.)
691  //
692  if (0 < (len = BIO_read(bio_out_x509, buffer_x509, 8100))) // returns number
693  // of bytes
694  // successfully
695  // read.
696  {
697  buffer_x509[len] = '\0';
698  strx509.Set((const char*)buffer_x509);
699 
700  EVP_PKEY* pPublicKey = X509_get_pubkey(x509);
701  if (nullptr != pPublicKey) {
702  OTPasswordData thePWData(
703  nullptr == pstrReason
704  ? "OTAsymmetricKey_OpenSSL::SaveCertToString"
705  : pstrReason->Get());
706 
707  dp->SetKeyAsCopyOf(*pPublicKey, false, &thePWData, pImportPassword);
708  EVP_PKEY_free(pPublicKey);
709  pPublicKey = nullptr;
710  }
711 
712  bSuccess = true;
713  }
714 
715  if (bSuccess) strOutput = strx509;
716 
717  return bSuccess;
718 }
OTLOG_IMPORT OTLogStream otErr
OTAsymmetricKey_OpenSSLPrivdp * dp
bool opentxs::OTAsymmetricKey_OpenSSL::SavePrivateKeyToString ( OTString strOutput,
const OTString pstrReason = nullptr,
const OTPassword pImportPassword = nullptr 
) const
virtual

Implements opentxs::OTAsymmetricKey.

Definition at line 721 of file OTAsymmetricKeyOpenSSL.cpp.

724 {
725  const EVP_CIPHER* pCipher =
726  EVP_des_ede3_cbc(); // todo security (revisit this mode...)
727 
728  if (!IsPrivate()) {
729  otErr << __FUNCTION__ << ": Error: !IsPrivate() (This function should "
730  "only be called on a private key.)\n";
731  return false;
732  }
733 
734  EVP_PKEY* pPrivateKey = dp->GetKeyLowLevel();
735  if (nullptr == pPrivateKey) {
736  otErr
737  << __FUNCTION__
738  << ": Error: Unexpected nullptr pPrivateKey. (Returning false.)\n";
739  return false;
740  }
741 
742  OpenSSL_BIO bio_out_pri = BIO_new(BIO_s_mem());
743  bio_out_pri.setFreeOnly(); // only BIO_free(), not BIO_free_all();
744 
745  OTPasswordData thePWData((nullptr != pstrReason)
746  ? pstrReason->Get()
747  : "OTAsymmetricKey_OpenSSL::"
748  "SavePrivateKeyToString is calling "
749  "PEM_write_bio_PrivateKey...");
750 
751  if (nullptr == pImportPassword)
752  PEM_write_bio_PrivateKey(bio_out_pri, pPrivateKey, pCipher, nullptr, 0,
754  &thePWData);
755  else
756  PEM_write_bio_PrivateKey(
757  bio_out_pri, pPrivateKey, pCipher, nullptr, 0, 0,
758  const_cast<void*>(
759  reinterpret_cast<const void*>(pImportPassword->getPassword())));
760 
761  bool bSuccess = false;
762 
763  int32_t len = 0;
764  uint8_t buffer_pri[4096] = ""; // todo hardcoded
765 
766  // todo hardcoded 4080 (see array above.)
767  if (0 < (len = BIO_read(bio_out_pri, buffer_pri, 4080))) // returns number
768  // of bytes
769  // successfully
770  // read.
771  {
772  buffer_pri[len] = '\0';
773  strOutput.Set((const char*)buffer_pri); // so I can write this string to
774  // file in a sec... todo cast
775  bSuccess = true;
776  }
777  else
778  otErr << __FUNCTION__ << ": Error : key length is not 1 or more!";
779 
780  return bSuccess;
781 }
OTLOG_IMPORT OTLogStream otErr
OTAsymmetricKey_OpenSSLPrivdp * dp
static EXPORT OT_OPENSSL_CALLBACK * GetPasswordCallback()

Friends And Related Function Documentation

friend class OTAsymmetricKey
friend

Definition at line 192 of file OTAsymmetricKeyOpenSSL.hpp.

friend class OTCrypto_OpenSSL
friend

Definition at line 195 of file OTAsymmetricKeyOpenSSL.hpp.

friend class OTLowLevelKeyData
friend

Definition at line 193 of file OTAsymmetricKeyOpenSSL.hpp.

Member Data Documentation

OTAsymmetricKey_OpenSSLPrivdp* opentxs::OTAsymmetricKey_OpenSSL::dp

Definition at line 229 of file OTAsymmetricKeyOpenSSL.hpp.


The documentation for this class was generated from the following files: