def test_calculate_interval(self): # Create the group manager. manager = GroupManager( Name("Alice"), Name("data_type"), Sqlite3GroupManagerDb(self.intervalDatabaseFilePath), 1024, 1, self.keyChain) self.setManager(manager) memberKeys = {} timePoint1 = Schedule.fromIsoString("20150825T093000") result = manager._calculateInterval(timePoint1, memberKeys) self.assertEqual("20150825T090000", Schedule.toIsoString(result.getStartTime())) self.assertEqual("20150825T100000", Schedule.toIsoString(result.getEndTime())) timePoint2 = Schedule.fromIsoString("20150827T073000") result = manager._calculateInterval(timePoint2, memberKeys) self.assertEqual("20150827T070000", Schedule.toIsoString(result.getStartTime())) self.assertEqual("20150827T080000", Schedule.toIsoString(result.getEndTime())) timePoint3 = Schedule.fromIsoString("20150827T043000") result = manager._calculateInterval(timePoint3, memberKeys) self.assertEqual(False, result.isValid()) timePoint4 = Schedule.fromIsoString("20150827T053000") result = manager._calculateInterval(timePoint4, memberKeys) self.assertEqual("20150827T050000", Schedule.toIsoString(result.getStartTime())) self.assertEqual("20150827T060000", Schedule.toIsoString(result.getEndTime()))
def setManager(self): schedule1 = Schedule() interval11 = RepetitiveInterval( Schedule.fromIsoString("20161001T000000"), Schedule.fromIsoString("20161031T000000"), 0, 24, 1, RepetitiveInterval.RepeatUnit.DAY) schedule1.addWhiteInterval(interval11) self.manager.addSchedule("schedule1", schedule1)
def addSchedule(self, scheduleName, managerStartDate, managerEndDate, managerStartHour, managerEndHour): schedule = Schedule() interval = RepetitiveInterval(Schedule.fromIsoString(managerStartDate), Schedule.fromIsoString(managerEndDate), managerStartHour, managerEndHour, 1, RepetitiveInterval.RepeatUnit.DAY) schedule.addWhiteInterval(interval) self.manager.addSchedule(scheduleName, schedule)
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_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 startConsuming(self): if self.consumeCatalog: contentName = Name( "/org/openmhealth/haitao/SAMPLE/fitness/physical_activity/time_location/catalog/20161024T213400" ) catalogInterest = Interest(contentName) self.face.expressInterest(catalogInterest, self.onCatalogConsumeComplete, self.onCatalogConsumeFailed) # self.consumer.consume(contentName, self.onCatalogConsumeComplete, self.onConsumeFailed) print "Trying to consume: " + contentName.toUri() else: contentName = Name( "/org/openmhealth/haitao/SAMPLE/fitness/physical_activity/time_location/" ) dataNum = 60 baseZFill = 3 basetimeString = "20160620T080" for i in range(0, dataNum): timeString = basetimeString + str(i).zfill(baseZFill) timeFloat = Schedule.fromIsoString(timeString) self.consumer.consume( Name(contentName).append(timeString), self.onConsumeComplete, self.onConsumeFailed) print "Trying to consume: " + Name(contentName).append( timeString).toUri()
def test_content_key_timeout(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): return self.handleExpressInterest(interest, onData, onTimeout) def handleExpressInterest(interest, onData, onTimeout): self.assertEqual(expectedInterest, interest.getName()) 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. testDb = Sqlite3ProducerDb(self.databaseFilePath) producer = Producer(prefix, suffix, face, self.keyChain, testDb) def onEncryptedKeys(result): self.assertEqual(4, timeoutCount[0]) self.assertEqual(0, len(result)) producer.createContentKey(testTime, onEncryptedKeys)
def startConsuming(self, userId, basetimeString, producedDataName, dataNum, outerDataName): contentName = Name(userId).append(Name("/SAMPLE/fitness/physical_activity/time_location/")) baseZFill = 2 for i in range(0, dataNum): timeString = basetimeString + str(i).zfill(baseZFill) + '00' timeFloat = Schedule.fromIsoString(timeString) self.consume(Name(contentName).append(timeString), producedDataName, outerDataName) print "Trying to consume: " + Name(contentName).append(timeString).toUri()
def startConsuming(self, userId, basetimeString, producedDataName, dataNum, outerDataName): contentName = Name(userId).append(Name("/SAMPLE/fitness/physical_activity/time_location/")) baseZFill = 3 for i in range(0, dataNum): timeString = basetimeString + str(i).zfill(baseZFill) timeFloat = Schedule.fromIsoString(timeString) self.consume(Name(contentName).append(timeString), producedDataName, outerDataName) print "Trying to consume: " + Name(contentName).append(timeString).toUri()
def test_get_group_key_without_regeneration(self): # Create the group manager. manager = GroupManager( Name("Alice"), Name("data_type"), Sqlite3GroupManagerDb(self.groupKeyDatabaseFilePath), 1024, 1, self.keyChain) self.setManager(manager) # Get the data list from the group manager. timePoint1 = Schedule.fromIsoString("20150825T093000") result = manager.getGroupKey(timePoint1) self.assertEqual(4, len(result)) # The first data packet contains the group's encryption key (public key). data1 = result[0] self.assertEqual( "/Alice/READ/data_type/E-KEY/20150825T090000/20150825T100000", data1.getName().toUri()) groupEKey1 = EncryptKey(data1.getContent()) # Get the second data packet and decrypt. data = result[1] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberA/ksk-123", data.getName().toUri()) # Add new members to the database. dataBlob = self.certificate.wireEncode() memberD = Data() memberD.wireDecode(dataBlob) memberD.setName(Name("/ndn/memberD/KEY/ksk-123/ID-CERT/123")) manager.addMember("schedule1", memberD) result2 = manager.getGroupKey(timePoint1, False) self.assertEqual(5, len(result2)) # Check that the new EKey is the same as the previous one. data2 = result2[0] self.assertEqual( "/Alice/READ/data_type/E-KEY/20150825T090000/20150825T100000", data2.getName().toUri()) groupEKey2 = EncryptKey(data2.getContent()) self.assertTrue(groupEKey1.getKeyBits().equals( groupEKey2.getKeyBits())) # Check the second data packet. data2 = result2[1] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberA/ksk-123", data2.getName().toUri())
def test_get_group_key_without_regeneration(self): # Create the group manager. manager = GroupManager( Name("Alice"), Name("data_type"), Sqlite3GroupManagerDb(self.groupKeyDatabaseFilePath), 1024, 1, self.keyChain) self.setManager(manager) # Get the data list from the group manager. timePoint1 = Schedule.fromIsoString("20150825T093000") result = manager.getGroupKey(timePoint1) self.assertEqual(4, len(result)) # The first data packet contains the group's encryption key (public key). data1 = result[0] self.assertEqual( "/Alice/READ/data_type/E-KEY/20150825T090000/20150825T100000", data1.getName().toUri()) groupEKey1 = EncryptKey(data1.getContent()) # Get the second data packet and decrypt. data = result[1] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberA/ksk-123", data.getName().toUri()) # Add new members to the database. dataBlob = self.certificate.wireEncode() memberD = Data() memberD.wireDecode(dataBlob) memberD.setName(Name("/ndn/memberD/KEY/ksk-123/ID-CERT/123")) manager.addMember("schedule1", memberD) result2 = manager.getGroupKey(timePoint1, False) self.assertEqual(5, len(result2)) # Check that the new EKey is the same as the previous one. data2 = result2[0] self.assertEqual( "/Alice/READ/data_type/E-KEY/20150825T090000/20150825T100000", data2.getName().toUri()) groupEKey2 = EncryptKey(data2.getContent()) self.assertTrue(groupEKey1.getKeyBits().equals(groupEKey2.getKeyBits())); # Check the second data packet. data2 = result2[1] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberA/ksk-123", data2.getName().toUri())
def publishGroupKeys(self): timePoint1 = Schedule.fromIsoString("20161024T083000") result = self.manager.getGroupKey(timePoint1) # The first is group public key, E-key # The rest are group private keys encrypted with each member's public key, D-key for i in range(0, len(result)): self.memoryContentCache.add(result[i]) self.initiateContentStoreInsertion( "/ndn/edu/ucla/remap/ndnfit/repo", result[i]) print "Publish key name: " + str( i) + " " + result[i].getName().toUri() self.updateGroupKeys = False
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 publishGroupKeys(self, timeStr): timePoint = Schedule.fromIsoString(timeStr) print timeStr result = self.manager.getGroupKey(timePoint) # The first is group public key, E-key # The rest are group private keys encrypted with each member's public key, D-key for i in range(0, len(result)): self.memoryContentCache.add(result[i]) self.initiateContentStoreInsertion( "/ndn/edu/ucla/remap/ndnfit/repo", result[i]) print "Publish key name: " + str( i) + " " + result[i].getName().toUri() print "key content: " + str(result[i].getContent().toBytes()) self.needToPublishGroupKeys = False
def startConsuming(self): if self.consumeCatalog: contentName = Name("/org/openmhealth/zhehao/SAMPLE/fitness/physical_activity/time_location/catalog/20160620T080000") self.consumer.consume(contentName, self.onCatalogConsumeComplete, self.onConsumeFailed) print "Trying to consume: " + contentName.toUri() else: contentName = Name("/org/openmhealth/zhehao/SAMPLE/fitness/physical_activity/time_location/") dataNum = 60 baseZFill = 3 basetimeString = "20160620T080" for i in range(0, dataNum): timeString = basetimeString + str(i).zfill(baseZFill) timeFloat = Schedule.fromIsoString(timeString) self.consumer.consume(Name(contentName).append(timeString), self.onConsumeComplete, self.onConsumeFailed) print "Trying to consume: " + Name(contentName).append(timeString).toUri()
def produce(self): # Produce the bounding box print "ready to produce" maxLong = -3600 minLong = 3600 maxLat = -3600 minLat = 3600 if len(self.rawData) == 0: print "No raw data as producer input" for item in self.rawData: print item if item["lng"] > maxLong: maxLong = item["lng"] if item["lng"] < minLong: minLong = item["lng"] if item["lat"] > maxLat: maxLat = item["lat"] if item["lat"] < minLat: minLat = item["lat"] result = json.dumps({ "maxlng": maxLong, "minlng": minLong, "maxlat": maxLat, "minlat": minLat, "size": len(self.rawData) }) if self.encrypted: # TODO: replace fixed timestamp for now for produced data, createContentKey as needed testTime1 = Schedule.fromIsoString("20160320T080000") self.producer.createContentKey(testTime1) self.producer.produce(testTime1, result) else: # Arbitrary produced data lifetime data = Data(Name(self.identityName).append("20160320T080000")) data.getMetaInfo().setFreshnessPeriod(400000) data.setContent(result) # If the interest's still within lifetime, this will satisfy the interest self.memoryContentCache.add(data) print "Produced data with name " + data.getName().toUri()
# Produce encrypted data for this user username = "******" # Insert into this repo repoPrefix = "/ndn/edu/ucla/remap/ndnfit/repo" testProducer = SampleProducer(face, username, memoryContentCache) basetimeString = "20161024T080" baseZFill = 3 baseLat = 34 baseLng = -118 # This should be less than 1 minute dataNum = 2 # Create the content key once originalTimeString = basetimeString + str(0).zfill(baseZFill) timeFloat = Schedule.fromIsoString(originalTimeString) testProducer.createContentKey(timeFloat) memoryContentCache.registerPrefix(Name(username), onRegisterFailed, onDataNotFound) catalogData = Data( Name(username).append( Name("/SAMPLE/fitness/physical_activity/time_location/catalog/")). append(originalTimeString)) catalogContentArray = [] for i in range(0, dataNum): emptyData = Data() timeString = basetimeString + str(i).zfill(baseZFill) timeFloat = Schedule.fromIsoString(timeString)
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): return self.handleExpressInterest(interest, onData, onTimeout) def handleExpressInterest(interest, onData, onTimeout): 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)
def test_get_group_key(self): # Create the group manager. manager = GroupManager( Name("Alice"), Name("data_type"), Sqlite3GroupManagerDb(self.groupKeyDatabaseFilePath), 1024, 1, self.keyChain) self.setManager(manager) # Get the data list from the group manager. timePoint1 = Schedule.fromIsoString("20150825T093000") result = manager.getGroupKey(timePoint1) self.assertEqual(4, len(result)) # The first data packet contains the group's encryption key (public key). data = result[0] self.assertEqual( "/Alice/READ/data_type/E-KEY/20150825T090000/20150825T100000", data.getName().toUri()) groupEKey = EncryptKey(data.getContent()) # Get the second data packet and decrypt. data = result[1] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberA/ksk-123", data.getName().toUri()) ####################################################### Start decryption. dataContent = data.getContent() # Get the nonce key. # dataContent is a sequence of the two EncryptedContent. encryptedNonce = EncryptedContent() encryptedNonce.wireDecode(dataContent) self.assertEqual(0, encryptedNonce.getInitialVector().size()) self.assertEqual(EncryptAlgorithmType.RsaOaep, encryptedNonce.getAlgorithmType()) decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep) blobNonce = encryptedNonce.getPayload() nonce = RsaAlgorithm.decrypt(self.decryptKeyBlob, blobNonce, decryptParams) # Get the payload. # Use the size of encryptedNonce to find the start of encryptedPayload. payloadContent = dataContent.buf()[encryptedNonce.wireEncode().size():] encryptedPayload = EncryptedContent() encryptedPayload.wireDecode(payloadContent) self.assertEqual(16, encryptedPayload.getInitialVector().size()) self.assertEqual(EncryptAlgorithmType.AesCbc, encryptedPayload.getAlgorithmType()) decryptParams.setAlgorithmType(EncryptAlgorithmType.AesCbc) decryptParams.setInitialVector(encryptedPayload.getInitialVector()) blobPayload = encryptedPayload.getPayload() largePayload = AesAlgorithm.decrypt(nonce, blobPayload, decryptParams) # Get the group D-KEY. groupDKey = DecryptKey(largePayload) ####################################################### End decryption. # Check the D-KEY. derivedGroupEKey = RsaAlgorithm.deriveEncryptKey( groupDKey.getKeyBits()) self.assertTrue(groupEKey.getKeyBits().equals( derivedGroupEKey.getKeyBits())) # Check the third data packet. data = result[2] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberB/ksk-123", data.getName().toUri()) # Check the fourth data packet. data = result[3] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberC/ksk-123", data.getName().toUri()) # Check invalid time stamps for getting the group key. timePoint2 = Schedule.fromIsoString("20150826T083000") self.assertEqual(0, len(manager.getGroupKey(timePoint2))) timePoint3 = Schedule.fromIsoString("20150827T023000") self.assertEqual(0, len(manager.getGroupKey(timePoint3)))
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") # 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): return self.handleExpressInterest(interest, onData, onTimeout) def handleExpressInterest(interest, onData, onTimeout): 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(testTimeRounded2, 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 setManager(self, manager): # Set up the first schedule. schedule1 = Schedule() interval11 = RepetitiveInterval( Schedule.fromIsoString("20150825T000000"), Schedule.fromIsoString("20150827T000000"), 5, 10, 2, RepetitiveInterval.RepeatUnit.DAY) interval12 = RepetitiveInterval( Schedule.fromIsoString("20150825T000000"), Schedule.fromIsoString("20150827T000000"), 6, 8, 1, RepetitiveInterval.RepeatUnit.DAY) interval13 = RepetitiveInterval( Schedule.fromIsoString("20150827T000000"), Schedule.fromIsoString("20150827T000000"), 7, 8) schedule1.addWhiteInterval(interval11) schedule1.addWhiteInterval(interval12) schedule1.addBlackInterval(interval13) # Set up the second schedule. schedule2 = Schedule() interval21 = RepetitiveInterval( Schedule.fromIsoString("20150825T000000"), Schedule.fromIsoString("20150827T000000"), 9, 12, 1, RepetitiveInterval.RepeatUnit.DAY) interval22 = RepetitiveInterval( Schedule.fromIsoString("20150827T000000"), Schedule.fromIsoString("20150827T000000"), 6, 8) interval23 = RepetitiveInterval( Schedule.fromIsoString("20150827T000000"), Schedule.fromIsoString("20150827T000000"), 2, 4) schedule2.addWhiteInterval(interval21) schedule2.addWhiteInterval(interval22) schedule2.addBlackInterval(interval23) # Add them to the group manager database. manager.addSchedule("schedule1", schedule1) manager.addSchedule("schedule2", schedule2) # Make some adaptions to certificate. dataBlob = self.certificate.wireEncode() memberA = Data() memberA.wireDecode(dataBlob, TlvWireFormat.get()) memberA.setName(Name("/ndn/memberA/KEY/ksk-123/ID-CERT/123")) memberB = Data() memberB.wireDecode(dataBlob, TlvWireFormat.get()) memberB.setName(Name("/ndn/memberB/KEY/ksk-123/ID-CERT/123")) memberC = Data() memberC.wireDecode(dataBlob, TlvWireFormat.get()) memberC.setName(Name("/ndn/memberC/KEY/ksk-123/ID-CERT/123")) # Add the members to the database. manager.addMember("schedule1", memberA) manager.addMember("schedule1", memberB) manager.addMember("schedule2", memberC)
# Produce encrypted data for this user username = "******" # Insert into this repo repoPrefix = "/ndn/edu/ucla/remap/ndnfit/repo" testProducer = SampleProducer(face, username, memoryContentCache) basetimeString = "20160620T080" baseZFill = 3 baseLat = 34 baseLng = -118 # This should be less than 1 minute dataNum = 60 # Create the content key once originalTimeString = basetimeString + str(0).zfill(baseZFill) timeFloat = Schedule.fromIsoString(originalTimeString) testProducer.createContentKey(timeFloat) memoryContentCache.registerPrefix(Name(username), onRegisterFailed, onDataNotFound) catalogData = Data(Name(username).append(Name("/data/fitness/physical_activity/time_location/catalog/")).append(originalTimeString).appendVersion(1)) catalogContentArray = [] for i in range(0, dataNum): emptyData = Data() timeString = basetimeString + str(i).zfill(baseZFill) timeFloat = Schedule.fromIsoString(timeString) dataObject = json.dumps({"lat": baseLat + random.randint(-10, 10), "timestamp": int(timeFloat / 1000), "lng": baseLng + random.randint(-10, 10)}) testProducer.producer.produce(emptyData, timeFloat, Blob(dataObject, False)) producedName = emptyData.getName()
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)
def test_database_functions(self): scheduleBlob = Blob(SCHEDULE, False) # Create a schedule. schedule = Schedule() schedule.wireDecode(scheduleBlob) # Create a member. params = RsaKeyParams() decryptKey = RsaAlgorithm.generateKey(params) encryptKey = RsaAlgorithm.deriveEncryptKey(decryptKey.getKeyBits()) keyBlob = encryptKey.getKeyBits() name1 = Name("/ndn/BoyA/ksk-123") name2 = Name("/ndn/BoyB/ksk-1233") name3 = Name("/ndn/GirlC/ksk-123") name4 = Name("/ndn/GirlD/ksk-123") name5 = Name("/ndn/Hello/ksk-123") # Add schedules into the database. self.database.addSchedule("work-time", schedule) self.database.addSchedule("rest-time", schedule) self.database.addSchedule("play-time", schedule) self.database.addSchedule("boelter-time", schedule) # Throw an exception when adding a schedule with an existing name. with self.assertRaises(GroupManagerDb.Error): self.database.addSchedule("boelter-time", schedule) # Add members into the database. self.database.addMember("work-time", name1, keyBlob) self.database.addMember("rest-time", name2, keyBlob) self.database.addMember("play-time", name3, keyBlob) self.database.addMember("play-time", name4, keyBlob) # Throw an exception when adding a member with a non-existing schedule name. with self.assertRaises(GroupManagerDb.Error): self.database.addMember("false-time", name5, keyBlob) self.database.addMember("boelter-time", name5, keyBlob) # Throw an exception when adding a member having an existing identity. with self.assertRaises(GroupManagerDb.Error): self.database.addMember("work-time", name5, keyBlob) # Test has functions. self.assertEqual(True, self.database.hasSchedule("work-time")) self.assertEqual(True, self.database.hasSchedule("rest-time")) self.assertEqual(True, self.database.hasSchedule("play-time")) self.assertEqual(False, self.database.hasSchedule("sleep-time")) self.assertEqual(False, self.database.hasSchedule("")) self.assertEqual(True, self.database.hasMember(Name("/ndn/BoyA"))) self.assertEqual(True, self.database.hasMember(Name("/ndn/BoyB"))) self.assertEqual(False, self.database.hasMember(Name("/ndn/BoyC"))) # Get a schedule. scheduleResult = self.database.getSchedule("work-time") self.assertTrue(scheduleResult.wireEncode().equals(scheduleBlob)) scheduleResult = self.database.getSchedule("play-time") self.assertTrue(scheduleResult.wireEncode().equals(scheduleBlob)) # Throw an exception when when there is no such schedule in the database. with self.assertRaises(GroupManagerDb.Error): self.database.getSchedule("work-time-11") # List all schedule names. names = self.database.listAllScheduleNames() self.assertTrue("work-time" in names) self.assertTrue("play-time" in names) self.assertTrue("rest-time" in names) self.assertTrue(not ("sleep-time" in names)) # List members of a schedule. memberMap = self.database.getScheduleMembers("play-time") self.assertTrue(len(memberMap) != 0) # When there's no such schedule, the return map's size should be 0. self.assertEquals(0, len(self.database.getScheduleMembers("sleep-time"))) # List all members. members = self.database.listAllMembers() self.assertTrue(Name("/ndn/GirlC") in members) self.assertTrue(Name("/ndn/GirlD") in members) self.assertTrue(Name("/ndn/BoyA") in members) self.assertTrue(Name("/ndn/BoyB") in members) # Rename a schedule. self.assertEqual(True, self.database.hasSchedule("boelter-time")) self.database.renameSchedule("boelter-time", "rieber-time") self.assertEqual(False, self.database.hasSchedule("boelter-time")) self.assertEqual(True, self.database.hasSchedule("rieber-time")) self.assertEqual("rieber-time", self.database.getMemberSchedule(Name("/ndn/Hello"))) # Update a schedule. newSchedule = Schedule() newSchedule.wireDecode(scheduleBlob) repetitiveInterval = RepetitiveInterval( Schedule.fromIsoString("20150825T000000"), Schedule.fromIsoString("20150921T000000"), 2, 10, 5, RepetitiveInterval.RepeatUnit.DAY) newSchedule.addWhiteInterval(repetitiveInterval) self.database.updateSchedule("rieber-time", newSchedule) scheduleResult = self.database.getSchedule("rieber-time") self.assertTrue(not scheduleResult.wireEncode().equals(scheduleBlob)) self.assertTrue(scheduleResult.wireEncode().equals(newSchedule.wireEncode())) # Add a new schedule when updating a non-existing schedule. self.assertEquals(False, self.database.hasSchedule("ralphs-time")) self.database.updateSchedule("ralphs-time", newSchedule) self.assertEquals(True, self.database.hasSchedule("ralphs-time")) # Update the schedule of a member. self.database.updateMemberSchedule(Name("/ndn/Hello"), "play-time") self.assertEqual("play-time", self.database.getMemberSchedule(Name("/ndn/Hello"))) # Delete a member. self.assertEqual(True, self.database.hasMember(Name("/ndn/Hello"))) self.database.deleteMember(Name("/ndn/Hello")) self.assertEqual(False, self.database.hasMember(Name("/ndn/Hello"))) # Delete a non-existing member. try: self.database.deleteMember(Name("/ndn/notExisting")) except Exception as ex: self.fail("Unexpected error deleting a non-existing member: " + repr(ex)) # Delete a schedule. All the members using this schedule should be deleted. self.database.deleteSchedule("play-time") self.assertEqual(False, self.database.hasSchedule("play-time")) self.assertEqual(False, self.database.hasMember(Name("/ndn/GirlC"))) self.assertEqual(False, self.database.hasMember(Name("/ndn/GirlD"))) # Delete a non-existing schedule. try: self.database.deleteSchedule("not-existing-time") except Exception as ex: self.fail("Unexpected error deleting a non-existing schedule: " + repr(ex))
def test_get_group_key(self): # Create the group manager. manager = GroupManager( Name("Alice"), Name("data_type"), Sqlite3GroupManagerDb(self.groupKeyDatabaseFilePath), 1024, 1, self.keyChain) self.setManager(manager) # Get the data list from the group manager. timePoint1 = Schedule.fromIsoString("20150825T093000") result = manager.getGroupKey(timePoint1) self.assertEqual(4, len(result)) # The first data packet contains the group's encryption key (public key). data = result[0] self.assertEqual( "/Alice/READ/data_type/E-KEY/20150825T090000/20150825T100000", data.getName().toUri()) groupEKey = EncryptKey(data.getContent()) # Get the second data packet and decrypt. data = result[1] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberA/ksk-123", data.getName().toUri()) ####################################################### Start decryption. dataContent = data.getContent() # Get the nonce key. # dataContent is a sequence of the two EncryptedContent. encryptedNonce = EncryptedContent() encryptedNonce.wireDecode(dataContent) self.assertEqual(0, encryptedNonce.getInitialVector().size()) self.assertEqual(EncryptAlgorithmType.RsaOaep, encryptedNonce.getAlgorithmType()) decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep) blobNonce = encryptedNonce.getPayload() nonce = RsaAlgorithm.decrypt(self.decryptKeyBlob, blobNonce, decryptParams) # Get the payload. # Use the size of encryptedNonce to find the start of encryptedPayload. payloadContent = dataContent.buf()[encryptedNonce.wireEncode().size():] encryptedPayload = EncryptedContent() encryptedPayload.wireDecode(payloadContent) self.assertEqual(16, encryptedPayload.getInitialVector().size()) self.assertEqual(EncryptAlgorithmType.AesCbc, encryptedPayload.getAlgorithmType()) decryptParams.setAlgorithmType(EncryptAlgorithmType.AesCbc) decryptParams.setInitialVector(encryptedPayload.getInitialVector()) blobPayload = encryptedPayload.getPayload() largePayload = AesAlgorithm.decrypt(nonce, blobPayload, decryptParams) # Get the group D-KEY. groupDKey = DecryptKey(largePayload) ####################################################### End decryption. # Check the D-KEY. derivedGroupEKey = RsaAlgorithm.deriveEncryptKey(groupDKey.getKeyBits()) self.assertTrue(groupEKey.getKeyBits().equals(derivedGroupEKey.getKeyBits())) # Check the third data packet. data = result[2] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberB/ksk-123", data.getName().toUri()) # Check the fourth data packet. data = result[3] self.assertEqual( "/Alice/READ/data_type/D-KEY/20150825T090000/20150825T100000/FOR/ndn/memberC/ksk-123", data.getName().toUri()) # Check invalid time stamps for getting the group key. timePoint2 = Schedule.fromIsoString("20150826T083000") self.assertEqual(0, len(manager.getGroupKey(timePoint2))) timePoint3 = Schedule.fromIsoString("20150827T023000") self.assertEqual(0, len(manager.getGroupKey(timePoint3)))