def handle(self, message):
        if not isinstance(message, CoinsRedeem) and not isinstance(
                message, CoinsReject) and not isinstance(message, CoinsAccept):
            if self.manager.walletMessageType.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'Coins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       self.manager.walletMessageType.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called Coins.handle() but cannot be there. Message: %s'
                    % message.identifier)

        if isinstance(message, CoinsRedeem):
            # we output this. Previous step was Hello. Do nothing.
            print 'Got a CoinsRedeem. I did not know we got these.'

        elif isinstance(message, CoinsAccept):
            self.removeSpentCoins(self.manager.entity.coins,
                                  self.manager.coins)

            self.manager.walletMessageType.removeCallback(self.handle)
            self.manager.success(message, self)

        elif isinstance(message, CoinsReject):
            self.reason = self.manager.walletMessageType.persistant.reason

            self.manager.walletMessageType.removeCallback(self.handle)
            # undo the damage and tell someone
            self.manager.failure(message, self)

        self._setLastState(message.identifier)
예제 #2
0
    def handle(self, message):
        if not isinstance(message, MintRequest) and not isinstance(message, MintAccept) and not isinstance(message, MintReject):
            if self.manager.messageType.globals.lastState == MessageHello: # we are now on a different message. Oops.
                raise MessageError('Mint should have already been removed. It was not. Very odd. Message: %s LastMessage: %s' % (message.identifier,
                                                                                                                        self.manager.messageType.globals.lastState))
            else:
                print 'message class: %s' % message.__class__
                raise MessageError('We somehow called Mint.handle() but cannot be there. Message: %s' % message.identifier)

        if isinstance(message, MintRequest):
                self.request_id = self.manager.messageType.persistant.request_id
                self.blinds = self.manager.messageType.persistant.blinds

                type, result = self.request(self.request_id, self.blinds, self.manager.entity.minting_keys_key_id, self.timeNow())
                
                if type == 'ACCEPT':
                    if self.request_id != result:
                        raise MessageError('request_id changed. Was: %s, Received: %s' % (self.request_id, result))

                    self.manager.messageType.removeCallback(self.handle)
                    self.__createAndOutput(MintAccept)
                    
                elif type == 'REJECT':
                    self.manager.messageType.persistant.reason = result

                    self.manager.messageType.removeCallback(self.handle)
                    self.__createAndOutput(MintReject)

                else:
                    raise MessageError('Received an impossible type: %s' % self.type)

        elif isinstance(message, MintAccept) or isinstance(message, MintReject):
            # we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)
    def handle(self, message):
        if not isinstance(message, BlankPresent) and not isinstance(message, BlankAccept) and not isinstance(message, BlankReject) \
                                                                                            and not isinstance(message, BlankFailure):
            if self.manager.walletMessageType.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'Blank should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       self.manager.walletMessageType.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called Blank.handle() but cannot be there. Message: %s'
                    % message.identifier)

        if isinstance(message, BlankPresent):
            # we output this. Previous step was Hello. Do nothing.
            self._verifyLastState(['DSDB_KEY_PASS'])
            print 'Got a BlankPresent. I did not know we got these.'

        elif isinstance(message, BlankAccept):
            self.manager.walletMessageType.persistant.coins = self.manager.coins
            self.manager.walletMessageType.removeCallback(
                self.handle)  #remove the callback. Not coming here again
            self._createAndOutputWallet(CoinsRedeem)

        elif isinstance(message, BlankFailure):
            self.reason = self.manager.walletMessageType.persistant.reason
            # undo the damage and tell someone
            self.manager.failure(message, self)

        elif isinstance(message, BlankReject):
            self.reason = self.manager.walletMessageType.persistant.reason
            self.manager.failure(message, self)

        self._setLastState(message.identifier)
    def handle(self, message):
        if not isinstance(message, DSDBKeyRequest) and not isinstance(
                message, DSDBKeyPass):
            if self.manager.isMessageType.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'RedeemCoins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       self.manager.isMessageType.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called RedeemCoins.handle() but cannot be there. Message: %s'
                    % message.identifier)

        self._verifyLastState([None])

        if isinstance(message, DSDBKeyRequest):
            # we output this. Previous step was Hello. Do nothing.
            print 'Got a DSDBKeyRequest. I did not know we got these.'

        elif isinstance(message, DSDBKeyPass):
            self.dsdb_certificate = self.manager.isMessageType.persistant.dsdb_certificate
            self.manager.persistant.dsdb_certificate = self.dsdb_certificate  # keep a copy for me
            self.manager.walletMessageType.persistant.dsdb_certificate = self.dsdb_certificate  # and we need to encode it

            if not self.validCertificate(self.dsdb_certificate,
                                         self.manager.cdd, self.timeNow()):
                raise MessageError('Invalid DSDB Certificate')

            self.createBlinds(self.dsdb_certificate, self.manager.coins)
            self.manager.isMessageType.removeCallback(
                self.handle)  # not coming back here again
            self._createAndOutputWallet(BlankPresent)

        self._setLastState(message.identifier)
