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 try: regex = f['regex'][0].getValue() except KeyError: matchRelation = f['relation'][0].getValue() matchUri = f['name'][0].getValue() matchName = Name(matchUri) passed = self._matchesRelation( objName, matchName, matchRelation) else: passed = NdnRegexMatcher.match(regex, objName) is not None if not passed: break if passed: return r return None
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 None != NdnRegexMatcher.match( self._regexFilterPattern, name.getSubName(len(self._prefix))) else: # Just perform a prefix match. return self._prefix.match(name)
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 try: regex = f['regex'][0].getValue() except KeyError: matchRelation = f['relation'][0].getValue() matchUri = f['name'][0].getValue() matchName = Name(matchUri) passed = self._matchesRelation(objName, matchName, matchRelation) else: passed = NdnRegexMatcher.match(regex, objName) is not None if not passed: break if passed: return r return None
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': 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 elif signerType == 'base64': 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: 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 = NdnRegexMatcher.match(identityRegex, signatureName) if identityMatch is not None: identityPrefix = Name(identityMatch.group(1)).append( Name(identityMatch.group(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 else: 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? try: relationType = keyLocatorInfo['relation'][0].getValue() except KeyError: pass else: 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? try: keyRegex = keyLocatorInfo['regex'][0].getValue() except KeyError: pass else: if NdnRegexMatcher.match(keyRegex, signatureName) is not None: return True else: failureReason[0] = ( "The custom signatureName \"" + signatureName.toUri() + "\" does not regex match simpleKeyRegex \"" + keyRegex + "\"") return False # is this a hyper-relation? try: hyperRelation = keyLocatorInfo['hyper-relation'][0] except KeyError: pass else: 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 = NdnRegexMatcher.match(keyRegex, signatureName) if keyMatch == None: failureReason[0] = ( "The custom hyper-relation signatureName \"" + signatureName.toUri() + "\" does not match the keyRegex \"" + keyRegex + "\"") return False keyMatchPrefix = keyMatch.expand(keyExpansion) nameMatch = NdnRegexMatcher.match(nameRegex, objectName) if nameMatch == None: failureReason[0] = ( "The custom hyper-relation objectName \"" + objectName.toUri() + "\" does not match the nameRegex \"" + nameRegex + "\"") return False nameMatchStr = nameMatch.expand(nameExpansion) if self._matchesRelation(Name(nameMatchStr), Name(keyMatchPrefix), relationType): return True else: failureReason[0] = ( "The custom hyper-relation nameMatch \"" + nameMatchStr + "\" does not match the keyMatchPrefix \"" + keyMatchPrefix + "\" using relation " + relationType) return False failureReason[0] = "Unrecognized checkerType: " + checkerType return False
def _checkSignatureMatch(self, signatureName, objectName, rule): """ 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. """ 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': cert = self._lookupCertificate(signerInfo['file-name'][0].getValue(), True) elif signerType == 'base64': cert = self._lookupCertificate(signerInfo['base64-string'][0].getValue(), False) else: return False if cert is None: return False else: return cert.getName().equals(signatureName) 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 = NdnRegexMatcher.match(identityRegex, signatureName) if identityMatch is not None: identityPrefix = Name(identityMatch.group(1)).append(Name(identityMatch.group(2))) return self._matchesRelation(objectName, identityPrefix, 'is-prefix-of') else: return False elif checkerType == 'customized': keyLocatorInfo = checker['key-locator'][0] # not checking type - only name is supported # is this a simple relation? try: relationType = keyLocatorInfo['relation'][0].getValue() except KeyError: pass else: matchName = Name(keyLocatorInfo['name'][0].getValue()) return self._matchesRelation(signatureName, matchName, relationType) # is this a simple regex? try: keyRegex = keyLocatorInfo['regex'][0].getValue() except KeyError: pass else: return NdnRegexMatcher.match(keyRegex, signatureName) is not None # is this a hyper-relation? try: hyperRelation = keyLocatorInfo['hyper-relation'][0] except KeyError: pass else: try: keyRegex = hyperRelation['k-regex'][0].getValue() keyMatch = NdnRegexMatcher.match(keyRegex, signatureName) keyExpansion = hyperRelation['k-expand'][0].getValue() keyMatchPrefix = keyMatch.expand(keyExpansion) nameRegex = hyperRelation['p-regex'][0].getValue() nameMatch = NdnRegexMatcher.match(nameRegex, objectName) nameExpansion = hyperRelation['p-expand'][0].getValue() nameMatchStr = nameMatch.expand(nameExpansion) relationType = hyperRelation['h-relation'][0].getValue() return self._matchesRelation(Name(nameMatchStr), Name(keyMatchPrefix), relationType) except: pass # unknown type return False
def _checkSignatureMatch(self, signatureName, objectName, rule): """ 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. """ 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': cert = self._lookupCertificate( signerInfo['file-name'][0].getValue(), True) elif signerType == 'base64': cert = self._lookupCertificate( signerInfo['base64-string'][0].getValue(), False) else: return False if cert is None: return False else: return cert.getName().equals(signatureName) 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 = NdnRegexMatcher.match(identityRegex, signatureName) if identityMatch is not None: identityPrefix = Name(identityMatch.group(1)).append( Name(identityMatch.group(2))) return self._matchesRelation(objectName, identityPrefix, 'is-prefix-of') else: return False elif checkerType == 'customized': keyLocatorInfo = checker['key-locator'][0] # not checking type - only name is supported # is this a simple relation? try: relationType = keyLocatorInfo['relation'][0].getValue() except KeyError: pass else: matchName = Name(keyLocatorInfo['name'][0].getValue()) return self._matchesRelation(signatureName, matchName, relationType) # is this a simple regex? try: keyRegex = keyLocatorInfo['regex'][0].getValue() except KeyError: pass else: return NdnRegexMatcher.match(keyRegex, signatureName) is not None # is this a hyper-relation? try: hyperRelation = keyLocatorInfo['hyper-relation'][0] except KeyError: pass else: try: keyRegex = hyperRelation['k-regex'][0].getValue() keyMatch = NdnRegexMatcher.match(keyRegex, signatureName) keyExpansion = hyperRelation['k-expand'][0].getValue() keyMatchPrefix = keyMatch.expand(keyExpansion) nameRegex = hyperRelation['p-regex'][0].getValue() nameMatch = NdnRegexMatcher.match(nameRegex, objectName) nameExpansion = hyperRelation['p-expand'][0].getValue() nameMatchStr = nameMatch.expand(nameExpansion) relationType = hyperRelation['h-relation'][0].getValue() return self._matchesRelation(Name(nameMatchStr), Name(keyMatchPrefix), relationType) except: pass # unknown type return False
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': 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 elif signerType == 'base64': 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: 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 = NdnRegexMatcher.match(identityRegex, signatureName) if identityMatch is not None: identityPrefix = Name(identityMatch.group(1)).append(Name(identityMatch.group(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 else: 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? try: relationType = keyLocatorInfo['relation'][0].getValue() except KeyError: pass else: 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? try: keyRegex = keyLocatorInfo['regex'][0].getValue() except KeyError: pass else: if NdnRegexMatcher.match(keyRegex, signatureName) is not None: return True else: failureReason[0] = ("The custom signatureName \"" + signatureName.toUri() + "\" does not regex match simpleKeyRegex \"" + keyRegex + "\"") return False # is this a hyper-relation? try: hyperRelation = keyLocatorInfo['hyper-relation'][0] except KeyError: pass else: 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 = NdnRegexMatcher.match(keyRegex, signatureName) if keyMatch == None: failureReason[0] = ( "The custom hyper-relation signatureName \"" + signatureName.toUri() + "\" does not match the keyRegex \"" + keyRegex + "\"") return False keyMatchPrefix = keyMatch.expand(keyExpansion) nameMatch = NdnRegexMatcher.match(nameRegex, objectName) if nameMatch == None: failureReason[0] = ( "The custom hyper-relation objectName \"" + objectName.toUri() + "\" does not match the nameRegex \"" + nameRegex + "\"") return False nameMatchStr = nameMatch.expand(nameExpansion) if self._matchesRelation( Name(nameMatchStr), Name(keyMatchPrefix), relationType): return True else: failureReason[0] = ( "The custom hyper-relation nameMatch \"" + nameMatchStr + "\" does not match the keyMatchPrefix \"" + keyMatchPrefix + "\" using relation " + relationType) return False failureReason[0] = "Unrecognized checkerType: " + checkerType return False