class PrintingPress(PermanentObjectMixin): INSTANCE = None #ISSUER = "PLAYGROUND PROJECT ROOT BANK - Q1 2014" SERIES_RANGE = 9999999999 """PASSWORD_SALT = "PRINTING_PRESS" ENCRYPTION_IV = "PENNYSAVEDEARNED" SIGNATURE_SIZE = 128""" @classmethod def CreateBankVault(cls, filename, certificate, privateKey, password, startingSerialNumber=0): seriesStringLength = len(str(cls.SERIES_RANGE)) seriesTemplate = "P%" + ("%0d"%seriesStringLength) + "d" series = seriesTemplate % random.randint(0,cls.SERIES_RANGE) cls.secureSaveState(filename, certificate, privateKey, password, serialNumber=startingSerialNumber, series=series) def __init__(self, certificate, password, bankStateVaultFileName): if not os.path.exists(bankStateVaultFileName): raise Exception ("No Bank State Vault %s" % bankStateVaultFileName) if PrintingPress.INSTANCE: raise Exception("Duplicate Printing Press") PrintingPress.INSTANCE = self self.__cert = certificate self.ISSUER = getCertSubject(self.__cert)["commonName"] self.__password = password self.__stateFileName = bankStateVaultFileName self.__loadState() def __loadState(self): self.__privateKey, state = self.secureLoadState(self.__stateFileName, self.__cert, self.__password) self.__signaturePad = RSA_SIGNATURE_MAC(self.__privateKey) self.__serialNumber = state["serialNumber"] self.__series = state["series"] def __saveState(self): self.CreateBankVault(self.__stateFileName, self.__cert, self.__privateKey, self.__password, self.__serialNumber) def __getNewSerialNumbers(self, count=1): baseSerialNumber = self.__serialNumber self.__serialNumber += count self.__saveState() return [baseSerialNumber+i for i in range(count)] def mintBitPoints(self, count, depositor): newSerialNumbers = self.__getNewSerialNumbers(count) bitPoints = [] for i in range(count): bitPoint = BitPoint.mintNew( issuer=self.ISSUER, serialNumber="%020d" % newSerialNumbers[i], timestamp=time.ctime() ) bitPointBin = bitPoint.mainDataBlob() bitPoint.setSignature(self.__signaturePad.sign(bitPointBin)) bitPoints.append(bitPoint) depositor(bitPoints)
def __loadState(self): self.__privateKey, state = self.secureLoadState( self.__stateFileName, self.__cert, self.__password) self.__signaturePad = RSA_SIGNATURE_MAC(self.__privateKey) self.__serialNumber = state["serialNumber"] self.__series = state["series"]
def __init__(self, bankcert, merchantaccount): self.__receivingAccount = merchantaccount self.__verifier = RSA_SIGNATURE_MAC(bankcert.public_key())
class PayingServerWallet(IMobileCodeServerWallet): def __init__(self, bankcert, merchantaccount): self.__receivingAccount = merchantaccount self.__verifier = RSA_SIGNATURE_MAC(bankcert.public_key()) def clearState(self, cookie): pass def getId(self): return "Paying Wallet 1.0" def processPayment(self, cookie, charges, paymentData): debugPrint("PayingServerWallet called processPayment with: charges =", charges, "cookie=", cookie, "paymentData(size)=", len(paymentData)) if charges == 0: return True, "" receiptpkt = Receipt.Deserialize(paymentData) # Check the validity of the signature check, reason = self.__receipt(receiptpkt) if check: receiptData = eval(receiptpkt.Receipt) # Since the receipt bytes have been signed by the bank that we trust, we assume it's safe to unpickle it ledgerline = pickle.loads(receiptData) # # Check the receipt's validity (correct amount and account and memo/cookie) # debugPrint("LedgerLine complete:", ledgerline.complete()) # debugPrint("LedgerLine amount:", ledgerline.getTransactionAmount(self.__receivingAccount)) # debugPrint("LedgerLine memo:", ledgerline.memo()) valid = True valid &= ledgerline.complete() valid &= ledgerline.getTransactionAmount( self.__receivingAccount) == charges valid &= ledgerline.memo(self.__receivingAccount) == str(cookie) if valid: debugPrint("PayingServerWallet has validated the receipt!") return True, "" return False, "PayingServerWallet processPayment received receipt failed checks" def __receipt(self, msgObj): try: receiptFile = "bank_receipt." + str(time.time()) sigFile = receiptFile + ".signature" debugPrint( "Paying Server Wallet: Receipt and signature received. Saving as %s and %s" % (receiptFile, sigFile)) receiptBytes = eval(msgObj.Receipt) sigBytes = eval(msgObj.ReceiptSignature) with open(receiptFile, "wb") as f: f.write(receiptBytes) with open(sigFile, "wb") as f: f.write(sigBytes) if not self.__verifier.verify(receiptBytes, sigBytes): responseTxt = "Received a receipt with mismatching signature.\n" responseTxt += "\tPlease report this to the bank administrator.\n" debugPrint("Paying Server Wallet: ", responseTxt) return False, "Received a receipt with mismatching signature." else: debugPrint( "Paying Server Wallet: Signature validated against the receipt." ) return True, "" except Exception as e: print(traceback.format_exc())