예제 #5
0
    def verifyCoins(self, coins, mintingKeys, blanks, dsdb_keycertificate,
                    cdds):
        failure = False
        failures = []

        if len(coins) != len(blanks):
            raise MessageError('Different amounts of coins and blanks')

        if len(coins) == 0:
            raise MessageError('Need atleast one coin')
            # this *should* be impossible due to the previus error.

        for i in range(len(coins)):
            type, result = self.verifySingleCoin(coins[i], mintingKeys,
                                                 blanks[i],
                                                 dsdb_keycertificate, cdds)
            if type == 'VALID':
                pass
            elif type == 'FAILURE':
                failure = True
                failures.append((coins[i], result))
            else:
                raise MessageError('Got an imposisble type: %s' % type)

        if failure:
            return 'REJECT', failures
        else:
            return 'ACCEPT', None
예제 #6
0
    def handle(self, message):
        if not isinstance(message, UnlockCoinsRequest) and not isinstance(
                message, UnlockCoinsPass) and not isinstance(
                    message, UnlockCoinsFailure):
            if message.messageLayer.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'UnlockCoins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       message.messageLayer.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called UnlockCoins.handle() but cannot be there. Message: %s'
                    % message.identifier)

        self._verifyLastState([])  # FIXME: Figure it out later

        if isinstance(message, UnlockCoinsRequest):
            # we output this. Previous step was in ?????
            print 'Got a UnlockCoinsRequest. I did not know we got these.'

        elif isinstance(message, UnlockCoinsPass):
            #FIXME: do something USEFUL here
            self.manager.dsdbMessageType.removeCallback(self.handle)

        elif isinstance(message, UnlockCoinsFailure):
            #FIXME: do something USEFUL here
            self.manager.dsdbMessageType.removeCallback(self.handle)
            #self.manager.failure(message, self)

        self._setLastState(message.identifier)
예제 #7
0
    def handle(self, message):
        if not isinstance(message, RedeemCoinsRequest) and not isinstance(
                message, RedeemCoinsAccept) and not isinstance(
                    message, RedeemCoinsReject):
            if message.messageLayer.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'RedeemCoins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       message.messageLayer.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called RedeemCoins.handle() but cannot be there. Message: %s'
                    % message.identifier)

        self._verifyLastState(
            ['']
        )  # we should have two of them in here when it works. (maybe three with REDEEM_COINS_REQUEST)

        if isinstance(message, RedeemCoinsRequest):
            # we output this. Previous step was in ????
            print 'Got a RedeemCoinsRequest. I did not know we got these.'

        elif isinstance(message, RedeemCoinsAccept):
            if self.isRequiresMRbeforeRCR:
                # We have our MintRequest and RedeemCoinsRequests in. All to do now is Fetch our coins!

                self.manager.isMessageType.persistant.request_id = self.manager.persistant.mintRequestID

                self.manager.isMessageType.removeCallback(
                    self.handle)  #remove the callback. Not coming here again
                self._createAndOutputIS(FetchMintedRequest)

            else:
                # We have done our RedeemCoinsRequest. Now do a MintRequest, and then finaly a FetchMintedRequest

                self.manager.isMessageType.persistant.request_id = self.manager.persistant.mintRequestID

                # setup blinds only for the MintRequest message
                blinds = []
                for b in self.manager.persistant.mintBlanks:
                    b.blind_blank(
                        self.manager.entity.cdds
                    )  # XXX should this be in makeBlanks() instead?
                    blinds.append((b.key_identifier, b.blind_value))
                self.manager.isMessageType.persistant.blinds = blinds

                self.manager.isMessageType.removeCallback(self.handle)
                self._createAndOutputIS(MintRequest)

        elif isinstance(message, RedeemCoinsReject):
            self.reason = self.manager.isMessageType.persistant.reason
            # undo the damage and tell someone
            self.manager.isMessageType.removeCallback(self.handle)
            self.manager.failure(message, self)

        self._setLastState(message.identifier)
