Exemplo n.º 1
0
class ConfigRegexChecker(ConfigChecker):
    """
    :param str regexString:
    """
    def __init__(self, regexString):
        super(ConfigRegexChecker, self).__init__()

        self._regex = NdnRegexTopMatcher(regexString)

    def checkNames(self, packetName, keyLocatorName, state):
        """
        :param Name packetName:
        :param Name keyLocatorName:
        :param ValidationState state:
        :rtype: bool
        """
        result = self._regex.match(keyLocatorName)
        if not result:
            state.fail(
                ValidationError(
                    ValidationError.POLICY_ERROR,
                    "KeyLocator check failed: regex " + self._regex.getExpr() +
                    " for packet " + packetName.toUri() +
                    " is invalid (KeyLocator=" + keyLocatorName.toUri() + ")"))

        return result
Exemplo n.º 2
0
    def __init__(self, packetNameRegexString, packetNameExpansion,
                 keyNameRegexString, keyNameExpansion, hyperRelation):
        super(ConfigHyperRelationChecker, self).__init__()

        self._packetNameRegex = NdnRegexTopMatcher(packetNameRegexString)
        self._packetNameExpansion = packetNameExpansion
        self._keyNameRegex = NdnRegexTopMatcher(keyNameRegexString)
        self._keyNameExpansion = keyNameExpansion
        self._hyperRelation = hyperRelation
Exemplo n.º 3
0
    def __init__(self, packetNameRegexString, packetNameExpansion,
          keyNameRegexString, keyNameExpansion, hyperRelation):
        super(ConfigHyperRelationChecker, self).__init__()

        self._packetNameRegex = NdnRegexTopMatcher(packetNameRegexString)
        self._packetNameExpansion = packetNameExpansion
        self._keyNameRegex = NdnRegexTopMatcher(keyNameRegexString)
        self._keyNameExpansion = keyNameExpansion
        self._hyperRelation = hyperRelation
Exemplo n.º 4
0
class ConfigRegexNameFilter(ConfigFilter):
    """
    ConfigRegexNameFilter extends ConfigFilter to check that the packet name
    matches the specified regular expression. The configuration
    {@code
    "filter
    {
    type name
    regex ^[^<KEY>]*<KEY><>*<ksk-.*>$
    }"}
    creates
    {@code ConfigRegexNameFilter("^[^<KEY>]*<KEY><>*<ksk-.*>$") }.

    :param str regexString: The regex string.
    """
    def __init__(self, regexString):
        super(ConfigRegexNameFilter, self).__init__()

        self._regex = NdnRegexTopMatcher(regexString)

    def matchName(self, packetName):
        """
        Implementation of the check for match.

        :param Name packetName: The packet name, which is already stripped of
          signature components if this is a signed Interest name.
        :return: True for a match.
        :rtype: bool
        """
        return self._regex.match(packetName)
Exemplo n.º 5
0
class ConfigRegexNameFilter(ConfigFilter):
    """
    ConfigRegexNameFilter extends ConfigFilter to check that the packet name
    matches the specified regular expression. The configuration
    {@code
    "filter
    {
    type name
    regex ^[^<KEY>]*<KEY><>*<ksk-.*>$
    }"}
    creates
    {@code ConfigRegexNameFilter("^[^<KEY>]*<KEY><>*<ksk-.*>$") }.

    :param str regexString: The regex string.
    """
    def __init__(self, regexString):
        super(ConfigRegexNameFilter, self).__init__()

        self._regex = NdnRegexTopMatcher(regexString)

    def matchName(self, packetName):
        """
        Implementation of the check for match.

        :param Name packetName: The packet name, which is already stripped of
          signature components if this is a signed Interest name.
        :return: True for a match.
        :rtype: bool
        """
        return self._regex.match(packetName)
