コード例 #1
0
    def checkVerificationPolicy(self, dataOrInterest, stepCount, onVerified,
                                onVerifyFailed, wireFormat = None):
        """
        If there is a rule matching the data or interest, and the matching
        certificate is missing, download it. If there is no matching rule,
        verification fails. Otherwise, verify the signature using the public key
        in the IdentityStorage.

        :param dataOrInterest: The Data object or interest with the signature to
          check.
        :type dataOrInterest: Data or Interest
        :param int stepCount: The number of verification steps that have been
          done, used to track the verification progress.
        :param onVerified: If the signature is verified, this calls
          onVerified(dataOrInterest).
        :type onVerified: function object
        :param onVerifyFailed: If the signature check fails, this calls
          onVerifyFailed(dataOrInterest).
        :type onVerifyFailed: function object
        :return: None for no further step for looking up a certificate chain.
        :rtype: ValidationRequest
        """
        if stepCount > self._maxDepth:
            onVerifyFailed(dataOrInterest)
            return None

        signature = self._extractSignature(dataOrInterest, wireFormat)
        # no signature -> fail
        if signature is None:
            onVerifyFailed(dataOrInterest)
            return None

        if not KeyLocator.canGetFromSignature(signature):
            # We only support signature types with key locators.
            onVerifyFailed(dataOrInterest)
            return None

        keyLocator = None
        try:
            keyLocator = KeyLocator.getFromSignature(signature)
        except:
            # No key locator -> fail.
            onVerifyFailed(dataOrInterest)
            return None

        signatureName = keyLocator.getKeyName()
        # no key name in KeyLocator -> fail
        if signatureName.size() == 0:
            onVerifyFailed(dataOrInterest)
            return None

        objectName = dataOrInterest.getName()
        matchType = "data"

        #for command interests, we need to ignore the last 4 components when matching the name
        if isinstance(dataOrInterest, Interest):
            objectName = objectName.getPrefix(-4)
            matchType = "interest"

        # first see if we can find a rule to match this packet
        try:
            matchedRule = self._findMatchingRule(objectName, matchType)
        except:
            matchedRule = None

        # no matching rule -> fail
        if matchedRule is None:
            onVerifyFailed(dataOrInterest)
            return None

        signatureMatches = self._checkSignatureMatch(signatureName, objectName,
                matchedRule)
        if not signatureMatches:
            onVerifyFailed(dataOrInterest)
            return None

        # before we look up keys, refresh any certificate directories
        self._refreshManager.refreshAnchors()

        # now finally check that the data or interest was signed correctly
        # if we don't actually have the certificate yet, create a
        # ValidationRequest for it
        foundCert = self._refreshManager.getCertificate(signatureName)
        if foundCert is None:
            foundCert = self._certificateCache.getCertificate(signatureName)
        if foundCert is None:
            certificateInterest = Interest(signatureName)
            def onCertificateDownloadComplete(certificate):
                certificate = IdentityCertificate(certificate)
                self._certificateCache.insertCertificate(certificate)
                self.checkVerificationPolicy(dataOrInterest, stepCount+1,
                        onVerified, onVerifyFailed)

            nextStep = ValidationRequest(certificateInterest,
                    onCertificateDownloadComplete, onVerifyFailed,
                    2, stepCount+1)

            return nextStep

        # for interests, we must check that the timestamp is fresh enough
        # I do this after (possibly) downloading the certificate to avoid
        # filling the cache with bad keys
        if isinstance(dataOrInterest, Interest):
            keyName = foundCert.getPublicKeyName()
            timestamp = dataOrInterest.getName().get(-4).toNumber()

            if not self._interestTimestampIsFresh(keyName, timestamp):
                onVerifyFailed(dataOrInterest)
                return None

        # certificate is known, verify the signature
        if self._verify(signature, dataOrInterest.wireEncode()):
            onVerified(dataOrInterest)
            if isinstance(dataOrInterest, Interest):
                self._updateTimestampForKey(keyName, timestamp)
        else:
            onVerifyFailed(dataOrInterest)
