Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTSubkey.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTSubkey.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/OTSubkey.hpp"
150 #include "crypto/OTASCIIArmor.hpp"
151 #include "crypto/OTCredential.hpp"
152 #include "OTLog.hpp"
153 
154 #include "irrxml/irrXML.hpp"
155 
156 // return -1 if error, 0 if nothing, and 1 if the node was processed.
157 
158 namespace opentxs
159 {
160 
162  : OTKeyCredential()
163 {
164  m_strContractType = "KEY CREDENTIAL";
165 }
166 
168  : OTKeyCredential(other)
169 {
170  m_strContractType = "KEY CREDENTIAL";
171 }
172 
174 {
175 }
176 
178 {
179  int32_t retval = OTKeyCredential::ProcessXMLNode(xml);
180 
181  // Here we call the parent class first.
182  // If the node is found there, or there is some error,
183  // then we just return either way. But if it comes back
184  // as '0', then nothing happened, and we'll continue executing.
185  //
186  // -- Note you can choose not to call the parent if
187  // you don't want to use any of those xml tags.
188  // As I do in the case of OTAccount.
189  if (retval != 0) return retval;
190 
191  OTString nodeName(xml->getNodeName());
192  if (nodeName.Compare("keyCredential")) {
193  m_strNymID = xml->getAttributeValue("nymID");
194  m_strMasterCredID = xml->getAttributeValue("masterCredentialID");
195 
196  OTLog::Output(1, "Loading keyCredential...\n");
197  retval = 1;
198  }
199  else if (nodeName.Compare("masterSigned")) {
201  OTLog::vError("Error in %s line %d: failed loading expected "
202  "master-signed version while loading "
203  "keyCredential.\n",
204  __FILE__, __LINE__);
205  return -1;
206  }
207  retval = 1;
208  }
209  return retval;
210 }
211 
213 {
215 
217  "<keyCredential nymID=\"%s\"\n" // a hash of the nymIDSource
218  " masterCredentialID=\"%s\" >\n\n", // Hash of the master credential
219  // that signed this subcredential.
220  GetNymID().Get(),
221  GetMasterCredID().Get());
222 
223  if (GetNymIDSource().Exists()) {
224  OTASCIIArmor ascSource;
225  ascSource.SetString(GetNymIDSource()); // A nym should always
226  // verify through its own
227  // source. (Whatever that
228  // may be.)
229  m_xmlUnsigned.Concatenate("<nymIDSource>\n%s</nymIDSource>\n\n",
230  ascSource.Get());
231  }
232  // MASTER-SIGNED INFO
237  }
238  // PUBLIC INFO (signed by subkey, contains master signed info.)
241  // GetMasterSigned() returns the contract
242  // containing the master-signed contents
243  // from the above block.
244  OTASCIIArmor ascMasterSigned(GetMasterSigned());
246  "<masterSigned>\n%s</masterSigned>\n\n", // Contains all the public
247  // info, signed by the
248  // master key.
249  ascMasterSigned.Get()); // Packaged up here inside a final,
250  // subkey-signed credential.
251  }
252  // PRIVATE INFO
253  //
254  // If we're saving the private credential info...
258  }
259 
260  // <=== SET IT BACK TO DEFAULT BEHAVIOR. Any other state
261  // processes ONCE, and then goes back to this again.
262  m_xmlUnsigned.Concatenate("</keyCredential>\n");
264 }
265 
267 {
268  // See if m_strMasterSigned was signed by my master credential.
269  OTSubkey masterKey(*m_pOwner);
270 
271  if (m_strMasterSigned.Exists() &&
273  // Here we need to MAKE SURE that the "master signed" version contains
274  // the same CONTENTS as the actual version.
275  if (!GetNymID().Compare(masterKey.GetNymID())) {
276  OTLog::vOutput(0, "%s: Failure, NymID of this key credential "
277  "doesn't match NymID of master-signed version of "
278  "this key credential.\n",
279  __FUNCTION__);
280  return false;
281  }
282 
283  if (!GetNymIDSource().Compare(masterKey.GetNymIDSource())) {
284  OTLog::vOutput(0, "%s: Failure, NymIDSource of this key credential "
285  "doesn't match NymIDSource of master-signed "
286  "version of this key credential.\n",
287  __FUNCTION__);
288  return false;
289  }
290 
291  if (!GetMasterCredID().Compare(masterKey.GetMasterCredID())) {
292  OTLog::vOutput(0, "%s: Failure, MasterCredID of this key "
293  "credential doesn't match MasterCredID of "
294  "master-signed version of this key credential.\n",
295  __FUNCTION__);
296  return false;
297  }
298 
299  if (GetPublicMap().size() > 0 &&
300  GetPublicMap() != masterKey.GetPublicMap()) {
301  OTLog::vOutput(0, "%s: Failure, public info of this key credential "
302  "doesn't match public info of master-signed "
303  "version of this key credential.\n",
304  __FUNCTION__);
305  return false;
306  }
307 
308  // Master-signed version of subkey does not contain the private keys,
309  // since normally the master is signing
310  // the public version of the sub credential (to validate it) and you
311  // don't want the public seeing your private keys.
312  // So we would never expect these to match, since the master signed
313  // version should have no private keys in it.
314  //
315  // if (GetPrivateMap() != masterKey.GetPrivateMap())
316  // {
317  // OTLog::vOutput(0, "%s: Failure, private info of this key
318  // credential doesn't match private info of master-signed version of
319  // this key credential.\n", __FUNCTION__);
320  // return false;
321  // }
322 
323  bool verifiedWithKey = masterKey.VerifyWithKey(
325 
326  // ON SERVER SIDE, THE ACTUAL SUBKEY doesn't have any public key, only
327  // the master-signed version of it.
328  // (The master-signed version being basically the only contents of the
329  // public version.)
330  // So we need to be able to, after verifying, load up those contents so
331  // they are available on the
332  // subkey itself, and not just on some master-signed version of itself
333  // hidden inside itself.
334  // Otherwise I would have to load up the master-signed version anytime
335  // the server-side wanted to
336  // mess with any of the keys.
337  // Thus: copy the public info from master signed, to* this, if the above
338  // call was successful
339  if (verifiedWithKey && GetPublicMap().size() == 0) {
340  // For master credential.
341  return SetPublicContents(masterKey.GetPublicMap());
342  }
343  return verifiedWithKey;
344  }
345  return false;
346 }
347 
348 } // namespace opentxs
static EXPORT void vError(const char *szError,...)
Definition: OTLog.cpp:800
void UpdatePublicCredentialToString(OTString &strAppendTo)
static EXPORT void Output(int32_t nVerbosity, const char *szOutput)
Definition: OTLog.cpp:710
EXPORT const OTAsymmetricKey & GetPublicKey() const
Definition: OTKeypair.cpp:229
const OTString & GetMasterCredID() const
void UpdatePublicContentsToString(OTString &strAppendTo)
void UpdateMasterPublicToString(OTString &strAppendTo)
virtual void UpdateContents()
Definition: OTSubkey.cpp:212
EXPORT bool VerifyWithKey(const OTAsymmetricKey &theKey, const OTPasswordData *pPWData=nullptr) const
Definition: OTContract.cpp:848
EXPORT void Concatenate(const char *arg,...)
Definition: OTString.cpp:1334
EXPORT bool Exists() const
Definition: OTString.cpp:1035
EXPORT bool SetString(const OTString &theData, bool bLineBreaks=true)
EXPORT bool Compare(const char *compare) const
Definition: OTString.cpp:1102
virtual ~OTSubkey()
Definition: OTSubkey.cpp:173
static EXPORT bool LoadEncodedTextField(irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput)
OTString m_strContractType
Definition: OTContract.hpp:178
const OTString & GetNymID() const
virtual int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)
Definition: OTSubkey.cpp:177
virtual bool SetPublicContents(const OTString::Map &mapPublic)
OTStringXML m_xmlUnsigned
Definition: OTContract.hpp:174
const OTString & GetNymIDSource() const
EXPORT const char * Get() const
Definition: OTString.cpp:1045
const OTString::Map & GetPublicMap() const
virtual bool VerifySignedByMaster()
Definition: OTSubkey.cpp:266
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
EXPORT bool LoadContractFromString(const OTString &theStr)
const OTString & GetMasterSigned() const
static EXPORT void vOutput(int32_t nVerbosity, const char *szOutput,...)
Definition: OTLog.cpp:768
virtual EXPORT void Release()
Definition: OTString.cpp:765
virtual int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)