def test_refer_to_temp():
        lvs = r'''
        #_r1: "a"/b/"c"
        #_r2: #_r1/d/"e"/f
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})

        lvs = r'''
        #_: _a/b/c/d/e & { b: _a }
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})
    def test_cyclic_reference():
        lvs = r'''
        #rule1: a/#rule2
        #rule2: b/#rule1
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})

        lvs = r'''
        #rule1: a <= #rule2
        #rule2: b <= #rule1
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})
 def test_redefinition():
     lvs = r'''
     #rule: "a"/b/"c"
     #rule: d/"e"/f
     '''
     with pytest.raises(SemanticError):
         Checker(compile_lvs(lvs), {})
    def test_missing_definition():
        lvs = r'''
        #rule1: #rule2/a
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})

        lvs = r'''
        #rule: a/b & { c: b }
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})

        lvs = r'''
        #rule: a/b & { b: c }
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})

        lvs = r'''
        #rule1: a <= #rule2
        '''
        with pytest.raises(SemanticError):
            Checker(compile_lvs(lvs), {})

        lvs = r'''
        #_: a & { a: $fn() }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert not checker.validate_user_fns()
    def test_temp_identifiers():
        lvs = r'''
        #_: "a"/b/"c"
        #_: d/"e"/f
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert checker.validate_user_fns()
        assert len(list(checker.match('/a/b/c'))) >= 1
        assert len(list(checker.match('/e/e/e'))) >= 1
        assert len(list(checker.match('/a/e/c'))) >= 2

        lvs = r'''
        #_: a/_/_/b/c & { b: a }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert checker.validate_user_fns()
        assert len(list(checker.match('/a/a/a/a/a'))) >= 1
        assert len(list(checker.match('/x/a/b/x/c'))) >= 1
        assert len(list(checker.match('/x/a/b/y/c'))) == 0
 def test_complicated_rule():
     lvs = r'''
     #r1: a/b/c & { c: b, c: a, a: "a"|"x" } | { b: "b"|"y" } <= #r2 | #r3
     #r2: x/y/z & { x: "xxx" }
     #r3: x/y/z & { y: "yyy" }
     '''
     checker = Checker(compile_lvs(lvs), {})
     assert len(list(checker.match('/a/b/c'))) >= 1
     assert len(list(checker.match('/x/y/z'))) >= 1
     assert len(list(checker.match('/x/x/x'))) >= 1
     assert len(list(checker.match('/a/a/a'))) >= 1
     assert len(list(checker.match('/a/c/a'))) == 0
     assert len(list(checker.match('/a/x/x'))) == 0
     assert checker.check('/a/b/c', '/xxx/yyy/zzz')
     assert checker.check('/x/y/z', '/xxx/xxx/xxx')
     assert checker.check('/x/x/x', '/xxx/yyy/zzz')
     assert checker.check('/a/a/a', '/xxx/xxx/xxx')
Exemple #7
0
def main():
    basedir = os.path.dirname(os.path.abspath(sys.argv[0]))
    tpm_path = os.path.join(basedir, 'privKeys')
    pib_path = os.path.join(basedir, 'pib.db')
    keychain = KeychainSqlite3(pib_path, TpmFile(tpm_path))

    trust_anchor = keychain['/lvs-test'].default_key().default_cert()
    print(f'Trust anchor name: {Name.to_str(trust_anchor.name)}')

    lvs_model = compile_lvs(lvs_text)
    checker = Checker(lvs_model, DEFAULT_USER_FNS)
    app = NDNApp(keychain=keychain)
    validator = lvs_validator(checker, app, trust_anchor.data)

    async def fetch_interest(article: str):
        try:
            name = Name.from_str(f'/lvs-test/article/xinyu/{article}')
            print(f'Sending Interest {Name.to_str(name)}')
            data_name, meta_info, content = await app.express_interest(
                name,
                must_be_fresh=True,
                can_be_prefix=True,
                lifetime=6000,
                validator=validator)
            print(f'Received Data Name: {Name.to_str(data_name)}')
            print(meta_info)
            print(bytes(content).decode() if content else None)
        except InterestNack as e:
            print(f'Nacked with reason={e.reason}')
        except InterestTimeout:
            print(f'Timeout')
        except InterestCanceled:
            print(f'Canceled')
        except ValidationFailure:
            print(f'Data failed to validate')

    async def ndn_main():
        await fetch_interest('hello')
        await fetch_interest('world')

        app.shutdown()

    app.run_forever(ndn_main())
