Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTMasterkey.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTMasterkey.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 
149 #include "crypto/OTMasterkey.hpp"
150 
151 #include "crypto/OTASCIIArmor.hpp"
152 #include "crypto/OTCredential.hpp"
153 #include "OTLog.hpp"
154 
155 #include <irrxml/irrXML.hpp>
156 
157 // return -1 if error, 0 if nothing, and 1 if the node was processed.
158 //
159 
160 namespace opentxs
161 {
162 
164 {
165  int32_t nReturnVal = ot_super::ProcessXMLNode(xml);
166 
167  // Here we call the parent class first.
168  // If the node is found there, or there is some error,
169  // then we just return either way. But if it comes back
170  // as '0', then nothing happened, and we'll continue executing.
171  //
172  // -- Note you can choose not to call the parent if
173  // you don't want to use any of those xml tags.
174  // As I do in the case of OTAccount.
175  //
176  if (0 != nReturnVal) return nReturnVal;
177  // else it was 0 (continue...)
178 
179  const OTString strNodeName(xml->getNodeName());
180 
181  if (strNodeName.Compare("masterCredential")) {
182  m_strNymID = xml->getAttributeValue("nymID");
183 
185 
186  otWarn << "Loading masterCredential...\n";
187 
188  nReturnVal = 1;
189  }
190 
191  return nReturnVal;
192 }
193 
195 {
197 
199  "<masterCredential nymID=\"%s\" >\n\n", // a hash of the nymIDSource
200  GetNymID().Get());
201 
202  if (GetNymIDSource().Exists()) {
203  OTASCIIArmor ascSource;
204  ascSource.SetString(GetNymIDSource()); // A nym should always
205  // verify through its own
206  // source. (Whatever that
207  // may be.)
208  m_xmlUnsigned.Concatenate("<nymIDSource>\n%s</nymIDSource>\n\n",
209  ascSource.Get());
210  }
211 
212  // PUBLIC INFO
213  //
214  // if (OTSubcredential::credPublicInfo == m_StoreAs) // PUBLIC INFO
215  // (Always save this in every state.)
216  {
218  }
219 
220  // PRIVATE INFO
221  //
222  // If we're saving the private credential info...
223  //
224  if (OTSubcredential::credPrivateInfo == m_StoreAs) // PRIVATE INFO
225  {
227 
229  }
230  // -------------------------------------------------
231  m_xmlUnsigned.Concatenate("</masterCredential>\n");
232 
233  m_StoreAs = OTSubcredential::credPrivateInfo; // <=== SET IT BACK TO DEFAULT
234  // BEHAVIOR. Any other state
235  // processes ONCE, and then
236  // goes back to this again.
237 }
238 
239 // Verify that m_strNymID is the same as the hash of m_strSourceForNymID. Also
240 // verify that
241 // *this == m_pOwner->GetMasterkey() (the master credential.) Verify the
242 // (self-signed)
243 // signature on *this.
244 //
246 {
247  // Verify that m_strNymID is the same as the hash of m_strSourceForNymID.
248  //
249  // We can't use super here, since OTSubcredential::VerifyInternally will
250  // verify
251  // m_strMasterCredID against the actual Master, which is not relevant to us
252  // in
253  // OTMasterkey. But this means if we need anything else that
254  // OTKeyCredential::VerifyInternally
255  // was doing, we will have to duplicate that here as well...
256  // if (!ot_super::VerifyInternally())
257  // return false;
258  if (!VerifyNymID()) return false;
259 
260  OT_ASSERT(nullptr != m_pOwner);
261  // Verify that *this == m_pOwner->GetMasterkey() (the master credential.)
262  //
263  if (this != &(m_pOwner->GetMasterkey())) {
264  otOut << __FUNCTION__ << ": Failure: Expected *this object to be the "
265  "same as m_pOwner->GetMasterkey(), "
266  "but it wasn't.\n";
267  return false;
268  }
269 
270  // Remember this note above: ...if we need anything else that
271  // OTKeyCredential::VerifyInternally
272  // was doing, we will have to duplicate that here as well...
273  // Since we aren't calling OTKeyCredential::VerifyInternally (the super) and
274  // since that function
275  // verifies that the credential is self-signed, we must do the same
276  // verification here:
277  //
278  // Any OTKeyCredential (both master and subkeys, but no other credentials)
279  // must ** sign itself.**
280  //
281  if (!VerifySignedBySelf()) {
282  otOut << __FUNCTION__ << ": Failed verifying master credential: it's "
283  "not signed by itself (its own signing "
284  "key.)\n";
285  return false;
286  }
287 
288  return true;
289 }
290 
291 // Should actually curl the URL, or lookup the blockchain value, or verify Cert
292 // against
293 // Cert Authority, etc. Due to the network slowdown of this step, we will
294 // eventually make
295 // a separate identity verification server.
296 //
298 {
299  // RULE: *Any* source except for a public key, will begin with a
300  // protocol specifier. Such as:
301  //
302  // http: (a normal URL)
303  // https: (a normal URL on https)
304  // bitcoin: (a bitcoin address)
305  // namecoin: (a namecoin address)
306  // i2p: (an i2p address)
307  // tor: (a tor address)
308  // freenet: (a freenet address)
309  // cert: (Subject and Issuer DN from the cert)
310  //
311  // If NO protocol specifier is found, the source is assumed
312  // to be a public key.
313  // Public key is the default because that's the original behavior
314  // of OT anyway: the public key was hashed to form the NymID. We will
315  // continue to support this as a default, but now we are additionally
316  // also allowing other sources such as Namecoin, Freenet, etc. As int64_t
317  // as a Nym's source hashes to its correct ID, and as long as its master
318  // credentials can be verified from that same source, then all master
319  // credentials can be verified (as well as subcredentials) from any source
320  // the user prefers.
321  //
322 
323  bool bVerified = false;
324 
325  const std::string str_raw_source(m_strSourceForNymID.Get());
326  std::string str_source;
327 
328  // It's a URL.
329  if (str_raw_source.compare(0, 5, "http:") == 0) {
330  str_source.insert(str_source.begin(), str_raw_source.begin() + 5,
331  str_raw_source.end());
332  bVerified = VerifySource_HTTP(str_source.c_str());
333  }
334  else if (str_raw_source.compare(0, 6, "https:") == 0) {
335  str_source.insert(str_source.begin(), str_raw_source.begin() + 6,
336  str_raw_source.end());
337  bVerified = VerifySource_HTTPS(str_source.c_str());
338  }
339  // It's a Bitcoin address.
340  else if (str_raw_source.compare(0, 8, "bitcoin:") == 0) {
341  str_source.insert(str_source.begin(), str_raw_source.begin() + 8,
342  str_raw_source.end());
343  bVerified = VerifySource_Bitcoin(str_source.c_str());
344  }
345  // It's a Namecoin address.
346  else if (str_raw_source.compare(0, 9, "namecoin:") == 0) {
347  str_source.insert(str_source.begin(), str_raw_source.begin() + 9,
348  str_raw_source.end());
349  bVerified = VerifySource_Namecoin(str_source.c_str());
350  }
351  // It's a Freenet URL.
352  else if (str_raw_source.compare(0, 8, "freenet:") == 0) {
353  str_source.insert(str_source.begin(), str_raw_source.begin() + 8,
354  str_raw_source.end());
355  bVerified = VerifySource_Freenet(str_source.c_str());
356  }
357  // It's a Tor URL.
358  else if (str_raw_source.compare(0, 4, "tor:") == 0) {
359  str_source.insert(str_source.begin(), str_raw_source.begin() + 4,
360  str_raw_source.end());
361  bVerified = VerifySource_TOR(str_source.c_str());
362  }
363  // It's an I2P URL.
364  else if (str_raw_source.compare(0, 4, "i2p:") == 0) {
365  str_source.insert(str_source.begin(), str_raw_source.begin() + 4,
366  str_raw_source.end());
367  bVerified = VerifySource_I2P(str_source.c_str());
368  }
369  // It's the Issuer/Subject DN info from a cert issued by a traditional
370  // certificate authority.
371  else if (str_raw_source.compare(0, 5, "cert:") == 0) {
372  str_source.insert(str_source.begin(), str_raw_source.begin() + 5,
373  str_raw_source.end());
374  bVerified = VerifySource_CA(str_source.c_str());
375  }
376  else // It's presumably a public key.
377  {
378  str_source = str_raw_source;
379  bVerified = VerifySource_Pubkey(str_source.c_str());
380  }
381 
382  return bVerified;
383 }
384 
386 {
387  /*
388  The source is a URL, http://blah.com/folder
389  If I download files from there, will I find my own masterkey inside?
390  If so, then I verify.
391  */
392 
393  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
394  "written, so this HTTP source cannot be "
395  "verified.\n";
396  // return false;
397 
398  // Todo security
399  otErr << "\nNOTE: Returning TRUE for TESTING PURPOSES, as if HTTP source "
400  "had verified."
401  "\n\n\n ----------------------- \n\n";
402 
403  return true;
404 }
405 
407 {
408  /*
409  The source is a URL, https://blah.com/folder
410  If I download files from there, will I find my own masterkey inside?
411  If so, then I verify.
412  */
413 
414  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
415  "written, so this HTTPS source cannot be "
416  "verified.\n";
417  // return false;
418 
419  // Todo security
420  otErr << "\nNOTE: Returning TRUE for TESTING PURPOSES, as if HTTPS source "
421  "had verified."
422  "\n\n\n ----------------------- \n\n";
423 
424  return true;
425 }
426 
428 {
429  /*
430  The source is a Bitcoin address
431  The last transfer from that address should have memo data with the hash of
432  the master credential.
433  I compare that to my own ID and they should match.
434  Alternately, to support multiple master credentials, have the last transfer
435  go to multiple addresses,
436  and each should have a memo with the master cred ID for each credential,
437  one of which should match my own.
438  If so, then I verify.
439  */
440 
441  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
442  "written, so this Bitcoin source cannot be "
443  "verified.\n";
444  // return false;
445 
446  // Todo security
447  otErr << "\nNOTE: Returning TRUE for TESTING PURPOSES, as if Bitcoin had "
448  "verified."
449  "\n\n\n ----------------------- \n\n";
450 
451  return true;
452 }
453 
455 {
456  /*
457  The source is a URL, http://blah.bit/folder
458  If I download files from there, will I find my own masterkey inside?
459  If so, then I verify.
460  */
461 
462  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
463  "written, so this Namecoin source cannot be "
464  "verified.\n";
465  // return false;
466 
467  // Todo security
468  otErr << "\nNOTE: Returning TRUE for TESTING PURPOSES, as if Namecoin had "
469  "verified."
470  "\n\n\n ----------------------- \n\n";
471 
472  return true;
473 }
474 
476 {
477  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
478  "written, so this Freenet source cannot be "
479  "verified.\n";
480  return false;
481 }
482 
484 {
485  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
486  "written, so this Tor source cannot be "
487  "verified.\n";
488  return false;
489 }
490 
492 {
493  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
494  "written, so this I2P source cannot be "
495  "verified.\n";
496  return false;
497 }
498 
500 {
501 
502  /*
503  The Source is the DN info on the Cert.
504  Therefore look at the Cert being used in this Masterkey.
505  Does it have the same DN info? Does it verify through its CA ?
506  Then it verifies.
507  */
508 
509  otErr << __FUNCTION__ << ": Failure: this function has not yet been "
510  "written, so this CA source cannot be verified.\n";
511  return false;
512 }
513 
515 {
516  // Verify signed by self.
517  //
518  // Note: Whenever VerifyAgainstSource is called, VerifyInternally is also
519  // called.
520  // And VerifyInternally, for all OTKeyCredentials, verifies already that the
521  // credential has been signed by its own private signing key.
522  // Since the credential is already verified as having signed itself, there's
523  // no
524  // reason to verify that redundantly here, so we just return true.
525  //
526  return true;
527 }
528 
530  : ot_super()
531 {
532  m_strContractType = "MASTER KEY CREDENTIAL";
533 }
534 
536  : ot_super(theOwner)
537 {
538  m_strContractType = "MASTER KEY CREDENTIAL";
539 }
540 
542 {
543 }
544 
545 } // namespace opentxs
bool VerifySource_Pubkey(const OTString strSource) const
void UpdatePublicCredentialToString(OTString &strAppendTo)
bool VerifySource_Freenet(const OTString strSource) const
bool VerifySource_I2P(const OTString strSource) const
bool VerifyAgainstSource() const
OTLOG_IMPORT OTLogStream otOut
void UpdatePublicContentsToString(OTString &strAppendTo)
EXPORT void Concatenate(const char *arg,...)
Definition: OTString.cpp:1334
EXPORT bool SetString(const OTString &theData, bool bLineBreaks=true)
bool VerifySource_Namecoin(const OTString strSource) const
virtual bool VerifyInternally()
bool VerifySource_TOR(const OTString strSource) const
#define OT_ASSERT(x)
Definition: Assert.hpp:150
virtual void UpdateContents()
bool VerifySource_Bitcoin(const OTString strSource) const
OTString m_strContractType
Definition: OTContract.hpp:178
const OTString & GetNymID() const
OTStringXML m_xmlUnsigned
Definition: OTContract.hpp:174
OTLOG_IMPORT OTLogStream otWarn
bool VerifySource_CA(const OTString strSource) const
const OTString & GetNymIDSource() const
EXPORT const char * Get() const
Definition: OTString.cpp:1045
OTLOG_IMPORT OTLogStream otErr
void UpdatePrivateContentsToString(OTString &strAppendTo)
EXPORT const OTMasterkey & GetMasterkey() const
EXPORT bool Exists(std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
Definition: OTStorage.cpp:584
bool VerifySource_HTTP(const OTString strSource) const
bool VerifySource_HTTPS(const OTString strSource) const
virtual int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)
virtual EXPORT void Release()
Definition: OTString.cpp:765
virtual int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)