def listAllClientBids(sock, symmetricEncryption, sessionId): mandatoryFields = [] mandatoryFields.append(Field("clientId", str)) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 4) clientId = msg["clientId"] mutex.acquire() if clientId not in CLIENTS.keys(): sendEncryptedMessage(sock, {"auctionsList": []}, symmetricEncryption, sessionId, 5) else: auctionsList = [] for auctionId in CLIENTS[clientId]: bids = [] if auctionId in OPEN_AUCTIONS.keys(): bids = OPEN_AUCTIONS[auctionId].getClientBids(clientId) else: #auctionId in CLOSED_AUCTIONS.keys() bids = CLOSED_AUCTIONS[auctionId].getClientBids(clientId) if bids != []: auctionsList.append(bids) sendEncryptedMessage(sock, {"auctionsList": auctionsList}, symmetricEncryption, sessionId, 5) mutex.release()
def createAuction(sock, symmetricEncryption, sessionId): global SERIAL_NUMBER #Gets auction details msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) mutex.acquire() msgRecv["auctionId"] = SERIAL_NUMBER creationTime = int(time()) msgRecv["creationTime"] = creationTime #Create auction with: auctionId = SERIAL_NUMBER auction = Auction(msgRecv) OPEN_AUCTIONS[SERIAL_NUMBER] = auction #Returns to manager auctionId sendEncryptedMessage(sock, { 'auctionId': SERIAL_NUMBER, "creationTime": creationTime }, symmetricEncryption, sessionId, 5) auction.timerThread = threading.Timer( msgRecv["duration"] * 60, closeAuctionTime, [SERIAL_NUMBER, msgRecv["creatorId"]]) auction.timerThread.start() SERIAL_NUMBER += 1 mutex.release()
def validateReceipt(): receipts = [] names = [] cert = getCertificate() clientId, _ = getUserInfo(cert) if not os.path.exists("receipts/" + clientId): print("No receipts found!") return for entry in scandir("receipts/" + clientId): names.append(entry.name) with open("receipts/" + clientId + "/" + entry.name, "r") as f: receipts.append(json.loads(f.read())) for i, name in enumerate(names): print("## {} ##".format(i+1)) print("Receipt name:", name) print("-----------------\n") while True: opt = input("$ ") if not match("^[0-9]+$", opt): print("ERROR: Insert a valid number!") continue opt = int(opt) if opt < 1 or opt > len(names): print("Error: Insert a number between 1 and " + str(len(names))) continue opt -= 1 break receipt = receipts[opt] auctionId = receipt["auctionId"] receipt = receipt["receipt"] sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(constants.REPOSITORY_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {"action":ActionTypes.VALIDATE_RECEIPT}, symmetricEncryption, sessionId, 3) sendEncryptedMessage(sock, {"auctionId":auctionId}, symmetricEncryption, sessionId, 4) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 5) sock.close() validateReceiptLoaded(receipt, msgRecv["dataToValidate"], auctionId)
def closeAuction(sock, clientCert, symmetricEncryption, sessionId): # Gets clientID to receive open auctions clientID, clientName = getUserInfo(clientCert) # Verify if the current client has auction open if clientID not in CLIENTS.keys() or len(CLIENTS[clientID]) == 0: sendEncryptedMessage(sock, {"openAuctionList": []}, symmetricEncryption, sessionId, 4) return # Gather info of all open auction of the client openAuctionList = [] for auctionId in CLIENTS[clientID]: openAuctionList.append(AUCTIONS[auctionId].auctionInfo) # Sends open auctions sendEncryptedMessage(sock, {'openAuctionList': openAuctionList}, symmetricEncryption, sessionId, 4) # Gets auctionID to close mandatoryFields = [] mandatoryFields.append(Field("auctionID", int)) msgRecv = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 5) auctionID = msgRecv['auctionID'] auction = AUCTIONS[auctionID] # Connect to the repository to close the auction sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock2.connect(constants.REPOSITORY_ADDR) symmetricEncryption2, sessionId2 = handshake.clientHandShake( sock2, privateKey, certificate, POSSIB_CIPHERS, POSSIB_MODES, POSSIB_PADDING) key = b64encode(auction.key).decode("ascii") # Sends the request to Repository sendEncryptedMessage(sock2, {'action': ActionTypes.CLOSE_AUCTION}, symmetricEncryption2, sessionId2, 3) sendEncryptedMessage(sock2, { "auctionID": auctionID, 'key': key }, symmetricEncryption2, sessionId2, 4) # Receive the winner bid msgRecv = readMessage(sock2, [], symmetricEncryption2, sessionId2, 5) # Send the winner bid to the creator sendEncryptedMessage(sock, { 'winnerBid': msgRecv["winnerBid"], "key": key }, symmetricEncryption, sessionId, 6) # Remove local info AUCTIONS.pop(auctionID) CLIENTS[clientID].remove(auctionID)
def listAllOpenAuctions(sock, symmetricEncryption, sessionId): mutex.acquire() openAuctionList = [] for auction in OPEN_AUCTIONS.values(): openAuctionList.append(auction.getAuctionInfo()) mutex.release() #Sends lists with all open auctions sendEncryptedMessage(sock, {"openAuctionList": openAuctionList}, symmetricEncryption, sessionId, 4)
def listAllClosedAuctions(sock, symmetricEncryption, sessionId): mutex.acquire() closedAuctionList = [] for auction in CLOSED_AUCTIONS.values(): closedAuctionList.append(auction.getAuctionInfo()) mutex.release() #sends list with all closed auctions sendEncryptedMessage(sock, {"closedAuctionList": closedAuctionList}, symmetricEncryption, sessionId, 4)
def validateReceipt(sock, clientCert, symmetricEncryption, sessionId): mandatoryFields = [] mandatoryFields.append(Field("auctionId", int)) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 4) auctionId = msg["auctionId"] clientId, clientName = getUserInfo(clientCert) mutex.acquire() if clientId not in CLIENTS.keys() or auctionId not in CLIENTS[clientId]: mutex.release() sendEncryptedMessage( sock, {"error": "No participation of the client on the auction"}, symmetricEncryption, sessionId, 5) return if auctionId in OPEN_AUCTIONS.keys(): sendEncryptedMessage( sock, {"dataToValidate": OPEN_AUCTIONS[auctionId].getAllData()}, symmetricEncryption, sessionId, 5) elif auctionId in CLOSED_AUCTIONS.keys(): sendEncryptedMessage( sock, {"dataToValidate": CLOSED_AUCTIONS[auctionId].getAllData()}, symmetricEncryption, sessionId, 5) else: sendEncryptedMessage(sock, {"error": "No auction with that id"}, symmetricEncryption, sessionId, 5) mutex.release()
def validateAuction(sock, symmetricEncryption, sessionId): auctionsList = [] mutex.acquire() for auction in OPEN_AUCTIONS.values(): auctionsList.append(auction.getAuctionInfo()) for auction in CLOSED_AUCTIONS.values(): auctionsList.append(auction.getAuctionInfo()) #sends list with all closed auctions sendEncryptedMessage(sock, {"auctionList": auctionsList}, symmetricEncryption, sessionId, 4) mandatoryFields = [] mandatoryFields.append(Field("auctionId", int)) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 5) auctionId = msg["auctionId"] if auctionId in OPEN_AUCTIONS.keys(): sendEncryptedMessage( sock, {"allData": OPEN_AUCTIONS[auctionId].getAllData()}, symmetricEncryption, sessionId, 6) elif auctionId in CLOSED_AUCTIONS.keys(): sendEncryptedMessage( sock, {"allData": CLOSED_AUCTIONS[auctionId].getAllData()}, symmetricEncryption, sessionId, 6) else: sendEncryptedMessage(sock, {"error": "No auction with that id"}, symmetricEncryption, sessionId, 6) mutex.release()
def checkOutcomeOfAuction(sock, clientCert, symmetricEncryption, sessionId): clientId, clientName = getUserInfo(clientCert) mutex.acquire() if clientId not in CLIENTS.keys(): mutex.release() sendEncryptedMessage(sock, {"participatedAuctionList": []}, symmetricEncryption, sessionId, 4) return auctions = [] for auctionId in CLIENTS[clientId]: auctions.append(CLOSED_AUCTIONS[auctionId].getAuctionInfo()) sendEncryptedMessage(sock, {"participatedAuctionList": auctions}, symmetricEncryption, sessionId, 4) mandatoryFields = [] mandatoryFields.append(Field("auctionId", int)) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 5) auctionId = msg["auctionId"] if auctionId not in CLOSED_AUCTIONS.keys(): mutex.release() sendEncryptedMessage(sock, {"error": "Invalid auctionId"}, sessionId, 6) return sendEncryptedMessage(sock, CLOSED_AUCTIONS[auctionId].getWinnerBid(), symmetricEncryption, sessionId, 6) mutex.release()
def listClientBids(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) clientId = input("Client Id to search: ") sock.connect(constants.REPOSITORY_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {'action':ActionTypes.LIST_ALL_CLIENT_BIDS}, symmetricEncryption, sessionId, 3) sendEncryptedMessage(sock, {'clientId':clientId}, symmetricEncryption, sessionId, 4) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 5) if len(msgRecv["auctionsList"]) == 0: print("No bids of this client") sock.close() return for auction in msgRecv["auctionsList"]: bids = [] if type(auction) == list: bids = auction elif type(auction) == dict: key = b64decode(bytes(auction["key"], "ascii")) for bid in auction["bidsList"]: decryptBid(bid, key) bids = auction["bidsList"] else: assert False for bid in bids: print("Client Id:", bid["clientId"]) print("Client Name:", bid["clientName"]) print("Client Certificate:", bid["clientCertificate"]) print("Amount:", bid["amount"]) print("Timestamp:", bid["timestamp"]) print("Nonce:", bid["nonce"]) print("Auction Id:", bid["auctionId"]) print("Auction Type:", bid["auctionType"]) print("------------------------\n") sock.close()
def closeAuctionTime(auctionId, creatorId): mutex.acquire() if auctionId not in OPEN_AUCTIONS.keys(): mutex.release() return sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(constants.MANAGER_ADDR) symmetricEncryption, sessionId = handshake.clientHandShake( sock, privateKey, certificate, POSSIB_CIPHERS, POSSIB_MODES, POSSIB_PADDING) sendEncryptedMessage(sock, {"action": ActionTypes.CLOSE_AUCTION_TIME}, symmetricEncryption, sessionId, 3) auction = OPEN_AUCTIONS[auctionId] sendEncryptedMessage(sock, {"auctionId": auctionId}, symmetricEncryption, sessionId, 4) mandatoryFields = [] mandatoryFields.append(BytesField("key")) msgRecv = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 5) _, participatingClients = auction.makePublic(msgRecv["key"]) creatorId = auction.getAuctionInfo()["creatorId"] if creatorId not in CLIENTS: CLIENTS[creatorId] = set() CLIENTS[creatorId].add(auctionId) for clientId in participatingClients: if clientId not in CLIENTS: CLIENTS[clientId] = set() CLIENTS[clientId].add(auctionID) if auction.getAuctionInfo()["type"] == "BlindShown": del CLIENTS_BIDS_COUNT[clientId][auctionID] #Moves auction from openAuctions to closedAuctions CLOSED_AUCTIONS[auctionId] = OPEN_AUCTIONS.pop(auctionId) mutex.release()
def closeAuctionTime(sock, symmetricEncryption, sessionId): # Receive bids to decript msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) auctionId = msgRecv["auctionId"] auction = AUCTIONS[auctionId] creatorId = auction.auctionInfo["creatorId"] cipherData = {"key": b64encode(auction.key).decode("ascii")} # Send data to repository sendEncryptedMessage(sock, cipherData, symmetricEncryption, sessionId, 5) # Remove local info AUCTIONS.pop(auctionId) CLIENTS[creatorId].remove(auctionId)
def run(self): symmetricEncryption, clientCert, clientIsServer, sessionId = handshake.serverHandShake( self.conn, privateKey, certificate) mandatoryFields = [] mandatoryFields.append(Field("action", int)) msg = readMessage(self.conn, mandatoryFields, symmetricEncryption, sessionId, 3) # client's requests if msg["action"] == ActionTypes.CREATE_AUCTION: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return createAuction(self.conn, clientCert, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.CLOSE_AUCTION: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return closeAuction(self.conn, clientCert, symmetricEncryption, sessionId) # repository's requests elif msg["action"] == ActionTypes.VALIDATE_BID: if not clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return validateBid(self.conn, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.CLOSE_AUCTION_TIME: if not clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return closeAuctionTime(self.conn, symmetricEncryption, sessionId) else: sendEncryptedMessage(self.conn, {"error": "Invalid action field"}, symmetricEncryption, sessionId, 4) self.conn.close()
def closeAuction(sock, symmetricEncryption, sessionId): #Gets AuctionID to close it msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) auctionID = msgRecv['auctionID'] mutex.acquire() if auctionID not in OPEN_AUCTIONS.keys(): mutex.release() sendEncryptedMessage(sock, {"error": "Auction already closed"}, sessionId, 5) return auction = OPEN_AUCTIONS[auctionID] auction.timerThread.cancel() winnerBid, participatingClients = auction.makePublic(msgRecv["key"]) creatorId = auction.getAuctionInfo()["creatorId"] if creatorId not in CLIENTS: CLIENTS[creatorId] = set() CLIENTS[creatorId].add(auctionID) for clientId in participatingClients: if clientId not in CLIENTS: CLIENTS[clientId] = set() CLIENTS[clientId].add(auctionID) if auction.getAuctionInfo()["type"] == "BlindShown": del CLIENTS_BIDS_COUNT[clientId][auctionID] #Moves auction from openAuctions to closedAuctions CLOSED_AUCTIONS[auctionID] = OPEN_AUCTIONS.pop(auctionID) sendEncryptedMessage(sock, {"winnerBid": winnerBid}, symmetricEncryption, sessionId, 5) mutex.release()
def listCloseAuctions(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #connect to the repository to get data sock.connect(constants.REPOSITORY_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {'action':ActionTypes.LIST_ALL_CLOSED_AUCTIONS}, symmetricEncryption, sessionId, 3) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) #display data closedAuctionList = msgRecv["closedAuctionList"] if len(closedAuctionList) == 0: print("No closed auctions") sock.close() return for auction in closedAuctionList: print("Auction Id: ", auction["auctionId"]) print("Name: ", auction["name"]) print("Description: ", auction["description"]) print("Type: ", auction["type"]) print("Duration: ", auction["duration"]) print("Creation Time: ", auction["creationTime"]) print("Difficulty: ", auction["difficulty"]) print("Base amount: ", auction["baseAmount"]) print("Validation Code\n" + auction["validationCode"]) print("Modification Code\n" + auction["modificationCode"]) print("Creator Id: ", auction["creatorId"]) print("Creator Name: ", auction["creatorName"]) print("--------------------------------------\n") sock.close()
def listAllAuctionBids(sock, symmetricEncryption, sessionId): mutex.acquire() auctionList = [] for auction in OPEN_AUCTIONS.values(): auctionList.append(auction.getAuctionInfo()) for auction in CLOSED_AUCTIONS.values(): auctionList.append(auction.getAuctionInfo()) sendEncryptedMessage(sock, {"auctionList": auctionList}, symmetricEncryption, sessionId, 4) mandatoryFields = [] mandatoryFields.append(Field("auctionID", int)) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 5) auctionId = msg["auctionID"] bidsList = [] if auctionId in OPEN_AUCTIONS.keys(): sendEncryptedMessage( sock, {"bidsList": OPEN_AUCTIONS[auctionId].getAuctionBids()}, symmetricEncryption, sessionId, 6) elif auctionId in CLOSED_AUCTIONS.keys(): auction = CLOSED_AUCTIONS[auctionId] bids = auction.getAuctionBids() key = auction.getKey() toSend = {"bidsList": bids, "key": key} sendEncryptedMessage(sock, toSend, symmetricEncryption, sessionId, 6) else: sendEncryptedMessage(sock, {"error": "No auction with that auctionID"}, symmetricEncryption, sessionId, 6) mutex.release()
def run(self): symmetricEncryption, clientCert, clientIsServer, sessionId = handshake.serverHandShake( self.conn, privateKey, certificate) mandatoryFields = [] mandatoryFields.append(Field("action", int)) msg = readMessage(self.conn, mandatoryFields, symmetricEncryption, sessionId, 3) #client's requests if msg["action"] == ActionTypes.NEW_BID: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return newBid(self.conn, clientCert, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.LIST_ALL_OPEN_AUCTIONS: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return listAllOpenAuctions(self.conn, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.LIST_ALL_CLOSED_AUCTIONS: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return listAllClosedAuctions(self.conn, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.LIST_ALL_CLIENT_BIDS: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return listAllClientBids(self.conn, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.LIST_ALL_AUCTION_BIDS: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return listAllAuctionBids(self.conn, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.CHECK_OUTCOME_OF_AUCTION: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return checkOutcomeOfAuction(self.conn, clientCert, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.VALIDATE_RECEIPT: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return validateReceipt(self.conn, clientCert, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.VALIDATE_AUCTION: if clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return validateAuction(self.conn, symmetricEncryption, sessionId) #manager's requests elif msg["action"] == ActionTypes.CREATE_AUCTION: if not clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return createAuction(self.conn, symmetricEncryption, sessionId) elif msg["action"] == ActionTypes.CLOSE_AUCTION: if not clientIsServer: sendEncryptedMessage(self.conn, {"error": "Action not allowed"}, symmetricEncryption, sessionId, 4) return closeAuction(self.conn, symmetricEncryption, sessionId) else: sendEncryptedMessage(self.conn, {"error": "Invalid action field"}, symmetricEncryption, sessionId, 4) return self.conn.close()
def createAuction(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Get type of auction while True: print("########################################\n" + \ "# #\n" + \ "# 1 - English Auction #\n" + \ "# 2 - Blind Auction (Entities Shown) #\n" + \ "# 3 - Blind Auction (Entities Hidden) #\n" + \ "# 0 - Go Back #\n" + \ "# #\n" + \ "########################################") choice = input("$ ") if not match("^[0-9]+$", choice): print("ERROR: Insert a valid number!") continue choice = int(choice) if choice == 1: type = "English" break elif choice == 2: type = "BlindShown" break elif choice == 3: type = "BlindHidden" break elif choice == 0: return else: print("ERROR: No option {}! Choose a number from 0 to 2.".format(choice)) continue # Get auction Name name = input("Auction name(Max 40): ")[:40] # Get auction duration (days:hours:minutes) while True: duration = input("Duration (days:hours:minutes): ") if not match("^[0-9]+:[0-9]+:[0-9]+$", duration): print("ERROR: Invalid input!") continue days, hours, minutes = duration.split(":") days = int(days) hours = int(hours) minutes = int(minutes) #convert all to minutes duration = (days * 24 * 60) + \ (hours * 60) + \ minutes if duration == 0: print("ERROR: Duration can't be zero") continue break # Get auction description description = input("Description (Max:200): ")[:200] print("Base amount") while True: baseAmount = input("$ ") if not match("^[0-9]+(\.[0-9][0-9]?)?$", baseAmount): print("ERROR: Insert a valid amount") continue baseAmount = float(baseAmount) if baseAmount < 0: print("ERROR: Insert a number greater than 0") continue break print("Difficulty") print("Value in the interval [0, 256[") print("Higher the number, higher the difficulty") while True: difficulty = input("$ ") if not match("^[0-9]+$", difficulty): print("ERROR: Insert a valid number!") continue difficulty = int(difficulty) if not (0 <= difficulty < 256): print("ERROR: Insert a number in the interval [0, 256[!") continue break #Get dinamic code of auction print("Validation Code") print("DISCLAIMER: We only do a syntax check on your code") print("so if there's any semantic error the auction will") print("reject all bids") print("You have acess to the variable \"data\" that is a dictionary") print("that has the fields:") if type == "English": print("amount") print("lastAmount : last amount made to this auction") elif type == "BlindShown": print("clientId") print("clientName") print("timestamp") print("clientCertificate") print("numberOfBids : Number of bids made by the creator of the bid to this auction") elif type == "Hidden": print("Nothin both identities and amount are hidden") print("The goal is to change the variable validBid to True or False") while True: filename = input("Filename: ") if filename == "": validationCode = "" break if not os.path.exists("code/" + filename): print("No such file") continue with open("code/" + filename) as f: validationCode = f.read() break print("---------") print("Modification code") print("DISCLAIMER: We only do a syntax check on your code") print("so if there's any semantic error the auction will") print("reject all bids") print("You have acess to the variable \"data\" that is a dictionary") print("that has the fields:") if type == "English": print("amount") print("lastAmount : last amount made to this auction") elif type == "BlindShown": print("clientId") print("clientName") print("timestamp") print("clientCertificate") print("numberOfBids : Number of bids made by the creator of the bid to this auction") elif type == "Hidden": print("Nothing both identities and amount are hidden") print("The goal is to change the variable payload with something to add to the block") while True: filename = input("Filename: ") if filename == "": modificationCode = "" break if not os.path.exists("code/" + filename): print("No such file") continue with open("code/" + filename) as f: modificationCode = f.read() break msg = {'name': name, 'duration': duration, 'description' : description, 'type' : type, "difficulty":difficulty, "baseAmount":baseAmount, 'validationCode':validationCode, "modificationCode":modificationCode } #connect to the manager to send the auction info sock.connect(constants.MANAGER_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {"action":ActionTypes.CREATE_AUCTION}, symmetricEncryption, sessionId, 3) sendEncryptedMessage(sock, msg, symmetricEncryption, sessionId, 4) #get info of created auction msg = readMessage(sock, [], symmetricEncryption, sessionId, 5) print("Auction created successfully with id", msg["auctionId"], "on", msg["creationTime"], "(timestamp)") sock.close()
def newBid(sock, clientCert, symmetricEncryption, sessionId): mutex.acquire() openAuctionList = [] for auction in OPEN_AUCTIONS.values(): openAuctionList.append(auction.getAuctionInfo()) #Sends lists with all open auctions sendEncryptedMessage(sock, {"openAuctionList": openAuctionList}, symmetricEncryption, sessionId, 4) mandatoryFields = [] mandatoryFields.append(Field("auctionId", int)) mandatoryFields.append(Field("timestamp", int)) mandatoryFields.append(Field("amount", float)) mandatoryFields.append(BytesField("nonce")) mandatoryFields.append(BytesField("signature")) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 5) auctionId = msg["auctionId"] if auctionId not in OPEN_AUCTIONS.keys(): sendEncryptedMessage(sock, {"error": "No auction with that id"}, symmetricEncryption, sessionId, 6) return clientId, clientName = getUserInfo(clientCert) clientCertBytes = b64encode(clientCert.public_bytes( Encoding.PEM)).decode("ascii") bid = { "timestamp": msg["timestamp"], "clientId": clientId, "clientName": clientName, "clientCertificate": clientCertBytes, "amount": msg["amount"], "nonce": msg["nonce"], "auctionId": auctionId, "auctionType": OPEN_AUCTIONS[auctionId].getAuctionInfo()["type"] } if not PublicKeyClient(clientCert.public_key()).verify( calculateHashOverFields(bid), b64decode(bytes(msg["signature"], "ascii"))): mutex.release() sendEncryptedMessage(sock, {"error": "Invalid signature over bid"}, symmetricEncryption, sessionId, 6) return sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock2.connect(constants.MANAGER_ADDR) symmetricEncryption2, sessionId2 = handshake.clientHandShake( sock2, privateKey, certificate, POSSIB_CIPHERS, POSSIB_MODES, POSSIB_PADDING) sendEncryptedMessage(sock2, {"action": ActionTypes.VALIDATE_BID}, symmetricEncryption2, sessionId2, 3) toValidate = {"clientValidation": msg["signature"], "bid": bid} auction = OPEN_AUCTIONS[auctionId] if auction.getAuctionInfo()["type"] == "BlindShown": if clientId not in CLIENTS_BIDS_COUNT.keys(): CLIENTS_BIDS_COUNT[clientId] = dict() if auctionId not in CLIENTS_BIDS_COUNT[clientId].keys(): CLIENTS_BIDS_COUNT[clientId][auctionId] = 0 toValidate["countBidsDone"] = CLIENTS_BIDS_COUNT[clientId][auctionId] sendEncryptedMessage(sock2, toValidate, symmetricEncryption2, sessionId2, 4) exceptionHappen = False try: msg = readMessage(sock2, [], symmetricEncryption2, sessionId2, 5) except ErrorMessage as e: exceptionHappen = True sendEncryptedMessage(sock, {"error": e.args[0]}, symmetricEncryption, sessionId, 6) if exceptionHappen: mutex.release() return sock2.close() blockNum, prevHash = auction.lastBlockInfo() blockNum += 1 cryptopuzzleChallange = { "difficulty": auction.getAuctionInfo()["difficulty"], "toMine": { "blockNumber": blockNum, "previousHash": prevHash, "data": msg } } sendEncryptedMessage(sock, cryptopuzzleChallange, symmetricEncryption, sessionId, 6) mandatoryFields = [] mandatoryFields.append(BytesField("hash")) mandatoryFields.append(BytesField("nonce")) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 7, 60) blockInfo = cryptopuzzleChallange["toMine"] blockInfo["nonce"] = msg["nonce"] valid, cause = verifyCryptopuzzle(msg["hash"], blockInfo, auction.getAuctionInfo()["difficulty"]) if not valid: mutex.release() sendEncryptedMessage(sock, {"error": cause}, symmetricEncryption, sessionId, 8) return if auction.getAuctionInfo()["type"] == "BlindShown": if clientId not in CLIENTS.keys(): CLIENTS[clientId] = set() CLIENTS[clientId].add(auctionId) auction.newBid(blockInfo["data"], blockInfo["nonce"], msg["hash"]) receipt = auction.getAllData() signature = privateKey.sign(calculateHashOverFields({"": receipt})) signature = b64encode(signature).decode("ascii") cert = b64encode(certificate.public_bytes(Encoding.PEM)).decode("ascii") sendEncryptedMessage(sock, { "receipt": receipt, "signature": signature, "certificate": cert }, symmetricEncryption, sessionId, 8) mutex.release()
def listAuctionBids(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(constants.REPOSITORY_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {'action':ActionTypes.LIST_ALL_AUCTION_BIDS}, symmetricEncryption, sessionId, 3) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) openAuctionList = msgRecv["auctionList"] if len(openAuctionList) == 0: print("No auctions") sock.close() return for i, auction in enumerate(openAuctionList): print("## {} ##".format(i+1)) print("Auction Id: ", auction["auctionId"]) print("Name: ", auction["name"]) print("Description: ", auction["description"]) print("Type: ", auction["type"]) print("Duration: ", auction["duration"]) print("Creation Time: ", auction["creationTime"]) print("Difficulty: ", auction["difficulty"]) print("Base amount: ", auction["baseAmount"]) print("Validation Code\n" + auction["validationCode"]) print("Modification Code\n" + auction["modificationCode"]) print("Creator Id: ", auction["creatorId"]) print("Creator Name: ", auction["creatorName"]) print("--------------------------------------\n") while True: opt = input("$ ") if not match("^[0-9]+$", opt): print("ERROR: Insert a valid number!") continue opt = int(opt) if opt < 1 or opt > len(openAuctionList): print("Error: Insert a number between 1 and " + str(len(openAuctionList))) continue opt -= 1 break sendEncryptedMessage(sock, {'auctionID': openAuctionList[opt]["auctionId"]}, symmetricEncryption, sessionId, 5) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 6) bidsList = msgRecv['bidsList'] if len(bidsList) == 0: print("No bids") sock.close() return auctionType = openAuctionList[opt]["type"] if "key" in msgRecv.keys(): key = b64decode(bytes(msgRecv["key"], "ascii")) for bid in bidsList: decryptBid(bid, key) for bid in bidsList: print("Client Id:", bid["clientId"]) print("Client Name:", bid["clientName"]) print("Client Certificate:", bid["clientCertificate"]) print("Amount:", bid["amount"]) print("Timestamp:", bid["timestamp"]) print("Nonce:", bid["nonce"]) print("Auction Id:", bid["auctionId"]) print("Auction Type:", bid["auctionType"]) print("------------------------\n") sock.close()
def checkOutcome(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(constants.REPOSITORY_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {'action':ActionTypes.CHECK_OUTCOME_OF_AUCTION}, symmetricEncryption, sessionId, 3) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) closedAuctionList = msgRecv["participatedAuctionList"] if len(closedAuctionList) == 0: print("No closed auctions participated") sock.close() return for i, auction in enumerate(closedAuctionList): print("## {} ##".format(i+1)) print("Auction Id: ", auction["auctionId"]) print("Name: ", auction["name"]) print("Description: ", auction["description"]) print("Type: ", auction["type"]) print("Duration: ", auction["duration"]) print("Creation Time: ", auction["creationTime"]) print("Difficulty: ", auction["difficulty"]) print("Base amount: ", auction["baseAmount"]) print("Validation Code\n" + auction["validationCode"]) print("Modification Code\n" + auction["modificationCode"]) print("Creator Id: ", auction["creatorId"]) print("Creator Name: ", auction["creatorName"]) print("--------------------------------------\n") print("Select an auction to check who won") while True: opt = input("$ ") if not match("^[0-9]+$", opt): print("ERROR: Insert a valid number!") continue opt = int(opt) if opt < 1 or opt > len(closedAuctionList): print("Error: Insert a number between 1 and " + str(len(closedAuctionList))) continue opt -= 1 break sendEncryptedMessage(sock, {'auctionId':closedAuctionList[opt]["auctionId"]}, symmetricEncryption, sessionId, 5) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 6) if msgRecv["winnerBid"] == {}: print("No winner!") return decryptBid( msgRecv["winnerBid"], b64decode(bytes(msgRecv["key"], "ascii")) ) print("Winner Bid") print("Client Id:", msgRecv["winnerBid"]["clientId"]) print("Client Name:", msgRecv["winnerBid"]["clientName"]) print("Client Certificate:", msgRecv["winnerBid"]["clientCertificate"]) print("Amount:", msgRecv["winnerBid"]["amount"]) print("Timestamp:", msgRecv["winnerBid"]["timestamp"]) print("Nonce:", msgRecv["winnerBid"]["nonce"]) print("Auction Id:", msgRecv["winnerBid"]["auctionId"]) print("Auction Type:", msgRecv["winnerBid"]["auctionType"]) sock.close()
def createAuction(sock, clientCert, symmetricEncryption, sessionId): # Receive auction info mandatoryFields = [] mandatoryFields.append(Field("name", str)) mandatoryFields.append(Field("duration", int)) mandatoryFields.append(Field("description", str)) mandatoryFields.append( Field("type", str, lambda v: v in ["English", "BlindShown", "BlindHidden"])) mandatoryFields.append(Field("difficulty", int)) mandatoryFields.append(Field("baseAmount", float)) mandatoryFields.append(Field("validationCode", str)) mandatoryFields.append(Field("modificationCode", str)) msgRecv = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 4) for code in [msgRecv["validationCode"], msgRecv["modificationCode"]]: with open("dummy.py", "w+") as f: f.write(code) #check syntax of validation code try: py_compile.compile("dummy.py", doraise=True) except py_compile.PyCompileError: sendEncryptedMessage( sock, {"error": "Dynamic code with syntatic errors"}, symmetricEncryption, sessionId, 5) return # Insert client id and name to auction info clientId, clientName = getUserInfo(clientCert) msgRecv["creatorId"] = clientId msgRecv["creatorName"] = clientName # Connect to repository to instantiate an auction sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock2.connect(constants.REPOSITORY_ADDR) symmetricEncryption2, sessionId2 = handshake.clientHandShake( sock2, privateKey, certificate, POSSIB_CIPHERS, POSSIB_MODES, POSSIB_PADDING) # Send auction info sendEncryptedMessage(sock2, {"action": ActionTypes.CREATE_AUCTION}, symmetricEncryption2, sessionId2, 3) sendEncryptedMessage(sock2, msgRecv, symmetricEncryption2, sessionId2, 4) # Receive auction Id of the created auction msgRecv2 = readMessage(sock2, [], symmetricEncryption2, sessionId2, 5) auctionId = msgRecv2['auctionId'] creationTime = msgRecv2['creationTime'] # Create some info on manager to show if users want to close auctions auctionInfo = msgRecv auctionInfo["auctionId"] = auctionId auctionInfo["creationTime"] = creationTime # Save that info AUCTIONS[auctionId] = Auction(auctionInfo, msgRecv["validationCode"], msgRecv["modificationCode"], msgRecv["baseAmount"]) if clientId in CLIENTS.keys(): CLIENTS[clientId].append(auctionId) else: CLIENTS[clientId] = [auctionId] sendEncryptedMessage(sock, { "auctionId": auctionId, "creationTime": creationTime }, symmetricEncryption, sessionId, 5)
def closeAuction(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(constants.MANAGER_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {'action':ActionTypes.CLOSE_AUCTION}, symmetricEncryption, sessionId, 3) #get all open auctions that this client created msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) openAuctionList = msgRecv["openAuctionList"] if len(openAuctionList) == 0: print("No aucton to close") sock.close() return for i, auction in enumerate(openAuctionList): print("## {} ##".format(i+1)) print("Auction Id: ", auction["auctionId"]) print("Name: ", auction["name"]) print("Description: ", auction["description"]) print("Type: ", auction["type"]) print("Duration: ", auction["duration"]) print("Creation Time: ", auction["creationTime"]) print("Difficulty: ", auction["difficulty"]) print("Base amount: ", auction["baseAmount"]) print("Validation Code\n" + auction["validationCode"]) print("Modification Code\n" + auction["modificationCode"]) print("Creator Id: ", auction["creatorId"]) print("Creator Name: ", auction["creatorName"]) print("--------------------------------------\n") #choose one while True: opt = input("$ ") if not match("^[0-9]+$", opt): print("ERROR: Insert a valid number!") continue opt = int(opt) if opt < 1 or opt > len(openAuctionList): print("Error: Insert a number between 1 and " + str(len(openAuctionList))) continue opt -= 1 break #send the serial number/auction Id of the chosen one sendEncryptedMessage(sock, {'auctionID':openAuctionList[opt]["auctionId"]}, symmetricEncryption, sessionId, 5) #wait to see if all went good msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 6) if msgRecv["winnerBid"] == {}: print("No winner!") return decryptBid( msgRecv["winnerBid"], b64decode(bytes(msgRecv["key"], "ascii")) ) print("Winner Bid") print("Client Id:", msgRecv["winnerBid"]["clientId"]) print("Client Name:", msgRecv["winnerBid"]["clientName"]) print("Client Certificate:", msgRecv["winnerBid"]["clientCertificate"]) print("Amount:", msgRecv["winnerBid"]["amount"]) print("Timestamp:", msgRecv["winnerBid"]["timestamp"]) print("Nonce:", msgRecv["winnerBid"]["nonce"]) print("Auction Id:", msgRecv["winnerBid"]["auctionId"]) print("Auction Type:", msgRecv["winnerBid"]["auctionType"]) sock.close()
def clientHandShake(sock, privKey, cert, supportCiphers, supportModes, supportPadding): """ """ sendMessage( sock, { "supportedCiphers": supportCiphers, "supportedModes": supportModes, "supportedPaddings": supportPadding }) ################################################## mandatoryFields = [] mandatoryFields.append(BytesField("certificate")) mandatoryFields.append(BytesField("authenticationData")) mandatoryFields.append(Field("chosenCipher", str)) mandatoryFields.append(Field("chosenMode", str)) mandatoryFields.append(Field("chosenPadding", str)) msg = readMessage(sock, mandatoryFields) certBytes = b64decode(bytes(msg["certificate"], "ascii")) valid, cause, serverCert, clientIsServer = assymetric.validCertificate( certBytes) if not clientIsServer: raise Exception #TODO if not valid: raise InvalidCertificate("Server's certificate not valid") cipher = msg["chosenCipher"] mode = msg["chosenMode"] paddingAlg = msg["chosenPadding"] sharedKey = macKey = symmetricEncryption = None if cipher not in supportCiphers: raise UnkownAlgorithm("Unkown cipher algorithm") elif cipher in POSSIB_AUTH_CIPHERS: #see if it's a cipher algorithm with authentication cipher = getattr(aead, cipher) sharedKey = urandom(32) symmetricEncryption = symetric.AuthenticatedEncryption( cipher, sharedKey) else: # if it's a valid algorithm macKey = urandom(SHA256.digest_size) if cipher == "ChaCha20": cipher = algorithms.ChaCha20 sharedKey = urandom(int(max(cipher.key_sizes) / 8)) symmetricEncryption = symetric.StreamEncryption(sharedKey, macKey) else: cipher = getattr(algorithms, cipher) if cipher == algorithms.AES: sharedKey = urandom(32) else: sharedKey = urandom(int(max(cipher.key_sizes) / 8)) if mode not in supportModes: raise UnkownAlgorithm("Unkown cipher mode") elif mode == "CBC": if paddingAlg not in supportPadding: raise UnkownAlgorithm("Unkown padding algorithm") symmetricEncryption = symetric.PaddedEncryption( cipher, sharedKey, macKey, getattr(padding, paddingAlg)) else: symmetricEncryption = symetric.NonPaddedEncryption( cipher, sharedKey, macKey, getattr(modes, mode)) publicKeyServer = assymetric.PublicKeyServer(serverCert.public_key()) encryptedSharedKey = publicKeyServer.encrypt(sharedKey) authenticationData = b64decode(bytes(msg["authenticationData"], "ascii")) signature = privKey.sign(authenticationData) sessionId = urandom(32) encryptedSessionId = publicKeyServer.encrypt(sessionId) msg = { "sharedKey": b64encode(encryptedSharedKey).decode("ascii"), "sessionId": b64encode(encryptedSessionId).decode("ascii"), "certificate": b64encode(cert.public_bytes(Encoding.PEM)).decode("ascii"), "signature": b64encode(signature).decode("ascii") } if macKey != None: encryptedMacKey = publicKeyServer.encrypt(macKey) msg["macKey"] = b64encode(encryptedMacKey).decode("ascii") else: msg["macKey"] = "" sendMessage(sock, msg) ################################################## sessionId = int(sessionId.hex(), 16) sendEncryptedMessage(sock, {"handshake finish": ""}, symmetricEncryption, sessionId, 1) ################################################## mandatoryFields = [] mandatoryFields.append(Field("handshake finish", str)) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 2) return symmetricEncryption, sessionId
def validateBid(sock, symmetricEncryption, sessionId): msg = readMessage(sock, [], symmetricEncryption, sessionId, 4) bid = msg["bid"] clientValidation = msg["clientValidation"] auction = AUCTIONS[bid["auctionId"]] type = auction.auctionInfo["type"] if type == "BlindShown": assert "countBidsDone" in msg.keys() countBidsDone = msg["countBidsDone"] else: countBidsDone = None if not bidValidation(auction.validationCode, type, deepcopy(bid), auction.lastAmount, countBidsDone): sendEncryptedMessage(sock, {"error": "Bid failed bid validation"}, symmetricEncryption, sessionId, 5) return payload = bidModification(auction.modificationCode, type, deepcopy(bid), auction.lastAmount, countBidsDone) if float(bid["amount"]) < auction.baseAmount: sendEncryptedMessage( sock, {"error": "Amount has to greater than the base amount"}, symmetricEncryption, sessionId, 5) return bidAmount = float(bid["amount"]) if type == "English": if bidAmount <= auction.lastAmount: sendEncryptedMessage( sock, {"error": "Amount has to greater than the last one"}, symmetricEncryption, sessionId, 5) return else: auction.lastAmount = bidAmount if type == "English" or type == "BlindHidden": for field in [ "clientId", "clientName", "clientCertificate", "timestamp" ]: bid[field] = auction.encryptField(bid[field]) clientValidation = auction.encryptField(clientValidation) if "Blind" in type: bid["amount"] = auction.encryptField(bid["amount"]) bid["nonce"] = auction.encryptField(bid["nonce"]) posValidation = { "bid": bid, "payload": payload, "clientValidation": clientValidation } signature = b64encode( privateKey.sign( calculateHashOverFields(posValidation))).decode("ascii") posValidation["managerValidation"] = { "signature": signature, "certificate": b64encode(certificate.public_bytes(Encoding.PEM)).decode("ascii") } sendEncryptedMessage(sock, posValidation, symmetricEncryption, sessionId, 5)
def validateAuction(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #connect to the repository to get data sock.connect(constants.REPOSITORY_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {'action':ActionTypes.VALIDATE_AUCTION}, symmetricEncryption, sessionId, 3) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) #display data auctionList = msgRecv["auctionList"] if len(auctionList) == 0: print("No auctions") sock.close() return for i, auction in enumerate(auctionList): print("## {} ##".format(i+1)) print("Auction Id: ", auction["auctionId"]) print("Name: ", auction["name"]) print("Description: ", auction["description"]) print("Type: ", auction["type"]) print("Duration: ", auction["duration"]) print("Creation Time: ", auction["creationTime"]) print("Difficulty: ", auction["difficulty"]) print("Base amount: ", auction["baseAmount"]) print("Validation Code\n" + auction["validationCode"]) print("Modification Code\n" + auction["modificationCode"]) print("Creator Id: ", auction["creatorId"]) print("Creator Name: ", auction["creatorName"]) print("--------------------------------------\n") while True: opt = input("$ ") if not match("^[0-9]+$", opt): print("ERROR: Insert a valid number!") continue opt = int(opt) if opt < 1 or opt > len(auctionList): print("Error: Insert a number between 1 and " + str(len(auctionList))) continue opt -= 1 break sendEncryptedMessage(sock, {"auctionId":auctionList[opt]["auctionId"]}, symmetricEncryption, sessionId, 5) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 6) sock.close() validateAuctionContent(msgRecv["allData"])
def serverHandShake(sock, privKey, cert): """ Function used by server's. They execute them after they receive a connection from a client to negotiate encrypt parameter and to authenticate both sides """ mandatoryFields = [] verification = lambda v: all(type(s) == str for s in v) mandatoryFields.append(Field("supportedCiphers", list, verification)) mandatoryFields.append(Field("supportedModes", list, verification)) mandatoryFields.append(Field("supportedPaddings", list, verification)) msg = readMessage(sock, mandatoryFields) cipherAlg = "" for cipher in POSSIB_CIPHERS: if cipher in msg["supportedCiphers"]: cipherAlg = cipher break if cipherAlg == "": raise UnkownAlgorithm("Unkown cipher algorithm") mode = paddingAlg = "" authEncryption = True if cipher not in POSSIB_AUTH_CIPHERS: authEncryption = False if cipher != "ChaCha20": for mod in POSSIB_MODES: if mod in msg["supportedModes"] and not (cipher == "CAST5" and mode == "CTR"): mode = mod break if mode == "": raise UnkownAlgorithm("Unkown cipher mode") if mode == "CBC": for padd in POSSIB_PADDING: if padd in msg["supportedPaddings"]: paddingAlg = padd break if paddingAlg == "": raise UnkownAlgorithm("Unkown padding algorithm") authenticationData = urandom(64) sendMessage( sock, { "chosenCipher": cipherAlg, "chosenMode": mode, "chosenPadding": paddingAlg, "certificate": b64encode(cert.public_bytes(Encoding.PEM)).decode("ascii"), "authenticationData": b64encode(authenticationData).decode("ascii") }) ################################################## mandatoryFields = [] mandatoryFields.append(BytesField("sharedKey")) mandatoryFields.append(BytesField("sessionId")) mandatoryFields.append(BytesField("certificate")) mandatoryFields.append(BytesField("signature")) mandatoryFields.append(BytesField("macKey")) msg = readMessage(sock, mandatoryFields) certBytes = b64decode(bytes(msg["certificate"], "ascii")) valid, cause, clientCert, clientIsServer = assymetric.validCertificate( certBytes) if not valid: raise InvalidCertificate("Client's invalid certificate") if clientIsServer: publicKeyClient = assymetric.PublicKeyServer(clientCert.public_key()) else: publicKeyClient = assymetric.PublicKeyClient(clientCert.public_key()) signature = b64decode(bytes(msg["signature"], "ascii")) try: publicKeyClient.verify(authenticationData, signature) except InvalidSignature: raise FailedClientAuthentication("Failed to authenticate client") try: sharedKey = privKey.decrypt(b64decode(bytes(msg["sharedKey"], "ascii"))) sessionId = privKey.decrypt(b64decode(bytes(msg["sessionId"], "ascii"))) sessionId = int(sessionId.hex(), 16) macKey = None if not authEncryption: macKey = privKey.decrypt(b64decode(bytes(msg["macKey"], "ascii"))) except: raise FailedDescrytingKeys("Decryption of shared keys failed") symmetricEncryption = None if cipherAlg in POSSIB_AUTH_CIPHERS: symmetricEncryption = symetric.AuthenticatedEncryption( getattr(aead, cipherAlg), sharedKey) else: if cipherAlg == "ChaCha20": symmetricEncryption = symetric.StreamEncryption(sharedKey, macKey) else: if mode == "CBC": symmetricEncryption = symetric.PaddedEncryption( getattr(algorithms, cipherAlg), sharedKey, macKey, getattr(padding, paddingAlg)) else: symmetricEncryption = symetric.NonPaddedEncryption( getattr(algorithms, cipherAlg), sharedKey, macKey, getattr(modes, mode)) ################################################## mandatoryFields = [] mandatoryFields.append(Field("handshake finish", str)) msg = readMessage(sock, mandatoryFields, symmetricEncryption, sessionId, 1) sendEncryptedMessage(sock, {"handshake finish": ""}, symmetricEncryption, sessionId, 2) return symmetricEncryption, clientCert, clientIsServer, sessionId
def newBid(): while True: amount = input("Amount to bid: ") if not match("^[0-9]+(\.[0-9][0-9]?)?$", amount): print("ERROR: Insert a valid amount") continue amount = float(amount) break sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(constants.REPOSITORY_ADDR) cert = getCertificate() symmetricEncryption, sessionId = clientHandShake(sock, privateKey, cert, ciphers, modes, paddings) sendEncryptedMessage(sock, {'action':ActionTypes.NEW_BID}, symmetricEncryption, sessionId, 3) msgRecv = readMessage(sock, [], symmetricEncryption, sessionId, 4) #display data openAuctionList = msgRecv["openAuctionList"] if len(openAuctionList) == 0: print("No open auctions") sock.close() return for i, auction in enumerate(openAuctionList): print("## {} ##".format(i+1)) print("Auction Id: ", auction["auctionId"]) print("Name: ", auction["name"]) print("Description: ", auction["description"]) print("Type: ", auction["type"]) print("Duration: ", auction["duration"]) print("Creation Time: ", auction["creationTime"]) print("Difficulty: ", auction["difficulty"]) print("Base amount: ", auction["baseAmount"]) print("Validation Code\n" + auction["validationCode"]) print("Modification Code\n" + auction["modificationCode"]) print("Creator Id: ", auction["creatorId"]) print("Creator Name: ", auction["creatorName"]) print("--------------------------------------\n") while True: opt = input("$ ") if not match("^[0-9]+$", opt): print("ERROR: Insert a valid number!") continue opt = int(opt) if opt < 1 or opt > len(openAuctionList): print("Error: Insert a number between 1 and " + str(len(openAuctionList))) continue opt -= 1 break clientId, clientName = getUserInfo(cert) auctionId = openAuctionList[opt]["auctionId"] auctionType = openAuctionList[opt]["type"] timestamp = int(time.time()) nonce = b64encode(urandom(32)).decode("ascii") bid = { "timestamp":timestamp, "clientId":clientId, "clientName":clientName, "clientCertificate":b64encode(cert.public_bytes(Encoding.PEM)).decode("ascii"), "amount":amount, "nonce":nonce, "auctionId":auctionId, "auctionType":auctionType } signature = b64encode(privateKey.sign(calculateHashOverFields(bid))).decode("ascii") sendEncryptedMessage(sock, {'auctionId': auctionId, "timestamp":timestamp, "nonce":nonce, "amount":amount, "signature":signature}, symmetricEncryption, sessionId, 5) cryptopuzzleChallange = readMessage(sock, [], symmetricEncryption, sessionId, 6) nonce, newHash = solveCriptopuzzle(cryptopuzzleChallange["difficulty"], cryptopuzzleChallange["toMine"]) sendEncryptedMessage(sock, {"nonce":nonce, "hash":newHash}, symmetricEncryption, sessionId, 7) msg = readMessage(sock, [], symmetricEncryption, sessionId, 8) if not validReceiptSignature(msg["signature"], msg["certificate"], msg["receipt"]): print("Signature on receipt received not valid") return else: print("Signature on receipt ok") if not os.path.exists("receipts"): os.mkdir("receipts") os.mkdir("receipts/" + clientId) if not os.path.exists("receipts/" + clientId): os.mkdir("receipts/" + clientId) while True: receiptName = input("Name for receipt: ") if receiptName == "": print("ERROR: Insert a valid name") continue break cryptopuzzleChallange["toMine"]["nonce"] = nonce receipt = { "whatISaw":{ 'bid': bid, "cryptopuzzleChallange":cryptopuzzleChallange }, "received":msg } f = open("receipts/" + clientId + "/" + receiptName + ".txt", "w+") f.write(json.dumps({"auctionId":auctionId, "receipt":receipt})) f.close() sock.close()