def __init__(self, face, username, memoryContentCache): # Set up face self.face = face # Set up the keyChain. identityStorage = MemoryIdentityStorage() privateKeyStorage = MemoryPrivateKeyStorage() self.keyChain = KeyChain( IdentityManager(identityStorage, privateKeyStorage), NoVerifyPolicyManager()) identityName = Name(username) self.certificateName = self.keyChain.createIdentityAndCertificate( identityName) self.keyChain.getIdentityManager().setDefaultIdentity(identityName) self.face.setCommandSigningInfo(self.keyChain, self.certificateName) self.databaseFilePath = "../policy_config/test_producer.db" self.catalogDatabaseFilePath = "../policy_config/test_producer_catalog.db" try: os.remove(self.databaseFilePath) except OSError: # no such file pass try: os.remove(self.catalogDatabaseFilePath) except OSError: # no such file pass self.testDb = Sqlite3ProducerDb(self.databaseFilePath) self.catalogDb = Sqlite3ProducerDb(self.catalogDatabaseFilePath) # TODO: as of right now, catalog has a different suffix, so need another instance of producer; that producer cannot share # the same DB with the first producer, otherwise there won't be a self.onEncryptedKeys call; as the catalog producer uses # its own C-key, and that key won't be encrypted by an E-key as no interest goes out # This sounds like something problematic from the library prefix = Name(username) suffix = Name("fitness/physical_activity/time_location") self.producer = Producer(Name(prefix), suffix, self.face, self.keyChain, self.testDb) catalogSuffix = Name(suffix).append("catalog") self.catalogProducer = Producer(Name(prefix), catalogSuffix, self.face, self.keyChain, self.catalogDb) self.memoryContentCache = memoryContentCache return
def test_database_functions(self): # Test construction. database = Sqlite3ProducerDb(self.databaseFilePath) # Create member. params = AesKeyParams(128) keyBlob1 = AesAlgorithm.generateKey(params).getKeyBits() keyBlob2 = AesAlgorithm.generateKey(params).getKeyBits() point1 = Schedule.fromIsoString("20150101T100000") point2 = Schedule.fromIsoString("20150102T100000") point3 = Schedule.fromIsoString("20150103T100000") point4 = Schedule.fromIsoString("20150104T100000") # Add keys into the database. database.addContentKey(point1, keyBlob1) database.addContentKey(point2, keyBlob1) database.addContentKey(point3, keyBlob2) # Throw an exception when adding a key to an existing time slot. with self.assertRaises(ProducerDb.Error): database.addContentKey(point1, keyBlob1) # Check has functions. self.assertEqual(True, database.hasContentKey(point1)) self.assertEqual(True, database.hasContentKey(point2)) self.assertEqual(True, database.hasContentKey(point3)) self.assertEqual(False, database.hasContentKey(point4)) # Get content keys. keyResult = database.getContentKey(point1) self.assertTrue(keyResult.equals(keyBlob1)) keyResult = database.getContentKey(point3) self.assertTrue(keyResult.equals(keyBlob2)) # Throw exception when there is no such time slot in the database. with self.assertRaises(ProducerDb.Error): database.getContentKey(point4) # Delete content keys. self.assertEqual(True, database.hasContentKey(point1)) database.deleteContentKey(point1) self.assertEqual(False, database.hasContentKey(point1)) # Delete at a non-existing time slot. try: database.deleteContentKey(point4) except Exception as ex: self.fail( "Unexpected error deleting a non-existing content key: " + repr(ex))
def test_producer_with_link(self): prefix = Name("/prefix") suffix = Name("/suffix") expectedInterest = Name(prefix) expectedInterest.append(Encryptor.NAME_COMPONENT_READ) expectedInterest.append(suffix) expectedInterest.append(Encryptor.NAME_COMPONENT_E_KEY) testTime = Schedule.fromIsoString("20150101T100001") timeoutCount = [0] # Prepare a TestFace to instantly answer calls to expressInterest. class TestFace(object): def __init__(self, handleExpressInterest): self.handleExpressInterest = handleExpressInterest def expressInterest(self, interest, onData, onTimeout, onNetworkNack): return self.handleExpressInterest(interest, onData, onTimeout, onNetworkNack) def handleExpressInterest(interest, onData, onTimeout, onNetworkNack): self.assertEqual(expectedInterest, interest.getName()) self.assertEqual(3, interest.getLink().getDelegations().size()) timeoutCount[0] += 1 onTimeout(interest) return 0 face = TestFace(handleExpressInterest) # Verify that if no response is received, the producer appropriately times # out. The result vector should not contain elements that have timed out. link = Link() link.addDelegation(10, Name("/test1")) link.addDelegation(20, Name("/test2")) link.addDelegation(100, Name("/test3")) self.keyChain.sign(link, self.certificateName) testDb = Sqlite3ProducerDb(self.databaseFilePath) producer = Producer(prefix, suffix, face, self.keyChain, testDb, 3, link) def onEncryptedKeys(result): self.assertEqual(4, timeoutCount[0]) self.assertEqual(0, len(result)) producer.createContentKey(testTime, onEncryptedKeys)
def test_content_key_request(self): prefix = Name("/prefix") suffix = Name("/a/b/c") expectedInterest = Name(prefix) expectedInterest.append(Encryptor.NAME_COMPONENT_READ) expectedInterest.append(suffix) expectedInterest.append(Encryptor.NAME_COMPONENT_E_KEY) cKeyName = Name(prefix) cKeyName.append(Encryptor.NAME_COMPONENT_SAMPLE) cKeyName.append(suffix) cKeyName.append(Encryptor.NAME_COMPONENT_C_KEY) timeMarker = Name("20150101T100000/20150101T120000") testTime1 = Schedule.fromIsoString("20150101T100001") testTime2 = Schedule.fromIsoString("20150101T110001") testTimeRounded1 = Name.Component("20150101T100000") testTimeRounded2 = Name.Component("20150101T110000") testTimeComponent2 = Name.Component("20150101T110001") # Create content keys required for this test case: for i in range(suffix.size()): self.createEncryptionKey(expectedInterest, timeMarker) expectedInterest = expectedInterest.getPrefix(-2).append( Encryptor.NAME_COMPONENT_E_KEY) expressInterestCallCount = [0] # Prepare a TestFace to instantly answer calls to expressInterest. class TestFace(object): def __init__(self, handleExpressInterest): self.handleExpressInterest = handleExpressInterest def expressInterest(self, interest, onData, onTimeout, onNetworkNack): return self.handleExpressInterest(interest, onData, onTimeout, onNetworkNack) def handleExpressInterest(interest, onData, onTimeout, onNetworkNack): expressInterestCallCount[0] += 1 interestName = Name(interest.getName()) interestName.append(timeMarker) self.assertTrue(interestName in self.encryptionKeys) onData(interest, self.encryptionKeys[interestName]) return 0 face = TestFace(handleExpressInterest) # Verify that the content key is correctly encrypted for each domain, and # the produce method encrypts the provided data with the same content key. testDb = Sqlite3ProducerDb(self.databaseFilePath) producer = Producer(prefix, suffix, face, self.keyChain, testDb) contentKey = [None] # Blob def checkEncryptionKeys(result, testTime, roundedTime, expectedExpressInterestCallCount): self.assertEqual(expectedExpressInterestCallCount, expressInterestCallCount[0]) self.assertEqual(True, testDb.hasContentKey(testTime)) contentKey[0] = testDb.getContentKey(testTime) params = EncryptParams(EncryptAlgorithmType.RsaOaep) for i in range(len(result)): key = result[i] keyName = key.getName() self.assertEqual(cKeyName, keyName.getSubName(0, 6)) self.assertEqual(keyName.get(6), roundedTime) self.assertEqual(keyName.get(7), Encryptor.NAME_COMPONENT_FOR) self.assertEqual(True, keyName.getSubName(8) in self.decryptionKeys) decryptionKey = self.decryptionKeys[keyName.getSubName(8)] self.assertEqual(True, decryptionKey.size() != 0) encryptedKeyEncoding = key.getContent() content = EncryptedContent() content.wireDecode(encryptedKeyEncoding) encryptedKey = content.getPayload() retrievedKey = RsaAlgorithm.decrypt(decryptionKey, encryptedKey, params) self.assertTrue(contentKey[0].equals(retrievedKey)) self.assertEqual(3, len(result)) # An initial test to confirm that keys are created for this time slot. contentKeyName1 = producer.createContentKey( testTime1, lambda keys: checkEncryptionKeys( keys, testTime1, testTimeRounded1, 3)) # Verify that we do not repeat the search for e-keys. The total # expressInterestCallCount should be the same. contentKeyName2 = producer.createContentKey( testTime2, lambda keys: checkEncryptionKeys( keys, testTime2, testTimeRounded2, 3)) # Confirm content key names are correct self.assertEqual(cKeyName, contentKeyName1.getPrefix(-1)) self.assertEqual(testTimeRounded1, contentKeyName1.get(6)) self.assertEqual(cKeyName, contentKeyName2.getPrefix(-1)) self.assertEqual(testTimeRounded2, contentKeyName2.get(6)) # Confirm that produce encrypts with the correct key and has the right name. testData = Data() producer.produce(testData, testTime2, Blob(DATA_CONTENT, False)) producedName = testData.getName() self.assertEqual(cKeyName.getPrefix(-1), producedName.getSubName(0, 5)) self.assertEqual(testTimeComponent2, producedName.get(5)) self.assertEqual(Encryptor.NAME_COMPONENT_FOR, producedName.get(6)) self.assertEqual(cKeyName, producedName.getSubName(7, 6)) self.assertEqual(testTimeRounded2, producedName.get(13)) dataBlob = testData.getContent() dataContent = EncryptedContent() dataContent.wireDecode(dataBlob) encryptedData = dataContent.getPayload() initialVector = dataContent.getInitialVector() params = EncryptParams(EncryptAlgorithmType.AesCbc, 16) params.setInitialVector(initialVector) decryptTest = AesAlgorithm.decrypt(contentKey[0], encryptedData, params) self.assertTrue(decryptTest.equals(Blob(DATA_CONTENT, False)))
def test_content_key_search(self): timeMarkerFirstHop = Name("20150101T070000/20150101T080000") timeMarkerSecondHop = Name("20150101T080000/20150101T090000") timeMarkerThirdHop = Name("20150101T100000/20150101T110000") prefix = Name("/prefix") suffix = Name("/suffix") expectedInterest = Name(prefix) expectedInterest.append(Encryptor.NAME_COMPONENT_READ) expectedInterest.append(suffix) expectedInterest.append(Encryptor.NAME_COMPONENT_E_KEY) cKeyName = Name(prefix) cKeyName.append(Encryptor.NAME_COMPONENT_SAMPLE) cKeyName.append(suffix) cKeyName.append(Encryptor.NAME_COMPONENT_C_KEY) testTime = Schedule.fromIsoString("20150101T100001") # Create content keys required for this test case: self.createEncryptionKey(expectedInterest, timeMarkerFirstHop) self.createEncryptionKey(expectedInterest, timeMarkerSecondHop) self.createEncryptionKey(expectedInterest, timeMarkerThirdHop) requestCount = [0] # Prepare a TestFace to instantly answer calls to expressInterest. class TestFace(object): def __init__(self, handleExpressInterest): self.handleExpressInterest = handleExpressInterest def expressInterest(self, interest, onData, onTimeout, onNetworkNack): return self.handleExpressInterest(interest, onData, onTimeout, onNetworkNack) def handleExpressInterest(interest, onData, onTimeout, onNetworkNack): self.assertEqual(expectedInterest, interest.getName()) gotInterestName = False for i in range(3): interestName = Name(interest.getName()) if i == 0: interestName.append(timeMarkerFirstHop) elif i == 1: interestName.append(timeMarkerSecondHop) elif i == 2: interestName.append(timeMarkerThirdHop) # matchesName will check the Exclude. if interest.matchesName(interestName): gotInterestName = True requestCount[0] += 1 break if gotInterestName: onData(interest, self.encryptionKeys[interestName]) return 0 face = TestFace(handleExpressInterest) # Verify that if a key is found, but not within the right time slot, the # search is refined until a valid time slot is found. testDb = Sqlite3ProducerDb(self.databaseFilePath) producer = Producer(prefix, suffix, face, self.keyChain, testDb) def onEncryptedKeys(result): self.assertEqual(3, requestCount[0]) self.assertEqual(1, len(result)) keyData = result[0] keyName = keyData.getName() self.assertEqual(cKeyName, keyName.getSubName(0, 4)) self.assertEqual(timeMarkerThirdHop.get(0), keyName.get(4)) self.assertEqual(Encryptor.NAME_COMPONENT_FOR, keyName.get(5)) self.assertEqual(expectedInterest.append(timeMarkerThirdHop), keyName.getSubName(6)) producer.createContentKey(testTime, onEncryptedKeys)