Exemplo n.º 6
0
class ConfigRegexChecker(ConfigChecker):
    """
    :param str regexString:
    """
    def __init__(self, regexString):
        super(ConfigRegexChecker, self).__init__()

        self._regex = NdnRegexTopMatcher(regexString)

    def checkNames(self, packetName, keyLocatorName, state):
        """
        :param Name packetName:
        :param Name keyLocatorName:
        :param ValidationState state:
        :rtype: bool
        """
        result = self._regex.match(keyLocatorName)
        if not result:
            state.fail(ValidationError(ValidationError.POLICY_ERROR,
              "KeyLocator check failed: regex " + self._regex.getExpr() +
              " for packet " + packetName.toUri() + " is invalid (KeyLocator=" +
              keyLocatorName.toUri() + ")"))

        return result
Exemplo n.º 7
0
class ConfigHyperRelationChecker(ConfigChecker):
    """
    :param str packetNameRegexString:
    :param str packetNameExpansion:
    :param str keyNameRegexString:
    :param str keyNameExpansion:
    :param int hyperRelation: The value for the ConfigNameRelation.Relation enum.
    """
    def __init__(self, packetNameRegexString, packetNameExpansion,
          keyNameRegexString, keyNameExpansion, hyperRelation):
        super(ConfigHyperRelationChecker, self).__init__()

        self._packetNameRegex = NdnRegexTopMatcher(packetNameRegexString)
        self._packetNameExpansion = packetNameExpansion
        self._keyNameRegex = NdnRegexTopMatcher(keyNameRegexString)
        self._keyNameExpansion = keyNameExpansion
        self._hyperRelation = hyperRelation

    def checkNames(self, packetName, keyLocatorName, state):
        """
        :param Name packetName:
        :param Name keyLocatorName:
        :param ValidationState state:
        :rtype: bool
        """
        if not self._packetNameRegex.match(packetName):
            state.fail(ValidationError(ValidationError.POLICY_ERROR,
              "The packet " + packetName.toUri() + " (KeyLocator=" +
              keyLocatorName.toUri() +
              ") does not match the hyper relation packet name regex " +
              self._packetNameRegex.getExpr()))
            return False
        if not self._keyNameRegex.match(keyLocatorName):
            state.fail(ValidationError(ValidationError.POLICY_ERROR,
              "The packet " + packetName.toUri() + " (KeyLocator=" +
              keyLocatorName.toUri() +
              ") does not match the hyper relation key name regex " +
              self._keyNameRegex.getExpr()))
            return False

        keyNameMatchExpansion = self._keyNameRegex.expand(self._keyNameExpansion)
        packetNameMatchExpansion = self._packetNameRegex.expand(
          self._packetNameExpansion)
        result = ConfigNameRelation.checkNameRelation(
          self._hyperRelation, keyNameMatchExpansion, packetNameMatchExpansion)
        if not result:
            state.fail(ValidationError(ValidationError.POLICY_ERROR,
              "KeyLocator check failed: hyper relation " +
              ConfigNameRelation.toString(self._hyperRelation) +
              " packet name match=" + packetNameMatchExpansion.toUri() +
              ", key name match=" + keyNameMatchExpansion.toUri() + " of packet " +
              packetName.toUri() + " (KeyLocator=" + keyLocatorName.toUri() +
              ") is invalid"))

        return result
Exemplo n.º 8
0
    def _findMatchingRule(self, objName, matchType):
        """
        Search the configuration file for the first rule that matches the data
        or signed interest name. In the case of interests, the name to match
        should exclude the timestamp, nonce, and signature components.
        :param Name objName: The name to be matched.
        :param string matchType: The rule type to match, "data" or "interest".
        """
        rules = self.config["validator/rule"]
        for r in rules:
            if r['for'][0].getValue() == matchType:
                passed = True
                try:
                    filters = r['filter']
                except KeyError:
                    # no filters means we pass!
                    return r
                else:
                    for f in filters:
                        # don't check the type - it can only be name for now
                        # we need to see if this is a regex or a relation
                        regexPattern = f.getFirstValue("regex")
                        if regexPattern == None:
                            matchRelation = f.getFirstValue("relation")
                            matchUri = f.getFirstValue("name")
                            matchName = Name(matchUri)
                            passed = self._matchesRelation(
                                objName, matchName, matchRelation)
                        else:
                            passed = NdnRegexTopMatcher(regexPattern).match(
                                objName)

                        if not passed:
                            break
                    if passed:
                        return r

        return None