예제 #8
0
    def handle(self, message):
        if not isinstance(message, LockCoinsRequest) and not isinstance(
                message, LockCoinsAccept) and not isinstance(
                    message, LockCoinsFailure):
            if self.manager.messageType.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'LockCoins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       self.manager.messageType.globals.lastState))
            else:
                print 'message class: %s' % message.__class__
                raise MessageError(
                    'We somehow called LockCoins.handle() but cannot be there. Message: %s'
                    % message.identifier)

        if isinstance(message, LockCoinsRequest):
            self.key_id = self.manager.messageType.persistant.key_id
            self.transaction_id = self.manager.messageType.persistant.transaction_id
            self.blanks = self.manager.messageType.persistant.blanks  # blanks is a tuple of mint_key_id and obfuscated serial

            self.type, self.result = self.lock(
                self.key_id, self.transaction_id, self.blanks,
                self.manager.dsdb_key, self.manager.entity.dsdb_database,
                self.manager.entity.dsdb_requests,
                self.manager.entity.minting_keys_key_id, self.timeNow())

            if self.type == 'ACCEPT':
                transaction_id, self.dsdb_lock = self.result
                if self.transaction_id != transaction_id:
                    raise MessageError(
                        'transaction_id changed. Was: %s, Received: %s' %
                        (self.transaction_id, transaction_id))
                self.manager.messageType.persistant.dsdb_lock = self.dsdb_lock

                self.manager.messageType.removeCallback(
                    self.handle)  # we are done here
                self.__createAndOutput(LockCoinsAccept)

            elif self.type == 'REJECT':
                self.manager.messageType.persistant.reason = self.result

                self.manager.messageType.removeCallback(
                    self.handle)  # we are done here
                self.__createAndOutput(LockCoinsFailure)

            else:
                raise MessageError('Received an impossible type: %s' %
                                   self.type)

        elif isinstance(message, LockCoinsAccept) or isinstance(
                message, LockCoinsFailure):
            # we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)
예제 #9
0
    def handle(self, message):
        if not isinstance(message, MintRequest) and not isinstance(
                message, MintAccept) and not isinstance(message, MintReject):
            if message.messageLayer.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'Mint should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       message.messageLayer.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called Mint.handle() but cannot be there. Message: %s'
                    % message.identifier)

        self._verifyLastState(
            ['']
        )  # I have no idea what will actually be here, nor to I care right now. This will show us.

        if isinstance(message, MintRequest):
            # we output this. Previous step was in ?????
            print 'Got a MintRequest. I did not know we got these.'

        elif isinstance(message, MintAccept):
            if self.manager.persistant.mintRequestID != self.manager.isMessageType.persistant.request_id:
                raise MessageError(
                    'request_id changed. Was: %s Now %s' %
                    (self.manager.persistant.mintingRequestID,
                     self.manager.isMessageType.persistant.request_id))

            if self.isRequiresMRbeforeRCR:
                # We've already done the MintRequest. Nothing stopping us from trying to Redeem now.
                self.manager.isMessageType.persistant.trasaction_id = self.manager.persistant.mintRequestID
                self.manager.isMessageType.persistant.target = self.manager.persistant.target
                self.manager.isMessageType.persistant.coins = self.manager.persistant.coins

                self.manager.isMessageType.removeCallback(self.handle)
                self._createAndOutputIS(RedeemCoinsRequest)
            else:
                # We already did the RedeemRequest. Time to fetch
                self.manager.isMessageType.persistant.request_id = self.manager.persistant.mintRequestID

                self.manager.isMessageType.removeCallback(self.handle)
                self._createAndOutputIS(FetchMintedRequest)

        elif isinstance(message, MintReject):
            self.reason = self.manager.isMessageType.persistant.reason

            self.manager.isMessageType.removeCallback(self.handle)

            # undo the damage and tell someone
            self.manager.failure(message, self)

        self._setLastState(message.identifier)
