Project

General

Profile

CommandValidatorConf » History » Revision 19

Revision 18 (Yingdi Yu, 03/18/2014 10:54 PM) → Revision 19/55 (Yingdi Yu, 03/18/2014 10:55 PM)

# Validator Configuration File Format 

 You can set up a `Validator` via a configuration file.  
 Next, we will show you how to write a configuration file. 

 The configuration file consists of **rules** that will be used in validation. 
 Here is an example of configuration file containing two rules. 

     rule 
     { 
       id "Simple Rule" 
       for data 
       type customized 
       filter 
       { 
         type name 
         name "/localhost/example" 
         relation isPrefixOf 
       } 
       signer 
       { 
         sig-type rsa-sha256 
         key-locator 
         { 
           type name 
           name "/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT" 
           relation equal 
         } 
       } 
     } 
     rule 
     { 
       id "Testbed Validation Rule" 
       for data 
       type hierarchical 
       filter 
       { 
         type name 
         regex "^<>*$" 
       } 
       trust-anchor 
       { 
         type file 
         file-name "testbed-trust-anchor.cert" 
       } 
     } 


 <font color='red'>**ATTENTION: The order of rules MATTERS!**</font> 

 A rule can be broken into two parts:  

 * The first part is to qualify packets to which the rule can be applied; 
 * The second part is to decide whether further validation process is necessary. 

 When receiving a packet, the validator will check it against rules in the configuration file one-by-one, 
 until reaching a rule that the packet qualifies for. 
 And the second part of the matching rule will be used to check the validity of the packet. 
 If the packet cannot qualify any rules, it is treated as an invalid packet. 
 Once a packet has been matched by a rule, it will not be checked against the rest rules. 
 Therefore, you should always put the most specific rule to the top, otherwise it will become useless. 

 In the example configuration, 
 the first rule indicates that all the data packets under the name prefix "/localhost/example" must be signed by a key whose certificate name is "/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT". 
 If a packet does not have a name under prefix "/localhost/example", validator will skip the first rule and check the second rule. 
 The second rule indicates that any data packets must be validated recursively back along a hierarchy with a trust anchor stored in a file called "testbed-trust-anchor.cert". 

 ## Rules in general 

 Before we go into the details of specific rules, we need to introduce several general properties of a rule. 

 A rule must have a **id** property which uniquely identify the rule in the configuration file, e.g., "Simple Rule", "Testbed Validation Rule". 

 A rule is either used to validate an interest packet or a data packet.  
 This information is specified in the property **for**. 
 Only two value can be specified: **data** and **interest**. 

 The property **type** indicates the type of rules. 
 There are some pre-defined rule types, such as **hierarchical**. 
 People can also customize their own rules by setting the type property to be **customized**. 

 A rule may have some other properties depending on the rule type.  
 Next, we will introduce the other properties for the each rule type. 

 ## Customized Rule 

 Two properties are required by customized rule: **filter** and **signer**. 
 And some optional properties may be needed, such as **relation** and etc.. 

 ### Filter Property 

 The **filter** property specifies the condition that a packet must fulfill. 
 A rule may contain more than one filters. 
 A packet can be captured by a rule only if the packet satisfies all the filters. 

 Filter has its own property **type**. 
 Although a rule may contain more than one filters, there is at most one filter of each type. 
 So far, we defined only one filter type: **name**. 
 In other word, only one filter can be specified for now. 

 There are two ways to express the restrictions on name.  
 The first way is to specify a relationship between the packet name and a particular name. 
 In this case, two more properties are required: **name** and **relation**. 
 A packet can fulfill the condition if the **name** and the packet name can establish the **relation**. 
 The value of **relation** property could be either **isPrefixOf** or **equal**.  
 For example, a filter: 

     filter 
     { 
       type name 
       name "/localhost/example" 
       relation isPrefixOf 
     } 

 can capture a packet with name "/localhost/example/data" but cannot catch a packet with name "/localhost/another_example". 

 And a filter  

     filter 
     { 
       type name 
       name "/localhost/example" 
       relation equal 
     } 

 can only catch a packet with the exact name "/localhost/example". 

 The second way is to specify an NDN regular expression that the packet name must match. 
 In this case, only one property **regex** is required. 
 The value of **regex** is an NDN regular expression. 
 A packet can satisfy the filter only if the regex can match the packet name. 
 If regex is used, an optional property **expand** may be specified if back reference is need to extract certain pattern out of the packet name. 
 For example, a filter  

     filter 
     { 
       type name 
       regex "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$" 
       expand "\\1\\2" 
     } 

 can catch all the identity certificates and extract the corresponding namespace of the certificate. 
 Note that, if expand property is not used or name property is used, the whole packet name is extracted.  

 ### Signer Property 

 The **signer** property defines the conditions that the `SignatureInfo` part of the packet must fulfill. 
 Same as the **filter** property, a rule may contain more than one **signer** properties. 
 A packet, however, only needs to satisfy one of the **signer** properties. 

 A signer property requires a **sig-type** property which specifies the acceptable signature type. 
 Right now only one signature type **rsa-sha256** is defined. 

 A signer property also requires a **key-locator** property which specifies the conditions on `KeyLocator`. 
 Right now only one key-locator type **name** is defined. 
 Such a type of key-locator contains the certificate name of the signing key. 
 Since the key-locator is a name, you can specify the conditions on it in the same way as the **filter** with type **name**. 
 For example, a signer could be: 

     signer 
     { 
       sig-type rsa-sha256 
       key-locator 
       { 
         type name 
         name "/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT" 
         relation equal 
       } 
     } 

 This signer property requires that the packet must have a rsa-sha256 signature generated by a key whose certificate name is "/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT". 

 In some cases, the signer property may contain a **trust-anchor** property which specifies the pre-trusted certificate. 
 For example, a signer with a trust-anchor property could be: 

     signer 
     { 
       sig-type rsa-sha256 
       key-locator 
       { 
         type name 
         regex "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$" 
         expand "\\1\\2" 
       } 
       trust-anchor 
       { 
         type file 
         file-name "testbed-trust-anchor.cert" 
       } 
     } 

 Note that the **trust-anchor** must fulfill the conditions specified in **sig-type** and **key-locator**. 

 ### Relation Property 

 The **relation** property is optional. 
 It is used only when we need to specify an additional condition between packet name and key-locator name. 
 
 If the **relation** property is specified, then the rule must contain: 1) a **filter** of type name, and 2) a **signer** with a key-locator of type name. 
 Otherwise, the rule is treated as invalid. 

 The **relation** property describes the relationship between the name extracted by the filter and the name extracted by the signer. 
 Three relationships can be specified: **equal** (=), **isPrefixOf** (>=), and **isStrictPrefixOf** (>). 

 ## Hierarchical Rule 

 As implied by its name, hierarchical rule requires that the packet name must be under the namespace of the packet signer. 
 Therefore, you only need to specify two properties in hierarchical rule:  

 * a filter of type name which restrict the scope of packets 
 * trust-anchors of the hierarchy 

 For the hierarchical rule in the example configuration, it is equivalent to a customized rule: 

     rule 
     { 
       id "Testbed Validation Rule" 
       for data 
       type customized 
       filter 
       { 
         type name 
         regex "^(<>*)$" 
         expand "\\1" 
       } 
       signer 
       { 
         sig-type rsa-sha256 
         key-locator 
         { 
           type name 
           regex "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$" 
           expand "\\1\\2" 
         } 
         trust-anchor 
         { 
           type file 
           file-name "testbed-trust-anchor.cert" 
         } 
       } 
       relation isStrictPrefixOf 
     } 

 ## Example Configuration For NLSR 

 The trust model of NLSR is semi-hierarchical. 
 The signing hierarchy is root->site->operator->router->NLSR->NLSR data 

 The root could be the self-signed testbed root key, and an example certificate name could be "/ndn/KEY/ksk-12345/ID-CERT/%01%02%03". 
 A site certificate is signed using the root key, and an example certificate name could be "/ndn/edu/ucla/KEY/ksk-13579/ID-CERT/%03%04%05". 
 A operator certificate is signed using the site key, and an example certificate name could be "/ndn/edu/ucla/KEY/operator/operator-1/ksk-24680/ID-CERT/%05%06%07". 
 A router certificate is signed using the operator key, and an example certificate name could be "/ndn/edu/ucla/KEY/router/router-1/ksk-67890/ID-CERT/%07%08%09". 
 A NLSR certificate is signed using the router key, and an example certificate name could be "/ndn/edu/ucla/router/router-1/KEY/NLSR/ksk-54321/ID-CERT/%01%03%05". 
 A typical NLSR data name could be "/ndn/edu/ucla/router/router-1/NLSR/LSA/LSType.1/%02%04%06". 

 The only place where hierarchy is broken is "operator->router". 
 So we can write a configuration file with three rules. 
 The first one is a customized rule that capture the normal NLSR data. 
 The second one is a customized rule that handles the exception case of the hierarchy (operator->router). 
 And the last one is a hierarchical rule that handles the normal cases of the hierarchy. 

 We put the NLSR data rule to the first place, because NLSR data packets are the most frequently checked. 
 The hierarchical exception rule is put to the second, because it is more specific than the last one. 

 And here is the configuration file: 

     rule 
     { 
       id "NSLR Data Rule" 
       for data 
       type customized 
       filter 
       { 
         type name 
         regex "^([^<NLSR><KEY>]*<NLSR>)[^<KEY>]*$" 
         expand "\\1" 
       } 
       signer 
       { 
         sig-type rsa-sha256 
         key-locator 
         { 
           type name 
           regex "^([^<KEY>]*)<KEY>(<>*<NLSR>)<ksk-.*><ID-CERT>$" 
           expand "\\1\\2" 
         } 
       } 
       relation equal 
     } 
     rule 
     { 
       id "NSLR Hierarchy Exception Rule" 
       for data 
       type customized 
       filter 
       { 
         type name 
         regex "^([^<KEY>]*)<KEY>([^<router>]*)<router><><ksk-.*><ID-CERT><>$" 
         expand "\\1\\2" 
       } 
       signer 
       { 
         sig-type rsa-sha256 
         key-locator 
         { 
           type name 
           regex "^([^<KEY>]*)<KEY>([^<operator>]*)<operator><><ksk-.*><ID-CERT>$" 
           expand "\\1\\2" 
         } 
       } 
       relation equal 
     } 
     rule 
     { 
       id "NSLR Hierarchical Rule" 
       for data 
       type hierarchical 
       target 
       { 
         type name 
         regex "^<>*$" "^(<>*)$" 
         expand "\\1" 
       } 
       trust-anchor 
       { 
         type file 
         file-name "testbed-trust-anchor.cert" 
       } 
     }