Exemplo n.º 9
0
    def doesMatch(self, name):
        """
        Check if the given name matches this filter. Match if name starts with
        this filter's prefix. If this filter has the optional regexFilter then
        the remaining components match the regexFilter regular expression.
        For example, the following InterestFilter:

           InterestFilter("/hello", "<world><>+")

        will match all Interests, whose name has the prefix `/hello` which is
        followed by a component `world` and has at least one more component
        after it. Examples:

           /hello/world/!
           /hello/world/x/y/z

        Note that the regular expression will need to match all remaining
        components (e.g., there are implicit heading `^` and trailing `$`
        symbols in the regular expression).

        :param Name name: The name to check against this filter.
        :return: True if name matches this filter, otherwise False.
        :rtype: bool
        """
        if len(name) < len(self._prefix):
            return False

        if self.hasRegexFilter():
            # Perform a prefix match and regular expression match for the
            # remaining components.
            if not self._prefix.match(name):
                return False

            return NdnRegexTopMatcher(self._regexFilterPattern).match(
                name.getSubName(len(self._prefix)))
        else:
            # Just perform a prefix match.
            return self._prefix.match(name)
Exemplo n.º 10
0
    def test_top_matcher_advanced(self):
        cm = NdnRegexTopMatcher("^(<.*>*)<.*>")
        res = cm.match(Name("/n/a/b/c"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual(Name("/n/a/b/"), cm.expand("\\1"))

        cm = NdnRegexTopMatcher("^(<.*>*)<.*><c>(<.*>)<.*>")
        res = cm.match(Name("/n/a/b/c/d/e/"))
        self.assertEqual(True, res)
        self.assertEqual(6, len(cm.getMatchResult()))
        self.assertEqual(Name("/n/a/d/"), cm.expand("\\1\\2"))

        cm = NdnRegexTopMatcher("(<.*>*)<.*>$")
        res = cm.match(Name("/n/a/b/c/"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual(Name("/n/a/b/"), cm.expand("\\1"))

        cm = NdnRegexTopMatcher("<.*>(<.*>*)<.*>$")
        res = cm.match(Name("/n/a/b/c/"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual(Name("/a/b/"), cm.expand("\\1"))

        cm = NdnRegexTopMatcher("<a>(<>*)<>$")
        res = cm.match(Name("/n/a/b/c/"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual(Name("/b/"), cm.expand("\\1"))

        cm = NdnRegexTopMatcher("^<ndn><(.*)\\.(.*)><DNS>(<>*)<>")
        res = cm.match(Name("/ndn/ucla.edu/DNS/yingdi/mac/ksk-1/"))
        self.assertEqual(True, res)
        self.assertEqual(6, len(cm.getMatchResult()))
        self.assertEqual(Name("/ndn/edu/ucla/yingdi/mac/"),
          cm.expand("<ndn>\\2\\1\\3"))

        cm = NdnRegexTopMatcher(
          "^<ndn><(.*)\\.(.*)><DNS>(<>*)<>", "<ndn>\\2\\1\\3")
        res = cm.match(Name("/ndn/ucla.edu/DNS/yingdi/mac/ksk-1/"))
        self.assertEqual(True, res)
        self.assertEqual(6, len(cm.getMatchResult()))
        self.assertEqual(Name("/ndn/edu/ucla/yingdi/mac/"), cm.expand())
Exemplo n.º 11
0
    def test_top_matcher(self):
        cm = NdnRegexTopMatcher("^<a><b><c>")
        res = cm.match(Name("/a/b/c/d"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual("a", cm.getMatchResult()[0].toEscapedString())
        self.assertEqual("b", cm.getMatchResult()[1].toEscapedString())
        self.assertEqual("c", cm.getMatchResult()[2].toEscapedString())
        self.assertEqual("d", cm.getMatchResult()[3].toEscapedString())

        cm = NdnRegexTopMatcher("<b><c><d>$")
        res = cm.match(Name("/a/b/c/d"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual("a", cm.getMatchResult()[0].toEscapedString())
        self.assertEqual("b", cm.getMatchResult()[1].toEscapedString())
        self.assertEqual("c", cm.getMatchResult()[2].toEscapedString())
        self.assertEqual("d", cm.getMatchResult()[3].toEscapedString())

        cm = NdnRegexTopMatcher("^<a><b><c><d>$")
        res = cm.match(Name("/a/b/c/d"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual("a", cm.getMatchResult()[0].toEscapedString())
        self.assertEqual("b", cm.getMatchResult()[1].toEscapedString())
        self.assertEqual("c", cm.getMatchResult()[2].toEscapedString())
        self.assertEqual("d", cm.getMatchResult()[3].toEscapedString())

        res = cm.match(Name("/a/b/c/d/e"))
        self.assertEqual(False, res)
        self.assertEqual(0, len(cm.getMatchResult()))

        cm = NdnRegexTopMatcher("<a><b><c><d>")
        res = cm.match(Name("/a/b/c/d"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual("a", cm.getMatchResult()[0].toEscapedString())
        self.assertEqual("b", cm.getMatchResult()[1].toEscapedString())
        self.assertEqual("c", cm.getMatchResult()[2].toEscapedString())
        self.assertEqual("d", cm.getMatchResult()[3].toEscapedString())

        cm = NdnRegexTopMatcher("<b><c>")
        res = cm.match(Name("/a/b/c/d"))
        self.assertEqual(True, res)
        self.assertEqual(4, len(cm.getMatchResult()))
        self.assertEqual("a", cm.getMatchResult()[0].toEscapedString())
        self.assertEqual("b", cm.getMatchResult()[1].toEscapedString())
        self.assertEqual("c", cm.getMatchResult()[2].toEscapedString())
        self.assertEqual("d", cm.getMatchResult()[3].toEscapedString())
Exemplo n.º 12
0
    def __init__(self, regexString):
        super(ConfigRegexNameFilter, self).__init__()

        self._regex = NdnRegexTopMatcher(regexString)
Exemplo n.º 13
0
class ConfigHyperRelationChecker(ConfigChecker):
    """
    :param str packetNameRegexString:
    :param str packetNameExpansion:
    :param str keyNameRegexString:
    :param str keyNameExpansion:
    :param int hyperRelation: The value for the ConfigNameRelation.Relation enum.
    """
    def __init__(self, packetNameRegexString, packetNameExpansion,
                 keyNameRegexString, keyNameExpansion, hyperRelation):
        super(ConfigHyperRelationChecker, self).__init__()

        self._packetNameRegex = NdnRegexTopMatcher(packetNameRegexString)
        self._packetNameExpansion = packetNameExpansion
        self._keyNameRegex = NdnRegexTopMatcher(keyNameRegexString)
        self._keyNameExpansion = keyNameExpansion
        self._hyperRelation = hyperRelation

    def checkNames(self, packetName, keyLocatorName, state):
        """
        :param Name packetName:
        :param Name keyLocatorName:
        :param ValidationState state:
        :rtype: bool
        """
        if not self._packetNameRegex.match(packetName):
            state.fail(
                ValidationError(
                    ValidationError.POLICY_ERROR,
                    "The packet " + packetName.toUri() + " (KeyLocator=" +
                    keyLocatorName.toUri() +
                    ") does not match the hyper relation packet name regex " +
                    self._packetNameRegex.getExpr()))
            return False
        if not self._keyNameRegex.match(keyLocatorName):
            state.fail(
                ValidationError(
                    ValidationError.POLICY_ERROR,
                    "The packet " + packetName.toUri() + " (KeyLocator=" +
                    keyLocatorName.toUri() +
                    ") does not match the hyper relation key name regex " +
                    self._keyNameRegex.getExpr()))
            return False

        keyNameMatchExpansion = self._keyNameRegex.expand(
            self._keyNameExpansion)
        packetNameMatchExpansion = self._packetNameRegex.expand(
            self._packetNameExpansion)
        result = ConfigNameRelation.checkNameRelation(
            self._hyperRelation, keyNameMatchExpansion,
            packetNameMatchExpansion)
        if not result:
            state.fail(
                ValidationError(
                    ValidationError.POLICY_ERROR,
                    "KeyLocator check failed: hyper relation " +
                    ConfigNameRelation.toString(self._hyperRelation) +
                    " packet name match=" + packetNameMatchExpansion.toUri() +
                    ", key name match=" + keyNameMatchExpansion.toUri() +
                    " of packet " + packetName.toUri() + " (KeyLocator=" +
                    keyLocatorName.toUri() + ") is invalid"))

        return result
Exemplo n.º 14
0
    def _checkSignatureMatch(self, signatureName, objectName, rule,
                             failureReason):
        """
        Once a rule is found to match data or a signed interest, the name in the
        KeyLocator must satisfy the condition in the 'checker' section of the rule,
        else the data or interest is rejected.

        :param Name signatureName: The certificate name from the KeyLocator .
        :param Name objectName: The name of the data packet or interest. In the
          case of signed interests, this excludes the timestamp, nonce and signature
          components.
        :param BoostInfoTree rule: The rule from the configuration file that matches
          the data or interest.
        :param Array<str> failureReason: If verification fails, set
          failureReason[0] to the failure reason string.
        :return: True if matches.
        :rtype: bool

        """
        checker = rule['checker'][0]
        checkerType = checker['type'][0].getValue()
        if checkerType == 'fixed-signer':
            signerInfo = checker['signer'][0]
            signerType = signerInfo['type'][0].getValue()
            if signerType == 'file':
                if self._isSecurityV1:
                    cert = self._lookupCertificate(
                        signerInfo['file-name'][0].getValue(), True)
                    if cert is None:
                        failureReason[0] = (
                            "Can't find fixed-signer certificate file: " +
                            signerInfo['file-name'][0].getValue())
                        return False
                else:
                    cert = self._lookupCertificateV2(
                        signerInfo['file-name'][0].getValue(), True)
                    if cert is None:
                        failureReason[0] = (
                            "Can't find fixed-signer certificate file: " +
                            signerInfo['file-name'][0].getValue())
                        return False
            elif signerType == 'base64':
                if self._isSecurityV1:
                    cert = self._lookupCertificate(
                        signerInfo['base64-string'][0].getValue(), False)
                    if cert is None:
                        failureReason[0] = (
                            "Can't find fixed-signer certificate base64: " +
                            signerInfo['base64-string'][0].getValue())
                        return False
                else:
                    cert = self._lookupCertificateV2(
                        signerInfo['base64-string'][0].getValue(), False)
                    if cert is None:
                        failureReason[0] = (
                            "Can't find fixed-signer certificate base64: " +
                            signerInfo['base64-string'][0].getValue())
                        return False
            else:
                failureReason[0] = ("Unrecognized fixed-signer signerType: " +
                                    signerType)
                return False

            if cert.getName().equals(signatureName):
                return True
            else:
                failureReason[0] = ("fixed-signer cert name \"" +
                                    cert.getName().toUri() +
                                    "\" does not equal signatureName \"" +
                                    signatureName.toUri() + "\"")
                return False
        elif checkerType == 'hierarchical':
            # this just means the data/interest name has the signing identity as a prefix
            # that means everything before 'ksk-?' in the key name
            identityRegex = '^([^<KEY>]*)<KEY>(<>*)<ksk-.+><ID-CERT>'
            identityMatch = NdnRegexTopMatcher(identityRegex)
            if identityMatch.match(signatureName):
                identityPrefix = identityMatch.expand("\\1").append(
                    identityMatch.expand("\\2"))
                if self._matchesRelation(objectName, identityPrefix,
                                         'is-prefix-of'):
                    return True
                else:
                    failureReason[0] = ("The hierarchical objectName \"" +
                                        objectName.toUri() +
                                        "\" is not a prefix of \"" +
                                        identityPrefix.toUri() + "\"")
                    return False

            if not self._isSecurityV1:
                # Check for a security v2 key name.
                identityRegex2 = "^(<>*)<KEY><>$"
                identityMatch2 = NdnRegexTopMatcher(identityRegex2)
                if identityMatch2.match(signatureName):
                    identityPrefix = identityMatch2.expand("\\1")
                    if self._matchesRelation(objectName, identityPrefix,
                                             'is-prefix-of'):
                        return True
                    else:
                        failureReason[0] = ("The hierarchical objectName \"" +
                                            objectName.toUri() +
                                            "\" is not a prefix of \"" +
                                            identityPrefix.toUri() + "\"")
                        return False

            failureReason[0] = ("The hierarchical identityRegex \"" +
                                identityRegex +
                                "\" does not match signatureName \"" +
                                signatureName.toUri() + "\"")
            return False
        elif checkerType == 'customized':
            keyLocatorInfo = checker['key-locator'][0]
            # not checking type - only name is supported

            # is this a simple relation?
            relationType = keyLocatorInfo.getFirstValue("relation")
            if relationType != None:
                matchName = Name(keyLocatorInfo['name'][0].getValue())
                if self._matchesRelation(signatureName, matchName,
                                         relationType):
                    return True
                else:
                    failureReason[0] = ("The custom signatureName \"" +
                                        signatureName.toUri() +
                                        "\" does not match matchName \"" +
                                        matchName.toUri() +
                                        "\" using relation " + relationType)
                    return False

            # Is this a simple regex?
            simpleKeyRegex = keyLocatorInfo.getFirstValue("regex")
            if simpleKeyRegex != None:
                if NdnRegexTopMatcher(simpleKeyRegex).match(signatureName):
                    return True
                else:
                    failureReason[0] = (
                        "The custom signatureName \"" + signatureName.toUri() +
                        "\" does not regex match simpleKeyRegex \"" +
                        simpleKeyRegex + "\"")
                    return False

            # is this a hyper-relation?
            hyperRelationList = keyLocatorInfo["hyper-relation"]
            if len(hyperRelationList) >= 1:
                hyperRelation = hyperRelationList[0]

                keyRegex = hyperRelation.getFirstValue('k-regex')
                keyExpansion = hyperRelation.getFirstValue('k-expand')
                nameRegex = hyperRelation.getFirstValue('p-regex')
                nameExpansion = hyperRelation.getFirstValue('p-expand')
                relationType = hyperRelation.getFirstValue('h-relation')
                if (keyRegex != None and keyExpansion != None
                        and nameRegex != None and nameExpansion != None
                        and relationType != None):
                    keyMatch = NdnRegexTopMatcher(keyRegex)
                    if not keyMatch.match(signatureName):
                        failureReason[0] = (
                            "The custom hyper-relation signatureName \"" +
                            signatureName.toUri() +
                            "\" does not match the keyRegex \"" + keyRegex +
                            "\"")
                        return False
                    keyMatchPrefix = keyMatch.expand(keyExpansion)

                    nameMatch = NdnRegexTopMatcher(nameRegex)
                    if not nameMatch.match(objectName):
                        failureReason[0] = (
                            "The custom hyper-relation objectName \"" +
                            objectName.toUri() +
                            "\" does not match the nameRegex \"" + nameRegex +
                            "\"")
                        return False
                    nameMatchExpansion = nameMatch.expand(nameExpansion)

                    if self._matchesRelation(nameMatchExpansion,
                                             keyMatchPrefix, relationType):
                        return True
                    else:
                        failureReason[0] = (
                            "The custom hyper-relation nameMatch \"" +
                            nameMatchExpansion.toUri() +
                            "\" does not match the keyMatchPrefix \"" +
                            keyMatchPrefix.toUri() + "\" using relation " +
                            relationType)
                        return False

        failureReason[0] = "Unrecognized checkerType: " + checkerType
        return False
Exemplo n.º 15
0
    def __init__(self, regexString):
        super(ConfigRegexNameFilter, self).__init__()

        self._regex = NdnRegexTopMatcher(regexString)
Exemplo n.º 16
0
    def _checkSignatureMatch(self, signatureName, objectName, rule, failureReason):
        """
        Once a rule is found to match data or a signed interest, the name in the
        KeyLocator must satisfy the condition in the 'checker' section of the rule,
        else the data or interest is rejected.

        :param Name signatureName: The certificate name from the KeyLocator .
        :param Name objectName: The name of the data packet or interest. In the
          case of signed interests, this excludes the timestamp, nonce and signature
          components.
        :param BoostInfoTree rule: The rule from the configuration file that matches
          the data or interest.
        :param Array<str> failureReason: If verification fails, set
          failureReason[0] to the failure reason string.
        :return: True if matches.
        :rtype: bool

        """
        checker = rule['checker'][0]
        checkerType = checker['type'][0].getValue()
        if checkerType == 'fixed-signer':
            signerInfo = checker['signer'][0]
            signerType = signerInfo['type'][0].getValue()
            if signerType == 'file':
                if self._isSecurityV1:
                    cert = self._lookupCertificate(
                      signerInfo['file-name'][0].getValue(), True)
                    if cert is None:
                        failureReason[0] = (
                          "Can't find fixed-signer certificate file: " +
                          signerInfo['file-name'][0].getValue())
                        return False
                else:
                    cert = self._lookupCertificateV2(
                      signerInfo['file-name'][0].getValue(), True)
                    if cert is None:
                        failureReason[0] = (
                          "Can't find fixed-signer certificate file: " +
                          signerInfo['file-name'][0].getValue())
                        return False
            elif signerType == 'base64':
                if self._isSecurityV1:
                    cert = self._lookupCertificate(
                      signerInfo['base64-string'][0].getValue(), False)
                    if cert is None:
                        failureReason[0] = (
                          "Can't find fixed-signer certificate base64: " +
                          signerInfo['base64-string'][0].getValue())
                        return False
                else:
                    cert = self._lookupCertificateV2(
                      signerInfo['base64-string'][0].getValue(), False)
                    if cert is None:
                        failureReason[0] = (
                          "Can't find fixed-signer certificate base64: " +
                          signerInfo['base64-string'][0].getValue())
                        return False
            else:
                failureReason[0] = ("Unrecognized fixed-signer signerType: " +
                  signerType)
                return False

            if cert.getName().equals(signatureName):
                return True
            else:
                failureReason[0] = ("fixed-signer cert name \"" +
                  cert.getName().toUri() + "\" does not equal signatureName \"" +
                  signatureName.toUri() + "\"")
                return False
        elif checkerType == 'hierarchical':
            # this just means the data/interest name has the signing identity as a prefix
            # that means everything before 'ksk-?' in the key name
            identityRegex = '^([^<KEY>]*)<KEY>(<>*)<ksk-.+><ID-CERT>'
            identityMatch = NdnRegexTopMatcher(identityRegex)
            if identityMatch.match(signatureName):
                identityPrefix = identityMatch.expand("\\1").append(
                  identityMatch.expand("\\2"))
                if self._matchesRelation(objectName, identityPrefix, 'is-prefix-of'):
                    return True
                else:
                    failureReason[0] = ("The hierarchical objectName \"" +
                      objectName.toUri() + "\" is not a prefix of \"" +
                      identityPrefix.toUri() + "\"")
                    return False

            if not self._isSecurityV1:
                # Check for a security v2 key name.
                identityRegex2 = "^(<>*)<KEY><>$"
                identityMatch2 = NdnRegexTopMatcher(identityRegex2)
                if identityMatch2.match(signatureName):
                    identityPrefix = identityMatch2.expand("\\1")
                    if self._matchesRelation(objectName, identityPrefix, 'is-prefix-of'):
                        return True
                    else:
                        failureReason[0] = ("The hierarchical objectName \"" +
                          objectName.toUri() + "\" is not a prefix of \"" +
                          identityPrefix.toUri() + "\"")
                        return False

            failureReason[0] = ("The hierarchical identityRegex \"" +
              identityRegex + "\" does not match signatureName \"" +
              signatureName.toUri() + "\"")
            return False
        elif checkerType == 'customized':
            keyLocatorInfo = checker['key-locator'][0]
            # not checking type - only name is supported

            # is this a simple relation?
            relationType = keyLocatorInfo.getFirstValue("relation")
            if relationType != None:
                matchName = Name(keyLocatorInfo['name'][0].getValue())
                if self._matchesRelation(signatureName, matchName, relationType):
                    return True
                else:
                    failureReason[0] = ("The custom signatureName \"" +
                      signatureName.toUri() + "\" does not match matchName \"" +
                      matchName.toUri() + "\" using relation " + relationType)
                    return False

            # Is this a simple regex?
            simpleKeyRegex = keyLocatorInfo.getFirstValue("regex")
            if simpleKeyRegex != None:
                if NdnRegexTopMatcher(simpleKeyRegex).match(signatureName):
                    return True
                else:
                    failureReason[0] = ("The custom signatureName \"" +
                      signatureName.toUri() +
                      "\" does not regex match simpleKeyRegex \"" +
                      simpleKeyRegex + "\"")
                    return False

            # is this a hyper-relation?
            hyperRelationList = keyLocatorInfo["hyper-relation"]
            if len(hyperRelationList) >= 1:
                hyperRelation = hyperRelationList[0]

                keyRegex = hyperRelation.getFirstValue('k-regex')
                keyExpansion = hyperRelation.getFirstValue('k-expand')
                nameRegex = hyperRelation.getFirstValue('p-regex')
                nameExpansion = hyperRelation.getFirstValue('p-expand')
                relationType = hyperRelation.getFirstValue('h-relation')
                if (keyRegex != None and keyExpansion != None and
                      nameRegex != None and nameExpansion != None and
                      relationType != None):
                    keyMatch = NdnRegexTopMatcher(keyRegex)
                    if not keyMatch.match(signatureName):
                        failureReason[0] = (
                          "The custom hyper-relation signatureName \"" +
                          signatureName.toUri() +
                          "\" does not match the keyRegex \"" + keyRegex + "\"")
                        return False
                    keyMatchPrefix = keyMatch.expand(keyExpansion)

                    nameMatch = NdnRegexTopMatcher(nameRegex)
                    if not nameMatch.match(objectName):
                        failureReason[0] = (
                          "The custom hyper-relation objectName \"" +
                          objectName.toUri() +
                          "\" does not match the nameRegex \"" + nameRegex + "\"")
                        return False
                    nameMatchExpansion = nameMatch.expand(nameExpansion)

                    if self._matchesRelation(
                          nameMatchExpansion, keyMatchPrefix, relationType):
                        return True
                    else:
                        failureReason[0] = (
                          "The custom hyper-relation nameMatch \"" +
                          nameMatchExpansion.toUri() +
                          "\" does not match the keyMatchPrefix \"" +
                          keyMatchPrefix.toUri() + "\" using relation " +
                          relationType)
                        return False

        failureReason[0] = "Unrecognized checkerType: " + checkerType
        return False