예제 #10
0
    def handle(self, message):
        if not isinstance(message, MintingKeyFetchDenomination) and not isinstance(message, MintingKeyFetchKeyID) and not \
                            isinstance(message, MintingKeyFailure) and not isinstance(message, MintingKeyPass):
            if self.manager.messageType.globals.lastState == MessageHello: # we are now on a different message. Oops.
                raise MessageError('MintingKey should have already been removed. It was not. Very odd. Message: %s LastMessage: %s' % (message.identifier,
                                                                                                                        self.manager.messageType.globals.lastState))
            else:
                print 'message class: %s' % message.__class__
                raise MessageError('We somehow called MintingKey.handle() but cannot be there. Message: %s' % message.identifier)

        if isinstance(message, MintingKeyFetchKeyID) or isinstance(message, MintingKeyFetchDenomination):
            if isinstance(message, MintingKeyFetchKeyID):
                self.key_id = self.manager.messageType.persistant.key_id
                self.denomination = None
            else:
                self.denomination = self.manager.messageType.persistant.denomination
                self.key_id = None

            type, result = self.findKey(self.key_id, self.denomination)

            if type == 'PASS':
                self.minting_certificate = result
                self.manager.messageType.persistant.minting_certificate = self.minting_certificate

                self.manager.messageType.removeCallback(self.handle)
                self.__createAndOutput(MintingKeyPass)
            elif type == 'FAILURE':
                self.manager.messageType.persistant.reason = result
                if result == 'Unknown key_id':
                    self.reason = 'Unknown key_id'

                    self.manager.messageType.persistant.reason = self.reason

                    self.manager.messageType.removeCallback(self.handle)
                    self.__createAndOutput(MintingKeyFailure)
                elif result == 'Unknown denomination':
                    self.reason = 'Unknown denomination'
                        
                    self.manager.messageType.persistant.reason = self.reason

                    self.manager.messageType.removeCallback(self.handle)
                    self.__createAndOutput(MintingKeyFailure)
                else:
                    raise MessageError('Received impossible result: %s' % result)
            else:
                raise MessageError('Received impossible type: %s' % type)

        elif isinstance(message, MintingKeyPass) or isinstance(message, MintingKeyFailure):
            # we output this. Next step can only be Goodbye
            print 'we should never get here. Message: %s' % message.identifier
            self.manager.messageType.removeCallback(self.handle)
예제 #11
0
    def handle(self, message):
        if not isinstance(message, FetchMintedRequest) and not isinstance(message, FetchMintedAccept) and not \
                        isinstance(message, FetchMintedFailure) and not isinstance(message, FetchMintedWait):
            if message.messageLayer.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'FetchMinted should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       message.messageLayer.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called FetchMinted.handle() but cannot be there. Message: %s'
                    % message.identifier)

        self._verifyLastState(
            ['REDEEM_COINS_ACCEPT', 'MINT_ACCEPT', 'FETCH_MINTED_REQUEST'])

        if isinstance(message, FetchMintedRequest):
            # we output this. Previous step was in ????
            print 'Got a FetchMintedRequest. I did not know we got these.'

        elif isinstance(message, FetchMintedAccept):
            self.signatures = self.manager.isMessageType.persistant.signatures
            self.manager.persistant.signatures = self.signatures

            successes, failures = self.verifySignatures(
                self.signatures,
                self.manager.persistant.mintingKeysDenomination,
                self.manager.persistant.mintBlanks, self.manager.entity.cdds)
            self.manager.persistant.newCoins = successes
            self.manager.persistant.mintingFailures = failures

            if successes:
                self.depositCoins(self.manager.entity.coins, successes)
                self.manager.success(self, message)
            if failures:
                self.manager.failure(self, message)

            self.manager.isMessageType.removeCallback(self.handle)

        elif isinstance(message, FetchMintedWait) or isinstance(
                message, FetchMintedFailure):
            self.reason = self.manager.isMessageType.persistant.reason
            # undo the damage and tell someone
            self.manager.failure(message, self)

            self.manager.isMessageType.removeCallback(self.handle)

        self._setLastState(message.identifier)
예제 #12
0
    def verifySignatures(self, signatures, minting_keys, minting_blanks, cdds):
        """verifies the signatures received and makes coins out of blanks."""
        successes = []
        failures = []

        if len(minting_blanks) != len(signatures):
            #FIXME: logging
            #pass # nothing we can do here. Try to salvage what we can. We are going to assume they still line up
            raise MessageError(
                'minting_blanks and signatures are different lengths'
            )  # screw it

        for i in range(len(signatures)):
            sig = signatures[i]
            bnk = minting_blanks[i]
            #FIXME another 'Only one CDD per transaction' belief. This one may be valid -- talking to IS
            cdd = cdds[minting_blanks[0].currency_identifier]
            unblinded = bnk.unblind_signature(sig)
            try:
                coin = bnk.newCoin(unblinded, cdd,
                                   minting_keys[bnk.denomination])
                # the call to newCoin verifies the signature
                successes.append(coin)
            except CryptoError:
                failures.append(bnk, sig)

        return successes, failures
