Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTAsymmetricKey.hpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTAsymmetricKey.hpp
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 #ifndef OPENTXS_CORE_CRYPTO_OTASYMMETRICKEY_HPP
134 #define OPENTXS_CORE_CRYPTO_OTASYMMETRICKEY_HPP
135 
136 #include "../util/Timer.hpp"
137 #include <list>
138 
139 namespace opentxs
140 {
141 
142 class OTASCIIArmor;
143 class OTAsymmetricKey;
144 class OTCaller;
145 class OTIdentifier;
146 class OTPassword;
147 class OTSignatureMetadata;
148 class OTString;
149 
150 typedef std::list<OTAsymmetricKey*> listOfAsymmetricKeys;
151 
152 // Todo:
153 // 1. Add this value to the config file so it becomes merely a default value
154 // here.
155 // 2. This timer solution isn't the full solution but only a stopgap measure.
156 // See notes in ReleaseKeyLowLevel for more -- ultimate solution will involve
157 // the callback itself, and some kind of encrypted storage of hashed
158 // passwords,
159 // using session keys, as well as an option to use ssh-agent and other
160 // standard
161 // APIs for protected memory.
162 //
163 // UPDATE: Am in the process now of adding the actual Master key. Therefore
164 // OT_MASTER_KEY_TIMEOUT
165 // was added for the actual mechanism, while OT_KEY_TIMER (a stopgap measure)
166 // was set to 0, which
167 // makes it of no effect. Probably OT_KEY_TIMER will be removed entirely (we'll
168 // see.)
169 //
170 #ifndef OT_KEY_TIMER
171 
172 #define OT_KEY_TIMER 30
173 
174 // TODO: Next release, as users get converted to file format 2.0 (master key)
175 // then reduce this timer from 30 to 0. (30 is just to help them convert.)
176 
177 //#define OT_KEY_TIMER 0
178 
179 //#define OT_MASTER_KEY_TIMEOUT 300 // This is in OTEnvelope.h
180 
181 // FYI: 1800 seconds is 30 minutes, 300 seconds is 5 mins.
182 #endif // OT_KEY_TIMER
183 
184 // This is the only part of the API that actually accepts objects as parameters,
185 // since the above objects have SWIG C++ wrappers.
186 //
187 EXPORT bool OT_API_Set_PasswordCallback(OTCaller& theCaller); // Caller must
188  // have Callback
189  // attached
190  // already.
191 
192 // For getting the password from the user, for using his private key.
193 //
194 extern "C" {
195 typedef int32_t OT_OPENSSL_CALLBACK(char* buf, int32_t size, int32_t rwflag,
196  void* userdata); // <== Callback type, used
197  // for declaring.
198 
201 }
202 
203 class OTAsymmetricKey // <========= OT ASYMMETRIC KEY
204 {
205 private:
207  OTAsymmetricKey& operator=(const OTAsymmetricKey&);
208 
209 public: // INSTANTIATION
210  EXPORT static OTAsymmetricKey* KeyFactory(); // Caller IS responsible to
211  // delete!
212  virtual OTAsymmetricKey* ClonePubKey() const; // Caller IS responsible to
213  // delete!
214 public: // PASSWORD CALLBACK
215  static void SetPasswordCallback(OT_OPENSSL_CALLBACK* pCallback);
216  EXPORT static OT_OPENSSL_CALLBACK* GetPasswordCallback();
217  static bool IsPasswordCallbackSet()
218  {
219  return (nullptr == s_pwCallback) ? false : true;
220  }
221  static bool SetPasswordCaller(OTCaller& theCaller);
222  static OTCaller* GetPasswordCaller();
223 
224 protected: // PASSWORD CALLBACK
227 
228 protected: // PROTECTED MEMBER DATA
229  OTASCIIArmor* m_p_ascKey; // base64-encoded, string form of key. (Encrypted
230  // too, for private keys. Should store it in this
231  // form most of the time.)
234  Timer m_timer; // Useful for keeping track how long since I last entered my
235  // passphrase...
236 public:
237  OTSignatureMetadata* m_pMetadata; // Just access this directly, like a
238  // struct. (Check for nullptr.)
239 
240  // To use m_metadata, call m_metadata.HasMetadata(). If it's true, then you
241  // can see
242  // these values:
243  // char m_metadata::GetKeyType() // Can be A, E, or S
244  // (authentication, encryption, or signing. Also, E would be unusual.)
245  // char m_metadata::FirstCharNymID() // Can be any letter from
246  // base62 alphabet. Represents first letter of a Nym's ID.
247  // char m_metadata::FirstCharMasterCredID() // Can be any letter from
248  // base62 alphabet. Represents first letter of a Master Credential ID (for
249  // that Nym.)
250  // char m_metadata::FirstCharSubCredID() // Can be any letter from
251  // base62 alphabet. Represents first letter of a SubCredential ID (signed by
252  // that Master.)
253  //
254  // Here's how metadata works: It's optional. You can set it, or not. If it's
255  // there, OT will add it to the signature
256  // on the contract itself, when this key is used to sign something.
257  // (OTSignature has the same OTSignatureMetadata
258  // struct.) Later on when verifying the signature, the metadata is used to
259  // speed up the lookup/verification process
260  // so we don't have to verify the signature against every single subkey
261  // available for that Nym.
262  // In practice, however, we are adding metadata to every single signature
263  // (except possibly cash...)
264  // (And we will make it mandatory for Nyms who use credentials.)
265  // PROTECTED MEMBER FUNCTIONS
266 protected:
267  void ReleaseKeyLowLevel(); // call this.
268  virtual void ReleaseKeyLowLevel_Hook() const = 0; // override this.
269  // CONSTRUCTION (PROTECTED)
270  EXPORT OTAsymmetricKey();
271 
272 public: // DESTRUCTION
273  EXPORT virtual ~OTAsymmetricKey();
274  virtual void Release();
275  void Release_AsymmetricKey();
276  void ReleaseKey();
277 
278  // PUBLIC METHODS
279  inline bool IsEmpty() const
280  {
281  return (nullptr == m_p_ascKey);
282  } // m_p_ascKey is the most basic value. m_pKey is derived from it, for
283  // example.
284  inline bool IsPublic() const
285  {
286  return m_bIsPublicKey;
287  }
288  inline bool IsPrivate() const
289  {
290  return m_bIsPrivateKey;
291  }
292  inline void SetAsPublic()
293  {
294  m_bIsPublicKey = true;
295  m_bIsPrivateKey = false;
296  } // Don't use this, normally it's not necessary.
297  inline void SetAsPrivate()
298  {
299  m_bIsPublicKey = false;
300  m_bIsPrivateKey = true;
301  } // (Only if you really know what you are doing.)
302  // We're moving to a system where the actual key isn't kept loaded in
303  // memory except under 2 circumstances: 1. We are using it currently,
304  // and we're going to destroy it when we're done with it. 2. A timer
305  // is running, and until the 10 minutes are up, the private key is
306  // available.
307  // But: Presumably it's stored in PROTECTED MEMORY, either with specific
308  // tricks used to prevent swapping and to zero after we're done, and to
309  // prevent core dumps, or it's stored in ssh-agent or some similar standard
310  // API (gpg-agent, keychain Mac Keychain, etc) or Windows protected memory
311  // etc etc. Inside OT I can also give the option to go with our own security
312  // tricks (listed above...) or to keep the timer length at 0, forcing the
313  // password to be entered over and over again. IDEA: When the user enters
314  // the passphrase for a specific Nym, hash it (so your plaintext passphrase
315  // isn't
316  // stored in memory anywhere) and then USE that hash as the passphrase on
317  // the actual key. (Meaning also that the user will not be able to use his
318  // passphrase outside of OT, until he EXPORTS the Nym, since he would also
319  // have
320  // to hash the passphrase before manipulating the raw key file.)
321  // At this point, we have the hash of the user's passphrase, which is what
322  // we
323  // actually use for opening his private key (which is also normally kept in
324  // an encrypted form, on the hard drive AND in RAM!!) So everything from
325  // above
326  // still applies: I don't want to reveal that hash, so I store it using
327  // tricks
328  // to secure the memory (I have to do this part anyway, ANYTIME I touch
329  // certain
330  // forms of data), or in ssh-agent, and so on, except a timer can be set
331  // after
332  // the user first enters his passphrase. For ultimate security, just set the
333  // timer to 0 and type your passphrase every single time. But instead let's
334  // say you set it to 10 minutes. I don't want to store that password hash,
335  // either. (The hash protects the plaintext password, but the hash IS the
336  // ACTUAL
337  // password, so while the plaintext PW is protected, the actual one is still
338  // not.)
339  // Therefore I will select some random data from OpenSSL for use as a
340  // TEMPORARY
341  // password, a session key, and then encrypt all the hashes to that session
342  // key.
343  // This way, the actual passphrases (hashed version) do NOT appear in
344  // memory, AND
345  // NEITHER DO the plaintext versions! You might ask, well then why not just
346  // encrypt
347  // the plaintext passphrase itself and use that? The answer is, to prevent
348  // making
349  // it recoverable. You don't even want someone to get that session key and
350  // then
351  // recover your PLAINTEXT password! Maybe he'll go use it on a thousand
352  // websites!
353  //
354  // Next: How to protect the session key (an OTSymmetricKey) from being
355  // found?
356  // First: destroy it often. Make a new session key EVERY time the timeout
357  // happens.
358  // Also: use it in protected memory as before. This could ALWAYS have a
359  // timeout
360  // of 0! If it's in ssh-agent, what more can you do? At least OT will make
361  // this
362  // configurable, and will be pretty damned secure in its own right.
363  // Ultimately
364  // the best solution here is an extern hardware such as a smart card.
365 
366  virtual bool CalculateID(OTIdentifier& theOutput) const; // Only works for
367  // public keys.
368 
369  // Load private or public key from local storage.
370  //
371  bool LoadPrivateKey(const OTString& strFoldername,
372  const OTString& strFilename,
373  const OTString* pstrReason = nullptr,
374  const OTPassword* pImportPassword = nullptr);
375  bool LoadPublicKey(const OTString& strFoldername,
376  const OTString& strFilename);
377 
378  virtual bool LoadPublicKeyFromPGPKey(
379  const OTASCIIArmor& strKey) = 0; // does NOT handle bookends.
380  // LoadPrivateKeyFromCertString
381  //
382  // "escaped" means pre-pended with "- " as in: - -----BEGIN
383  // CERTIFICATE....
384  //
385  virtual bool LoadPrivateKeyFromCertString(
386  const OTString& strCert, bool bEscaped = true,
387  const OTString* pstrReason = nullptr,
388  const OTPassword* pImportPassword = nullptr) = 0; // Used when importing
389  // an
390  // exported Nym into a wallet.
391  // Load Public Key from Cert (file or string)
392  //
393  virtual bool LoadPublicKeyFromCertString(
394  const OTString& strCert, bool bEscaped = true,
395  const OTString* pstrReason = nullptr,
396  const OTPassword* pImportPassword = nullptr) = 0; // DOES handle
397  // bookends, AND
398  // escapes.
400  const OTString& strFoldername, const OTString& strFilename,
401  const OTString* pstrReason = nullptr,
402  const OTPassword* pImportPassword = nullptr); // DOES handle bookends.
403  virtual bool SaveCertToString(
404  OTString& strOutput, const OTString* pstrReason = nullptr,
405  const OTPassword* pImportPassword = nullptr) const = 0;
406  virtual bool SavePrivateKeyToString(
407  OTString& strOutput, const OTString* pstrReason = nullptr,
408  const OTPassword* pImportPassword = nullptr) const = 0;
409  virtual bool ReEncryptPrivateKey(const OTPassword& theExportPassword,
410  bool bImporting) const = 0;
411  // PUBLIC KEY
412 
413  // * Get the public key in ASCII-armored format --
414  // OTASCIIArmor
415  // * Get the public key in ASCII-armored format WITH bookends -- OTString
416  // - ------- BEGIN PUBLIC KEY --------
417  // Notice the "- " before the rest of the bookend starts.
418  EXPORT bool GetPublicKey(OTASCIIArmor& strKey) const;
419  EXPORT bool GetPublicKey(OTString& strKey, bool bEscaped = true) const;
420  // (Below) Decodes a public key from ASCII armor into an actual key pointer
421  // and sets that as the m_pKey on this object.
422  EXPORT bool SetPublicKey(const OTASCIIArmor& strKey);
423  EXPORT bool SetPublicKey(const OTString& strKey, bool bEscaped = false);
424  // (Above) Decodes a public key from bookended key string into an actual key
425  // pointer, and sets that as the m_pKey on this object.
426  // This is the version that will handle the bookends ( -----BEGIN PUBLIC
427  // KEY-----)
428 
429  // PRIVATE KEY
430  // Get the private key in ASCII-armored format with bookends
431  // - ------- BEGIN ENCRYPTED PRIVATE KEY --------
432  // Notice the "- " before the rest of the bookend starts.
433  bool GetPrivateKey(OTString& strKey, bool bEscaped = true) const;
434  bool GetPrivateKey(OTASCIIArmor& strKey) const; // Get the private key in
435  // ASCII-armored format
436 
437  // Decodes a private key from ASCII armor into an actual key pointer
438  // and sets that as the m_pKey on this object.
439  // This is the version that will handle the bookends ( -----BEGIN ENCRYPTED
440  // PRIVATE KEY-----)
441  bool SetPrivateKey(const OTString& strKey, bool bEscaped = false);
442  bool SetPrivateKey(const OTASCIIArmor& strKey); // Decodes a private key
443  // from ASCII armor into an
444  // actual key pointer and
445  // sets that as the m_pKey
446  // on this object.
447 };
448 
449 } // namespace opentxs
450 
451 #endif // OPENTXS_CORE_CRYPTO_OTASYMMETRICKEY_HPP
virtual OTAsymmetricKey * ClonePubKey() const
static EXPORT OTAsymmetricKey * KeyFactory()
virtual bool ReEncryptPrivateKey(const OTPassword &theExportPassword, bool bImporting) const =0
std::list< OTAsymmetricKey * > listOfAsymmetricKeys
Definition: Timer.hpp:31
virtual bool LoadPublicKeyFromCertString(const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)=0
static OTCaller * s_pCaller
EXPORT OT_OPENSSL_CALLBACK souped_up_pass_cb
bool LoadPublicKey(const OTString &strFoldername, const OTString &strFilename)
int32_t OT_OPENSSL_CALLBACK(char *buf, int32_t size, int32_t rwflag, void *userdata)
OTSignatureMetadata * m_pMetadata
virtual bool LoadPrivateKeyFromCertString(const OTString &strCert, bool bEscaped=true, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)=0
EXPORT OT_OPENSSL_CALLBACK default_pass_cb
bool LoadPublicKeyFromCertFile(const OTString &strFoldername, const OTString &strFilename, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
virtual bool SaveCertToString(OTString &strOutput, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr) const =0
static OTCaller * GetPasswordCaller()
bool SetPrivateKey(const OTString &strKey, bool bEscaped=false)
static OT_OPENSSL_CALLBACK * s_pwCallback
static bool SetPasswordCaller(OTCaller &theCaller)
EXPORT bool SetPublicKey(const OTASCIIArmor &strKey)
virtual bool LoadPublicKeyFromPGPKey(const OTASCIIArmor &strKey)=0
bool GetPrivateKey(OTString &strKey, bool bEscaped=true) const
EXPORT bool GetPublicKey(OTASCIIArmor &strKey) const
virtual bool SavePrivateKeyToString(OTString &strOutput, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr) const =0
virtual bool CalculateID(OTIdentifier &theOutput) const
static void SetPasswordCallback(OT_OPENSSL_CALLBACK *pCallback)
virtual void ReleaseKeyLowLevel_Hook() const =0
static bool IsPasswordCallbackSet()
bool LoadPrivateKey(const OTString &strFoldername, const OTString &strFilename, const OTString *pstrReason=nullptr, const OTPassword *pImportPassword=nullptr)
static EXPORT OT_OPENSSL_CALLBACK * GetPasswordCallback()
virtual EXPORT ~OTAsymmetricKey()
EXPORT bool OT_API_Set_PasswordCallback(OTCaller &theCaller)