Exemple #8
0
def main():
    basedir = os.path.dirname(os.path.abspath(sys.argv[0]))
    tpm_path = os.path.join(basedir, 'privKeys')
    pib_path = os.path.join(basedir, 'pib.db')
    keychain = KeychainSqlite3(pib_path, TpmFile(tpm_path))

    trust_anchor = keychain['/lvs-test'].default_key().default_cert()
    admin_cert = keychain['/lvs-test/admin/ndn'].default_key().default_cert()
    author_cert = keychain['/lvs-test/author/xinyu'].default_key(
    ).default_cert()
    print(f'Trust anchor name: {Name.to_str(trust_anchor.name)}')
    print(f'Admin name: {Name.to_str(admin_cert.name)}')
    print(f'Author name: {Name.to_str(author_cert.name)}')

    lvs_model = compile_lvs(lvs_text)
    checker = Checker(lvs_model, DEFAULT_USER_FNS)
    # The following manual checks are listed for demonstration only.
    # In real implementation they are automatically done
    root_of_trust = checker.root_of_trust()
    print(f'LVS model root of trust: {root_of_trust}')
    print(f'LVS model user functions provided: {checker.validate_user_fns()}')
    ta_matches = sum((m[0] for m in checker.match(trust_anchor.name)),
                     start=[])
    assert len(ta_matches) > 0
    assert root_of_trust.issubset(ta_matches)
    print(f'Trust anchor matches the root of trust: OK')

    app = NDNApp(keychain=keychain)

    # Note: This producer example does not use LVS validator at all
    # Also, the content of keychain is as follows:
    #   /lvs-test
    #   +->* /lvs-test/KEY/%5Cs%F8%B5%D9k%D2%D2
    #        +->* /lvs-test/KEY/%5Cs%F8%B5%D9k%D2%D2/self/v=1647829075409
    # --
    #   /lvs-test/admin/ndn
    #   +->* /lvs-test/admin/ndn/KEY/z%C7%D2%B0%22%FB%D0%F3
    #        +->  /lvs-test/admin/ndn/KEY/z%C7%D2%B0%22%FB%D0%F3/self/v=1647828984149
    #        +->* /lvs-test/admin/ndn/KEY/z%C7%D2%B0%22%FB%D0%F3/lvs-test/v=1647829580626
    # --
    # * /lvs-test/author/xinyu
    #   +->* /lvs-test/author/xinyu/KEY/%18%F9%A7CP%F6%BD%1B
    #        +->  /lvs-test/author/xinyu/KEY/%18%F9%A7CP%F6%BD%1B/self/v=1647828975217
    #        +->* /lvs-test/author/xinyu/KEY/%18%F9%A7CP%F6%BD%1B/ndn/v=1647829957196

    @app.route('/lvs-test/article/xinyu/hello')
    def on_interest(name, param, _app_param):
        print(f'>> I: {Name.to_str(name)}, {param}')
        content = "Hello,".encode()
        data_name = name + [Component.from_version(timestamp())]
        app.put_data(data_name, content=content, freshness_period=10000)
        print(f'<< D: {Name.to_str(data_name)}')
        print(f'Content: {content.decode()}')
        print('')

    @app.route('/lvs-test/article/xinyu/world')
    def on_interest(name, param, _app_param):
        print(f'>> I: {Name.to_str(name)}, {param}')
        content = "world!".encode()
        data_name = name + [Component.from_version(timestamp())]
        app.put_data(data_name, content=content, freshness_period=10000)
        print(f'<< D: {Name.to_str(data_name)}')
        print(f'Content: {content.decode()}')
        print('')

    @app.route(trust_anchor.name)
    def on_interest(name, param, _app_param):
        print(f'>> I: {Name.to_str(name)}, {param}')
        app.put_raw_packet(trust_anchor.data)
        print(f'<< D: {Name.to_str(trust_anchor.name)}')
        print('')

    @app.route(admin_cert.name)
    def on_interest(name, param, _app_param):
        print(f'>> I: {Name.to_str(name)}, {param}')
        app.put_raw_packet(admin_cert.data)
        print(f'<< D: {Name.to_str(admin_cert.name)}')
        print('')

    @app.route(author_cert.name)
    def on_interest(name, param, _app_param):
        print(f'>> I: {Name.to_str(name)}, {param}')
        app.put_raw_packet(author_cert.data)
        print(f'<< D: {Name.to_str(author_cert.name)}')
        print('')

    print('Start serving ...')
    app.run_forever()
    def test_user_fns():
        lvs = r'''
        #r1: /a/b/c & { b: $eq(a), c: $eq_type("v=0") }
        '''
        checker = Checker(compile_lvs(lvs), DEFAULT_USER_FNS)
        assert checker.validate_user_fns()
        assert len(list(checker.match('/a/b/v=1'))) == 0
        assert len(list(checker.match('/e/e/v=1'))) == 1
        assert len(list(checker.match('/e/e/c'))) == 0

        lvs = r'''
        #r1: /a/b/c & { c: $eq(a, b), c: $eq_type("8=") }
        '''
        checker = Checker(compile_lvs(lvs), DEFAULT_USER_FNS)
        assert checker.validate_user_fns()
        assert len(list(checker.match('/a/b/c'))) == 0
        assert len(list(checker.match('/v=0/v=0/v=0'))) == 0
        assert len(list(checker.match('/e/e/e'))) == 1
    def test_signing_suggest():        
        with TemporaryDirectory() as tmpdirname:
            pib_file = os.path.join(tmpdirname, 'pib.db')
            tpm_dir = os.path.join(tmpdirname, 'privKeys')
            KeychainSqlite3.initialize(pib_file, 'tpm-file', tpm_dir)
            keychain = KeychainSqlite3(pib_file, TpmFile(tpm_dir))
            assert len(keychain) == 0

            la_id = keychain.touch_identity('/la')
            la_cert = la_id.default_key().default_cert().data
            la_cert_data = parse_certificate(la_cert)
            la_cert_name = la_cert_data.name
            la_signer = keychain.get_signer({'cert': la_cert_name})

            la_author_id = keychain.touch_identity('/la/author/1')
            la_author_cert_name, la_author_cert = derive_cert(la_author_id.default_key().name, 
                                                              Component.from_str('la-signer'), 
                                                              la_cert_data.content, la_signer, 
                                                              datetime.utcnow(), 100)
            keychain.import_cert(la_id.default_key().name, la_author_cert_name, la_author_cert)

            ny_id = keychain.touch_identity('/ny')
            ny_cert = ny_id.default_key().default_cert().data
            ny_cert_data = parse_certificate(ny_cert)
            ny_cert_name = ny_cert_data.name
            ny_signer = keychain.get_signer({'cert': ny_cert_name})

            ny_author_id = keychain.touch_identity('/ny/author/2')
            ny_author_cert_name, ny_author_cert = derive_cert(ny_author_id.default_key().name, 
                                                              Component.from_str('ny-signer'),
                                                              ny_cert_data.content, ny_signer, 
                                                              datetime.utcnow(), 100)
            keychain.import_cert(ny_id.default_key().name, ny_author_cert_name, ny_author_cert)


            lvs = r'''
            #KEY: "KEY"/_/_/_
            #article: /"article"/_topic/_ & { _topic: "eco" | "spo" } <= #author
            #author: /site/"author"/_/#KEY <= #anchor
            #anchor: /site/#KEY & {site: "la" | "ny" }
            '''
            checker = Checker(compile_lvs(lvs), {})

            assert checker.suggest("/article/eco/day1", keychain) == la_author_cert_name
            assert checker.suggest("/article/life/day1", keychain) is None
            
            lvs = r'''
            #KEY: "KEY"/_/_/_
            #LAKEY: "KEY"/_/_signer/_ & { _signer: "la-signer" }
            #article: /"article"/_topic/_ & { _topic: "eco" | "spo" } <= #author
            #author: /site/"author"/_/#LAKEY <= #anchor
            #anchor: /site/#KEY & {site: "la"}
            '''
            checker = Checker(compile_lvs(lvs), {})
            assert checker.suggest("/article/eco/day1", keychain) == la_author_cert_name
            
            lvs = r'''
            #KEY: "KEY"/_/_/_version & { _version: $eq_type("v=0") }
            #article: /"article"/_topic/_ & { _topic: "life" | "fin" } <= #author
            #author: /site/"author"/_/#KEY & { site: "ny" } <= #anchor
            #anchor: /site/#KEY & { site: "ny" }
            '''
            checker = Checker(compile_lvs(lvs), DEFAULT_USER_FNS)
            assert checker.suggest("/article/fin/day1", keychain) == ny_author_cert_name
            
            lvs = r'''
            #KEY: "KEY"/_/_/_version & { _version: $eq_type("v=0") }
            #NYKEY: "KEY"/_/_signer/_version& { _signer: "ny-signer", _version: $eq_type("v=0")}
            #article: /"article"/_topic/_ <= #author
            #author: /site/"author"/_/#NYKEY <= #anchor
            #anchor: /site/#KEY & {site: "ny"}
            #site: "ny"
            '''
            checker = Checker(compile_lvs(lvs), DEFAULT_USER_FNS)
            assert checker.suggest("/article/eco/day1", keychain) == ny_author_cert_name        
 def test_compile():
     lvs = r'''
     #rule: "a"/b/"c"
     '''
     checker = Checker(compile_lvs(lvs), {})
     assert checker.validate_user_fns()
    def test_rule_expansion():
        lvs = r'''
        #r1: a/_
        #r2: #r1/"c" & { a: "xyz" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/xyz/abc/c'))) == 1
        assert len(list(checker.match('/a/abc/c'))) == 0

        lvs = r'''
        #r1: a/_
        #r2: /"c"/#r1 & { a: "xyz" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/c/xyz/abc'))) == 1
        assert len(list(checker.match('/c/a/abc'))) == 0

        lvs = r'''
        #r1: a/_ & { a: "a"|"b" }
        #r2: #r1/_ & { a: "a"|"c" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/a/b/c'))) >= 1
        assert len(list(checker.match('/b/c/a'))) == 0
        assert len(list(checker.match('/c/a/b'))) == 0
        assert len(list(checker.match('/a/b'))) >= 1
        assert len(list(checker.match('/b/c'))) >= 1
        assert len(list(checker.match('/c/a'))) == 0

        lvs = r'''
        #r1: a/_ & { a: "a" } | { a: "b" }
        #r2: #r1/_ & { a: "a" } | { a: "c" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/a/b/c'))) >= 1
        assert len(list(checker.match('/b/c/a'))) == 0
        assert len(list(checker.match('/c/a/b'))) == 0
        assert len(list(checker.match('/a/b'))) >= 1
        assert len(list(checker.match('/b/c'))) >= 1
        assert len(list(checker.match('/c/a'))) == 0

        lvs = r'''
        #r1: a/_ & { a: "a" } | { a: "b" }
        #r2: #r1/c & { c: "c" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/a/b/c'))) >= 1
        assert len(list(checker.match('/b/c/c'))) >= 1
        assert len(list(checker.match('/c/a/c'))) == 0

        lvs = r'''
        #r1: a/b & { a: "a" } | { b: "b" }
        #r2: #r1/c & { c: "c" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/a/b/c'))) >= 1
        assert len(list(checker.match('/b/b/c'))) >= 1
        assert len(list(checker.match('/a/a/c'))) >= 1
    def test_named_pattern():
        lvs = r'''
        #r1: a/b/a
        #r2: #r1/a & { a: "xyz" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/xyz/b/xyz/xyz'))) == 1
        assert len(list(checker.match('/a/b/a/xyz'))) == 0
        assert len(list(checker.match('/a/b/a'))) == 1
        assert len(list(checker.match('/a/b/c'))) == 0

        lvs = r'''
        #r1: a/b/a & { a: "abc"|"def" }
        #r2: #r1/a & { a: "abc" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/abc/b/abc/abc'))) == 1
        assert len(list(checker.match('/def/b/def/abc'))) == 0
        assert len(list(checker.match('/def/b/def/def'))) == 0
        assert len(list(checker.match('/abc/b/def'))) == 0
        assert len(list(checker.match('/def/b/def'))) == 1

        lvs = r'''
        #r1: a/b/a
        #r2: /a <= #r1
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert not checker.check('/xyz', '/a/b/a')
        assert checker.check('/a', '/a/b/a')
    def test_temp_pattern():
        lvs = r'''
        #r1: _a/b/_a
        #r2: #r1/_a & { _a: "xyz" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/a/b/c/xyz'))) == 1
        assert len(list(checker.match('/a/b/c/d'))) == 0

        lvs = r'''
        #r1: _a/b/_a & { _a: "abc"|"def" }
        #r2: #r1/_a & { _a: "xyz" }
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert len(list(checker.match('/abc/b/abc/xyz'))) == 1
        assert len(list(checker.match('/abc/b/xyz/xyz'))) == 0
        assert len(list(checker.match('/abc/b/def/xyz'))) == 1

        lvs = r'''
        #r1: _a/b/_a
        #r2: /_a <= #r1
        '''
        checker = Checker(compile_lvs(lvs), {})
        assert checker.check('/xyz', '/a/b/c')
 def test_future_reference():
     lvs = r'''
     #_r1: a/b/c & { a: b }
     '''
     checker = Checker(compile_lvs(lvs), {})
     assert not list(checker.match('/a/b/c'))