예제 #13
0
 def resumeConversation(self, message, result):
     if isinstance(message, BlankPresent):
         self.setHandler(BlankAndMintingKey(
             self, message))  # First we receive the blanks
     elif isinstance(message, MintAccept) or isinstance(
             message, MintReject):
         self.setHandler(Mint(
             self, message))  # Then we (may) try to mint our own blanks
     elif isinstance(message, LockCoinsFailure) or isinstance(
             message, LockCoinsAccept):
         self.setHandler(LockCoins(
             self, message))  # We also have to try to lock the coins...
     elif isinstance(message, CoinsRedeem):
         self.setHandler(
             Coins(self, message)
         )  # We locked the coins, and they are valid. We sent a BlankAccept. Next we get told to redeem them
     elif isinstance(message, RedeemCoinsReject) or isinstance(
             message, RedeemCoinsAccept):
         self.setHandler(
             RedeemCoins(self, message)
         )  # Now we redeem them (note: the next step may be to try to mint them...)
     elif isinstance(message, FetchMintedWait) or isinstance(
             message, FetchMintedFailure) or isinstance(
                 message, FetchMintedAccept):
         self.setHandler(FetchMinted(
             self, message))  # And finally, get the coins.
     elif isinstance(message, UnlockCoinsPass) or isinstance(
             message, UnlockCoinsFailure):
         self.setHandler(UnlockCoins(
             self, message))  # If we erred, we unlock to be nice
     else:
         raise MessageError('Message %s does not continue a conversation' %
                            message.identifier)
예제 #14
0
    def __init__(self, messageType, entity):
        self.messageType = messageType
        self.entity = entity  # the entity that spawned us
        self.dsdb_key = self.entity.dsdb_key

        if not self.messageType.globals.status.can(
                MessageStatuses.PrivilegeServer):
            raise MessageError(
                'given messageType does not have PrivilegeServer')

        class messages:
            pass

        self.messages = messages
        del messages

        #create conversation starting messages to trigger self.startConversation
        self.messages.LCR = LockCoinsRequest(self.startConversation)
        self.messages.UCR = UnlockCoinsRequest(self.startConversation)

        #add all of our special mesasges as MessageHandlers
        self.messageType.addMessageHandler(self.messages.LCR)
        self.messageType.addMessageHandler(self.messages.UCR)

        #everything that can't start a conversation
        self.messageType.addMessageHandler(LockCoinsAccept())
        self.messageType.addMessageHandler(LockCoinsFailure())
        self.messageType.addMessageHandler(UnlockCoinsPass())
        self.messageType.addMessageHandler(UnlockCoinsFailure())

        self.manager = None
예제 #15
0
    def handle(self, message):
        if not isinstance(message, FetchMintedRequest) and not isinstance(message, FetchMintedFailure) and not \
                            isinstance(message, FetchMintedWait) and not isinstance(message, FetchMintedAccept):
            if self.manager.messageType.globals.lastState == MessageHello: # we are now on a different message. Oops.
                raise MessageError('FetchMinted should have already been removed. It was not. Very odd. Message: %s' % message.identifier)
                self.manager.messageType.removeCallback(self.handle)
            else:
                print 'message class: %s' % message.__class__
                raise MessageError('We somehow called FetchMinted.handle() but cannot be there. Message: %s' % message.identifier)

        if isinstance(message, FetchMintedRequest):
            self.request_id = self.manager.messageType.persistant.request_id

            # FIXME: Hack to ensure we try to mint things. Run the minting right now, if we have it
            self.manager.entity.attemptToMint() # this tries to mint everything waiting
            
            type, result = self.findRequest(self.request_id, self.manager.entity.credited_transactions)

            if type == 'ACCEPT':
                self.signatures = result
                self.manager.messageType.persistant.signatures = result
                self.__createAndOutput(FetchMintedAccept)

            elif type == 'WAIT':
                self.reason = result
                self.manager.messageType.persistant.reason = result
                self.__createAndOutput(FetchMintedWait)

            elif type == 'FAILURE':
                self.reason = result
                self.manager.messageType.persistant.reason = result
                self.__createAndOutput(FetchMintedFailure)

            else:
                raise MessageError('Received unknown type: %s' % type)

        elif isinstance(message, FetchMintedAccept):
            # we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)

        elif isinstance(message, FetchMintedFailure):
            #we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)

        elif isinstance(message, FetchMintedWait):
            # we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)
예제 #16
0
 def startConversation(self, message, result):
     if isinstance(message, self.messages.LCR.__class__):
         self.setHandler(LockCoins(self, message))
     elif isinstance(message, self.messages.UCR.__class__):
         self.setHandler(UnlockCoins(self, message))
     else:
         raise MessageError("Message %s does not start a conversation" %
                            message.identifier)
    def createBlinds(self, dsdb_certificate, coins):
        if len(coins) == 0:
            raise MessageError('Can not blind no coins!')

        blinds = []
        for c in coins:
            blinds.append(self.createBlind(dsdb_certificate, c))

        self.manager.walletMessageType.persistant.blanks = blinds
