Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TokenLucre.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * TokenLucre.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 "../core/stdafx.hpp"
134 
135 #include "TokenLucre.hpp"
136 #include "DigitalCash.hpp"
137 #include "Mint.hpp"
138 #include "Token.hpp"
139 
140 #include "../core/crypto/OTEnvelope.hpp"
141 
142 #if defined(OT_CASH_USING_LUCRE)
143 #include "../core/crypto/OpenSSL_BIO.hpp"
144 #endif
145 
146 #include "../core/OTLog.hpp"
147 
148 // SUBCLASSES OF OTTOKEN FOR EACH DIGITAL CASH ALGORITHM.
149 
150 #if defined(OT_CASH_USING_MAGIC_MONEY)
151 // Todo: Someday...
152 #endif // Magic Money
153 
154 namespace opentxs
155 {
156 
157 #if defined(OT_CASH_USING_LUCRE) && defined(OT_CRYPTO_USING_OPENSSL)
158 
160  : ot_super()
161 {
162 }
163 
165  const OTIdentifier& ASSET_ID)
166  : ot_super(SERVER_ID, ASSET_ID)
167 {
168 }
169 
171  : ot_super(thePurse)
172 {
173 }
174 
176 {
177 }
178 
179 // Lucre step 2 (client generates coin request)
180 // nDenomination must be one of the denominations supported by the mint.
181 // sets m_nTokenCount and populates the maps with prototokens (in ASCII-armored
182 // format.)
184  int64_t lDenomination,
185  int32_t nTokenCount)
186 {
187  // otErr << "%s <bank public info> <coin request private output file>
188  // <coin request public output file>\n", argv[0]);
189  //
190  if (Token::blankToken != m_State) {
191  otErr << "Token_Lucre::GenerateTokenRequest: Blank token expected.\n";
192  return false;
193  }
194 
195  LucreDumper setDumper; // todo security.
196 
197  OpenSSL_BIO bioBank = BIO_new(
198  BIO_s_mem()); // Input. We must supply the bank's public lucre info
199 
200  // This version base64-DECODES the ascii-armored string passed in,
201  // and then sets the decoded plaintext string onto the string.
202  // OTString::OTString(const OTASCIIArmor & strValue)
203  OTASCIIArmor ascPublicMint;
204 
205  theMint.GetPublic(ascPublicMint, lDenomination);
206  // otErr << "DEBUG: OTToken public asc: \n%s\n", ascPublicMint.Get());
207 
208  OTString strPublicMint(ascPublicMint);
209  // otErr << "DEBUG: OTToken public str: \n%s\n", strPublicMint.Get());
210 
211  // Get the bank's public key (now decoded in strPublicMint)
212  // and put it into bioBank so we can use it with Lucre.
213  BIO_puts(bioBank, strPublicMint.Get());
214 
215  // Instantiate a PublicBank (Lucre) object.
216  // We will use it to generate all the prototokens in the loop below.
217  PublicBank bank;
218  bank.ReadBIO(bioBank);
219 
220  Release(); // note: why is this here? I guess to release the prototokens,
221  // the signature (is there one?) and m_ascSpendable (exists?
222  // doubt it.) This WAS also doing "InitToken" (no longer) which
223  // WAS setting series and expiration range back to 0 (no longer.)
224  // Which was causing problems for all series above 0. I'm leaving
225  // this call here, to do the stuff I guess it was put here for.
226  // But things such as the series, expiration date range, and
227  // token count, etc are no longer (inadvertantly) set to 0 here
228  // on this line. I'm also moving the SetSeriesAndExpiration call
229  // to be BELOW this line, since it's not apparently needed above
230  // this line anyway.
231 
232  // We are supposed to set these values here.
233  // The server actually sets them again, for security reasons.
234  // But we should still set them since server may choose to reject the
235  // request.
236  // Update: the series information on this token IS used by the server, since
237  // more than
238  // one mint may be currently valid, and since the server has to process the
239  // request using
240  // the proper mint, corresponding to the same mint that was used to GENERATE
241  // that request.
242  // So the server uses the series value from this token in order to choose
243  // which mint is loaded,
244  // on the server side. When this call WAS above the Release() call above,
245  // these values were
246  // getting wiped in Release back to 0. So I've moved it below the Release()
247  // call. (I've also
248  // stopped wiping them in Release.)
249  //
250  SetSeriesAndExpiration(theMint.GetSeries(), theMint.GetValidFrom(),
251  theMint.GetValidTo());
252 
253  const int32_t nFinalTokenCount =
254  (nTokenCount < Token::GetMinimumPrototokenCount())
256  : nTokenCount;
257 
258  // Token count is actually 1 (always) with Lucre, although this lib has
259  // potential to work with
260  // multiple proto-tokens, you can see this loop as though it always executes
261  // just once.
262  for (int32_t i = 0; i < nFinalTokenCount; i++) {
263  OpenSSL_BIO bioCoin = BIO_new(BIO_s_mem()); // These two are output. We
264  // must write these bios,
265  // after
266  OpenSSL_BIO bioPublicCoin = BIO_new(
267  BIO_s_mem()); // the operation, back into some form we can use
268 
269  CoinRequest req(bank);
270 
271  // write the private coin request to BIO
272  req.WriteBIO(bioCoin);
273 
274  // write the public coin request to BIO
275  ((PublicCoinRequest*)&req)->WriteBIO(bioPublicCoin);
276 
277  // Convert the two bios to our format
278  char privateCoinBuffer[4096],
279  publicCoinBuffer[4096]; // todo stop hardcoding these string lengths
280  int32_t privatecoinLen = BIO_read(bioCoin, privateCoinBuffer,
281  4000); // cutting it a little short on
282  // purpose, with the buffer.
283  // Just makes me feel more
284  // comfortable for some reason.
285  int32_t publiccoinLen = BIO_read(bioPublicCoin, publicCoinBuffer, 4000);
286 
287  if (privatecoinLen && publiccoinLen) {
288  // With this, we have the Lucre public and private bank info
289  // converted to OTStrings
290  OTString strPublicCoin;
291  strPublicCoin.Set(publicCoinBuffer, publiccoinLen);
292  OTString strPrivateCoin;
293  strPrivateCoin.Set(privateCoinBuffer, privatecoinLen);
294 
295  OTASCIIArmor* pArmoredPublic = new OTASCIIArmor(strPublicCoin);
296  OTASCIIArmor* pArmoredPrivate = new OTASCIIArmor();
297 
299  ((nullptr != pArmoredPublic) && (nullptr != pArmoredPrivate)),
300  "ERROR: Unable to allocate memory in "
301  "Token_Lucre::GenerateTokenRequest\n");
302 
303  // Change the state. It's no longer a blank token, but a prototoken.
305 
306  // Seal the private coin info up into an encrypted Envelope
307  // and set it onto pArmoredPrivate (which was just added to our
308  // internal map, above.)
309  OTEnvelope theEnvelope;
310  theEnvelope.Seal(theNym, strPrivateCoin); // Todo check the return
311  // values on these two
312  // functions
313  theEnvelope.GetAsciiArmoredData(*pArmoredPrivate);
314 
315  m_mapPublic[i] = pArmoredPublic;
316  m_mapPrivate[i] = pArmoredPrivate;
317 
318  m_nTokenCount = nFinalTokenCount;
319  SetDenomination(lDenomination);
320  }
321  else {
322  // Error condition todo
323  }
324  }
325 
326  return true;
327 }
328 
329 // Lucre step 4: client unblinds token -- now it's ready for use.
330 // Final unblinded spendable token is encrypted to theNym for safe storage.
331 //
332 bool Token_Lucre::ProcessToken(const OTPseudonym& theNym, Mint& theMint,
333  Token& theRequest)
334 {
335  // otErr << "%s <bank public info> <private coin request> <signed coin
336  // request> <coin>\n",
337  bool bReturnValue = false;
338 
339  // When the Mint has signed a token and sent it back to the client,
340  // the client must unblind the token and set it as spendable. Thus,
341  // this function is only performed on tokens in the signedToken state.
342  if (Token::signedToken != m_State) {
343  otErr << "Signed token expected in Token_Lucre::ProcessToken\n";
344  return false;
345  }
346 
347  // Lucre
348  LucreDumper setDumper; // todo security.
349 
350  OpenSSL_BIO bioBank = BIO_new(BIO_s_mem()); // input
351  OpenSSL_BIO bioSignature = BIO_new(BIO_s_mem()); // input
352  OpenSSL_BIO bioPrivateRequest = BIO_new(BIO_s_mem()); // input
353  OpenSSL_BIO bioCoin = BIO_new(BIO_s_mem()); // output
354 
355  // Get the bank's public key (decoded into strPublicMint)
356  // and put it into bioBank so we can use it with Lucre.
357  //
358  OTASCIIArmor ascPublicMint;
359  theMint.GetPublic(ascPublicMint, GetDenomination());
360  OTString strPublicMint(ascPublicMint);
361  BIO_puts(bioBank, strPublicMint.Get());
362 
363  // Get the existing signature into a bio.
364  // otErr << "DEBUGGING, m_Signature: -------------%s--------------\n",
365  // m_Signature.Get());
366  OTString strSignature(m_Signature);
367  BIO_puts(bioSignature, strSignature.Get());
368 
369  // I need the Private coin request also. (Only the client has this private
370  // coin request data.)
371  OTASCIIArmor thePrototoken; // The server sets m_nChosenIndex when it signs
372  // the token.
373  bool bFoundToken =
374  theRequest.GetPrivatePrototoken(thePrototoken, m_nChosenIndex);
375 
376  if (bFoundToken) {
377  // otErr << "THE PRIVATE REQUEST ARMORED
378  // CONTENTS:\n------------------>%s<-----------------------\n",
379  // thePrototoken.Get());
380 
381  // Decrypt the prototoken
382  OTString strPrototoken;
383  OTEnvelope theEnvelope(thePrototoken);
384  theEnvelope.Open(theNym, strPrototoken); // todo check return value.
385 
386  // otErr << "THE PRIVATE REQUEST
387  // CONTENTS:\n------------------>%s<-----------------------\n",
388  // strPrototoken.Get());
389 
390  // copy strPrototoken to a BIO
391  BIO_puts(bioPrivateRequest, strPrototoken.Get());
392 
393  // ------- Okay, the BIOs are all loaded.... let's process...
394 
395  PublicBank bank(bioBank);
396  CoinRequest req(bioPrivateRequest);
397 
398  // TODO make sure I'm not leaking memory with these ReadNumbers
399  // Probably need to be calling some free function for each one.
400 
401  // Apparently reading the request id here and then just discarding it...
402  ReadNumber(bioSignature, "request=");
403 
404  // Versus the signature data, which is read into bnSignature apparently.
405  BIGNUM* bnSignature = ReadNumber(bioSignature, "signature=");
406  DumpNumber("signature=", bnSignature);
407 
408  // Produce the final unblinded token in Coin coin, and write it to
409  // bioCoin...
410  Coin coin; // Coin Request, processes into Coin, with Bank and Signature
411  // passed in.
412  req.ProcessResponse(&coin, bank, bnSignature); // Notice still
413  // apparently "request"
414  // info is discarded.
415  coin.WriteBIO(bioCoin);
416 
417  // convert bioCoin to a C-style string...
418  char CoinBuffer[1024]; // todo stop hardcoding these string lengths
419  int32_t coinLen =
420  BIO_read(bioCoin, CoinBuffer, 1000); // cutting it a little short on
421  // purpose, with the buffer.
422  // Just makes me feel more
423  // comfortable for some reason.
424 
425  if (coinLen) {
426  // ...to OTString...
427  OTString strCoin;
428  strCoin.Set(CoinBuffer, coinLen);
429 
430  // otErr << "Processing token...\n%s\n", strCoin.Get());
431 
432  // ...to Envelope stored in m_ascSpendable (encrypted and
433  // base64-encoded)
434  OTEnvelope theEnvelope;
435  theEnvelope.Seal(theNym, strCoin); // Todo check the return values
436  // on these two functions
437  theEnvelope.GetAsciiArmoredData(
438  m_ascSpendable); // Here's the final product.
439 
440  // otErr << "NEW SPENDABLE
441  // token...\n--------->%s<----------------\n",
442  // m_ascSpendable.Get());
443 
444  // Now the coin is encrypted from here on out, and otherwise
445  // ready-to-spend.
447  bReturnValue = true;
448 
449  // Lastly, we free the signature data, which is no longer needed,
450  // and which could be
451  // otherwise used to trace the token. (Which we don't want.)
453  }
454  }
455  // Todo log error here if the private prototoken is not found. (Very strange
456  // if so!!)
457  // else {}
458 
459  return bReturnValue;
460 }
461 
462 #endif // defined(OT_CASH_USING_LUCRE) && defined(OT_CRYPTO_USING_OPENSSL)
463 
464 } // namespace opentxs
int32_t m_nChosenIndex
Definition: Token.hpp:246
static EXPORT int32_t GetMinimumPrototokenCount()
Definition: Token.cpp:180
void WriteBIO(BIO *bio)
OTASCIIArmor m_Signature
Definition: Token.hpp:227
Definition: bank.h:185
void DumpNumber(BIO *out, const char *szTitle, const BIGNUM *bn, const char *szTrailer=_NL)
BIGNUM * ReadNumber(BIO *in, const char *szTitle)
virtual EXPORT bool GenerateTokenRequest(const OTPseudonym &theNym, Mint &theMint, int64_t lDenomination, int32_t nTokenCount=Token::GetMinimumPrototokenCount())
Definition: TokenLucre.cpp:183
virtual EXPORT ~Token_Lucre()
Definition: TokenLucre.cpp:175
EXPORT bool Open(const OTPseudonym &theRecipient, OTString &theOutput, const OTPasswordData *pPWData=nullptr)
Definition: OTEnvelope.cpp:581
EXPORT bool Seal(const OTPseudonym &theRecipient, const OTString &theInput)
Definition: OTEnvelope.cpp:521
int32_t GetSeries() const
Definition: Mint.hpp:214
EXPORT bool GetPrivatePrototoken(OTASCIIArmor &ascPrototoken, int32_t nTokenIndex)
Definition: Token.cpp:1062
void SetDenomination(int64_t lVal)
Definition: Token.hpp:413
void ReadBIO(BIO *bio)
void WriteBIO(BIO *bio)
bool GetPublic(OTASCIIArmor &theArmor, int64_t lDenomination)
Definition: Mint.cpp:574
time64_t GetValidTo() const
Definition: Mint.hpp:222
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
Definition: OTString.cpp:1055
EXPORT bool GetAsciiArmoredData(OTASCIIArmor &theArmoredText, bool bLineBreaks=true) const
Definition: OTEnvelope.cpp:162
int64_t GetDenomination() const
Definition: Token.hpp:409
virtual void Release()
Definition: Token.cpp:286
mapOfPrototokens m_mapPrivate
Definition: Token.hpp:240
#define OT_ASSERT_MSG(x, s)
Definition: Assert.hpp:155
time64_t GetValidFrom() const
Definition: Mint.hpp:218
void ProcessResponse(Coin *pCoin, PublicBank &bank, BIGNUM *bnSignedCoinRequest)
Definition: bank.h:311
void SetSeriesAndExpiration(int32_t nSeries, time64_t VALID_FROM, time64_t VALID_TO)
Definition: Token.hpp:373
OTASCIIArmor m_ascSpendable
Definition: Token.hpp:224
int32_t m_nTokenCount
Definition: Token.hpp:244
EXPORT const char * Get() const
Definition: OTString.cpp:1045
OTLOG_IMPORT OTLogStream otErr
virtual EXPORT bool ProcessToken(const OTPseudonym &theNym, Mint &theMint, Token &theRequest)
Definition: TokenLucre.cpp:332
mapOfPrototokens m_mapPublic
Definition: Token.hpp:237
tokenState m_State
Definition: Token.hpp:269
virtual EXPORT void Release()
Definition: OTString.cpp:765