コード例 #2
0
    def checkVerificationPolicy(self,
                                dataOrInterest,
                                stepCount,
                                onVerified,
                                onVerifyFailed,
                                wireFormat=None):
        """
        If there is a rule matching the data or interest, and the matching
        certificate is missing, download it. If there is no matching rule,
        verification fails. Otherwise, verify the signature using the public key
        in the IdentityStorage.

        :param dataOrInterest: The Data object or interest with the signature to
          check.
        :type dataOrInterest: Data or Interest
        :param int stepCount: The number of verification steps that have been
          done, used to track the verification progress.
        :param onVerified: If the signature is verified, this calls
          onVerified(dataOrInterest).
        :type onVerified: function object
        :param onVerifyFailed: If the signature check fails, this calls
          onVerifyFailed(dataOrInterest).
        :type onVerifyFailed: function object
        :return: None for no further step for looking up a certificate chain.
        :rtype: ValidationRequest
        """
        if stepCount > self._maxDepth:
            onVerifyFailed(dataOrInterest)
            return None

        signature = self._extractSignature(dataOrInterest, wireFormat)
        # no signature -> fail
        if signature is None:
            onVerifyFailed(dataOrInterest)
            return None

        if not KeyLocator.canGetFromSignature(signature):
            # We only support signature types with key locators.
            onVerifyFailed(dataOrInterest)
            return None

        keyLocator = None
        try:
            keyLocator = KeyLocator.getFromSignature(signature)
        except:
            # No key locator -> fail.
            onVerifyFailed(dataOrInterest)
            return None

        signatureName = keyLocator.getKeyName()
        # no key name in KeyLocator -> fail
        if signatureName.size() == 0:
            onVerifyFailed(dataOrInterest)
            return None

        objectName = dataOrInterest.getName()
        matchType = "data"

        #for command interests, we need to ignore the last 4 components when matching the name
        if isinstance(dataOrInterest, Interest):
            objectName = objectName.getPrefix(-4)
            matchType = "interest"

        # first see if we can find a rule to match this packet
        try:
            matchedRule = self._findMatchingRule(objectName, matchType)
        except:
            matchedRule = None

        # no matching rule -> fail
        if matchedRule is None:
            onVerifyFailed(dataOrInterest)
            return None

        signatureMatches = self._checkSignatureMatch(signatureName, objectName,
                                                     matchedRule)
        if not signatureMatches:
            onVerifyFailed(dataOrInterest)
            return None

        # before we look up keys, refresh any certificate directories
        self._refreshManager.refreshAnchors()

        # now finally check that the data or interest was signed correctly
        # if we don't actually have the certificate yet, create a
        # ValidationRequest for it
        foundCert = self._refreshManager.getCertificate(signatureName)
        if foundCert is None:
            foundCert = self._certificateCache.getCertificate(signatureName)
        if foundCert is None:
            certificateInterest = Interest(signatureName)

            def onCertificateDownloadComplete(certificate):
                certificate = IdentityCertificate(certificate)
                self._certificateCache.insertCertificate(certificate)
                self.checkVerificationPolicy(dataOrInterest, stepCount + 1,
                                             onVerified, onVerifyFailed)

            nextStep = ValidationRequest(certificateInterest,
                                         onCertificateDownloadComplete,
                                         onVerifyFailed, 2, stepCount + 1)

            return nextStep

        # for interests, we must check that the timestamp is fresh enough
        # I do this after (possibly) downloading the certificate to avoid
        # filling the cache with bad keys
        if isinstance(dataOrInterest, Interest):
            keyName = foundCert.getPublicKeyName()
            timestamp = dataOrInterest.getName().get(-4).toNumber()

            if not self._interestTimestampIsFresh(keyName, timestamp):
                onVerifyFailed(dataOrInterest)
                return None

        # certificate is known, verify the signature
        if self._verify(signature, dataOrInterest.wireEncode()):
            onVerified(dataOrInterest)
            if isinstance(dataOrInterest, Interest):
                self._updateTimestampForKey(keyName, timestamp)
        else:
            onVerifyFailed(dataOrInterest)