예제 #18
0
    def getCDD(self, cdds, blanks):
        """Returns the CDD for the blanks. Assumes only one CDD (Raise MessageError if multiple)."""
        try:
            currency_identifier = blanks[0].currency_identifier
        except IndexError:
            raise MessageError('No blanks')

        #FIXME: somehow allow multiple cdds?
        for b in blanks:
            if currency_identifier != b.currency_identifier:
                raise MessageError(
                    'This client is too stupid to deal with more than one currency.'
                )

        if not cdds.has_key(currency_identifier):
            return 'Unknown issuer'
        else:
            return cdds[currency_identifier]
 def _verifyLastState(self, state):
     """_verifyLastState is used to make sure that we are progressing properly through messages which can start at Hello.
     For any message which can start at Hello, perform a check to make sure that we have the required lastState in the manager.
     A lastState of None is the beginning.
     """
     if not self.manager.lastMessageIdentifier in state:
         raise MessageError(
             'Did not find expected last state. Found: %s, Wanted: %s' %
             (self.manager.lastMessageIdentifier, state))
예제 #20
0
    def handle(self, message):
        if not isinstance(message, DSDBKeyRequest) and not isinstance(message, DSDBKeyPass):
            if self.manager.messageType.globals.lastState == MessageHello: # we are now on a different message. Oops.
                raise MessageError('DSDBKey should have already been removed. It was not. Very odd. Message: %s LastMessage: %s' % (message.identifier,
                                                                                                                        self.manager.messageType.globals.lastState))
            else:
                print 'message class: %s' % message.__class__
                raise MessageError('We somehow called DSDBKey.handle() but cannot be there. Message: %s' % message.identifier)

        if isinstance(message, DSDBKeyRequest):
                self.dsdb_certificate = self.dsdbKey()

                self.manager.messageType.persistant.dsdb_certificate = self.dsdb_certificate
                self.__createAndOutput(DSDBKeyPass)

        elif isinstance(message, DSDBKeyPass):
            # we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)
예제 #21
0
 def _verifyLastState(self, state):
     """_verifyLastState is used to make sure that we are progressing properly through messages which can start at Hello.
     For any message which can start at Hello, perform a check to make sure that we have the required lastState in the manager.
     A lastState of None is the beginning.
     """
     return  #FIXME: lastState isn't being set due to function calls. Figure this out later. (Note: not having this breaks verification)
     if not self.manager.lastMessageIdentifier in state:
         raise MessageError(
             'Did not find expected last state. Found: %s, Wanted: %s' %
             (self.manager.lastMessageIdentifier, state))
예제 #22
0
    def handle(self, message):
        if not isinstance(message, UnlockCoinsRequest) and not isinstance(
                message, UnlockCoinsPass) and not isinstance(
                    message, UnlockCoinsFailure):
            if self.manager.messageType.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'UnlockCoins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       self.manager.messageType.globals.lastState))
            else:
                print 'message class: %s' % message.__class__
                raise MessageError(
                    'We somehow called UnlockCoins.handle() but cannot be there. Message: %s'
                    % message.identifier)

        if isinstance(message, UnlockCoinsRequest):
            self.transaction_id = self.manager.messageType.persistant.transaction_id

            self.type, self.result = self.unlock(self.transaction_id)

            if self.type == 'ACCEPT':
                self.manager.messageType.removeCallback(self.handle)
                self.__createAndOutput(UnlockCoinsPass)

            elif self.type == 'REJECT':
                transaction_id, self.reason = self.result
                if self.transaction_id != transaction_id:
                    raise MessageError(
                        'transaction_id changed. Was: %s, Now: %s' %
                        (self.transation_id, transaction_id))
                self.manager.messageType.persistant.reason = self.reason

                self.manager.messageType.removeCallback(self.handle)
                self.__createAndOutput(UnlockCoinsFailure)

            else:
                raise MessageError('Received an impossible type: %s' %
                                   self.type)

        elif isinstance(message, UnlockCoinsPass) or isinstance(
                message, UnlockCoinsFailure):
            # we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)
예제 #23
0
    def lock(self, dsdb_key_id, transaction_id, blanks, dsdb_key,
             dsdb_database, dsdb_requests, minting_keys_key_id, now):
        failure = False
        failures = []

        blanksAndSerials = []

        # FIXME: This code does not work well with threading. To fix, change testBlank to something closer to unblind with
        #        possible errors for being unable to blind or a bad minting key. Then do the call to lockBlanks which then
        #        tries one by one to lock the serials in the database. If it gets any failures, it unwinds the locks it has
        #        done and gives the errors it came across.
        #
        #        Actually, FIXME: Does the protocol allow us to just stop if we have bad keys in minting keys or are we supposed
        #                         just keep going coming up with all the errors we can find?
        if len(blanks) == 0:
            raise MessageError('request %s has no blinds' % request_id)

        if not self.validDSDBKeyID(dsdb_key_id, dsdb_key, now):
            return 'REJECT', 'Key ID of DSDB is unknown or expired'

        for b in blanks:
            type, result = self.testBlank(b, dsdb_key_id, dsdb_key,
                                          dsdb_database, dsdb_requests,
                                          minting_keys_key_id, now)
            if type == 'ACCEPT':
                blanksAndSerials.append(
                    (b, result))  # Add the tuple of the blank and the serial
            elif type == 'REJECT':
                failure = True
                failures.append((b, result))
            else:
                raise MessageError('Received impossible type: %s' % type)

        if failure:
            return 'REJECT', failures

        dsdb_lock_time = self.lockBlanks(transaction_id, blanksAndSerials,
                                         dsdb_key, dsdb_database,
                                         dsdb_requests, now)

        return 'ACCEPT', (transaction_id, dsdb_lock_time)
