Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTKeyCredential.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTKeyCredential.cpp
4  *
5  */
6 
7 // A nym contains a list of credentials
8 //
9 // Each credential contains a "master" subkey, and a list of subkeys
10 // signed by that master.
11 //
12 // The same class (subkey) is used because there are master credentials
13 // and subkey credentials, so we're using a single "subkey" class to
14 // encapsulate each credential, both for the master credential and
15 // for each subkey credential.
16 //
17 // Each subkey has 3 key pairs: encryption, signing, and authentication.
18 //
19 // Each key pair has 2 OTAsymmetricKeys (public and private.)
20 
21 /************************************************************
22  -----BEGIN PGP SIGNED MESSAGE-----
23  Hash: SHA1
24 
25  * OPEN TRANSACTIONS
26  *
27  * Financial Cryptography and Digital Cash
28  * Library, Protocol, API, Server, CLI, GUI
29  *
30  * -- Anonymous Numbered Accounts.
31  * -- Untraceable Digital Cash.
32  * -- Triple-Signed Receipts.
33  * -- Cheques, Vouchers, Transfers, Inboxes.
34  * -- Basket Currencies, Markets, Payment Plans.
35  * -- Signed, XML, Ricardian-style Contracts.
36  * -- Scripted smart contracts.
37  *
38  * Copyright (C) 2010-2013 by "Fellow Traveler" (A pseudonym)
39  *
40  * EMAIL:
42  *
43  * BITCOIN: 1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
44  *
45  * KEY FINGERPRINT (PGP Key in license file):
46  * 9DD5 90EB 9292 4B48 0484 7910 0308 00ED F951 BB8E
47  *
48  * OFFICIAL PROJECT WIKI(s):
49  * https://github.com/FellowTraveler/Moneychanger
50  * https://github.com/FellowTraveler/Open-Transactions/wiki
51  *
52  * WEBSITE:
53  * http://www.OpenTransactions.org/
54  *
55  * Components and licensing:
56  * -- Moneychanger..A Java client GUI.....LICENSE:.....GPLv3
57  * -- otlib.........A class library.......LICENSE:...LAGPLv3
58  * -- otapi.........A client API..........LICENSE:...LAGPLv3
59  * -- opentxs/ot....Command-line client...LICENSE:...LAGPLv3
60  * -- otserver......Server Application....LICENSE:....AGPLv3
61  * Github.com/FellowTraveler/Open-Transactions/wiki/Components
62  *
63  * All of the above OT components were designed and written by
64  * Fellow Traveler, with the exception of Moneychanger, which
65  * was contracted out to Vicky C ([email protected]).
66  * The open-source community has since actively contributed.
67  *
68  * -----------------------------------------------------
69  *
70  * LICENSE:
71  * This program is free software: you can redistribute it
72  * and/or modify it under the terms of the GNU Affero
73  * General Public License as published by the Free Software
74  * Foundation, either version 3 of the License, or (at your
75  * option) any later version.
76  *
77  * ADDITIONAL PERMISSION under the GNU Affero GPL version 3
78  * section 7: (This paragraph applies only to the LAGPLv3
79  * components listed above.) If you modify this Program, or
80  * any covered work, by linking or combining it with other
81  * code, such other code is not for that reason alone subject
82  * to any of the requirements of the GNU Affero GPL version 3.
83  * (==> This means if you are only using the OT API, then you
84  * don't have to open-source your code--only your changes to
85  * Open-Transactions itself must be open source. Similar to
86  * LGPLv3, except it applies to software-as-a-service, not
87  * just to distributing binaries.)
88  *
89  * Extra WAIVER for OpenSSL, Lucre, and all other libraries
90  * used by Open Transactions: This program is released under
91  * the AGPL with the additional exemption that compiling,
92  * linking, and/or using OpenSSL is allowed. The same is true
93  * for any other open source libraries included in this
94  * project: complete waiver from the AGPL is hereby granted to
95  * compile, link, and/or use them with Open-Transactions,
96  * according to their own terms, as long as the rest of the
97  * Open-Transactions terms remain respected, with regard to
98  * the Open-Transactions code itself.
99  *
100  * Lucre License:
101  * This code is also "dual-license", meaning that Ben Lau-
102  * rie's license must also be included and respected, since
103  * the code for Lucre is also included with Open Transactions.
104  * See Open-Transactions/src/otlib/lucre/LUCRE_LICENSE.txt
105  * The Laurie requirements are light, but if there is any
106  * problem with his license, simply remove the Lucre code.
107  * Although there are no other blind token algorithms in Open
108  * Transactions (yet. credlib is coming), the other functions
109  * will continue to operate.
110  * See Lucre on Github: https://github.com/benlaurie/lucre
111  * -----------------------------------------------------
112  * You should have received a copy of the GNU Affero General
113  * Public License along with this program. If not, see:
114  * http://www.gnu.org/licenses/
115  *
116  * If you would like to use this software outside of the free
117  * software license, please contact FellowTraveler.
118  * (Unfortunately many will run anonymously and untraceably,
119  * so who could really stop them?)
120  *
121  * DISCLAIMER:
122  * This program is distributed in the hope that it will be
123  * useful, but WITHOUT ANY WARRANTY; without even the implied
124  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
125  * PURPOSE. See the GNU Affero General Public License for
126  * more details.
127 
128  -----BEGIN PGP SIGNATURE-----
129  Version: GnuPG v1.4.9 (Darwin)
130 
131  iQIcBAEBAgAGBQJRSsfJAAoJEAMIAO35UbuOQT8P/RJbka8etf7wbxdHQNAY+2cC
132  vDf8J3X8VI+pwMqv6wgTVy17venMZJa4I4ikXD/MRyWV1XbTG0mBXk/7AZk7Rexk
133  KTvL/U1kWiez6+8XXLye+k2JNM6v7eej8xMrqEcO0ZArh/DsLoIn1y8p8qjBI7+m
134  aE7lhstDiD0z8mwRRLKFLN2IH5rAFaZZUvj5ERJaoYUKdn4c+RcQVei2YOl4T0FU
135  LWND3YLoH8naqJXkaOKEN4UfJINCwxhe5Ke9wyfLWLUO7NamRkWD2T7CJ0xocnD1
136  sjAzlVGNgaFDRflfIF4QhBx1Ddl6wwhJfw+d08bjqblSq8aXDkmFA7HeunSFKkdn
137  oIEOEgyj+veuOMRJC5pnBJ9vV+7qRdDKQWaCKotynt4sWJDGQ9kWGWm74SsNaduN
138  TPMyr9kNmGsfR69Q2Zq/FLcLX/j8ESxU+HYUB4vaARw2xEOu2xwDDv6jt0j3Vqsg
139  x7rWv4S/Eh18FDNDkVRChiNoOIilLYLL6c38uMf1pnItBuxP3uhgY6COm59kVaRh
140  nyGTYCDYD2TK+fI9o89F1297uDCwEJ62U0Q7iTDp5QuXCoxkPfv8/kX6lS6T3y9G
141  M9mqIoLbIQ1EDntFv7/t6fUTS2+46uCrdZWbQ5RjYXdrzjij02nDmJAm2BngnZvd
142  kamH0Y/n11lCvo1oQxM+
143  =uSzz
144  -----END PGP SIGNATURE-----
145  **************************************************************/
146 
147 #include "stdafx.hpp"
148 
150 
151 #include "crypto/OTCredential.hpp"
152 #include "OTLog.hpp"
153 #include "crypto/OTSignature.hpp"
154 #include "OTStorage.hpp"
155 
156 namespace opentxs
157 {
158 
160 {
162 }
163 
164 // NOTE: You might ask, if we are using theSignature's metadata to narrow down
165 // the key type,
166 // then why are we still passing the key type as a separate parameter? Good
167 // question. Because
168 // often, theSignature will have no metadata at all! In that case, normally we
169 // would just NOT
170 // return any keys, period. Because we assume, if a key credential signed it,
171 // then it WILL have
172 // metadata, and if it doesn't have metadata, then a key credential did NOT sign
173 // it, and therefore
174 // we know from the get-go that none of the keys from the key credentials will
175 // work to verify it,
176 // either. That's why, normally, we don't return any keys if theSignature has no
177 // metadata.
178 // BUT...Let's say you know this, that the signature has no metadata, yet you
179 // also still believe
180 // it may be signed with one of these keys. Further, while you don't know
181 // exactly which key it
182 // actually is, let's say you DO know by context that it's a signing key, or an
183 // authentication key,
184 // or an encryption key. So you specify that. In which case, OT should return
185 // all possible matching
186 // pubkeys based on that 1-letter criteria, instead of its normal behavior,
187 // which is to return all
188 // possible matching pubkeys based on a full match of the metadata.
189 //
191  listOfAsymmetricKeys& listOutput, const OTSignature& theSignature,
192  char cKeyType) const // 'S' (signing key) or 'E' (encryption key)
193  // or 'A' (authentication key)
194 {
195  // Key type was not specified, because we only want keys that match the
196  // metadata on theSignature.
197  // And if theSignature has no metadata, then we want to return 0 keys.
198  if (('0' == cKeyType) && !theSignature.getMetaData().HasMetadata())
199  return 0;
200 
201  // By this point, we know that EITHER exact metadata matches must occur, and
202  // the signature DOES have metadata, ('0')
203  // OR the search is only for 'A', 'E', or 'S' candidates, based on cKeyType,
204  // and that the signature's metadata
205  // can additionally narrow the search down, if it's present, which in this
206  // case it's not guaranteed to be.
207  int32_t nCount = 0;
208  switch (cKeyType) {
209  // Specific search only for signatures with metadata.
210  // FYI, theSignature.getMetaData().HasMetadata() is true, in this case.
211  case '0': {
212  // That's why I can just assume theSignature has a key type here:
213  switch (theSignature.getMetaData().GetKeyType()) {
214  case 'A':
215  nCount =
216  m_AuthentKey.GetPublicKeyBySignature(listOutput, theSignature);
217  break; // bInclusive=false by default
218  case 'E':
219  nCount =
220  m_EncryptKey.GetPublicKeyBySignature(listOutput, theSignature);
221  break; // bInclusive=false by default
222  case 'S':
223  nCount =
224  m_SigningKey.GetPublicKeyBySignature(listOutput, theSignature);
225  break; // bInclusive=false by default
226  default:
227  otErr << __FUNCTION__
228  << ": Unexpected keytype value in signature metadata: "
229  << theSignature.getMetaData().GetKeyType() << " (failure)\n";
230  return 0;
231  }
232  break;
233  }
234  // Generalized search which specifies key type and returns keys
235  // even for signatures with no metadata. (When metadata is present,
236  // it's still used to eliminate keys.)
237  case 'A':
238  nCount = m_AuthentKey.GetPublicKeyBySignature(listOutput, theSignature,
239  true);
240  break; // bInclusive=true
241  case 'E':
242  nCount = m_EncryptKey.GetPublicKeyBySignature(listOutput, theSignature,
243  true);
244  break; // bInclusive=true
245  case 'S':
246  nCount = m_SigningKey.GetPublicKeyBySignature(listOutput, theSignature,
247  true);
248  break; // bInclusive=true
249  default:
250  otErr << __FUNCTION__
251  << ": Unexpected value for cKeyType (should be 0, A, E, or S): "
252  << cKeyType << "\n";
253  return 0;
254  }
255  return nCount;
256 }
257 
258 // Verify that m_strNymID is the same as the hash of m_strSourceForNymID.
259 // Subkey verifies (master does not): NymID against Masterkey NymID, and master
260 // credential ID against hash of master credential.
261 // (How? Because OTMasterkey overrides this function and does NOT call the
262 // parent, whereas OTSubkey does.)
263 // Then verify the (self-signed) signature on *this.
264 //
266 {
267  // Verify that m_strNymID is the same as the hash of m_strSourceForNymID.
268  if (!ot_super::VerifyInternally()) return false;
269 
270  // Any OTKeyCredential (both master and subkeys, but no other credentials)
271  // must ** sign itself.**
272  //
273  if (!VerifySignedBySelf()) {
274  otOut << __FUNCTION__ << ": Failed verifying key credential: it's not "
275  "signed by itself (its own signing key.)\n";
276  return false;
277  }
278 
279  return true;
280 }
281 
282 // otErr << "%s line %d: \n", __FILE__, __LINE__);
283 
285  : ot_super()
286 {
287 }
289  : ot_super(theOwner)
290 {
291 }
292 
294 {
295  Release_Subkey();
296 }
297 
298 // virtual
300 {
301  Release_Subkey(); // My own cleanup is done here.
302 
303  // Next give the base class a chance to do the same...
304  ot_super::Release(); // since I've overridden the base class, I call it
305  // now...
306 }
307 
309 {
310  // Release any dynamically allocated members here. (Normally.)
311 }
312 
313 bool OTKeyCredential::GenerateKeys(int32_t nBits) // Gotta start
314  // somewhere.
315 {
316  const bool bSign = m_SigningKey.MakeNewKeypair(nBits);
317  const bool bAuth = m_AuthentKey.MakeNewKeypair(nBits);
318  const bool bEncr = m_EncryptKey.MakeNewKeypair(nBits);
319 
320  OT_ASSERT(bSign && bAuth && bEncr);
321 
322  m_SigningKey.SaveAndReloadBothKeysFromTempFile(); // Keys won't be right
323  // until this happens.
324  m_AuthentKey.SaveAndReloadBothKeysFromTempFile(); // (Necessary evil until
325  // better fix.)
327 
328  // Since the keys were all generated successfully, we need to copy their
329  // certificate data into the m_mapPublicInfo and m_mapPrivateInfo (string
330  // maps.)
331  //
332  OTString strPublicKey, strPrivateCert;
333  OTString::Map mapPublic, mapPrivate;
334 
335  const OTString strReason("Generating keys for new credential...");
336 
337  const bool b1 = m_SigningKey.GetPublicKey(
338  strPublicKey, false); // bEscaped=true by default.
339  const bool b2 =
340  m_SigningKey.SaveCertAndPrivateKeyToString(strPrivateCert, &strReason);
341 
342  if (b1)
343  mapPublic.insert(
344  std::pair<std::string, std::string>("S", strPublicKey.Get()));
345  if (b2)
346  mapPrivate.insert(
347  std::pair<std::string, std::string>("S", strPrivateCert.Get()));
348 
349  strPublicKey.Release();
350  strPrivateCert.Release();
351  const bool b3 = m_AuthentKey.GetPublicKey(
352  strPublicKey, false); // bEscaped=true by default.
353  const bool b4 =
354  m_AuthentKey.SaveCertAndPrivateKeyToString(strPrivateCert, &strReason);
355 
356  if (b3)
357  mapPublic.insert(
358  std::pair<std::string, std::string>("A", strPublicKey.Get()));
359  if (b4)
360  mapPrivate.insert(
361  std::pair<std::string, std::string>("A", strPrivateCert.Get()));
362 
363  strPublicKey.Release();
364  strPrivateCert.Release();
365  const bool b5 = m_EncryptKey.GetPublicKey(
366  strPublicKey, false); // bEscaped=true by default.
367  const bool b6 =
368  m_EncryptKey.SaveCertAndPrivateKeyToString(strPrivateCert, &strReason);
369 
370  if (b5)
371  mapPublic.insert(
372  std::pair<std::string, std::string>("E", strPublicKey.Get()));
373  if (b6)
374  mapPrivate.insert(
375  std::pair<std::string, std::string>("E", strPrivateCert.Get()));
376 
377  if (3 != mapPublic.size()) {
378  otErr << "In " << __FILE__ << ", line " << __LINE__
379  << ": Failed getting public keys in "
380  "OTKeyCredential::GenerateKeys.\n";
381  return false;
382  }
383  else
384  ot_super::SetPublicContents(mapPublic);
385 
386  if (3 != mapPrivate.size()) {
387  otErr << "In " << __FILE__ << ", line " << __LINE__
388  << ": Failed getting private keys in "
389  "OTKeyCredential::GenerateKeys.\n";
390  return false;
391  }
392  else
393  ot_super::SetPrivateContents(mapPrivate);
394 
395  return true;
396 }
397 
398 // virtual
400 {
401  // NOTE: We might use this on the server side, we'll see, but so far on the
402  // client
403  // side, we won't need to use this function, since SetPrivateContents
404  // already does
405  // the dirty work of extracting the public keys and setting them.
406  //
407 
408  if (mapPublic.size() != 3) {
409  otErr << __FILE__ << " line " << __LINE__
410  << ": Failure: Expected 3 in mapPublic.size(), but the actual "
411  "value was: " << mapPublic.size() << "\n";
412  return false;
413  }
414 
415  auto itAuth = mapPublic.find("A"); // Authentication key
416  if (mapPublic.end() == itAuth) {
417  otErr << __FILE__ << " line " << __LINE__
418  << ": Failure: Unable to find public authentication key.\n";
419  return false;
420  }
421 
422  auto itEncr = mapPublic.find("E"); // Encryption key
423  if (mapPublic.end() == itEncr) {
424  otErr << __FILE__ << " line " << __LINE__
425  << ": Failure: Unable to find public encryption key.\n";
426  return false;
427  }
428 
429  auto itSign = mapPublic.find("S"); // Signing key
430  if (mapPublic.end() == itSign) {
431  otErr << __FILE__ << " line " << __LINE__
432  << ": Failure: Unable to find public signing key.\n";
433  return false;
434  }
435 
436  if (ot_super::SetPublicContents(mapPublic)) {
437 
438  OTString strKey;
439  strKey.Set(itAuth->second.c_str());
440  if (!m_AuthentKey.SetPublicKey(strKey)) {
441  otErr << __FILE__ << " line " << __LINE__
442  << ": Failure: Unable to set public authentication key based "
443  "on string:\n" << strKey << "\n";
444  return false;
445  }
446 
447  strKey.Release();
448  strKey.Set(itEncr->second.c_str());
449  if (!m_EncryptKey.SetPublicKey(strKey)) {
450  otErr << __FILE__ << " line " << __LINE__
451  << ": Failure: Unable to set public encryption key based on "
452  "string:\n" << strKey << "\n";
453  return false;
454  }
455 
456  strKey.Release();
457  strKey.Set(itSign->second.c_str());
458  if (!m_SigningKey.SetPublicKey(strKey)) {
459  otErr << __FILE__ << " line " << __LINE__
460  << ": Failure: Unable to set public signing key based on "
461  "string:\n" << strKey << "\n";
462  return false;
463  }
464 
465  return true; // SUCCESS! This means the input, mapPublic, actually
466  // contained an "A" key, an "E"
467  // key, and an "S" key (and nothing else) and that all three of those
468  // public keys actually loaded
469  // from string form into their respective key object members.
470  }
471 
472  return false;
473 }
474 
475 // NOTE: With OTKeyCredential, if you call SetPrivateContents, you don't have to
476 // call SetPublicContents,
477 // since SetPrivateContents will automatically set the public contents, since
478 // the public certs are available
479 // from the private certs. Not all credentials do this, but keys do. So you
480 // might ask, why did I still
481 // provide a version of SetPublicContents for OTKeyCredential? Just to fit the
482 // convention, also also because
483 // perhaps on the server side, public contents will be the only ones available,
484 // and private ones will never
485 // be set.
486 
487 // virtual
489  const OTString::Map& mapPrivate,
490  const OTPassword* pImportPassword) // if not nullptr, it means to use this
491  // password by default.
492 {
493 
494  if (mapPrivate.size() != 3) {
495  otErr << __FILE__ << " line " << __LINE__
496  << ": Failure: Expected 3 in mapPrivate(), but the actual value "
497  "was: " << mapPrivate.size() << "\n";
498  return false;
499  }
500 
501  auto itAuth = mapPrivate.find("A"); // Authentication key
502  if (mapPrivate.end() == itAuth) {
503  otErr << __FILE__ << " line " << __LINE__
504  << ": Failure: Unable to find private authentication key.\n";
505  return false;
506  }
507 
508  auto itEncr = mapPrivate.find("E"); // Encryption key
509  if (mapPrivate.end() == itEncr) {
510  otErr << __FILE__ << " line " << __LINE__
511  << ": Failure: Unable to find private encryption key.\n";
512  return false;
513  }
514 
515  auto itSign = mapPrivate.find("S"); // Signing key
516  if (mapPrivate.end() == itSign) {
517  otErr << __FILE__ << " line " << __LINE__
518  << ": Failure: Unable to find private signing key.\n";
519  return false;
520  }
521 
522  if (ot_super::SetPrivateContents(mapPrivate, pImportPassword)) {
523  const OTString strReason("Loading private key from credential.");
524  OTString::Map mapPublic;
525 
526  OTString strPrivate;
527  strPrivate.Set(itAuth->second.c_str()); // strPrivate now contains the
528  // private Cert string.
529 
530  if (false ==
532  strPrivate, false /*bEscaped true by default*/, &strReason,
533  pImportPassword)) {
534  otErr << __FILE__ << " line " << __LINE__
535  << ": Failure: Unable to set private authentication key "
536  "based on string.\n";
537  // otErr << __FILE__ << " line " << __LINE__ <<
538  // ": Failure: Unable to set private authentication key
539  // based on string:\n" << strPrivate << "\n";
540  return false;
541  }
542  else // Success loading the private key. Let's grab the public key
543  // here.
544  {
545  OTString strPublic;
546 
547  if ((false ==
549  strPrivate, false /* bEscaped true by default */,
550  &strReason, pImportPassword)) ||
551  (false ==
553  strPublic, false /* bEscaped true by default */))) {
554  otErr << __FILE__ << " line " << __LINE__
555  << ": Failure: Unable to set public authentication key "
556  "based on private string.\n";
557  // otErr << __FILE__ << " line " << __LINE__ <<
558  // ": Failure: Unable to set public
559  // authentication key based on private string:\n" << strPrivate
560  // << "\n";
561  return false;
562  }
563  mapPublic.insert(
564  std::pair<std::string, std::string>("A", strPublic.Get()));
565  }
566 
567  strPrivate.Release();
568  strPrivate.Set(itEncr->second.c_str());
569 
570  if (false ==
572  strPrivate, false /*bEscaped true by default*/, &strReason,
573  pImportPassword)) {
574  otErr << __FILE__ << " line " << __LINE__
575  << ": Failure: Unable to set private encryption key based on "
576  "string.\n";
577  // otErr << __FILE__ << " line " << __LINE__ <<
578  // ": Failure: Unable to set private encryption key based
579  // on string:\n" << strPrivate << "\n";
580  return false;
581  }
582  else // Success loading the private key. Let's grab the public key
583  // here.
584  {
585  OTString strPublic;
586 
587  if ((false ==
589  strPrivate, false /* bEscaped true by default */,
590  &strReason, pImportPassword)) ||
591  (false ==
593  strPublic, false /* bEscaped true by default */))) {
594  otErr << __FILE__ << " line " << __LINE__
595  << ": Failure: Unable to set public encryption key based "
596  "on private string.\n";
597  // otErr << __FILE__ << " line " << __LINE__ <<
598  // ": Failure: Unable to set public encryption
599  // key based on private string:\n" << strPrivate << "\n";
600  return false;
601  }
602  mapPublic.insert(
603  std::pair<std::string, std::string>("E", strPublic.Get()));
604  }
605 
606  strPrivate.Release();
607  strPrivate.Set(itSign->second.c_str());
608 
609  if (false ==
611  strPrivate, false /*bEscaped true by default*/, &strReason,
612  pImportPassword)) {
613  otErr << __FILE__ << " line " << __LINE__
614  << ": Failure: Unable to set private signing key based on "
615  "string.\n";
616  // otErr << __FILE__ << " line " << __LINE__ <<
617  // ": Failure: Unable to set private signing key based on
618  // string:\n" << strPrivate << "\n";
619  return false;
620  }
621  else // Success loading the private key. Let's grab the public key
622  // here.
623  {
624  OTString strPublic;
625 
626  if ((false ==
628  strPrivate, false /* bEscaped true by default */,
629  &strReason, pImportPassword)) ||
630  (false ==
632  strPublic, false /* bEscaped true by default */))) {
633  otErr << __FILE__ << " line " << __LINE__
634  << ": Failure: Unable to set public signing key based on "
635  "private string.\n";
636  // otErr << __FILE__ << " line " << __LINE__ <<
637  // ": Failure: Unable to set public signing key
638  // based on private string:\n" << strPrivate << "\n";
639  return false;
640  }
641  mapPublic.insert(
642  std::pair<std::string, std::string>("S", strPublic.Get()));
643  }
644 
645  if (!ot_super::SetPublicContents(mapPublic)) {
646  otErr << __FILE__ << " line " << __LINE__
647  << ": Failure: While trying to call: "
648  "ot_super::SetPublicContents(mapPublic)\n"; // Should never
649  // happen (it
650  // always just
651  // returns
652  // true.)
653  return false;
654  }
655 
656  return true; // SUCCESS! This means the input, mapPrivate, actually
657  // contained an "A" key, an "E"
658  // key, and an "S" key (and nothing else) and that all three of those
659  // private keys actually loaded
660  // from string form into their respective key object members. We also
661  // set the public keys in here, FYI.
662  }
663 
664  return false;
665 }
666 
668  const OTPasswordData* pPWData)
669 {
670  return m_SigningKey.SignContract(theContract, pPWData);
671 }
672 
673 bool OTKeyCredential::ReEncryptKeys(const OTPassword& theExportPassword,
674  bool bImporting)
675 {
676  OTString strSign, strAuth, strEncr;
677 
678  const bool bSign =
679  m_SigningKey.ReEncrypt(theExportPassword, bImporting, strSign);
680  bool bAuth = false;
681  bool bEncr = false;
682 
683  if (bSign) {
684  bAuth = m_AuthentKey.ReEncrypt(theExportPassword, bImporting, strAuth);
685 
686  if (bAuth)
687  bEncr =
688  m_EncryptKey.ReEncrypt(theExportPassword, bImporting, strEncr);
689  }
690 
691  const bool bSuccessReEncrypting = (bSign && bAuth && bEncr);
692  bool bSuccess = false;
693 
694  // If success, we now have the updated versions of the private certs.
695  //
696  if (bSuccessReEncrypting) {
697  OTString::Map mapPrivate;
698 
699  for (auto& it : m_mapPrivateInfo) {
700  std::string str_key_type = it.first; // A, E, S.
701  std::string str_key_contents = it.second;
702 
703  if ("A" == str_key_type) {
704  mapPrivate.insert(
705  std::pair<std::string, std::string>("A", strAuth.Get()));
706  }
707  else if ("E" == str_key_type)
708  mapPrivate.insert(
709  std::pair<std::string, std::string>("E", strEncr.Get()));
710  else if ("S" == str_key_type)
711  mapPrivate.insert(
712  std::pair<std::string, std::string>("S", strSign.Get()));
713 
714  else // Should never happen, but if there are other keys here, we'll
715  // preserve 'em.
716  {
717  mapPrivate.insert(std::pair<std::string, std::string>(
718  str_key_type, str_key_contents));
719  OT_FAIL; // really this should never happen.
720  }
721  }
722 
723  if (3 != mapPrivate.size())
724  otErr << __FUNCTION__ << ": Unexpected, mapPrivate does not have "
725  "exactly a size of 3. \n";
726 
727  else {
728  // Logic: If I'm IMPORTING, bImporting is true, and that means the
729  // Nym WAS
730  // encrypted to its own external passphrase (whenever it was
731  // exported) and
732  // in order to IMPORT it, I re-encrypted all the keys from the
733  // exported passphrase,
734  // to the wallet master key (this was done above in ReEncrypt.)
735  // So now that I am loading up the private contents again based on
736  // those
737  // re-encrypted keys, I will want to use the normal wallet master
738  // key to load
739  // them. (So I pass nullptr.)
740  //
741  // But if I'm EXPORTING, bImporting is false, and that means the Nym
742  // WAS
743  // encrypted to the wallet's master passphrase, until just above
744  // when I ReEncrypted
745  // it to its own external passphrase. So now that I am attempting to
746  // reload the
747  // keys based on this new external passphrase, I need to pass it in
748  // so it can be
749  // used for that loading. (So I pass &theExportPassword.)
750  //
751  bSuccess = SetPrivateContents(
752  mapPrivate, bImporting ? nullptr : &theExportPassword);
753  }
754  }
755 
756  return bSuccess; // Note: Caller must re-sign credential after doing this,
757  // to keep these changes.
758 }
759 
761 {
762  char cMetaKeyType; // Can be A, E, or S (authentication, encryption, or
763  // signing. Also, E would be unusual.)
764  char cMetaNymID = '0'; // Can be any letter from base62 alphabet. Represents
765  // first letter of a Nym's ID.
766  char cMetaMasterCredID = '0'; // Can be any letter from base62 alphabet.
767  // Represents first letter of a Master
768  // Credential ID (for that Nym.)
769  char cMetaSubCredID = '0'; // Can be any letter from base62 alphabet.
770  // Represents first letter of a SubCredential ID
771  // (signed by that Master.)
772 
773  OTString strSubcredID;
774  GetIdentifier(strSubcredID);
775 
776  const bool bNymID = GetNymID().At(0, cMetaNymID);
777  const bool bCredID = m_pOwner->GetMasterCredID().At(0, cMetaMasterCredID);
778  const bool bSubID =
779  strSubcredID.At(0, cMetaSubCredID); // In the case of the master
780  // credential, this will repeat the
781  // previous one.
782 
783  if (!bNymID || !bCredID || !bSubID) {
784  otWarn << __FUNCTION__ << ": No metadata available:\n "
785  << "bNymID"
786  << " is " << (bNymID ? "True" : "False") << ", "
787  << "bCredID"
788  << " is " << (bNymID ? "True" : "False") << ", "
789  << "bSubID"
790  << " is " << (bNymID ? "True" : "False") << "";
791  }
792 
793  OTSignatureMetadata theMetadata;
794 
795  cMetaKeyType = 'A';
796  theMetadata.SetMetadata(cMetaKeyType, cMetaNymID, cMetaMasterCredID,
797  cMetaSubCredID);
798  m_AuthentKey.SetMetadata(theMetadata);
799 
800  cMetaKeyType = 'E';
801  theMetadata.SetMetadata(cMetaKeyType, cMetaNymID, cMetaMasterCredID,
802  cMetaSubCredID);
803  m_EncryptKey.SetMetadata(theMetadata);
804 
805  cMetaKeyType = 'S';
806  theMetadata.SetMetadata(cMetaKeyType, cMetaNymID, cMetaMasterCredID,
807  cMetaSubCredID);
808  m_SigningKey.SetMetadata(theMetadata);
809 }
810 
811 } // namespace opentxs
std::map< std::string, std::string > Map
Definition: OTString.hpp:162
bool SetMetadata(char metaKeyType, char metaNymID, char metaMasterCredID, char metaSubCredID)
EXPORT bool ReEncrypt(const OTPassword &theExportPassword, bool bImporting, OTString &strOutput)
Definition: OTKeypair.cpp:692
std::list< OTAsymmetricKey * > listOfAsymmetricKeys
EXPORT const OTAsymmetricKey & GetPublicKey() const
Definition: OTKeypair.cpp:229
EXPORT int32_t GetPublicKeysBySignature(listOfAsymmetricKeys &listOutput, const OTSignature &theSignature, char cKeyType= '0') const
bool Sign(OTContract &theContract, const OTPasswordData *pPWData=nullptr)
EXPORT bool SaveAndReloadBothKeysFromTempFile(OTString *pstrOutputCert=nullptr, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
Definition: OTKeypair.cpp:333
OTLOG_IMPORT OTLogStream otOut
EXPORT void SetMetadata(const OTSignatureMetadata &theMetadata)
Definition: OTKeypair.cpp:200
virtual bool SetPrivateContents(const OTString::Map &mapPrivate, const OTPassword *pImportPassword=nullptr)
EXPORT bool VerifyWithKey(const OTAsymmetricKey &theKey, const OTPasswordData *pPWData=nullptr) const
Definition: OTContract.cpp:848
EXPORT bool SetPublicKey(const OTASCIIArmor &strKey)
Definition: OTKeypair.cpp:526
EXPORT const OTString & GetMasterCredID() const
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
Definition: OTString.cpp:1055
#define OT_ASSERT(x)
Definition: Assert.hpp:150
virtual bool SetPrivateContents(const OTString::Map &mapPrivate, const OTPassword *pImportPassword=nullptr)
EXPORT bool LoadPublicKeyFromCertString(const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
Definition: OTKeypair.cpp:409
const OTString & GetNymID() const
virtual EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
Definition: OTContract.cpp:317
#define OT_FAIL
Definition: Assert.hpp:139
EXPORT bool At(uint32_t index, char &c) const
Definition: OTString.cpp:1025
EXPORT bool LoadPrivateKeyFromCertString(const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
Definition: OTKeypair.cpp:396
virtual bool SetPublicContents(const OTString::Map &mapPublic)
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
Definition: OTString.cpp:1045
bool ReEncryptKeys(const OTPassword &theExportPassword, bool bImporting)
OTLOG_IMPORT OTLogStream otErr
EXPORT bool SaveCertAndPrivateKeyToString(OTString &strOutput, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
Definition: OTKeypair.cpp:277
virtual bool SetPublicContents(const OTString::Map &mapPublic)
EXPORT bool MakeNewKeypair(int32_t nBits=1024)
Definition: OTKeypair.cpp:430
EXPORT bool SignContract(OTContract &theContract, const OTPasswordData *pPWData=nullptr)
Definition: OTKeypair.cpp:494
bool GenerateKeys(int32_t nBits=1024)
virtual EXPORT void Release()
Definition: OTString.cpp:765