def test_interest_timestamp(self): interestName = Name('/ndn/ucla/edu/something') certName = self.keyChain.getPib().getIdentity(self.identityName).getKey( self.keyName).getDefaultCertificate().getName() face = Face("localhost") face.setCommandSigningInfo(self.keyChain, certName) oldInterest = Interest(interestName) face.makeCommandInterest(oldInterest) time.sleep(0.1) # make sure timestamps are different newInterest = Interest(interestName) face.makeCommandInterest(newInterest) vr = doVerify(self.policyManager, newInterest) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager returned ValidationRequest but certificate is known") self.assertEqual(vr.failureCount, 0, "Verification of valid interest failed") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) vr = doVerify(self.policyManager, oldInterest) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager returned ValidationRequest but certificate is known") self.assertEqual(vr.successCount, 0, "Verification of stale interest succeeded") self.assertEqual(vr.failureCount, 1, "Failure callback called {} times instead of 1".format( vr.failureCount))
def main(): interest = Interest() interest.wireDecode(TlvInterest) dump("Interest:") dumpInterest(interest) # Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()) encoding = interest.wireEncode() dump("") dump("Re-encoded interest", encoding.toHex()) reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) dump("Re-decoded Interest:") dumpInterest(reDecodedInterest) freshInterest = Interest(Name("/ndn/abc")) freshInterest.setMustBeFresh(False) dump(freshInterest.toUri()) freshInterest.setMinSuffixComponents(4) freshInterest.setMaxSuffixComponents(6) freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST) freshInterest.getKeyLocator().setKeyData(bytearray( [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F])) freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny() freshInterest.setInterestLifetimeMilliseconds(30000) freshInterest.setChildSelector(1) freshInterest.setMustBeFresh(True); freshInterest.setScope(2) identityStorage = MemoryIdentityStorage() privateKeyStorage = MemoryPrivateKeyStorage() keyChain = KeyChain(IdentityManager(identityStorage, privateKeyStorage), SelfVerifyPolicyManager(identityStorage)) # Initialize the storage. keyName = Name("/testname/DSK-123") certificateName = keyName.getSubName(0, keyName.size() - 1).append( "KEY").append(keyName[-1]).append("ID-CERT").append("0") identityStorage.addKey(keyName, KeyType.RSA, Blob(DEFAULT_RSA_PUBLIC_KEY_DER)) privateKeyStorage.setKeyPairForKeyName( keyName, KeyType.RSA, DEFAULT_RSA_PUBLIC_KEY_DER, DEFAULT_RSA_PRIVATE_KEY_DER) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, certificateName) face.makeCommandInterest(freshInterest) reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) dump("") dump("Re-decoded fresh Interest:") dumpInterest(reDecodedFreshInterest) keyChain.verifyInterest( reDecodedFreshInterest, makeOnVerified("Freshly-signed Interest"), makeOnVerifyFailed("Freshly-signed Interest"))
def main(): # Silence the warning from Interest wire encode. Interest.setDefaultCanBePrefix(True) interest = Interest() interest.wireDecode(TlvInterest) dump("Interest:") dumpInterest(interest) # Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()) encoding = interest.wireEncode() dump("") dump("Re-encoded interest", encoding.toHex()) reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) dump("Re-decoded Interest:") dumpInterest(reDecodedInterest) freshInterest = (Interest(Name("/ndn/abc")) .setMustBeFresh(False) .setMinSuffixComponents(4) .setMaxSuffixComponents(6) .setInterestLifetimeMilliseconds(30000) .setChildSelector(1) .setMustBeFresh(True)) freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST) freshInterest.getKeyLocator().setKeyData(bytearray( [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F])) freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny() freshInterest.getForwardingHint().add(1, Name("/A")) dump(freshInterest.toUri()) # Set up the KeyChain. keyChain = KeyChain("pib-memory:", "tpm-memory:") keyChain.importSafeBag(SafeBag (Name("/testname/KEY/123"), Blob(DEFAULT_RSA_PRIVATE_KEY_DER, False), Blob(DEFAULT_RSA_PUBLIC_KEY_DER, False))) validator = Validator(ValidationPolicyFromPib(keyChain.getPib())) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName()) face.makeCommandInterest(freshInterest) reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) dump("") dump("Re-decoded fresh Interest:") dumpInterest(reDecodedFreshInterest) validator.validate( reDecodedFreshInterest, makeSuccessCallback("Freshly-signed Interest"), makeFailureCallback("Freshly-signed Interest"))
def main(): # Silence the warning from Interest wire encode. Interest.setDefaultCanBePrefix(True) interest = Interest() interest.wireDecode(TlvInterest) dump("Interest:") dumpInterest(interest) # Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()) encoding = interest.wireEncode() dump("") dump("Re-encoded interest", encoding.toHex()) reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) dump("Re-decoded Interest:") dumpInterest(reDecodedInterest) freshInterest = (Interest( Name("/ndn/abc")).setMustBeFresh(False).setMinSuffixComponents( 4).setMaxSuffixComponents(6).setInterestLifetimeMilliseconds( 30000).setChildSelector(1).setMustBeFresh(True)) freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST) freshInterest.getKeyLocator().setKeyData( bytearray([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F ])) freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny() freshInterest.getForwardingHint().add(1, Name("/A")) dump(freshInterest.toUri()) # Set up the KeyChain. keyChain = KeyChain("pib-memory:", "tpm-memory:") keyChain.importSafeBag( SafeBag(Name("/testname/KEY/123"), Blob(DEFAULT_RSA_PRIVATE_KEY_DER, False), Blob(DEFAULT_RSA_PUBLIC_KEY_DER, False))) validator = Validator(ValidationPolicyFromPib(keyChain.getPib())) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName()) face.makeCommandInterest(freshInterest) reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) dump("") dump("Re-decoded fresh Interest:") dumpInterest(reDecodedFreshInterest) validator.validate(reDecodedFreshInterest, makeSuccessCallback("Freshly-signed Interest"), makeFailureCallback("Freshly-signed Interest"))
def main(): interest = Interest() interest.wireDecode(TlvInterest) dump("Interest:") dumpInterest(interest) # Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()) encoding = interest.wireEncode() dump("") dump("Re-encoded interest", encoding.toHex()) reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) dump("Re-decoded Interest:") dumpInterest(reDecodedInterest) freshInterest = (Interest( Name("/ndn/abc")).setMustBeFresh(False).setMinSuffixComponents( 4).setMaxSuffixComponents(6).setInterestLifetimeMilliseconds( 30000).setChildSelector(1).setMustBeFresh(True)) freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST) freshInterest.getKeyLocator().setKeyData( bytearray([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F ])) freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny() freshInterest.getForwardingHint().add(1, Name("/A")) dump(freshInterest.toUri()) # Set up the KeyChain. pibImpl = PibMemory() keyChain = KeyChain(pibImpl, TpmBackEndMemory(), SelfVerifyPolicyManager(pibImpl)) # This puts the public key in the pibImpl used by the SelfVerifyPolicyManager. keyChain.importSafeBag( SafeBag(Name("/testname/KEY/123"), Blob(DEFAULT_RSA_PRIVATE_KEY_DER, False), Blob(DEFAULT_RSA_PUBLIC_KEY_DER, False))) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName()) face.makeCommandInterest(freshInterest) reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) dump("") dump("Re-decoded fresh Interest:") dumpInterest(reDecodedFreshInterest) keyChain.verifyInterest(reDecodedFreshInterest, makeOnVerified("Freshly-signed Interest"), makeOnValidationFailed("Freshly-signed Interest"))
class TestConfigPolicyManager(ut.TestCase): def setUp(self): testCertDirectory = 'policy_config/certs' self.testCertFile = os.path.join(testCertDirectory, 'test.cert') # Reuse the policy_config subdirectory for the temporary SQLite file. self.databaseFilePath = "policy_config/test-public-info.db" try: os.remove(self.databaseFilePath) except OSError: # no such file pass self.identityStorage = BasicIdentityStorage(self.databaseFilePath) self.privateKeyStorage = MemoryPrivateKeyStorage() self.identityManager = IdentityManager(self.identityStorage, self.privateKeyStorage) self.policyManager = ConfigPolicyManager('policy_config/simple_rules.conf') self.identityName = Name('/TestConfigPolicyManager/temp') # to match the anchor cert keyName = Name(self.identityName).append('ksk-1416010123') self.privateKeyStorage.setKeyPairForKeyName( keyName, KeyType.RSA, TEST_RSA_PUBLIC_KEY_DER, TEST_RSA_PRIVATE_KEY_DER) self.identityStorage.addKey( keyName, KeyType.RSA, Blob(TEST_RSA_PUBLIC_KEY_DER)) cert = self.identityManager.selfSign(keyName) self.identityStorage.setDefaultKeyNameForIdentity(keyName) self.identityManager.addCertificateAsDefault(cert) self.keyChain = KeyChain(self.identityManager, self.policyManager) self.keyName = keyName self.face = Face() def tearDown(self): try: os.remove(self.databaseFilePath) except OSError: pass self.privateKeyStorage.deleteKeyPair(self.keyName) self.face.shutdown() try: os.remove(self.testCertFile) except OSError: pass def test_no_verify(self): policyManager = NoVerifyPolicyManager() identityName = Name('TestValidator/Null').appendVersion(int(time.time())) keyChain = KeyChain(self.identityManager, policyManager) keyChain.createIdentityAndCertificate(identityName) data = Data(Name(identityName).append('data')) keyChain.signByIdentity(data, identityName) vr = doVerify(policyManager, data) self.assertFalse(vr.hasFurtherSteps, "NoVerifyPolicyManager returned a ValidationRequest") self.assertEqual(vr.failureCount, 0, "Verification failed with NoVerifyPolicyManager") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) def test_self_verification(self): policyManager = SelfVerifyPolicyManager(self.identityStorage) keyChain = KeyChain(self.identityManager, policyManager) identityName = Name('TestValidator/RsaSignatureVerification') keyChain.createIdentityAndCertificate(identityName) data = Data(Name('/TestData/1')) keyChain.signByIdentity(data, identityName) vr = doVerify(policyManager, data) self.assertFalse(vr.hasFurtherSteps, "SelfVerifyPolicyManager returned a ValidationRequest") self.assertEqual(vr.failureCount, 0, "Verification of identity-signed data failed") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) data2 = Data(Name('/TestData/2')) vr = doVerify(policyManager, data2) self.assertFalse(vr.hasFurtherSteps, "SelfVerifyPolicyManager returned a ValidationRequest") self.assertEqual(vr.successCount, 0, "Verification of unsigned data succeeded") self.assertEqual(vr.failureCount, 1, "Verification failure callback called {} times instead of 1".format( vr.failureCount)) def test_interest_timestamp(self): interestName = Name('/ndn/ucla/edu/something') certName = self.identityManager.getDefaultCertificateNameForIdentity( self.identityName) self.face.setCommandSigningInfo(self.keyChain, certName) oldInterest = Interest(interestName) self.face.makeCommandInterest(oldInterest) time.sleep(0.1) # make sure timestamps are different newInterest = Interest(interestName) self.face.makeCommandInterest(newInterest) vr = doVerify(self.policyManager, newInterest) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager returned ValidationRequest but certificate is known") self.assertEqual(vr.failureCount, 0, "Verification of valid interest failed") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) vr = doVerify(self.policyManager, oldInterest) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager returned ValidationRequest but certificate is known") self.assertEqual(vr.successCount, 0, "Verification of stale interest succeeded") self.assertEqual(vr.failureCount, 1, "Failure callback called {} times instead of 1".format( vr.failureCount)) def _removeFile(self, filename): try: os.remove(filename) except OSError: # no such file pass def test_refresh_10s(self): with open('policy_config/testData', 'r') as dataFile: encodedData = dataFile.read() data = Data() dataBlob = Blob(b64decode(encodedData)) data.wireDecode(dataBlob) # needed, since the KeyChain will express interests in unknown # certificates vr = doVerify(self.policyManager, data) self.assertTrue(vr.hasFurtherSteps, "ConfigPolicyManager did not create ValidationRequest for unknown certificate") self.assertEqual(vr.successCount, 0, "ConfigPolicyManager called success callback with pending ValidationRequest") self.assertEqual(vr.failureCount, 0, "ConfigPolicyManager called failure callback with pending ValidationRequest") # now save the cert data to our anchor directory, and wait # we have to sign it with the current identity or the # policy manager will create an interest for the signing certificate with open(self.testCertFile, 'w') as certFile: cert = IdentityCertificate() certData = b64decode(CERT_DUMP) cert.wireDecode(Blob(certData, False)) self.keyChain.signByIdentity(cert, self.identityName) encodedCert = b64encode(cert.wireEncode().toBuffer()) certFile.write(Blob(encodedCert, False).toRawStr()) # still too early for refresh to pick it up vr = doVerify(self.policyManager, data) self.assertTrue(vr.hasFurtherSteps, "ConfigPolicyManager refresh occured sooner than specified") self.assertEqual(vr.successCount, 0, "ConfigPolicyManager called success callback with pending ValidationRequest") self.assertEqual(vr.failureCount, 0, "ConfigPolicyManager called failure callback with pending ValidationRequest") time.sleep(6) # now we should find it vr = doVerify(self.policyManager, data) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager did not refresh certificate store") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) self.assertEqual(vr.failureCount, 0, "ConfigPolicyManager did not verify valid signed data")
def main(): interest = Interest() interest.wireDecode(TlvInterest) dump("Interest:") dumpInterest(interest) # Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()) encoding = interest.wireEncode() dump("") dump("Re-encoded interest", encoding.toHex()) reDecodedInterest = Interest() reDecodedInterest.wireDecode(encoding) dump("Re-decoded Interest:") dumpInterest(reDecodedInterest) freshInterest = (Interest( Name("/ndn/abc")).setMustBeFresh(False).setMinSuffixComponents( 4).setMaxSuffixComponents(6).setInterestLifetimeMilliseconds( 30000).setChildSelector(1).setMustBeFresh(True)) freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST) freshInterest.getKeyLocator().setKeyData( bytearray([ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F ])) freshInterest.getExclude().appendComponent(Name("abc")[0]).appendAny() dump(freshInterest.toUri()) identityStorage = MemoryIdentityStorage() privateKeyStorage = MemoryPrivateKeyStorage() keyChain = KeyChain(IdentityManager(identityStorage, privateKeyStorage), SelfVerifyPolicyManager(identityStorage)) # Initialize the storage. keyName = Name("/testname/DSK-123") certificateName = keyName.getSubName( 0, keyName.size() - 1).append("KEY").append( keyName[-1]).append("ID-CERT").append("0") identityStorage.addKey(keyName, KeyType.RSA, Blob(DEFAULT_RSA_PUBLIC_KEY_DER)) privateKeyStorage.setKeyPairForKeyName(keyName, KeyType.RSA, DEFAULT_RSA_PUBLIC_KEY_DER, DEFAULT_RSA_PRIVATE_KEY_DER) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, certificateName) face.makeCommandInterest(freshInterest) reDecodedFreshInterest = Interest() reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()) dump("") dump("Re-decoded fresh Interest:") dumpInterest(reDecodedFreshInterest) keyChain.verifyInterest(reDecodedFreshInterest, makeOnVerified("Freshly-signed Interest"), makeOnVerifyFailed("Freshly-signed Interest"))
rp.setStartBlockId(0) interest = Interest(Name("/example/repo/1").append("insert").append(rp.wireEncode())) identityStorage = MemoryIdentityStorage() privateKeyStorage = MemoryPrivateKeyStorage() keyChain = KeyChain(IdentityManager(identityStorage, privateKeyStorage), SelfVerifyPolicyManager(identityStorage)) # Initialize the storage. keyName = Name("/testname/DSK-123") certificateName = keyName.getSubName(0, keyName.size() - 1).append( "KEY").append(keyName[-1]).append("ID-CERT").append("0") identityStorage.addKey(keyName, KeyType.RSA, Blob(DEFAULT_RSA_PUBLIC_KEY_DER)) privateKeyStorage.setKeyPairForKeyName( keyName, KeyType.RSA, DEFAULT_RSA_PUBLIC_KEY_DER, DEFAULT_RSA_PRIVATE_KEY_DER) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, certificateName) face.makeCommandInterest(interest) callbacks = Callbacks() print interest.getName().toUri() face.expressInterest(interest, callbacks.onData, callbacks.onTimeout) face.registerPrefix(dataPrefix, callbacks.onInterest, callbacks.onRegisterFailed) while True: face.processEvents() time.sleep(0.1)
class TestConfigPolicyManager(ut.TestCase): def setUp(self): testCertDirectory = 'policy_config/certs' self.testCertFile = os.path.join(testCertDirectory, 'test.cert') self.identityStorage = MemoryIdentityStorage() self.privateKeyStorage = MemoryPrivateKeyStorage() self.identityManager = IdentityManager(self.identityStorage, self.privateKeyStorage) self.policyManager = ConfigPolicyManager('policy_config/simple_rules.conf') self.identityName = Name('/TestConfigPolicyManager/temp') # to match the anchor cert keyName = Name(self.identityName).append('ksk-1416010123') self.privateKeyStorage.setKeyPairForKeyName( keyName, KeyType.RSA, TEST_RSA_PUBLIC_KEY_DER, TEST_RSA_PRIVATE_KEY_DER) self.identityStorage.addKey( keyName, KeyType.RSA, Blob(TEST_RSA_PUBLIC_KEY_DER)) cert = self.identityManager.selfSign(keyName) self.identityStorage.setDefaultKeyNameForIdentity(keyName) self.identityManager.addCertificateAsDefault(cert) self.keyChain = KeyChain(self.identityManager, self.policyManager) self.keyName = keyName self.face = Face() def tearDown(self): self.privateKeyStorage.deleteKeyPair(self.keyName) self.face.shutdown() try: os.remove(self.testCertFile) except OSError: pass def test_no_verify(self): policyManager = NoVerifyPolicyManager() identityName = Name('TestValidator/Null').appendVersion(int(time.time())) keyChain = KeyChain(self.identityManager, policyManager) keyChain.createIdentityAndCertificate(identityName) data = Data(Name(identityName).append('data')) keyChain.signByIdentity(data, identityName) vr = doVerify(policyManager, data) self.assertFalse(vr.hasFurtherSteps, "NoVerifyPolicyManager returned a ValidationRequest") self.assertEqual(vr.failureCount, 0, "Verification failed with NoVerifyPolicyManager") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) def test_self_verification(self): policyManager = SelfVerifyPolicyManager(self.identityStorage) keyChain = KeyChain(self.identityManager, policyManager) identityName = Name('TestValidator/RsaSignatureVerification') keyChain.createIdentityAndCertificate(identityName) data = Data(Name('/TestData/1')) keyChain.signByIdentity(data, identityName) vr = doVerify(policyManager, data) self.assertFalse(vr.hasFurtherSteps, "SelfVerifyPolicyManager returned a ValidationRequest") self.assertEqual(vr.failureCount, 0, "Verification of identity-signed data failed") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) data2 = Data(Name('/TestData/2')) vr = doVerify(policyManager, data2) self.assertFalse(vr.hasFurtherSteps, "SelfVerifyPolicyManager returned a ValidationRequest") self.assertEqual(vr.successCount, 0, "Verification of unsigned data succeeded") self.assertEqual(vr.failureCount, 1, "Verification failure callback called {} times instead of 1".format( vr.failureCount)) def test_interest_timestamp(self): interestName = Name('/ndn/ucla/edu/something') certName = self.identityManager.getDefaultCertificateNameForIdentity( self.identityName) self.face.setCommandSigningInfo(self.keyChain, certName) oldInterest = Interest(interestName) self.face.makeCommandInterest(oldInterest) time.sleep(0.1) # make sure timestamps are different newInterest = Interest(interestName) self.face.makeCommandInterest(newInterest) vr = doVerify(self.policyManager, newInterest) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager returned ValidationRequest but certificate is known") self.assertEqual(vr.failureCount, 0, "Verification of valid interest failed") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) vr = doVerify(self.policyManager, oldInterest) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager returned ValidationRequest but certificate is known") self.assertEqual(vr.successCount, 0, "Verification of stale interest succeeded") self.assertEqual(vr.failureCount, 1, "Failure callback called {} times instead of 1".format( vr.failureCount)) def _removeFile(self, filename): try: os.remove(filename) except OSError: # no such file pass def test_refresh_10s(self): with open('policy_config/testData', 'r') as dataFile: encodedData = dataFile.read() data = Data() dataBlob = Blob(b64decode(encodedData)) data.wireDecode(dataBlob) # needed, since the KeyChain will express interests in unknown # certificates vr = doVerify(self.policyManager, data) self.assertTrue(vr.hasFurtherSteps, "ConfigPolicyManager did not create ValidationRequest for unknown certificate") self.assertEqual(vr.successCount, 0, "ConfigPolicyManager called success callback with pending ValidationRequest") self.assertEqual(vr.failureCount, 0, "ConfigPolicyManager called failure callback with pending ValidationRequest") # now save the cert data to our anchor directory, and wait # we have to sign it with the current identity or the # policy manager will create an interest for the signing certificate with open(self.testCertFile, 'w') as certFile: cert = IdentityCertificate() certData = b64decode(CERT_DUMP) cert.wireDecode(Blob(certData, False)) self.keyChain.signByIdentity(cert, self.identityName) encodedCert = b64encode(cert.wireEncode().toBytes()) certFile.write(Blob(encodedCert, False).toRawStr()) # still too early for refresh to pick it up vr = doVerify(self.policyManager, data) self.assertTrue(vr.hasFurtherSteps, "ConfigPolicyManager refresh occured sooner than specified") self.assertEqual(vr.successCount, 0, "ConfigPolicyManager called success callback with pending ValidationRequest") self.assertEqual(vr.failureCount, 0, "ConfigPolicyManager called failure callback with pending ValidationRequest") time.sleep(6) # now we should find it vr = doVerify(self.policyManager, data) self.assertFalse(vr.hasFurtherSteps, "ConfigPolicyManager did not refresh certificate store") self.assertEqual(vr.successCount, 1, "Verification success called {} times instead of 1".format( vr.successCount)) self.assertEqual(vr.failureCount, 0, "ConfigPolicyManager did not verify valid signed data")
class Server: def __init__(self, emit_func): self.emit = emit_func self.running = True self.event_list = [] # 1. If you use default constructor, when NFD is not started, # TcpTransport will be used instead of UnixTransport. # 2. Both TcpTransport and UnixTransport are not connected # before the first Interest is sent. # file_path = Face._getUnixSocketFilePathForLocalhost() # transport = UnixTransport() # connection_info = UnixTransport.ConnectionInfo(file_path) # self.face = Face(transport, connection_info) self.keychain = KeyChain() self.face = None def start_reconnection(self): """ Start reconnection process. NOT thread safe. """ self.face.shutdown() self.face = None def get_or_create_certificate(self): id_name = Name('/ndncc') cur_id = self.keychain.createIdentityV2(id_name) return cur_id.getDefaultKey().getDefaultCertificate().name def connection_test(self): interest = Interest("/localhost/nfd/faces/events") interest.mustBeFresh = True interest.canBePrefix = True interest.interestLifetimeMilliseconds = 1000 try: def empty(*_args, **_kwargs): pass self.face.expressInterest(interest, empty, empty, empty) return True except (ConnectionRefusedError, BrokenPipeError, OSError): return False async def run(self): while self.running: logging.info("Restarting face...") self.face = Face() self.face.setCommandSigningInfo(self.keychain, self.get_or_create_certificate()) if self.connection_test(): logging.info("Face creation succeeded") face_event = asyncio.get_event_loop().create_task(self.face_event()) while self.running and self.face is not None: try: self.face.processEvents() except AttributeError: logging.info("Attribute error.") self.start_reconnection() await asyncio.sleep(0.01) await face_event else: logging.info("Face creation failed") await asyncio.sleep(3) @staticmethod def face_event_to_dict(msg): ret = {} if msg.face_event_kind == 1: ret['face_event_kind'] = "CREATED" elif msg.face_event_kind == 2: ret['face_event_kind'] = "DESTROYED" elif msg.face_event_kind == 3: ret['face_event_kind'] = "UP" elif msg.face_event_kind == 4: ret['face_event_kind'] = "DOWN" else: ret['face_event_kind'] = "unknown" ret['face_id'] = str(msg.face_id) ret['local_uri'] = msg.local_uri.decode("utf-8") ret['remote_uri'] = msg.uri.decode("utf-8") if msg.face_scope == 1: ret['face_scope'] = "local" else: ret['face_scope'] = "non-local" if msg.face_persistency == 0: ret['face_persistency'] = "persistent" elif msg.face_event_kind == 1: ret['face_persistency'] = "on-demand" elif msg.face_persistency == 2: ret['face_persistency'] = "permanent" else: ret['face_persistency'] = "unknown" if msg.link_type == 0: ret['link_type'] = "point-to-point" elif msg.link_type == 1: ret['link_type'] = "multi-access" elif msg.link_type == 2: ret['link_type'] = "ad-hoc" else: ret['link_type'] = "unknown" ret['flags'] = str(msg.flags) return ret @staticmethod def response_to_dict(msg): ret = {'st_code': msg.st_code, 'st_text': msg.st_text.decode('utf-8')} return ret async def face_event(self): last_seq = -1 retry_time = 3000 retry_count_limit = 60000 // retry_time retry_count = 0 while self.running and self.face: name = Name("/localhost/nfd/faces/events") face_interest = Interest() if last_seq >= 0: name.appendSequenceNumber(last_seq + 1) face_interest.canBePrefix = False else: face_interest.mustBeFresh = True face_interest.canBePrefix = True logging.info("Face event notification stream %s", name.toUri()) face_interest.name = name # face_interest.interestLifetimeMilliseconds = 60000 face_interest.interestLifetimeMilliseconds = retry_time ret = await fetch_data_packet(self.face, face_interest) timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") if isinstance(ret, Data): retry_count = 0 last_seq = ret.name[-1].toSequenceNumber() face_event = FaceEventNotificationMessage() try: ProtobufTlv.decode(face_event, ret.content) dic = self.face_event_to_dict(face_event.face_event_notification) dic['seq'] = str(last_seq) dic['time'] = timestamp self.emit('face event', dic) self.event_list.append(dic) except RuntimeError as exc: logging.fatal('Decode failed %s', exc) last_seq = -1 elif ret is None: if retry_count >= retry_count_limit: logging.info("No response: face event") last_seq = -1 retry_count = 0 else: retry_count += 1 else: logging.info("NFD is not running: start reconnection") self.start_reconnection() return await asyncio.sleep(0.1) async def issue_command_interest(self, interest): ret = await fetch_data_packet(self.face, interest) if isinstance(ret, Data): response = ControlResponseMessage() try: ProtobufTlv.decode(response, ret.content) dic = self.response_to_dict(response.control_response) logging.info("Issue command Interest with %s", dic) return dic except RuntimeError as exc: logging.fatal('Decode failed %s', exc) return None async def add_face(self, uri): # It's not easy to distinguish udp4://127.0.0.1 and udp4://spurs.cs.ucla.edu # if reduce(lambda a, b: a or b, (x.isalpha() for x in uri)): # uri = socket.gethostbyname(uri) if uri[-1] == "/": uri = uri[:-1] if uri.find("://") < 0: uri = "udp4://" + uri if len(uri.split(":")) < 3: uri = uri + ":6363" interest = self.make_command('faces', 'create', uri=uri) return await self.issue_command_interest(interest) async def remove_face(self, face_id: int): interest = self.make_command('faces', 'destroy', face_id=face_id) return await self.issue_command_interest(interest) async def add_route(self, name: str, face_id: int): interest = self.make_command('rib', 'register', name=Name(name), face_id=face_id) return await self.issue_command_interest(interest) async def remove_route(self, name: str, face_id: int): interest = self.make_command('rib', 'unregister', name=Name(name), face_id=face_id) return await self.issue_command_interest(interest) async def set_strategy(self, name: str, strategy: str): interest = self.make_command('strategy-choice', 'set', name=Name(name), strategy=Name(strategy)) return await self.issue_command_interest(interest) async def unset_strategy(self, name: str): interest = self.make_command('strategy-choice', 'unset', name=Name(name)) return await self.issue_command_interest(interest) def run_server(self, work_loop): asyncio.set_event_loop(work_loop) try: work_loop.run_until_complete(self.run()) finally: work_loop.close() @staticmethod def start_server(emit_func): done = threading.Event() server = None def create_and_run(): nonlocal server, done server = Server(emit_func) work_loop = asyncio.new_event_loop() asyncio.set_event_loop(work_loop) done.set() try: work_loop.run_until_complete(server.run()) finally: work_loop.close() thread = threading.Thread(target=create_and_run) thread.setDaemon(True) thread.start() done.wait() return server def make_command(self, module, verb, **kwargs): name = Name('/localhost/nfd').append(module).append(verb) # Command Parameters cmd_param = ControlCommandMessage() if 'name' in kwargs: name_param = kwargs['name'] for compo in name_param: cmd_param.control_parameters.name.component.append(compo.getValue().toBytes()) if 'strategy' in kwargs: name_param = kwargs['strategy'] for compo in name_param: cmd_param.control_parameters.strategy.name.component.append(compo.getValue().toBytes()) for key in ['uri', 'local_uri']: if key in kwargs: setattr(cmd_param.control_parameters, key, kwargs[key].encode('utf-8')) for key in ['face_id', 'origin', 'cost', 'capacity', 'count', 'base_cong_mark', 'def_cong_thres', 'mtu', 'flags', 'mask', 'exp_period']: if key in kwargs: setattr(cmd_param.control_parameters, key, kwargs[key]) param_blob = ProtobufTlv.encode(cmd_param) name.append(Name.Component(param_blob)) # Command Interest Components ret = Interest(name) ret.canBePrefix = True self.face.makeCommandInterest(ret) return ret @staticmethod def list_key_tree(): """ Return the id-key-cert tree in a JSON like dict object. """ pib = KeyChain().getPib() identities = pib._identities._identityNames ret = {} try: default_id = pib.getDefaultIdentity().getName() except Pib.Error: default_id = Name('/') for id_name in identities: id_obj = pib.getIdentity(Name(id_name)) cur_id = {'default': '*' if id_name == default_id else ' '} try: default_key = id_obj.getDefaultKey().getName() except Pib.Error: default_key = Name('/') keys = id_obj._getKeys()._keyNames cur_id['keys'] = {} for key_name in keys: key_obj = id_obj.getKey(Name(key_name)) cur_key = {'default': '*' if key_name == default_key else ' '} try: default_cert = key_obj.getDefaultCertificate().getName() except Pib.Error: default_cert = Name('/') key_type = key_obj.getKeyType() if key_type <= 4: cur_key['key_type'] = ['NONE', 'RSA', 'EC', 'AES', 'HMAC'][key_type] else: cur_key['key_type'] = 'unknown' certs = key_obj._getCertificates()._certificateNames cur_key['certs'] = {} for cert_name in certs: cert_obj = key_obj.getCertificate(Name(cert_name)) signature = cert_obj.getSignature() cur_cert = { 'default': '*' if cert_name == default_cert else ' ', 'not_before': str(cert_obj.getValidityPeriod().getNotBefore()), 'not_after': str(cert_obj.getValidityPeriod().getNotAfter()), 'issuer_id': cert_obj.getIssuerId().toEscapedString(), 'key_locator': signature.getKeyLocator().getKeyName().toUri(), 'signature_type': cert_obj.getSignature().__class__.__name__, } cur_key['certs'][cert_name.toUri()] = cur_cert cur_id['keys'][key_name.toUri()] = cur_key ret[id_name.toUri()] = cur_id return ret @staticmethod def create_identity(name): key_chain = KeyChain() try: cur_id = key_chain.getPib().getIdentity(Name(name)) key_chain.createKey(cur_id) except Pib.Error: key_chain.createIdentityV2(Name(name)) @staticmethod def delete_security_object(name, kind): key_chain = KeyChain() logging.info("Delete security object %s %s", name, kind) if kind == "c": id_name = CertificateV2.extractIdentityFromCertName(Name(name)) key_name = CertificateV2.extractKeyNameFromCertName(Name(name)) cur_id = key_chain.getPib().getIdentity(id_name) cur_key = cur_id.getKey(key_name) key_chain.deleteCertificate(cur_key, Name(name)) elif kind == "k": id_name = PibKey.extractIdentityFromKeyName(Name(name)) cur_id = key_chain.getPib().getIdentity(id_name) cur_key = cur_id.getKey(Name(name)) key_chain.deleteKey(cur_id, cur_key) else: key_chain.deleteIdentity(Name(name)) async def query_face_id(self, uri): query_filter = FaceQueryFilterMessage() query_filter.face_query_filter.uri = uri.encode('utf-8') query_filter_msg = ProtobufTlv.encode(query_filter) name = Name("/localhost/nfd/faces/query").append(Name.Component(query_filter_msg)) interest = Interest(name) interest.mustBeFresh = True interest.canBePrefix = True ret = await fetch_data_packet(self.face, interest) if not isinstance(ret, Data): return None msg = FaceStatusMessage() try: ProtobufTlv.decode(msg, ret.content) except RuntimeError as exc: logging.fatal("Decoding Error %s", exc) return None if len(msg.face_status) <= 0: return None return msg.face_status[0].face_id async def autoconf(self): """ Automatically connect to ndn testbed. Add route /ndn and /localhop/nfd. """ uri = urllib.request.urlopen("http://ndn-fch.named-data.net/").read().decode('utf-8') uri = socket.gethostbyname(uri) uri = "udp4://" + uri + ":6363" interest = self.make_command('faces', 'create', uri=uri) ret = await fetch_data_packet(self.face, interest) if not isinstance(ret, Data): return False, "Create face failed" response = ControlResponseMessage() try: ProtobufTlv.decode(response, ret.content) except RuntimeError as exc: logging.info('Decode failed %s', exc) return False, "Create face failed" # # Ignore duplicated face # if response.control_response.st_code not in {200, 409}: # return False, "Create face failed" face_id = await self.query_face_id(uri) if face_id is None: return False, "Create face failed" route = Name("/ndn") interest = self.make_command('rib', 'register', name=route, face_id=face_id, origin=66, cost=100) await fetch_data_packet(self.face, interest) route = Name("/localhop/nfd") interest = self.make_command('rib', 'register', name=route, face_id=face_id, origin=66, cost=100) await fetch_data_packet(self.face, interest) return True, "Auto-configuration finished"
while not done: #pick a random data name data_part = suffix #str(randint(0,N)) fullName = Name(data_prefix).append(Name(data_part)) # currently we need to provide the version ourselves when we # poke the repo ts = int(time.time()*1000) fullName.appendVersion(int(ts)) command = createInsertInterest(fullName) versionStr = fullName.get(-1).toEscapedString() logger.debug('inserting: ' + versionStr) repo_face.makeCommandInterest(command) lastFailCount = failure.call_count lastSuccessCount = success.call_count repo_face.expressInterest(command, success, failure) insertTable.append({'version':versionStr, 'insert_request':time.time()}) while success.call_count == lastSuccessCount and failure.call_count == lastFailCount: repo_face.processEvents() time.sleep(0.1) # only expecting to insert one segment (<1k) for each request # check on the insert status # TODO: kick off a greenlet instead of setting global variable? if success.call_count > lastSuccessCount and current_insertion >= 0: lastFailCount = failure.call_count lastSuccessCount = success.call_count
class TemperatureProducer(object): """ A temperature sensor that publishes data periodically. Temperature Data packets have the name of /<prefix>/<timestamp> """ def __init__(self, prefix: Name, repo_name: Optional[Name]): self.prefix = prefix self.repo_name = repo_name self.face = Face() self.keychain = KeyChain() self.running = True self.name_str_to_data = dict() self.face.setCommandSigningInfo(self.keychain, self.keychain.getDefaultCertificateName()) self.face.registerPrefix(self.prefix, None, lambda prefix: logging.error("Prefix registration failed: %s", prefix)) self.filter_id = self.face.setInterestFilter(self.prefix, self.on_interest) event_loop = asyncio.get_event_loop() event_loop.create_task(self.face_loop()) self.latest_tp = 0 async def send_cmd_interest(self): event_loop = asyncio.get_event_loop() face_task = event_loop.create_task(self.face_loop()) parameter = RepoCommandParameterMessage() for compo in self.prefix: parameter.repo_command_parameter.name.component.append(compo.getValue().toBytes()) parameter.repo_command_parameter.start_block_id = self.latest_tp parameter.repo_command_parameter.end_block_id = parameter.repo_command_parameter.start_block_id param_blob = ProtobufTlv.encode(parameter) # Prepare cmd interest name = Name(self.repo_name).append("insert").append(Name.Component(param_blob)) interest = Interest(name) interest.canBePrefix = True self.face.makeCommandInterest(interest) logging.info("Express interest: {}".format(interest.getName())) ret = await fetch_data_packet(self.face, interest) if not isinstance(ret, Data): logging.warning("Insertion failed") else: # Parse response response = RepoCommandResponseMessage() try: ProtobufTlv.decode(response, ret.content) logging.info('Insertion command accepted: status code {}' .format(response.repo_command_response.status_code)) except RuntimeError as exc: logging.warning('Response decoding failed', exc) async def face_loop(self): while self.running: self.face.processEvents() await asyncio.sleep(0.001) def get_temp(self) -> int: return random.randint(0, 35) def publish_temp_packet(self): tp = int(time.time()) tp = tp - (tp % 5) self.latest_tp = tp data_name = Name(self.prefix).append(str(self.latest_tp)) data = Data(data_name) temp = self.get_temp() content_blob = Blob(temp.to_bytes(2, byteorder='little')) data.setContent(content_blob) data.metaInfo.setFreshnessPeriod(1000000) logging.info('Publish temp data {}, {} degree'.format(data.getName(), temp)) self.keychain.sign(data) self.name_str_to_data[str(data.getName())] = data if use_repo is True: event_loop = asyncio.get_event_loop() event_loop.create_task(self.send_cmd_interest()) logging.info("send repo insertion command") def on_interest(self, _prefix, interest: Interest, face, _filter_id, _filter): name = str(interest.getName()) if name in self.name_str_to_data: self.face.putData(self.name_str_to_data[name]) logging.info('Serve data: {}'.format(name)) async def run(self): """ Need to publish data with period of at least 5 second, otherwise Data packets are not immutable """ while self.running: self.publish_temp_packet() await asyncio.sleep(0.5) self.face.unsetInterestFilter(self.filter_id) await asyncio.sleep(4.5) self.filter_id = self.face.setInterestFilter(self.prefix, self.on_interest)
class PutfileClient(object): """ This client serves random segmented data """ def __init__(self, args): self.repo_name = Name(args.repo_name) self.file_path = args.file_path self.name_at_repo = Name(args.name) self.face = Face() self.keychain = KeyChain() self.face.setCommandSigningInfo( self.keychain, self.keychain.getDefaultCertificateName()) self.running = True self.m_name_str_to_data = dict() self.n_packets = 0 self.prepare_data() self.face.registerPrefix(self.name_at_repo, None, self.on_register_failed) self.face.setInterestFilter(self.name_at_repo, self.on_interest) async def face_loop(self): while self.running: self.face.processEvents() await asyncio.sleep(0.001) def prepare_data(self): """ Shard file into data packets. """ logging.info('preparing data') with open(self.file_path, 'rb') as binary_file: b_array = bytearray(binary_file.read()) if len(b_array) == 0: logging.warning("File is 0 bytes") return self.n_packets = int((len(b_array) - 1) / MAX_BYTES_IN_DATA_PACKET + 1) logging.info('There are {} packets in total'.format(self.n_packets)) seq = 0 for i in range(0, len(b_array), MAX_BYTES_IN_DATA_PACKET): data = Data(Name(self.name_at_repo).append(str(seq))) data.metaInfo.freshnessPeriod = 100000 data.setContent( b_array[i:min(i + MAX_BYTES_IN_DATA_PACKET, len(b_array))]) data.metaInfo.setFinalBlockId( Name.Component.fromSegment(self.n_packets - 1)) self.keychain.signWithSha256(data) self.m_name_str_to_data[str(data.getName())] = data seq += 1 @staticmethod def on_register_failed(prefix): logging.error("Prefix registration failed: %s", prefix) def on_interest(self, _prefix, interest: Interest, face, _filter_id, _filter): logging.info('On interest: {}'.format(interest.getName())) if str(interest.getName()) in self.m_name_str_to_data: self.face.putData(self.m_name_str_to_data[str(interest.getName())]) logging.info('Serve data: {}'.format(interest.getName())) else: logging.info('Data does not exist: {}'.format(interest.getName())) async def insert_segmented_file(self): event_loop = asyncio.get_event_loop() face_task = event_loop.create_task(self.face_loop()) parameter = RepoCommandParameterMessage() for compo in self.name_at_repo: parameter.repo_command_parameter.name.component.append( compo.getValue().toBytes()) parameter.repo_command_parameter.start_block_id = 0 parameter.repo_command_parameter.end_block_id = self.n_packets - 1 param_blob = ProtobufTlv.encode(parameter) # Prepare cmd interest name = Name(self.repo_name).append('insert').append( Name.Component(param_blob)) interest = Interest(name) self.face.makeCommandInterest(interest) logging.info('Send insert command interest') ret = await fetch_data_packet(self.face, interest) if not isinstance(ret, Data): logging.warning('Insert failed') return response = RepoCommandResponseMessage() try: ProtobufTlv.decode(response, ret.content) except RuntimeError as exc: logging.warning('Response decoding failed', exc) process_id = response.repo_command_response.process_id status_code = response.repo_command_response.status_code logging.info('Insertion process {} accepted: status code {}'.format( process_id, status_code)) # Use insert check command to probe if insert process is completed checker = CommandChecker(self.face, self.keychain) while True: response = await checker.check_insert(self.repo_name, process_id) if response is None or response.repo_command_response.status_code == 300: await asyncio.sleep(1) elif response.repo_command_response.status_code == 200: logging.info( 'Insert process {} status: {}, insert_num: {}'.format( process_id, response.repo_command_response.status_code, response.repo_command_response.insert_num)) break else: # Shouldn't get here assert (False) self.running = False await face_task
privateKeyStorage = MemoryPrivateKeyStorage() keyChain = KeyChain(IdentityManager(identityStorage, privateKeyStorage), SelfVerifyPolicyManager(identityStorage)) # Initialize the storage. keyName = Name("/testname/DSK-123") certificateName = keyName.getSubName( 0, keyName.size() - 1).append("KEY").append( keyName[-1]).append("ID-CERT").append("0") identityStorage.addKey(keyName, KeyType.RSA, Blob(DEFAULT_RSA_PUBLIC_KEY_DER)) privateKeyStorage.setKeyPairForKeyName(keyName, KeyType.RSA, DEFAULT_RSA_PUBLIC_KEY_DER, DEFAULT_RSA_PRIVATE_KEY_DER) # Make a Face just so that we can sign the interest. face = Face("localhost") face.setCommandSigningInfo(keyChain, certificateName) face.makeCommandInterest(interest) callbacks = Callbacks() print interest.getName().toUri() face.expressInterest(interest, callbacks.onData, callbacks.onTimeout) face.registerPrefix(dataPrefix, callbacks.onInterest, callbacks.onRegisterFailed) while True: face.processEvents() time.sleep(0.1)