예제 #24
0
 def startConversation(self, message, result):
     if isinstance(message, DSDBKeyRequest):
         self.setHandler(DSDBKey(self, message))
     elif isinstance(message, FetchMintedRequest):
         self.setHandler(FetchMinted(self, message))
     elif isinstance(message, MintRequest):
         self.setHandler(Mint(self, message))
     elif isinstance(message, MintingKeyFetchDenomination) or isinstance(message, MintingKeyFetchKeyID):
         self.setHandler(MintingKey(self, message))
     elif isinstance(message, RedeemCoinsRequest):
         self.setHandler(RedeemCoins(self, message))
     else:
         raise MessageError("Message %s does not start a conversation" % message.identifier)
    def resumeConversation(self, message, result):
        if isinstance(message, DSDBKeyPass):
            self.setHandler(DSDBKey(self, message))
        elif isinstance(message, BlankReject) or isinstance(
                message, BlankFailure) or isinstance(message, BlankAccept):
            self.setHandler(Blank(self, message))
        elif isinstance(message, CoinsReject) or isinstance(
                message, CoinsAccept):
            self.setHandler(Coins(self, message))

        else:
            raise MessageError('Message %s does not continue a conversation' %
                               message.identifier)
예제 #26
0
    def handle(self, message):
        if not isinstance(message, LockCoinsRequest) and not isinstance(
                message, LockCoinsAccept) and not isinstance(
                    message, LockCoinsFailure):
            if message.messageLayer.globals.lastState == MessageHello:  # we are now on a different message. Oops.
                raise MessageError(
                    'LockCoins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s'
                    % (message.identifier,
                       message.messageLayer.globals.lastState))
            else:
                raise MessageError(
                    'We somehow called LockCoins.handle() but cannot be there. Message: %s'
                    % message.identifier)

        self._verifyLastState(['BlankAndMintingKey', 'LOCK_COINS_REQUEST'])

        if isinstance(message, LockCoinsRequest):
            # we output this. Previous step was in BlankAndMintingKey
            print 'Got a LockCoinsRequest. I did not know we got these.'

        elif isinstance(message, LockCoinsAccept):
            self.dsdb_lock = self.manager.dsdbMessageType.persistant.dsdb_lock
            self.manager.persistant.dsdb_lock = self.dsdb_lock

            if not self.validDSDBLock(self.dsdb_lock, self.timeNow()):
                raise MessageError('Invalid DSDB Lock')

            self.manager.dsdbMessageType.removeCallback(
                self.handle
            )  #remove the callback to the DSDB. Not coming here again

            self._createAndOutputWallet(BlankAccept)

        elif isinstance(message, LockCoinsFailure):
            self.reason = self.manager.dsdbMessageType.persistant.reason
            # undo the damage and tell someone
            self.manager.failure(message, self)

        self._setLastState(message.identifier)
예제 #27
0
    def redeem(self, transaction_id, target, coins, currency_description_document, minting_keys_key_id, dsdb_database, dsdb_requests,
                                                                                                        credited_transactions):
        """redeem checks the validity of the coins.
        redeem first checks the validity of the coins. It then verifies the target.
        Finally, it tries to redeem all the coins at once. This action first verifies then updates the DSDB.
        """
        failure = False
        failures = []

        if len(coins) == 0:
            raise MessageError('transaction %s has no coins' % transaction_id)

        if len(coins) != len(set(coins)):
            return 'REJECT', 'Sent two copies of the same coin!' #FIXME: This error isn't in the standard

        for c in coins:
            type, result = self.testCoin(c, transaction_id, currency_description_document, minting_keys_key_id)
            if type == 'ACCEPT':
                pass
            elif type == 'REJECT':
                failure = True
                failures.append( (coin, result) )
            else:
                raise MessageError('Received impossible type: %s' % type)

        if failure:
            return 'REJECT', failures

        if not self.checkValidTarget(target, credited_transactions):
            return 'REJECT', 'Unknown target'
        
        type, result = self.redeemCoins(transaction_id, target, coins, dsdb_database, dsdb_requests, credited_transactions)
        if type == 'ACCEPT':
            return 'ACCEPT', None
        elif type == 'REJECT':
            return 'REJECT', result
        else:
            raise MessageError('Received impossible type: %s' % type)
