Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTSymmetricKey.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTSymmetricKey.cpp
4  *
5  */
6 
7 /************************************************************
8  -----BEGIN PGP SIGNED MESSAGE-----
9  Hash: SHA1
10 
11  * OPEN TRANSACTIONS
12  *
13  * Financial Cryptography and Digital Cash
14  * Library, Protocol, API, Server, CLI, GUI
15  *
16  * -- Anonymous Numbered Accounts.
17  * -- Untraceable Digital Cash.
18  * -- Triple-Signed Receipts.
19  * -- Cheques, Vouchers, Transfers, Inboxes.
20  * -- Basket Currencies, Markets, Payment Plans.
21  * -- Signed, XML, Ricardian-style Contracts.
22  * -- Scripted smart contracts.
23  *
24  * Copyright (C) 2010-2013 by "Fellow Traveler" (A pseudonym)
25  *
26  * EMAIL:
28  *
29  * BITCOIN: 1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
30  *
31  * KEY FINGERPRINT (PGP Key in license file):
32  * 9DD5 90EB 9292 4B48 0484 7910 0308 00ED F951 BB8E
33  *
34  * OFFICIAL PROJECT WIKI(s):
35  * https://github.com/FellowTraveler/Moneychanger
36  * https://github.com/FellowTraveler/Open-Transactions/wiki
37  *
38  * WEBSITE:
39  * http://www.OpenTransactions.org/
40  *
41  * Components and licensing:
42  * -- Moneychanger..A Java client GUI.....LICENSE:.....GPLv3
43  * -- otlib.........A class library.......LICENSE:...LAGPLv3
44  * -- otapi.........A client API..........LICENSE:...LAGPLv3
45  * -- opentxs/ot....Command-line client...LICENSE:...LAGPLv3
46  * -- otserver......Server Application....LICENSE:....AGPLv3
47  * Github.com/FellowTraveler/Open-Transactions/wiki/Components
48  *
49  * All of the above OT components were designed and written by
50  * Fellow Traveler, with the exception of Moneychanger, which
51  * was contracted out to Vicky C ([email protected]).
52  * The open-source community has since actively contributed.
53  *
54  * -----------------------------------------------------
55  *
56  * LICENSE:
57  * This program is free software: you can redistribute it
58  * and/or modify it under the terms of the GNU Affero
59  * General Public License as published by the Free Software
60  * Foundation, either version 3 of the License, or (at your
61  * option) any later version.
62  *
63  * ADDITIONAL PERMISSION under the GNU Affero GPL version 3
64  * section 7: (This paragraph applies only to the LAGPLv3
65  * components listed above.) If you modify this Program, or
66  * any covered work, by linking or combining it with other
67  * code, such other code is not for that reason alone subject
68  * to any of the requirements of the GNU Affero GPL version 3.
69  * (==> This means if you are only using the OT API, then you
70  * don't have to open-source your code--only your changes to
71  * Open-Transactions itself must be open source. Similar to
72  * LGPLv3, except it applies to software-as-a-service, not
73  * just to distributing binaries.)
74  *
75  * Extra WAIVER for OpenSSL, Lucre, and all other libraries
76  * used by Open Transactions: This program is released under
77  * the AGPL with the additional exemption that compiling,
78  * linking, and/or using OpenSSL is allowed. The same is true
79  * for any other open source libraries included in this
80  * project: complete waiver from the AGPL is hereby granted to
81  * compile, link, and/or use them with Open-Transactions,
82  * according to their own terms, as long as the rest of the
83  * Open-Transactions terms remain respected, with regard to
84  * the Open-Transactions code itself.
85  *
86  * Lucre License:
87  * This code is also "dual-license", meaning that Ben Lau-
88  * rie's license must also be included and respected, since
89  * the code for Lucre is also included with Open Transactions.
90  * See Open-Transactions/src/otlib/lucre/LUCRE_LICENSE.txt
91  * The Laurie requirements are light, but if there is any
92  * problem with his license, simply remove the Lucre code.
93  * Although there are no other blind token algorithms in Open
94  * Transactions (yet. credlib is coming), the other functions
95  * will continue to operate.
96  * See Lucre on Github: https://github.com/benlaurie/lucre
97  * -----------------------------------------------------
98  * You should have received a copy of the GNU Affero General
99  * Public License along with this program. If not, see:
100  * http://www.gnu.org/licenses/
101  *
102  * If you would like to use this software outside of the free
103  * software license, please contact FellowTraveler.
104  * (Unfortunately many will run anonymously and untraceably,
105  * so who could really stop them?)
106  *
107  * DISCLAIMER:
108  * This program is distributed in the hope that it will be
109  * useful, but WITHOUT ANY WARRANTY; without even the implied
110  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
111  * PURPOSE. See the GNU Affero General Public License for
112  * more details.
113 
114  -----BEGIN PGP SIGNATURE-----
115  Version: GnuPG v1.4.9 (Darwin)
116 
117  iQIcBAEBAgAGBQJRSsfJAAoJEAMIAO35UbuOQT8P/RJbka8etf7wbxdHQNAY+2cC
118  vDf8J3X8VI+pwMqv6wgTVy17venMZJa4I4ikXD/MRyWV1XbTG0mBXk/7AZk7Rexk
119  KTvL/U1kWiez6+8XXLye+k2JNM6v7eej8xMrqEcO0ZArh/DsLoIn1y8p8qjBI7+m
120  aE7lhstDiD0z8mwRRLKFLN2IH5rAFaZZUvj5ERJaoYUKdn4c+RcQVei2YOl4T0FU
121  LWND3YLoH8naqJXkaOKEN4UfJINCwxhe5Ke9wyfLWLUO7NamRkWD2T7CJ0xocnD1
122  sjAzlVGNgaFDRflfIF4QhBx1Ddl6wwhJfw+d08bjqblSq8aXDkmFA7HeunSFKkdn
123  oIEOEgyj+veuOMRJC5pnBJ9vV+7qRdDKQWaCKotynt4sWJDGQ9kWGWm74SsNaduN
124  TPMyr9kNmGsfR69Q2Zq/FLcLX/j8ESxU+HYUB4vaARw2xEOu2xwDDv6jt0j3Vqsg
125  x7rWv4S/Eh18FDNDkVRChiNoOIilLYLL6c38uMf1pnItBuxP3uhgY6COm59kVaRh
126  nyGTYCDYD2TK+fI9o89F1297uDCwEJ62U0Q7iTDp5QuXCoxkPfv8/kX6lS6T3y9G
127  M9mqIoLbIQ1EDntFv7/t6fUTS2+46uCrdZWbQ5RjYXdrzjij02nDmJAm2BngnZvd
128  kamH0Y/n11lCvo1oQxM+
129  =uSzz
130  -----END PGP SIGNATURE-----
131  **************************************************************/
132 
133 #include "stdafx.hpp"
134 
135 #include "crypto/OTSymmetricKey.hpp"
136 #include "crypto/OTASCIIArmor.hpp"
138 #include "crypto/OTCrypto.hpp"
139 #include "crypto/OTEnvelope.hpp"
140 #include "OTIdentifier.hpp"
141 #include "OTLog.hpp"
142 #include "crypto/OTPassword.hpp"
143 #include "crypto/OTPasswordData.hpp"
144 
145 #include <memory>
146 
147 extern "C" {
148 #ifdef _WIN32
149 #include <winsock2.h>
150 #pragma comment(lib, "ws2_32.lib")
151 #else
152 #include <netinet/in.h>
153 #endif
154 }
155 
156 namespace opentxs
157 {
158 
159 // This class stores the iteration count, the salt, and the encrypted key.
160 // These are all generated or set when you call GenerateKey.
161 
162 // Note: this calculates its ID based only on m_dataEncryptedKey,
163 // and does NOT include salt, IV, iteration count, etc when
164 // generating the hash for the ID.
165 //
166 void OTSymmetricKey::GetIdentifier(OTIdentifier& theIdentifier) const
167 {
168  // const bool bCalc =
169  theIdentifier.CalculateDigest(m_dataEncryptedKey);
170 }
171 
172 void OTSymmetricKey::GetIdentifier(OTString& strIdentifier) const
173 {
174  OTIdentifier theIdentifier;
175  const bool bCalc = theIdentifier.CalculateDigest(m_dataEncryptedKey);
176  if (bCalc) theIdentifier.GetString(strIdentifier);
177 }
178 
179 // Changes the passphrase on an existing symmetric key.
180 //
182  const OTPassword& newPassphrase)
183 {
184  OT_ASSERT(m_uIterationCount > 1000);
185  OT_ASSERT(m_bIsGenerated);
186 
187  // Todo: validate the passphrases exist or whatever?
188 
189  otInfo << " Begin: " << __FUNCTION__
190  << ": Changing password on symmetric key...\n";
191 
192  OTPassword theActualKey;
193 
194  if (!GetRawKeyFromPassphrase(oldPassphrase, theActualKey)) return false;
195 
196  OTPayload dataIV, dataSalt;
197 
198  // NOTE: I can't randomize the IV because then anything that was
199  // encrypted with this key before, will fail to decrypt. (Ruining
200  // the whole point of changing the passphrase...)
201  //
202  // UPDATE: I think this is false. I think the IV is for the encryption of
203  // the symmetric key itself, whereas the content has its own IV in
204  // OTEnvelope.
205  //
207  otErr << __FUNCTION__ << ": Failed generating iv for changing "
208  "passphrase on a symmetric key. (Returning "
209  "false.)\n";
210  return false;
211  }
212 
213  if (!dataSalt.Randomize(OTCryptoConfig::SymmetricSaltSize())) {
214  otErr << __FUNCTION__ << ": Failed generating random salt for changing "
215  "passphrase on a symmetric key. (Returning "
216  "false.)\n";
217  return false;
218  }
219 
220  m_dataIV = dataIV;
221  m_dataSalt = dataSalt;
222  m_bHasHashCheck = false;
223 
224  m_dataHashCheck.Release();
225  m_dataEncryptedKey.Release();
226 
227  // Generate the new derived key from the new passphrase.
228  //
229  std::unique_ptr<OTPassword> pNewDerivedKey(
230  CalculateNewDerivedKeyFromPassphrase(newPassphrase)); // asserts
231  // already.
232 
233  // Below this point, pNewDerivedKey is NOT null. (And will be cleaned up
234  // automatically.)
235 
236  //
237  // Below this point, pNewDerivedKey contains a symmetric key derived from
238  // the new salt, the iteration
239  // count, and the new password that was passed in. We will store the salt
240  // and iteration count inside this
241  // OTSymmetricKey object, and we'll store an encrypted copy of the
242  // ActualKey, encrypted to pNewDerivedKey.
243  // We'll also store the new IV, which is used while encrypting the actual
244  // key, and which must be used again
245  // while decrypting it later.
246  //
247  // Encrypt theActualKey using pNewDerivedKey, which is clear/raw already.
248  // (Both are OTPasswords.)
249  // Put the result into the OTPayload m_dataEncryptedKey.
250  //
251  const bool bEncryptedKey = OTCrypto::It()->Encrypt(
252  *pNewDerivedKey, // pNewDerivedKey is a symmetric key, in clear form.
253  // Used for encrypting theActualKey.
254  reinterpret_cast<const char*>(
255  theActualKey.getMemory_uint8()), // This is the Plaintext that's
256  // being encrypted.
257  static_cast<uint32_t>(theActualKey.getMemorySize()),
258  m_dataIV, // generated above.
259  m_dataEncryptedKey); // OUTPUT. (Ciphertext.)
260  m_bIsGenerated = bEncryptedKey;
261 
262  otInfo << " End: " << __FUNCTION__
263  << ": (Changing passphrase on symmetric key...) "
264  << (m_bIsGenerated ? "SUCCESS" : "FAILED") << "\n";
265 
266  return m_bIsGenerated;
267 }
268 
269 // Generates this OTSymmetricKey based on an OTPassword. The generated key is
270 // stored in encrypted form, based on a derived key from that password.
271 //
272 
273 // Done: Change pDerivedKey to ppDerivedKey, since you CANNOT derive a key
274 // BEFORE calling
275 // GenerateKey, since the salt and iteration count are both part of the
276 // derivation process!!
277 
278 // ppDerivedKey: CALLER RESPONSIBLE TO DELETE. (optional arg.)
279 
280 // Output. If you want, I can pass this back to you.
281 bool OTSymmetricKey::GenerateKey(const OTPassword& thePassphrase,
282  OTPassword** ppDerivedKey)
283 {
284  OT_ASSERT(m_uIterationCount > 1000);
285  OT_ASSERT(!m_bIsGenerated);
286  // OT_ASSERT(thePassphrase.isPassword());
287 
288  otInfo << " Begin: " << __FUNCTION__
289  << ": GENERATING keys and passwords...\n";
290 
291  if (!m_dataIV.Randomize(OTCryptoConfig::SymmetricIvSize())) {
292  otErr << __FUNCTION__ << ": Failed generating iv for encrypting a "
293  "symmetric key. (Returning false.)\n";
294  return false;
295  }
296 
297  if (!m_dataSalt.Randomize(OTCryptoConfig::SymmetricSaltSize())) {
298  otErr << __FUNCTION__
299  << ": Failed generating random salt. (Returning false.)\n";
300  return false;
301  }
302 
303  // Generate actual key (a randomized memory space.)
304  // We will use the derived key for encrypting the actual key.
305  //
306  OTPassword theActualKey;
307 
308  {
309  int32_t nRes =
311  if (0 > nRes) {
312  OT_FAIL;
313  }
314  uint32_t uRes =
315  static_cast<uint32_t>(nRes); // we need an uint32_t value.
316 
317  if (OTCryptoConfig::SymmetricKeySize() != uRes) {
318  otErr << __FUNCTION__
319  << ": Failed generating symmetric key. (Returning false.)\n";
320  return false;
321  }
322  }
323  // We didn't bother generating the derived key if the above three
324  // randomizations failed.
325 
326  // Generate derived key from passphrase.
327  //
328  std::unique_ptr<OTPassword> pDerivedKey(
329  CalculateNewDerivedKeyFromPassphrase(thePassphrase));
330 
331  OT_ASSERT(nullptr != pDerivedKey);
332 
333  // Below this point, pDerivedKey is NOT null. (And we only clean it up later
334  // if we created it.)
335 
336  //
337  // Below this point, pDerivedKey contains a symmetric key derived from the
338  // salt, the iteration
339  // count, and the password that was passed in. We will store the salt and
340  // iteration count inside this
341  // OTSymmetricKey object, and we'll store an encrypted copy of the
342  // ActualKey, encrypted to pDerivedKey.
343  // We'll also store the IV, which is generated while encrypting the actual
344  // key, and which must be used
345  // while decrypting it later.
346  //
347  // Encrypt theActualKey using pDerivedKey, which is clear/raw already. (Both
348  // are OTPasswords.)
349  // Put the result into the OTPayload m_dataEncryptedKey.
350  //
351  const bool bEncryptedKey = OTCrypto::It()->Encrypt(
352  *pDerivedKey, // pDerivedKey is a symmetric key, in clear form. Used for
353  // encrypting theActualKey.
354  reinterpret_cast<const char*>(
355  theActualKey.getMemory_uint8()), // This is the Plaintext that's
356  // being encrypted.
357  static_cast<uint32_t>(theActualKey.getMemorySize()),
358  m_dataIV, // generated above.
359  m_dataEncryptedKey); // OUTPUT. (Ciphertext.)
360  m_bIsGenerated = bEncryptedKey;
361 
362  otInfo << " End: " << __FUNCTION__
363  << ": (GENERATING keys and passwords...) "
364  << (m_bIsGenerated ? "SUCCESS" : "FAILED") << "\n";
365 
366  // return the pDerivedKey, if wanted.
367  if (nullptr != ppDerivedKey) {
368  *ppDerivedKey = pDerivedKey.release();
369  }
370 
371  return m_bIsGenerated;
372 }
373 
375 {
376  OT_ASSERT(m_uIterationCount > 1000);
377 
378  if (!m_bIsGenerated) {
379  otErr << __FUNCTION__ << ": No Key Generated, run GenerateKey(), and "
380  "this function will not be needed!";
381  OT_FAIL;
382  }
383 
384  if (HasHashCheck()) {
385  otErr << __FUNCTION__
386  << ": Already have a HashCheck, no need to create one!";
387  return false;
388  }
389 
390  OT_ASSERT(m_dataHashCheck.IsEmpty());
391 
392  OTPassword* pDerivedKey =
393  CalculateNewDerivedKeyFromPassphrase(thePassphrase); // asserts already.
394 
395  if (nullptr ==
396  pDerivedKey) // A pointerpointer was passed in... (caller will
397  // be responsible then, to delete.)
398  {
399  otErr << __FUNCTION__ << ": failed to calculate derived key";
400  return false;
401  }
402 
403  if (!HasHashCheck()) {
404  otErr
405  << __FUNCTION__
406  << ": Still don't have a hash check (even after generating one)\n!"
407  "this is bad. Will assert.";
408  OT_FAIL;
409  }
410 
411  return true;
412 }
413 
415 {
416  if (!HasHashCheck()) {
417  otOut << __FUNCTION__ << ": Warning! We don't have a hash-check yet... "
418  "will create one anyway.";
419  }
420 
421  if (!m_dataHashCheck.IsEmpty()) m_dataHashCheck.zeroMemory();
422  OT_ASSERT(m_dataHashCheck.IsEmpty());
423 
424  m_bHasHashCheck = false;
425 
426  return GenerateHashCheck(thePassphrase);
427 }
428 
429 /*
430  To generate a symmetric key:
431 
432  1. First we generate the plain symmetric key itself using RAND_bytes().
433  2. Then we generate the salt using RAND_bytes()
434  3. Then we use thePassword and the salt to derive a key using PBKDF2.
435  4. Then we encrypt the plain symmetric key using the derived key from
436  PBKDF2.
437  5. Then we store the salt and the encrypted symmetric key. (We discard the
438  derived key.)
439  6. (Use the plain symmetric key to encrypt the plaintext.)
440 
441  To use the symmetric key:
442 
443  1. We use thePassword from user input, and the stored salt, with PBKDF2 to
444  derive a key.
445  2. Use the derived key to decrypt the encrypted symmetric key.
446  3. (Use the decrypted symmetric key to decrypt the ciphertext.)
447  */
448 
449 // Done: add a "get Key" function which takes the OTPassword, generates the
450 // derived key using salt already on
451 // OTSymmetricKey object, then decrypts the encrypted symmetric key (using
452 // derived key) and returns clear symmetric
453 // key back as another OTPassword object.
454 
455 // Assumes key is already generated. Tries to get the raw clear key from its
456 // encrypted form, via
457 // its passphrase being used to derive a key for that purpose.
458 //
459 // If returns true, theRawKeyOutput will contain the decrypted symmetric key, in
460 // an OTPassword object.
461 // Otherwise returns false if failure.
462 //
463 
464 // The derived key is used for decrypting the actual symmetric key.
465 // It's called the derived key because it is derived from the passphrase.
466 //
467 // CALLER IS RESPONSIBLE TO DELETE.
468 //
470  const OTPassword& thePassphrase, bool bCheckForHashCheck /*= true*/) const
471 {
472  // OT_ASSERT(m_bIsGenerated);
473  // OT_ASSERT(thePassphrase.isPassword());
474  OTPassword* pDerivedKey = nullptr;
475 
476  OTPayload tmpDataHashCheck = m_dataHashCheck;
477 
478  if (bCheckForHashCheck) {
479  if (!HasHashCheck()) {
480  otErr << __FUNCTION__ << ": Unable to calculate derived key, as "
481  "hash check is missing!";
482  OT_FAIL;
483  }
484  OT_ASSERT(!tmpDataHashCheck.IsEmpty());
485  }
486  else {
487  if (!HasHashCheck()) {
488  otOut << __FUNCTION__ << ": Warning!! No hash check, ignoring... "
489  "(since bCheckForHashCheck was set false)";
490  OT_ASSERT(tmpDataHashCheck.IsEmpty());
491  }
492  }
493 
494  pDerivedKey = OTCrypto::It()->DeriveNewKey(
495  thePassphrase, m_dataSalt, m_uIterationCount, tmpDataHashCheck);
496 
497  return pDerivedKey; // can be null
498 }
499 
500 // CALLER IS RESPONSIBLE TO DELETE.
502  const OTPassword& thePassphrase)
503 {
504  // OT_ASSERT(m_bIsGenerated);
505  // OT_ASSERT(thePassphrase.isPassword());
506  OTPassword* pDerivedKey = nullptr;
507 
508  if (!HasHashCheck()) {
509  m_dataHashCheck.zeroMemory();
510 
511  pDerivedKey = OTCrypto::It()->DeriveNewKey(
512  thePassphrase, m_dataSalt, m_uIterationCount, m_dataHashCheck);
513  }
514  else {
515  otErr << __FUNCTION__
516  << ": Calling Wrong function!! Hash check already exists!";
517  }
518 
519  OT_ASSERT(nullptr != pDerivedKey);
520  OT_ASSERT(!m_dataHashCheck.IsEmpty());
521 
522  m_bHasHashCheck = true;
523 
524  return pDerivedKey;
525 }
526 
527 // Assumes key is already generated. Tries to get the raw clear key from its
528 // encrypted form, via its passphrase being used to derive a key for that
529 // purpose.
530 //
532  const OTPassword& thePassphrase, OTPassword& theRawKeyOutput,
533  OTPassword* pDerivedKey) const // Optionally pass this, to save me the step.
534 {
535  OT_ASSERT(m_bIsGenerated);
536  // OT_ASSERT(thePassphrase.isPassword());
537 
538  std::unique_ptr<OTPassword> theDerivedAngel;
539 
540  if (nullptr == pDerivedKey) {
541  // todo, security: Do we have to create all these OTPassword objects on
542  // the stack, just
543  // as a general practice? In which case I can't use this factory how I'm
544  // using it now...
545  //
546 
547  pDerivedKey = CalculateDerivedKeyFromPassphrase(
548  thePassphrase, false); // asserts already.
549 
550  theDerivedAngel.reset(pDerivedKey);
551  }
552  // Below this point, pDerivedKey is NOT null. And we only clean it up if we
553  // created it.
554 
555  //
556  // Below this point, pDerivedKey contains a derived symmetric key, from the
557  // salt, the iteration
558  // count, and the password that was passed in. The salt and iteration count
559  // were both stored inside this
560  // OTSymmetricKey object since this key was originally generated, and we
561  // store an encrypted copy of the
562  // ActualKey already, as well-- it's encrypted to the Derived Key. (We also
563  // store the IV from that
564  // encryption bit.)
565  //
566  return GetRawKeyFromDerivedKey(*pDerivedKey, theRawKeyOutput);
567 }
568 
569 // Assumes key is already generated. Tries to get the raw clear key from its
570 // encrypted form, via a derived key.
571 //
572 // If returns true, theRawKeyOutput will contain the decrypted symmetric key, in
573 // an OTPassword object.
574 // Otherwise returns false if failure.
575 //
577  OTPassword& theRawKeyOutput) const
578 {
579  OT_ASSERT(m_bIsGenerated);
580  OT_ASSERT(theDerivedKey.isMemory());
581 
582  const char* szFunc = "OTSymmetricKey::GetRawKeyFromDerivedKey";
583 
584  // Decrypt theActualKey using theDerivedKey, which is clear/raw already.
585  // (Both are OTPasswords.)
586  // Put the result into theRawKeyOutput.
587  //
588  // theDerivedKey is a symmetric key, in clear form. Used here
589  // for decrypting m_dataEncryptedKey into theRawKeyOutput.
590  //
591  otInfo
592  << szFunc
593  << ": *Begin) Attempting to recover actual key using derived key...\n";
594 
595  const bool bDecryptedKey = OTCrypto::It()->Decrypt(
596  theDerivedKey, // We're using theDerivedKey to decrypt
597  // m_dataEncryptedKey.
598 
599  // Here's what we're trying to decrypt: the encrypted
600  // form of the symmetric key.
601  //
602  static_cast<const char*>(
603  m_dataEncryptedKey.GetPayloadPointer()), // The Ciphertext.
604  m_dataEncryptedKey.GetSize(),
605  m_dataIV, // Created when *this symmetric key was generated. Both are
606  // already stored.
607  theRawKeyOutput); // OUTPUT. (Recovered plaintext of symmetric key.) You
608  // can pass OTPassword& OR OTPayload& here (either
609  // will work.)
610 
611  otInfo << szFunc
612  << ": (End) attempt to recover actual key using derived key...\n";
613  return bDecryptedKey;
614 }
615 
616 // The highest-level possible interface (used by the API)
617 //
618 // static NOTE: this version circumvents the master key.
620  bool bAskTwice) // returns a
621  // text
622  // OTPassword,
623  // or nullptr.
624 {
625  // Caller MUST delete!
626 
627  OTPassword* pPassUserInput =
628  OTPassword::CreateTextBuffer(); // already asserts.
629  // pPassUserInput->zeroMemory(); // This was causing the password to come
630  // out blank.
631  //
632  // Below this point, pPassUserInput must be returned, or deleted. (Or it
633  // will leak.)
634 
635  const char* szDisplay = "OTSymmetricKey::GetPassphraseFromUser";
636  OTPasswordData thePWData((nullptr == pstrDisplay) ? szDisplay
637  : pstrDisplay->Get());
638  thePWData.setUsingOldSystem(); // So the cached key doesn't interfere, since
639  // this is for a plain symmetric key.
640 
641  const int32_t nCallback =
643  pPassUserInput->getBlockSize(), bAskTwice ? 1 : 0,
644  static_cast<void*>(&thePWData));
645  const uint32_t uCallback = static_cast<uint32_t>(nCallback);
646  if ((nCallback > 0) && // Success retrieving the passphrase from the user.
647  pPassUserInput->SetSize(uCallback)) {
648  // otOut << "%s: Retrieved passphrase (blocksize %d, actual size
649  // %d) from user: %s\n", __FUNCTION__,
650  // pPassUserInput->getBlockSize(), nCallback,
651  // pPassUserInput->getPassword());
652  return pPassUserInput; // Caller MUST delete!
653  }
654  else {
655  delete pPassUserInput;
656  pPassUserInput = nullptr;
657  otOut
658  << __FUNCTION__
659  << ": Sorry, unable to retrieve passphrase from user. (Failure.)\n";
660  }
661 
662  return nullptr;
663 }
664 
665 // static
667  const OTString* pstrDisplay,
668  const OTPassword* pAlreadyHavePW)
669 {
670  std::unique_ptr<OTPassword> pPassUserInput;
671 
672  if (nullptr == pAlreadyHavePW) {
673  const char* szDisplay = "Creating new symmetric key.";
674  const OTString strDisplay(
675  (nullptr == pstrDisplay) ? szDisplay : pstrDisplay->Get());
676 
677  pPassUserInput.reset(OTSymmetricKey::GetPassphraseFromUser(
678  &strDisplay, true)); // bAskTwice=false by default.
679  }
680  else
681  pPassUserInput.reset(const_cast<OTPassword*>(pAlreadyHavePW));
682 
683  bool bSuccess = false;
684 
685  if (nullptr != pPassUserInput) // Success retrieving the passphrase from the
686  // user. (Now let's generate the key...)
687  {
688  otLog3 << __FUNCTION__
689  << ": Calling OTSymmetricKey theKey.GenerateKey()...\n";
690  OTSymmetricKey theKey(*pPassUserInput);
691  const bool bGenerated = theKey.IsGenerated();
692  // otOut << "%s: Finished calling OTSymmetricKey
693  // theKey.GenerateKey()...\n", __FUNCTION__);
694 
695  if (bGenerated && theKey.SerializeTo(strOutput))
696  bSuccess = true;
697  else
698  otWarn << __FUNCTION__
699  << ": Sorry, unable to generate key. (Failure.)\n";
700  }
701  else
702  otWarn
703  << __FUNCTION__
704  << ": Sorry, unable to retrieve password from user. (Failure.)\n";
705 
706  return bSuccess;
707 }
708 
709 // static
711  const OTString& strPlaintext, OTString& strOutput,
712  const OTString* pstrDisplay, bool bBookends,
713  const OTPassword* pAlreadyHavePW)
714 {
715  if (!strKey.Exists() || !strPlaintext.Exists()) {
716  otWarn << __FUNCTION__ << ": Nonexistent: either the key or the "
717  "plaintext. Please supply. (Failure.)\n";
718  return false;
719  }
720 
721  OTSymmetricKey theKey;
722 
723  if (!theKey.SerializeFrom(strKey)) {
724  otWarn << __FUNCTION__ << ": Failed trying to load symmetric key from "
725  "string. (Returning false.)\n";
726  return false;
727  }
728 
729  // By this point, we know we have a plaintext and a symmetric Key.
730  //
731  return OTSymmetricKey::Encrypt(theKey, strPlaintext, strOutput, pstrDisplay,
732  bBookends, pAlreadyHavePW);
733 }
734 
735 // static
737  const OTString& strPlaintext, OTString& strOutput,
738  const OTString* pstrDisplay, bool bBookends,
739  const OTPassword* pAlreadyHavePW)
740 {
741  if (!theKey.IsGenerated()) {
742  otWarn << __FUNCTION__
743  << ": Failure: theKey.IsGenerated() was false. (The calling "
744  "code probably should have checked that key already...)\n";
745  return false;
746  }
747 
748  if (!strPlaintext.Exists()) {
749  otWarn << __FUNCTION__
750  << ": Plaintext is empty. Please supply. (Failure.)\n";
751  return false;
752  }
753 
754  // By this point, we know we have a plaintext and a symmetric Key.
755  //
756  std::unique_ptr<OTPassword> pPassUserInput;
757 
758  if (nullptr == pAlreadyHavePW) {
759  const char* szDisplay = "Password-protecting a plaintext.";
760  const OTString strDisplay(
761  (nullptr == pstrDisplay) ? szDisplay : pstrDisplay->Get());
762 
763  pPassUserInput.reset(OTSymmetricKey::GetPassphraseFromUser(
764  &strDisplay)); // bAskTwice=false by default.
765  }
766  else
767  pPassUserInput.reset(const_cast<OTPassword*>(pAlreadyHavePW));
768 
769  OTASCIIArmor ascOutput;
770  bool bSuccess = false;
771 
772  if (nullptr != pPassUserInput) // Success retrieving the passphrase from the
773  // user. (Now let's encrypt...)
774  {
775  OTEnvelope theEnvelope;
776 
777  if (theEnvelope.Encrypt(strPlaintext,
778  const_cast<OTSymmetricKey&>(theKey),
779  *pPassUserInput) &&
780  theEnvelope.GetAsciiArmoredData(ascOutput)) {
781  bSuccess = true;
782 
783  if (bBookends) {
784  return ascOutput.WriteArmoredString(
785  strOutput, "SYMMETRIC MSG", // todo hardcoding.
786  false); // bEscaped=false
787  }
788  else {
789  strOutput.Set(ascOutput.Get());
790  }
791  }
792  else {
793  otWarn << __FUNCTION__ << ": Failed trying to encrypt. (Sorry.)\n";
794  }
795  }
796  else
797  otWarn
798  << __FUNCTION__
799  << ": Sorry, unable to retrieve passphrase from user. (Failure.)\n";
800 
801  return bSuccess;
802 }
803 
804 // static
805 bool OTSymmetricKey::Decrypt(const OTString& strKey, OTString& strCiphertext,
806  OTString& strOutput, const OTString* pstrDisplay,
807  const OTPassword* pAlreadyHavePW)
808 {
809 
810  if (!strKey.Exists()) {
811  otWarn
812  << __FUNCTION__
813  << ": Nonexistent: The symmetric key. Please supply. (Failure.)\n";
814  return false;
815  }
816 
817  OTSymmetricKey theKey;
818 
819  if (!theKey.SerializeFrom(strKey)) {
820  otWarn << __FUNCTION__ << ": Failed trying to load symmetric key from "
821  "string. (Returning false.)\n";
822  return false;
823  }
824 
825  // By this point, we know we have a ciphertext envelope and a symmetric Key.
826  //
827  return OTSymmetricKey::Decrypt(theKey, strCiphertext, strOutput,
828  pstrDisplay, pAlreadyHavePW);
829 }
830 
831 // static
833  const OTString& strCiphertext, OTString& strOutput,
834  const OTString* pstrDisplay,
835  const OTPassword* pAlreadyHavePW)
836 {
837  if (!theKey.IsGenerated()) {
838  otWarn << __FUNCTION__
839  << ": Failure: theKey.IsGenerated() was false. (The calling "
840  "code probably should have checked for that...)\n";
841  return false;
842  }
843 
844  OTASCIIArmor ascArmor;
845  const bool bLoadedArmor = OTASCIIArmor::LoadFromString(
846  ascArmor, strCiphertext); // str_bookend="-----BEGIN" by default
847 
848  if (!bLoadedArmor || !ascArmor.Exists()) {
849  otErr << __FUNCTION__ << ": Failure loading ciphertext envelope:\n\n"
850  << strCiphertext << "\n\n";
851  return false;
852  }
853 
854  // By this point, we know we have a ciphertext envelope and a symmetric Key.
855  //
856  std::unique_ptr<OTPassword> pPassUserInput;
857 
858  if (nullptr == pAlreadyHavePW) {
859  const char* szDisplay = "Decrypting a password-protected ciphertext.";
860  const OTString strDisplay(
861  (nullptr == pstrDisplay) ? szDisplay : pstrDisplay->Get());
862 
863  pPassUserInput.reset(OTSymmetricKey::GetPassphraseFromUser(
864  &strDisplay)); // bAskTwice=false by default.
865  }
866 
867  bool bSuccess = false;
868 
869  if (pPassUserInput || // Success retrieving the passphrase from the
870  pAlreadyHavePW) // user, or passphrase was provided out of scope.
871  {
872  OTEnvelope theEnvelope(ascArmor);
873 
874  if (theEnvelope.Decrypt(strOutput, theKey, pPassUserInput
875  ? *pPassUserInput
876  : *pAlreadyHavePW)) {
877  bSuccess = true;
878  }
879  else {
880  otWarn << __FUNCTION__ << ": Failed trying to decrypt. (Sorry.)\n";
881  }
882  }
883  else
884  otWarn
885  << __FUNCTION__
886  << ": Sorry, unable to retrieve passphrase from user. (Failure.)\n";
887 
888  return bSuccess;
889 }
890 
891 bool OTSymmetricKey::SerializeTo(OTString& strOutput, bool bEscaped) const
892 {
893  OTASCIIArmor ascOutput;
894 
895  if (SerializeTo(ascOutput))
896  return ascOutput.WriteArmoredString(strOutput, "SYMMETRIC KEY",
897  bEscaped);
898 
899  return false;
900 }
901 
902 bool OTSymmetricKey::SerializeFrom(const OTString& strInput, bool bEscaped)
903 {
904  OTASCIIArmor ascInput;
905 
906  if (strInput.Exists() &&
907  ascInput.LoadFromString(const_cast<OTString&>(strInput), bEscaped,
908  "-----BEGIN OT ARMORED SYMMETRIC KEY")) {
909  return SerializeFrom(ascInput);
910  }
911 
912  return false;
913 }
914 
916 {
917  OTPayload theOutput;
918 
919  if (SerializeTo(theOutput)) {
920  ascOutput.SetData(theOutput);
921  return true;
922  }
923 
924  return false;
925 }
926 
928 {
929  OTPayload theInput;
930 
931  if (ascInput.Exists() && ascInput.GetData(theInput)) {
932  return SerializeFrom(theInput);
933  }
934  return false;
935 }
936 
938 {
939 
940  uint16_t from_bool_is_generated = (m_bIsGenerated ? 1 : 0);
941  uint16_t n_is_generated = static_cast<uint16_t>(
942  htons(static_cast<uint16_t>(from_bool_is_generated)));
943  uint16_t n_key_size_bits =
944  static_cast<uint16_t>(htons(static_cast<uint16_t>(m_nKeySize)));
945 
946  uint32_t n_iteration_count =
947  static_cast<uint32_t>(htonl(static_cast<uint32_t>(m_uIterationCount)));
948 
949  uint32_t n_salt_size = static_cast<uint32_t>(
950  htonl(static_cast<uint32_t>(m_dataSalt.GetSize())));
951  uint32_t n_iv_size =
952  static_cast<uint32_t>(htonl(static_cast<uint32_t>(m_dataIV.GetSize())));
953  uint32_t n_enc_key_size = static_cast<uint32_t>(
954  htonl(static_cast<uint32_t>(m_dataEncryptedKey.GetSize())));
955 
956  uint32_t n_hash_check_size = static_cast<uint32_t>(
957  htonl(static_cast<uint32_t>(m_dataHashCheck.GetSize())));
958 
959  otLog5 << __FUNCTION__
960  << ": is_generated: " << static_cast<int32_t>(ntohs(n_is_generated))
961  << " key_size_bits: "
962  << static_cast<int32_t>(ntohs(n_key_size_bits))
963  << " iteration_count: "
964  << static_cast<int64_t>(ntohl(n_iteration_count))
965  << " \n "
966  "salt_size: " << static_cast<int64_t>(ntohl(n_salt_size))
967  << " iv_size: " << static_cast<int64_t>(ntohl(n_iv_size))
968  << " enc_key_size: " << static_cast<int64_t>(ntohl(n_enc_key_size))
969  << " \n";
970 
971  theOutput.Concatenate(reinterpret_cast<void*>(&n_is_generated),
972  static_cast<uint32_t>(sizeof(n_is_generated)));
973 
974  theOutput.Concatenate(reinterpret_cast<void*>(&n_key_size_bits),
975  static_cast<uint32_t>(sizeof(n_key_size_bits)));
976 
977  theOutput.Concatenate(reinterpret_cast<void*>(&n_iteration_count),
978  static_cast<uint32_t>(sizeof(n_iteration_count)));
979 
980  theOutput.Concatenate(reinterpret_cast<void*>(&n_salt_size),
981  static_cast<uint32_t>(sizeof(n_salt_size)));
982 
983  OT_ASSERT(nullptr != m_dataSalt.GetPayloadPointer());
984  theOutput.Concatenate(m_dataSalt.GetPayloadPointer(), m_dataSalt.GetSize());
985 
986  theOutput.Concatenate(reinterpret_cast<void*>(&n_iv_size),
987  static_cast<uint32_t>(sizeof(n_iv_size)));
988 
989  OT_ASSERT(nullptr != m_dataIV.GetPayloadPointer());
990  theOutput.Concatenate(m_dataIV.GetPayloadPointer(), m_dataIV.GetSize());
991 
992  theOutput.Concatenate(reinterpret_cast<void*>(&n_enc_key_size),
993  static_cast<uint32_t>(sizeof(n_enc_key_size)));
994 
995  OT_ASSERT(nullptr != m_dataEncryptedKey.GetPayloadPointer());
996  theOutput.Concatenate(m_dataEncryptedKey.GetPayloadPointer(),
997  m_dataEncryptedKey.GetSize());
998 
999  theOutput.Concatenate(reinterpret_cast<void*>(&n_hash_check_size),
1000  static_cast<uint32_t>(sizeof(n_hash_check_size)));
1001 
1002  OT_ASSERT(nullptr != m_dataHashCheck.GetPayloadPointer());
1003  theOutput.Concatenate(m_dataHashCheck.GetPayloadPointer(),
1004  m_dataHashCheck.GetSize());
1005 
1006  return true;
1007 }
1008 
1009 // Notice I don't theInput.reset(), because what if this
1010 // key was being read from a larger file containing several
1011 // keys? I should just continue reading from the current
1012 // position, and let the CALLER reset first, if that's his
1013 // intention.
1014 //
1016 {
1017  const char* szFunc = "OTSymmetricKey::SerializeFrom";
1018 
1019  uint32_t nRead = 0;
1020 
1021  // Read network-order "is generated" flag. (convert to host order)
1022  //
1023  uint16_t n_is_generated = 0;
1024 
1025  if (0 == (nRead = theInput.OTfread(
1026  reinterpret_cast<uint8_t*>(&n_is_generated),
1027  static_cast<uint32_t>(sizeof(n_is_generated))))) {
1028  otErr << szFunc << ": Error reading n_is_generated.\n";
1029  return false;
1030  }
1031 
1032  // convert from network to HOST endian.
1033  //
1034  uint16_t host_is_generated =
1035  static_cast<uint16_t>(ntohs(static_cast<uint16_t>(n_is_generated)));
1036 
1037  if (1 == host_is_generated)
1038  m_bIsGenerated = true;
1039  else if (0 == host_is_generated)
1040  m_bIsGenerated = false;
1041  else {
1042  otErr << szFunc << ": Error: host_is_generated, Bad value: "
1043  << static_cast<int32_t>(host_is_generated)
1044  << ". (Expected 0 or 1.)\n";
1045  return false;
1046  }
1047 
1048  otLog5 << __FUNCTION__
1049  << ": is_generated: " << static_cast<int32_t>(host_is_generated)
1050  << " \n";
1051 
1052  // Read network-order "key size in bits". (convert to host order)
1053  //
1054  uint16_t n_key_size_bits = 0;
1055 
1056  if (0 == (nRead = theInput.OTfread(
1057  reinterpret_cast<uint8_t*>(&n_key_size_bits),
1058  static_cast<uint32_t>(sizeof(n_key_size_bits))))) {
1059  otErr << szFunc << ": Error reading n_key_size_bits.\n";
1060  return false;
1061  }
1062 
1063  // convert from network to HOST endian.
1064 
1065  m_nKeySize = static_cast<uint16_t>(ntohs(n_key_size_bits));
1066 
1067  otLog5 << __FUNCTION__
1068  << ": key_size_bits: " << static_cast<int32_t>(m_nKeySize) << " \n";
1069 
1070  // Read network-order "iteration count". (convert to host order)
1071  //
1072  uint32_t n_iteration_count = 0;
1073 
1074  if (0 == (nRead = theInput.OTfread(
1075  reinterpret_cast<uint8_t*>(&n_iteration_count),
1076  static_cast<uint32_t>(sizeof(n_iteration_count))))) {
1077  otErr << szFunc << ": Error reading n_iteration_count.\n";
1078  return false;
1079  }
1080  OT_ASSERT(nRead == static_cast<uint32_t>(sizeof(n_iteration_count)));
1081 
1082  // convert from network to HOST endian.
1083 
1084  m_uIterationCount = static_cast<uint32_t>(ntohl(n_iteration_count));
1085 
1086  otLog5 << __FUNCTION__
1087  << ": iteration_count: " << static_cast<int64_t>(m_uIterationCount)
1088  << " \n";
1089 
1090  // Read network-order "salt size". (convert to host order)
1091  //
1092  uint32_t n_salt_size = 0;
1093 
1094  if (0 == (nRead = theInput.OTfread(
1095  reinterpret_cast<uint8_t*>(&n_salt_size),
1096  static_cast<uint32_t>(sizeof(n_salt_size))))) {
1097  otErr << szFunc << ": Error reading n_salt_size.\n";
1098  return false;
1099  }
1100  OT_ASSERT(nRead == static_cast<uint32_t>(sizeof(n_salt_size)));
1101 
1102  // convert from network to HOST endian.
1103 
1104  const uint32_t lSaltSize =
1105  static_cast<uint32_t>(ntohl(static_cast<uint32_t>(n_salt_size)));
1106 
1107  otLog5 << __FUNCTION__
1108  << ": salt_size value: " << static_cast<int64_t>(lSaltSize) << " \n";
1109 
1110  // Then read the Salt itself.
1111  //
1112  m_dataSalt.SetPayloadSize(lSaltSize);
1113 
1114  if (0 == (nRead = theInput.OTfread(static_cast<uint8_t*>(const_cast<void*>(
1115  m_dataSalt.GetPayloadPointer())),
1116  static_cast<uint32_t>(lSaltSize)))) {
1117  otErr << szFunc << ": Error reading salt for symmetric key.\n";
1118  return false;
1119  }
1120  otLog5 << __FUNCTION__
1121  << ": salt length actually read: " << static_cast<int64_t>(nRead)
1122  << " \n";
1123  OT_ASSERT(nRead == static_cast<uint32_t>(lSaltSize));
1124 
1125  // Read network-order "IV size". (convert to host order)
1126  //
1127  uint32_t n_iv_size = 0;
1128 
1129  if (0 ==
1130  (nRead = theInput.OTfread(reinterpret_cast<uint8_t*>(&n_iv_size),
1131  static_cast<uint32_t>(sizeof(n_iv_size))))) {
1132  otErr << szFunc << ": Error reading n_iv_size.\n";
1133  return false;
1134  }
1135 
1136  OT_ASSERT(nRead == static_cast<uint32_t>(sizeof(n_iv_size)));
1137 
1138  // convert from network to HOST endian.
1139 
1140  const uint32_t lIVSize = ntohl(n_iv_size);
1141 
1142  otLog5 << __FUNCTION__
1143  << ": iv_size value: " << static_cast<int64_t>(lIVSize) << " \n";
1144 
1145  // Then read the IV itself.
1146  //
1147  m_dataIV.SetPayloadSize(lIVSize);
1148 
1149  if (0 == (nRead = theInput.OTfread(static_cast<uint8_t*>(const_cast<void*>(
1150  m_dataIV.GetPayloadPointer())),
1151  static_cast<uint32_t>(lIVSize)))) {
1152  otErr << szFunc << ": Error reading IV for symmetric key.\n";
1153  return false;
1154  }
1155 
1156  otLog5 << __FUNCTION__
1157  << ": iv length actually read: " << static_cast<int64_t>(nRead)
1158  << " \n";
1159 
1160  OT_ASSERT(nRead == static_cast<uint32_t>(lIVSize));
1161 
1162  // Read network-order "encrypted key size". (convert to host order)
1163  //
1164  uint32_t n_enc_key_size = 0;
1165 
1166  if (0 == (nRead = theInput.OTfread(
1167  reinterpret_cast<uint8_t*>(&n_enc_key_size),
1168  static_cast<uint32_t>(sizeof(n_enc_key_size))))) {
1169  otErr << szFunc << ": Error reading n_enc_key_size.\n";
1170  return false;
1171  }
1172  OT_ASSERT(nRead == static_cast<uint32_t>(sizeof(n_enc_key_size)));
1173 
1174  // convert from network to HOST endian.
1175 
1176  const uint32_t lEncKeySize = ntohl(n_enc_key_size);
1177 
1178  otLog5 << __FUNCTION__
1179  << ": enc_key_size value: " << static_cast<int64_t>(lEncKeySize)
1180  << " \n";
1181 
1182  // Then read the Encrypted Key itself.
1183  //
1184  m_dataEncryptedKey.SetPayloadSize(lEncKeySize);
1185 
1186  if (0 ==
1187  (nRead = theInput.OTfread(static_cast<uint8_t*>(const_cast<void*>(
1188  m_dataEncryptedKey.GetPayloadPointer())),
1189  static_cast<uint32_t>(lEncKeySize)))) {
1190  otErr << szFunc << ": Error reading encrypted symmetric key.\n";
1191  return false;
1192  }
1193 
1194  otLog5 << __FUNCTION__ << ": encrypted key length actually read: "
1195  << static_cast<int64_t>(nRead) << " \n";
1196 
1197  OT_ASSERT(nRead == static_cast<uint32_t>(lEncKeySize));
1198 
1199  // Read network-order "hash check size". (convert to host order)
1200  //
1201  uint32_t n_hash_check_size = 0;
1202 
1203  if (0 == (nRead = theInput.OTfread(
1204  reinterpret_cast<uint8_t*>(&n_hash_check_size),
1205  static_cast<uint32_t>(sizeof(n_hash_check_size))))) {
1206  otErr << szFunc << ": Error reading n_hash_check_size.\n";
1207  otErr
1208  << szFunc
1209  << ": Looks like we don't have a hash check yet! (will make one)\n";
1210  m_bHasHashCheck = false;
1211  return false;
1212  }
1213  OT_ASSERT(nRead == static_cast<uint32_t>(sizeof(n_hash_check_size)));
1214 
1215  // convert from network to HOST endian.
1216 
1217  const uint32_t lHashCheckSize = ntohl(n_hash_check_size);
1218 
1219  otLog5 << __FUNCTION__ << ": hash_check_size value: "
1220  << static_cast<int64_t>(lHashCheckSize) << " \n";
1221 
1222  // Then read the Hashcheck itself.
1223  //
1224  m_dataHashCheck.SetPayloadSize(lHashCheckSize);
1225 
1226  if (0 ==
1227  (nRead = theInput.OTfread(static_cast<uint8_t*>(const_cast<void*>(
1228  m_dataHashCheck.GetPayloadPointer())),
1229  static_cast<uint32_t>(lHashCheckSize)))) {
1230  otErr << szFunc << ": Error reading hash check data.\n";
1231  return false;
1232  }
1233 
1234  otLog5 << __FUNCTION__
1235  << ": hash check data actually read: " << static_cast<int64_t>(nRead)
1236  << " \n";
1237 
1238  OT_ASSERT(nRead == static_cast<uint32_t>(lHashCheckSize));
1239 
1240  m_bHasHashCheck = !m_dataHashCheck.IsEmpty();
1241 
1242  return true;
1243 }
1244 
1246  : m_bIsGenerated(false)
1247  , m_bHasHashCheck(false)
1248  , m_nKeySize(OTCryptoConfig::SymmetricKeySize() * 8)
1249  , // 128 (in bits)
1250  m_uIterationCount(OTCryptoConfig::IterationCount())
1251 {
1252 }
1253 
1255  : m_bIsGenerated(false)
1256  , m_bHasHashCheck(false)
1257  , m_nKeySize(OTCryptoConfig::SymmetricKeySize() * 8)
1258  , // 128 (in bits)
1259  m_uIterationCount(OTCryptoConfig::IterationCount())
1260 {
1261  // const bool bGenerated =
1262  GenerateKey(thePassword);
1263 }
1264 
1266 {
1268 }
1269 
1271 {
1272  m_bIsGenerated = false;
1273  m_uIterationCount = OTCryptoConfig::IterationCount();
1274  m_nKeySize = OTCryptoConfig::SymmetricKeySize() * 8; // 128 (in bits)
1275 
1276  m_dataSalt.Release();
1277  m_dataIV.Release();
1278  m_dataEncryptedKey.Release();
1279 }
1280 
1282 {
1284 
1285  // no call to ot_super::Release() here, since this is a base class
1286  // (currently with no children...)
1287 }
1288 
1289 } // namespace opentxs
EXPORT const uint8_t * getMemory_uint8() const
Definition: OTPassword.cpp:582
static EXPORT OTCrypto * It()
Definition: OTCrypto.cpp:630
EXPORT OTPassword * CalculateNewDerivedKeyFromPassphrase(const OTPassword &thePassphrase)
static EXPORT uint32_t SymmetricIvSize()
Definition: OTCrypto.cpp:391
EXPORT bool CalculateDigest(const OTData &dataInput)
virtual bool Encrypt(const OTPassword &theRawSymmetricKey, const char *szInput, uint32_t lInputLength, const OTPayload &theIV, OTPayload &theEncryptedOutput) const =0
EXPORT uint32_t getMemorySize() const
Definition: OTPassword.cpp:619
static EXPORT uint32_t IterationCount()
Definition: OTCrypto.cpp:375
EXPORT OT_OPENSSL_CALLBACK souped_up_pass_cb
EXPORT bool SerializeFrom(OTPayload &theInput)
EXPORT bool Decrypt(OTString &theOutput, const OTSymmetricKey &theKey, const OTPassword &thePassword)
Definition: OTEnvelope.cpp:364
OTLOG_IMPORT OTLogStream otOut
EXPORT bool ReGenerateHashCheck(const OTPassword &thePassphrase)
OTLOG_IMPORT OTLogStream otLog3
EXPORT char * getPasswordWritable_char()
Definition: OTPassword.cpp:568
static EXPORT uint32_t SymmetricSaltSize()
Definition: OTCrypto.cpp:379
EXPORT bool WriteArmoredString(OTString &strOutput, const std::string str_type, bool bEscaped=false) const
EXPORT bool Encrypt(const OTString &theInput, OTSymmetricKey &theKey, const OTPassword &thePassword)
Definition: OTEnvelope.cpp:245
EXPORT bool GetRawKeyFromPassphrase(const OTPassword &thePassphrase, OTPassword &theRawKeyOutput, OTPassword *pDerivedKey=nullptr) const
EXPORT bool Exists() const
Definition: OTString.cpp:1035
static EXPORT bool LoadFromString(OTASCIIArmor &ascArmor, const OTString &strInput, std::string str_bookend="-----BEGIN")
EXPORT int32_t randomizeMemory(uint32_t size=DEFAULT_SIZE)
Definition: OTPassword.cpp:890
static EXPORT bool Decrypt(const OTString &strKey, OTString &strCiphertext, OTString &strOutput, const OTString *pstrDisplay=nullptr, const OTPassword *pAlreadyHavePW=nullptr)
static EXPORT OTPassword * GetPassphraseFromUser(const OTString *pstrDisplay=nullptr, bool bAskTwice=false)
EXPORT bool SetSize(uint32_t size)
Definition: OTPassword.cpp:758
static EXPORT OTPassword * CreateTextBuffer()
Definition: OTPassword.cpp:429
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
Definition: OTString.cpp:1055
EXPORT bool GetRawKeyFromDerivedKey(const OTPassword &theDerivedKey, OTPassword &theRawKeyOutput) const
static EXPORT bool Encrypt(const OTString &strKey, const OTString &strPlaintext, OTString &strOutput, const OTString *pstrDisplay=nullptr, bool bBookends=true, const OTPassword *pAlreadyHavePW=nullptr)
EXPORT void Release_SymmetricKey()
EXPORT bool GetAsciiArmoredData(OTASCIIArmor &theArmoredText, bool bLineBreaks=true) const
Definition: OTEnvelope.cpp:162
EXPORT bool GenerateKey(const OTPassword &thePassphrase, OTPassword **ppDerivedKey=nullptr)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
EXPORT bool SerializeTo(OTPayload &theOutput) const
EXPORT void SetPayloadSize(uint32_t lNewSize)
Definition: OTPayload.cpp:313
OTLOG_IMPORT OTLogStream otInfo
EXPORT void setUsingOldSystem(bool bUsing=true)
EXPORT OTPassword * CalculateDerivedKeyFromPassphrase(const OTPassword &thePassphrase, bool bCheckForHashCheck=true) const
EXPORT bool GetData(OTData &theData, bool bLineBreaks=true) const
#define OT_FAIL
Definition: Assert.hpp:139
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
Definition: OTString.cpp:1045
EXPORT const void * GetPayloadPointer() const
Definition: OTPayload.cpp:318
OTLOG_IMPORT OTLogStream otErr
virtual EXPORT void Release()
EXPORT bool isMemory() const
Definition: OTPassword.cpp:542
EXPORT bool GenerateHashCheck(const OTPassword &thePassphrase)
virtual bool Decrypt(const OTPassword &theRawSymmetricKey, const char *szInput, uint32_t lInputLength, const OTPayload &theIV, OTCrypto_Decrypt_Output theDecryptedOutput) const =0
EXPORT bool ChangePassphrase(const OTPassword &oldPassphrase, const OTPassword &newPassphrase)
EXPORT uint32_t getBlockSize() const
Definition: OTPassword.cpp:595
EXPORT void GetString(OTString &theStr) const
EXPORT uint32_t OTfread(uint8_t *data, uint32_t size)
Definition: OTData.cpp:214
EXPORT bool SetData(const OTData &theData, bool bLineBreaks=true)
EXPORT bool IsEmpty() const
Definition: OTData.cpp:291
virtual EXPORT void Release()
Definition: OTData.cpp:257
EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
virtual OTPassword * DeriveNewKey(const OTPassword &userPassword, const OTPayload &dataSalt, uint32_t uIterations, OTPayload &dataCheckHash) const =0
EXPORT bool Randomize(uint32_t size)
Definition: OTData.cpp:310
static EXPORT bool CreateNewKey(OTString &strOutput, const OTString *pstrDisplay=nullptr, const OTPassword *pAlreadyHavePW=nullptr)
EXPORT void Concatenate(const void *data, uint32_t size)
Definition: OTData.cpp:333
static EXPORT uint32_t SymmetricKeySize()
Definition: OTCrypto.cpp:383
uint32_t GetSize() const
Definition: OTData.hpp:174
virtual EXPORT ~OTSymmetricKey()
EXPORT void zeroMemory() const
Definition: OTData.cpp:238
OTLOG_IMPORT OTLogStream otLog5