예제 #28
0
    def handle(self, message):
        if not isinstance(message, RedeemCoinsRequest) and not isinstance(message, RedeemCoinsAccept) and not isinstance(message, RedeemCoinsReject):
            if self.manager.messageType.globals.lastState == MessageHello: # we are now on a different message. Oops.
                raise MessageError('RedeemCoins should have already been removed. It was not. Very odd. Message: %s LastMessage: %s' % (message.identifier,
                                                                                                                        self.manager.messageType.globals.lastState))
            else:
                print 'message class: %s' % message.__class__
                raise MessageError('We somehow called RedeemCoins.handle() but cannot be there. Message: %s' % message.identifier)

        if isinstance(message, RedeemCoinsRequest):
                self.transaction_id = self.manager.messageType.persistant.transaction_id
                self.target = self.manager.messageType.persistant.target
                self.coins = self.manager.messageType.persistant.coins

                type, result = self.redeem(self.transaction_id, self.target, self.coins, self.manager.entity.cdd,
                                           self.manager.entity.minting_keys_key_id, self.manager.entity.dsdb_database,
                                           self.manager.entity.dsdb_requests, self.manager.entity.credited_transactions)

                if type == 'ACCEPT':
                    self.manager.messageType.removeCallback(self.handle)
                    self.__createAndOutput(RedeemCoinsAccept)

                elif type == 'REJECT':
                    self.manager.messageType.persistant.reason = result
                    self.manager.messageType.removeCallback(self.handle)
                    self.__createAndOutput(RedeemCoinsReject)

                else:
                    raise MessageError('Received an impossible type: %s' % self.type)

        elif isinstance(message, RedeemCoinsAccept) or isinstance(message, RedeemCoinReject):
            # we output this. Next step can only be Goodbye
            self.manager.messageType.removeCallback(self.handle)

        else:
            raise MessageError('Trying to handle a message we are not designed for: %s' % message.identifier)
    def __init__(self, walletMessageType, entity, coins):
        self.walletMessageType = walletMessageType
        self.entity = entity

        #self.isMessageType = isMessageType
        if not self.walletMessageType.globals.status.can(
                MessageStatuses.PrivilegeClient):
            raise MessageError(
                'given messageType does not have PrivilegeClient')

        class messages:
            pass

        self.walletMessages = messages()
        self.isMessages = messages()
        del messages

        # All the responses we can get from the IS
        self.isMessages.DKP = DSDBKeyPass(self.resumeConversation)

        # All the responses we can get from the other wallet
        self.walletMessages.BR = BlankReject(self.resumeConversation)
        self.walletMessages.BF = BlankFailure(self.resumeConversation)
        self.walletMessages.BA = BlankAccept(self.resumeConversation)
        self.walletMessages.CR = CoinsReject(self.resumeConversation)
        self.walletMessages.CA = CoinsAccept(self.resumeConversation)

        # Add handlers for all the messages using walletMessages if continues conversation
        self.walletMessageType.addMessageHandler(BlankPresent())
        self.walletMessageType.addMessageHandler(self.walletMessages.BR)
        self.walletMessageType.addMessageHandler(self.walletMessages.BF)
        self.walletMessageType.addMessageHandler(self.walletMessages.BA)
        self.walletMessageType.addMessageHandler(CoinsRedeem())
        self.walletMessageType.addMessageHandler(self.walletMessages.CR)
        self.walletMessageType.addMessageHandler(self.walletMessages.CA)

        self.coins = coins

        class state:
            pass

        self.persistant = state()
        del state

        self.lastMessageIdentifier = None
예제 #30
0
    def checkValidObfuscatedBlanksAndKnownIssuers(self, blanks, cdds,
                                                  mintingKeysKeyID):
        failure = False
        failures = []

        if len(blanks) == 0:
            raise MessageError('Need atleast one blank!')

        for b in blanks:
            if not self.checkValidObfuscatedBlank(b, cdds, mintingKeysKeyID):
                failure = True
                failures.append((b, 'Malformed blank'))
            elif not self.checkKnownIssuer(b, self.manager.entity.cdds):
                failure = True
                failures.append((b, 'Unknown issuer'))

        if failure:
            return 'FAILED', failures
        else:
            return 'PASS', None