def test_full_name(self): data = Data() data.wireDecode(codedData) # Check the full name format. self.assertEqual(data.getFullName().size(), data.getName().size() + 1) self.assertEqual(data.getName(), data.getFullName().getPrefix(-1)) self.assertEqual(data.getFullName().get(-1).getValue().size(), 32) # Check the independent digest calculation. sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) sha256.update(Blob(codedData).toBytes()) newDigest = Blob(bytearray(sha256.finalize()), False) self.assertTrue(newDigest.equals( data.getFullName().get(-1).getValue())) # Check the expected URI. self.assertEqual( data.getFullName().toUri(), "/ndn/abc/sha256digest=" + "96556d685dcb1af04be4ae57f0e7223457d4055ea9b3d07c0d337bef4a8b3ee9") # Changing the Data packet should change the full name. saveFullName = Name(data.getFullName()) data.setContent(Blob()) self.assertNotEqual(data.getFullName().get(-1), saveFullName.get(-1))
def test_setter_getter(self): content = EncryptedContent() self.assertEqual(content.getAlgorithmType(), None) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) self.assertEqual(content.getKeyLocator().getType(), None) content.setAlgorithmType(EncryptAlgorithmType.RsaOaep) self.assertEqual(content.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) self.assertEqual(content.getKeyLocator().getType(), None) keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.getKeyName().set("/test/key/locator") content.setKeyLocator(keyLocator) self.assertTrue(content.getKeyLocator().getType() != None) self.assertTrue(content.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) content.setPayload(Blob(message, False)) self.assertTrue(content.getPayload().equals(Blob(message, False))) content.setInitialVector(Blob(iv, False)) self.assertTrue(content.getInitialVector().equals(Blob(iv, False))) encoded = content.wireEncode() contentBlob = Blob(encrypted, False) self.assertTrue(contentBlob.equals(encoded))
def test_setter_getter(self): content = EncryptedContent() self.assertEqual(content.getAlgorithmType(), None) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) self.assertEqual(content.getKeyLocator().getType(), None) content.setAlgorithmType(EncryptAlgorithmType.RsaOaep) self.assertEqual(content.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) self.assertEqual(content.getKeyLocator().getType(), None) keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.getKeyName().set("/test/key/locator") content.setKeyLocator(keyLocator) self.assertTrue(content.getKeyLocator().getType() != None) self.assertTrue(content.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) content.setPayload(Blob(message, False)) self.assertTrue(content.getPayload().equals(Blob(message, False))) content.setInitialVector(Blob(iv, False)) self.assertTrue(content.getInitialVector().equals(Blob(iv, False))) encoded = content.wireEncode() contentBlob = Blob(encrypted, False) self.assertTrue(contentBlob.equals(encoded))
def test_encryption_decryption(self): encryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep, 0) privateKeyBlob = Blob(b64decode(PRIVATE_KEY)) publicKeyBlob = Blob(b64decode(PUBLIC_KEY)) decryptKey = DecryptKey(privateKeyBlob) encryptKey = RsaAlgorithm.deriveEncryptKey(decryptKey.getKeyBits()) encodedPublic = publicKeyBlob derivedPublicKey = encryptKey.getKeyBits() self.assertTrue(encodedPublic.equals(derivedPublicKey)) plainBlob = Blob(PLAINTEXT, False) encryptBlob = RsaAlgorithm.encrypt( encryptKey.getKeyBits(), plainBlob, encryptParams) receivedBlob = RsaAlgorithm.decrypt( decryptKey.getKeyBits(), encryptBlob, encryptParams) self.assertTrue(plainBlob.equals(receivedBlob)) cipherBlob = Blob(CIPHERTEXT_OAEP, False) decryptedBlob = RsaAlgorithm.decrypt( decryptKey.getKeyBits(), cipherBlob, encryptParams) self.assertTrue(plainBlob.equals(decryptedBlob)) # Now test RsaPkcs. encryptParams = EncryptParams(EncryptAlgorithmType.RsaPkcs, 0) encryptBlob = RsaAlgorithm.encrypt( encryptKey.getKeyBits(), plainBlob, encryptParams) receivedBlob = RsaAlgorithm.decrypt( decryptKey.getKeyBits(), encryptBlob, encryptParams) self.assertTrue(plainBlob.equals(receivedBlob)) cipherBlob = Blob(CIPHERTEXT_PKCS, False) decryptedBlob = RsaAlgorithm.decrypt( decryptKey.getKeyBits(), cipherBlob, encryptParams) self.assertTrue(plainBlob.equals(decryptedBlob))
def test_encryption_decryption(self): encryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep, 0) privateKeyBlob = Blob(b64decode(PRIVATE_KEY)) publicKeyBlob = Blob(b64decode(PUBLIC_KEY)) decryptKey = DecryptKey(privateKeyBlob) encryptKey = RsaAlgorithm.deriveEncryptKey(decryptKey.getKeyBits()) encodedPublic = publicKeyBlob derivedPublicKey = encryptKey.getKeyBits() self.assertTrue(encodedPublic.equals(derivedPublicKey)) plainBlob = Blob(PLAINTEXT, False) encryptBlob = RsaAlgorithm.encrypt(encryptKey.getKeyBits(), plainBlob, encryptParams) receivedBlob = RsaAlgorithm.decrypt(decryptKey.getKeyBits(), encryptBlob, encryptParams) self.assertTrue(plainBlob.equals(receivedBlob)) cipherBlob = Blob(CIPHERTEXT_OAEP, False) decryptedBlob = RsaAlgorithm.decrypt(decryptKey.getKeyBits(), cipherBlob, encryptParams) self.assertTrue(plainBlob.equals(decryptedBlob)) # Now test RsaPkcs. encryptParams = EncryptParams(EncryptAlgorithmType.RsaPkcs, 0) encryptBlob = RsaAlgorithm.encrypt(encryptKey.getKeyBits(), plainBlob, encryptParams) receivedBlob = RsaAlgorithm.decrypt(decryptKey.getKeyBits(), encryptBlob, encryptParams) self.assertTrue(plainBlob.equals(receivedBlob)) cipherBlob = Blob(CIPHERTEXT_PKCS, False) decryptedBlob = RsaAlgorithm.decrypt(decryptKey.getKeyBits(), cipherBlob, encryptParams) self.assertTrue(plainBlob.equals(decryptedBlob))
def test_generic_signature(self): # Test correct encoding. signature = GenericSignature() signature.setSignatureInfoEncoding( Blob(experimentalSignatureInfo, False), None) signatureValue = Blob([1, 2, 3, 4], False) signature.setSignature(signatureValue) self.freshData.setSignature(signature) encoding = self.freshData.wireEncode() decodedData = Data() decodedData.wireDecode(encoding) decodedSignature = decodedData.getSignature() self.assertEqual(decodedSignature.getTypeCode(), experimentalSignatureType) self.assertTrue( Blob(experimentalSignatureInfo, False).equals(decodedSignature.getSignatureInfoEncoding())) self.assertTrue(signatureValue.equals(decodedSignature.getSignature())) # Test bad encoding. signature = GenericSignature() signature.setSignatureInfoEncoding( Blob(experimentalSignatureInfoNoSignatureType, False), None) signature.setSignature(signatureValue) self.freshData.setSignature(signature) gotError = True try: self.freshData.wireEncode() gotError = False except: pass if not gotError: self.fail( "Expected encoding error for experimentalSignatureInfoNoSignatureType" ) signature = GenericSignature() signature.setSignatureInfoEncoding( Blob(experimentalSignatureInfoBadTlv, False), None) signature.setSignature(signatureValue) self.freshData.setSignature(signature) gotError = True try: self.freshData.wireEncode() gotError = False except: pass if not gotError: self.fail( "Expected encoding error for experimentalSignatureInfoBadTlv")
def test_generic_signature(self): # Test correct encoding. signature = GenericSignature() signature.setSignatureInfoEncoding( Blob(experimentalSignatureInfo, False), None) signatureValue = Blob([1, 2, 3, 4], False) signature.setSignature(signatureValue) self.freshData.setSignature(signature) encoding = self.freshData.wireEncode() decodedData = Data() decodedData.wireDecode(encoding) decodedSignature = decodedData.getSignature() self.assertEqual(decodedSignature.getTypeCode(), experimentalSignatureType) self.assertTrue(Blob(experimentalSignatureInfo, False).equals (decodedSignature.getSignatureInfoEncoding())) self.assertTrue(signatureValue.equals(decodedSignature.getSignature())) # Test bad encoding. signature = GenericSignature() signature.setSignatureInfoEncoding( Blob(experimentalSignatureInfoNoSignatureType, False), None) signature.setSignature(signatureValue) self.freshData.setSignature(signature) gotError = True try: self.freshData.wireEncode() gotError = False except: pass if not gotError: self.fail("Expected encoding error for experimentalSignatureInfoNoSignatureType") signature = GenericSignature() signature.setSignatureInfoEncoding( Blob(experimentalSignatureInfoBadTlv, False), None) signature.setSignature(signatureValue) self.freshData.setSignature(signature) gotError = True try: self.freshData.wireEncode() gotError = False except: pass if not gotError: self.fail("Expected encoding error for experimentalSignatureInfoBadTlv")
def test_content_asymmetric_encrypt_small(self): for input in encryptorRsaTestInputs: rawContent = Blob( bytearray([ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73 ]), False) data = Data() rsaParams = RsaKeyParams(1024) keyName = Name("test") decryptKey = RsaAlgorithm.generateKey(rsaParams) encryptKey = RsaAlgorithm.deriveEncryptKey(decryptKey.getKeyBits()) eKey = encryptKey.getKeyBits() dKey = decryptKey.getKeyBits() encryptParams = EncryptParams(input.type) Encryptor.encryptData(data, rawContent, keyName, eKey, encryptParams) self.assertTrue( data.getName().equals(Name("/FOR").append(keyName)), input.testName) extractContent = EncryptedContent() extractContent.wireDecode(data.getContent()) self.assertTrue( keyName.equals(extractContent.getKeyLocator().getKeyName()), input.testName) self.assertEqual(extractContent.getInitialVector().size(), 0, input.testName) self.assertEqual(extractContent.getAlgorithmType(), input.type, input.testName) recovered = extractContent.getPayload() decrypted = RsaAlgorithm.decrypt(dKey, recovered, encryptParams) self.assertTrue(rawContent.equals(decrypted), input.testName)
def test_content_asymmetric_encrypt_small(self): for input in encryptorRsaTestInputs: rawContent = Blob(bytearray([ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73 ]), False) data = Data() rsaParams = RsaKeyParams(1024) keyName = Name("test") decryptKey = RsaAlgorithm.generateKey(rsaParams) encryptKey = RsaAlgorithm.deriveEncryptKey(decryptKey.getKeyBits()) eKey = encryptKey.getKeyBits() dKey = decryptKey.getKeyBits() encryptParams = EncryptParams(input.type) Encryptor.encryptData(data, rawContent, keyName, eKey, encryptParams) self.assertTrue(data.getName().equals(Name("/FOR").append(keyName)), input.testName) extractContent = EncryptedContent() extractContent.wireDecode(data.getContent()) self.assertTrue( keyName.equals(extractContent.getKeyLocator().getKeyName()), input.testName) self.assertEqual( extractContent.getInitialVector().size(), 0, input.testName) self.assertEqual( extractContent.getAlgorithmType(), input.type, input.testName) recovered = extractContent.getPayload() decrypted = RsaAlgorithm.decrypt(dKey, recovered, encryptParams) self.assertTrue(rawContent.equals(decrypted), input.testName)
def test_full_name(self): data = Data() data.wireDecode(codedData) # Check the full name format. self.assertEqual(data.getFullName().size(), data.getName().size() + 1) self.assertEqual(data.getName(), data.getFullName().getPrefix(-1)) self.assertEqual(data.getFullName().get(-1).getValue().size(), 32) # Check the independent digest calculation. sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) sha256.update(Blob(codedData).toBytes()) newDigest = Blob(bytearray(sha256.finalize()), False) self.assertTrue(newDigest.equals(data.getFullName().get(-1).getValue())) # Check the expected URI. self.assertEqual( data.getFullName().toUri(), "/ndn/abc/sha256digest=" + "96556d685dcb1af04be4ae57f0e7223457d4055ea9b3d07c0d337bef4a8b3ee9") # Changing the Data packet should change the full name. saveFullName = Name(data.getFullName()) data.setContent(Blob()) self.assertNotEqual(data.getFullName().get(-1), saveFullName.get(-1))
def test_constructor(self): # Check default settings. content = EncryptedContent() self.assertEqual(content.getAlgorithmType(), None) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) self.assertEqual(content.getKeyLocator().getType(), None) # Check an encrypted content with IV. keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.getKeyName().set("/test/key/locator") rsaOaepContent = EncryptedContent() rsaOaepContent.setAlgorithmType( EncryptAlgorithmType.RsaOaep).setKeyLocator(keyLocator).setPayload( Blob(message, False)).setInitialVector(Blob(iv, False)) self.assertEqual(rsaOaepContent.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContent.getPayload().equals(Blob( message, False))) self.assertTrue(rsaOaepContent.getInitialVector().equals( Blob(iv, False))) self.assertTrue(rsaOaepContent.getKeyLocator().getType() != None) self.assertTrue(rsaOaepContent.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) # Encoding. encryptedBlob = Blob(encrypted, False) encoded = rsaOaepContent.wireEncode() self.assertTrue(encryptedBlob.equals(encoded)) # Decoding. rsaOaepContent2 = EncryptedContent() rsaOaepContent2.wireDecode(encryptedBlob) self.assertEqual(rsaOaepContent2.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContent2.getPayload().equals( Blob(message, False))) self.assertTrue(rsaOaepContent2.getInitialVector().equals( Blob(iv, False))) self.assertTrue(rsaOaepContent2.getKeyLocator().getType() != None) self.assertTrue(rsaOaepContent2.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) # Check the no IV case. rsaOaepContentNoIv = EncryptedContent() rsaOaepContentNoIv.setAlgorithmType( EncryptAlgorithmType.RsaOaep).setKeyLocator(keyLocator).setPayload( Blob(message, False)) self.assertEqual(rsaOaepContentNoIv.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContentNoIv.getPayload().equals( Blob(message, False))) self.assertTrue(rsaOaepContentNoIv.getInitialVector().isNull()) self.assertTrue(rsaOaepContentNoIv.getKeyLocator().getType() != None) self.assertTrue(rsaOaepContentNoIv.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) # Encoding. encryptedBlob2 = Blob(encryptedNoIv, False) encodedNoIv = rsaOaepContentNoIv.wireEncode() self.assertTrue(encryptedBlob2.equals(encodedNoIv)) # Decoding. rsaOaepContentNoIv2 = EncryptedContent() rsaOaepContentNoIv2.wireDecode(encryptedBlob2) self.assertEqual(rsaOaepContentNoIv2.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContentNoIv2.getPayload().equals( Blob(message, False))) self.assertTrue(rsaOaepContentNoIv2.getInitialVector().isNull()) self.assertTrue(rsaOaepContentNoIv2.getKeyLocator().getType() != None) self.assertTrue( rsaOaepContentNoIv2.getKeyLocator().getKeyName().equals( Name("/test/key/locator")))
def test_import_export(self): privateKeyPkcs1Base64 = ( "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n" + "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n" + "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n" + "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n" + "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n" + "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n" + "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n" + "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n" + "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n" + "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n" + "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n" + "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n" + "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n" + "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n" + "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n" + "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n" + "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n" + "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n" + "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n" + "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n" + "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n" + "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n" + "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n" + "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n" + "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n") for tpm in self.backEndList: if tpm is self.backEndOsx: # TODO: Implement TpmBackEndOsx import/export. continue keyName = Name("/Test/KeyName/KEY/1") tpm.deleteKey(keyName) self.assertEquals(False, tpm.hasKey(keyName)) privateKey = TpmPrivateKey() privateKeyPkcs1Encoding = Blob(base64.b64decode(privateKeyPkcs1Base64)) privateKey.loadPkcs1(privateKeyPkcs1Encoding.buf()) password = Blob("password").toBytes() encryptedPkcs8 = privateKey.toEncryptedPkcs8(password) tpm.importKey(keyName, encryptedPkcs8.buf(), password) self.assertEquals(True, tpm.hasKey(keyName)) try: # Can't import the same keyName again. tpm.importKey(keyName, encryptedPkcs8.buf(), password) self.fail("Did not throw the expected exception") except TpmBackEnd.Error: pass else: self.fail("Did not throw the expected exception") exportedKey = tpm.exportKey(keyName, password) self.assertEquals(True, tpm.hasKey(keyName)) privateKey2 = TpmPrivateKey() privateKey2.loadEncryptedPkcs8(exportedKey.buf(), password) privateKey2Pkcs1Encoding = privateKey2.toPkcs1() self.assertTrue(privateKeyPkcs1Encoding.equals(privateKey2Pkcs1Encoding)) tpm.deleteKey(keyName) self.assertEquals(False, tpm.hasKey(keyName)) try: tpm.exportKey(keyName, password) self.fail("Did not throw the expected exception") except TpmBackEnd.Error: pass else: self.fail("Did not throw the expected exception")
class Component(object): """ Create a new Name.Component. :param value: (optional) If value is already a Blob or Name.Component, then take another pointer to the value. Otherwise, create a new Blob with a copy of the value. If omitted, create an empty component. :type value: Blob or Name.Component or value for Blob constructor """ def __init__(self, value = None): if type(value) is Name.Component: # Use the existing Blob in the other Component. self._value = value._value elif value == None: self._value = Blob([]) else: # Blob will make a copy. self._value = value if isinstance(value, Blob) else Blob(value) def getValue(self): """ Get the value of the component. :return: The component value. :rtype: Blob """ return self._value def toEscapedString(self, result = None): """ Convert this component to a string, escaping characters according to the NDN URI Scheme. This also adds "..." to a value with zero or more ".". :param BytesIO result: (optional) The BytesIO stream to write to. If omitted, return a str with the result. :return: The result as a string (only if result is omitted). :rtype: str """ if result == None: return Name.toEscapedString(self._value.buf()) else: Name.toEscapedString(self._value.buf(), result) def toNumber(self): """ Interpret this name component as a network-ordered number and return an integer. :return: The integer number. :rtype: int """ result = 0 for i in range(self._value.size()): result *= 256 result += self._value.buf()[i] return result def toNumberWithMarker(self, marker): """ Interpret this name component as a network-ordered number with a marker and return an integer. :param int marker: The required first byte of the component. :return: The integer number. :rtype: int :raises RuntimeError: If the first byte of the component does not equal the marker. """ if self._value.size() <= 0 or self._value.buf()[0] != marker: raise RuntimeError( "Name component does not begin with the expected marker") result = 0 for i in range(1, self._value.size()): result *= 256 result += self._value.buf()[i] return result def toSegment(self): """ Interpret this name component as a segment number according to NDN naming conventions for "Segment number" (marker 0x00). http://named-data.net/doc/tech-memos/naming-conventions.pdf :return: The integer segment number. :rtype: int :raises RuntimeError: If the first byte of the component is not the expected marker. """ return self.toNumberWithMarker(0x00) def toSegmentOffset(self): """ Interpret this name component as a segment byte offset according to NDN naming conventions for segment "Byte offset" (marker 0xFB). http://named-data.net/doc/tech-memos/naming-conventions.pdf :return: The integer segment byte offset. :rtype: int :raises RuntimeError: If the first byte of the component is not the expected marker. """ return self.toNumberWithMarker(0xFB) def toVersion(self): """ Interpret this name component as a version number according to NDN naming conventions for "Versioning" (marker 0xFD). Note that this returns the exact number from the component without converting it to a time representation. http://named-data.net/doc/tech-memos/naming-conventions.pdf :return: The integer version number. :rtype: int :raises RuntimeError: If the first byte of the component is not the expected marker. """ return self.toNumberWithMarker(0xFD) def toTimestamp(self): """ Interpret this name component as a timestamp according to NDN naming conventions for "Timestamp" (marker 0xFC). http://named-data.net/doc/tech-memos/naming-conventions.pdf :return: The number of microseconds since the UNIX epoch (Thursday, 1 January 1970) not counting leap seconds. :rtype: int :raises RuntimeError: If the first byte of the component is not the expected marker. """ return self.toNumberWithMarker(0xFC) def toSequenceNumber(self): """ Interpret this name component as a sequence number according to NDN naming conventions for "Sequencing" (marker 0xFE). http://named-data.net/doc/tech-memos/naming-conventions.pdf :return: The integer sequence number. :rtype: int :raises RuntimeError: If the first byte of the component is not the expected marker. """ return self.toNumberWithMarker(0xFE) def equals(self, other): """ Check if this is the same component as other. :param Name.Component other: The other Component to compare with. :return: True if the components are equal, otherwise False. :rtype: bool """ return self._value.equals(other._value) def compare(self, other): """ Compare this to the other Component using NDN canonical ordering. :param Name.Component other: The other Component to compare with. :return: 0 If they compare equal, -1 if self comes before other in the canonical ordering, or 1 if self comes after other in the canonical ordering. :rtype: int :see: http://named-data.net/doc/0.2/technical/CanonicalOrder.html """ if self._value.size() < other._value.size(): return -1 if self._value.size() > other._value.size(): return 1 # The components are equal length. Just do a byte compare. return self._value.compare(other._value) @staticmethod def fromNumber(number): """ Create a component whose value is the nonNegativeInteger encoding of the number. :param int number: The number to be encoded. :return: The component value. :rtype: Name.Component """ encoder = TlvEncoder(8) encoder.writeNonNegativeInteger(number) return Name.Component(Blob(encoder.getOutput(), False)) @staticmethod def fromNumberWithMarker(number, marker): """ Create a component whose value is the marker appended with the nonNegativeInteger encoding of the number. :param int number: The number to be encoded. :param int marker: The marker to use as the first byte of the component. :return: The component value. :rtype: Name.Component """ encoder = TlvEncoder(9) # Encode backwards. encoder.writeNonNegativeInteger(number) encoder.writeNonNegativeInteger(marker) return Name.Component(Blob(encoder.getOutput(), False)) # Python operators def __eq__(self, other): return type(other) is Name.Component and self.equals(other) def __ne__(self, other): return not self == other def __le__(self, other): return self.compare(other) <= 0 def __lt__(self, other): return self.compare(other) < 0 def __ge__(self, other): return self.compare(other) >= 0 def __gt__(self, other): return self.compare(other) > 0 def __len__(self): return self._value.size()
def test_import_export(self): privateKeyPkcs1Base64 = ( "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n" + "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n" + "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n" + "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n" + "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n" + "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n" + "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n" + "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n" + "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n" + "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n" + "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n" + "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n" + "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n" + "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n" + "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n" + "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n" + "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n" + "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n" + "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n" + "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n" + "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n" + "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n" + "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n" + "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n" + "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n") for tpm in self.backEndList: if tpm is self.backEndOsx: # TODO: Implement TpmBackEndOsx import/export. continue keyName = Name("/Test/KeyName/KEY/1") tpm.deleteKey(keyName) self.assertEqual(False, tpm.hasKey(keyName)) privateKey = TpmPrivateKey() privateKeyPkcs1Encoding = Blob(base64.b64decode(privateKeyPkcs1Base64)) privateKey.loadPkcs1(privateKeyPkcs1Encoding.buf()) password = Blob("password").toBytes() encryptedPkcs8 = privateKey.toEncryptedPkcs8(password) tpm.importKey(keyName, encryptedPkcs8.buf(), password) self.assertEqual(True, tpm.hasKey(keyName)) try: # Can't import the same keyName again. tpm.importKey(keyName, encryptedPkcs8.buf(), password) self.fail("Did not throw the expected exception") except TpmBackEnd.Error: pass else: self.fail("Did not throw the expected exception") exportedKey = tpm.exportKey(keyName, password) self.assertEqual(True, tpm.hasKey(keyName)) privateKey2 = TpmPrivateKey() privateKey2.loadEncryptedPkcs8(exportedKey.buf(), password) privateKey2Pkcs1Encoding = privateKey2.toPkcs1() self.assertTrue(privateKeyPkcs1Encoding.equals(privateKey2Pkcs1Encoding)) tpm.deleteKey(keyName) self.assertEqual(False, tpm.hasKey(keyName)) try: tpm.exportKey(keyName, password) self.fail("Did not throw the expected exception") except TpmBackEnd.Error: pass else: self.fail("Did not throw the expected exception")
class KeyLocator(object): """ Create a new KeyLocator object, possibly copying values from another object. :param KeyLocator value: (optional) If value is a KeyLocator, copy its values. If value is omitted, set the fields to unspecified. """ def __init__(self, value = None): if value == None: self._type = None self._keyName = ChangeCounter(Name()) self._keyData = Blob() elif type(value) is KeyLocator: # Copy its values. self._type = value._type self._keyName = ChangeCounter(Name(value.getKeyName())) self._keyData = value._keyData else: raise RuntimeError( "Unrecognized type for KeyLocator constructor: " + repr(type(value))) self._changeCount = 0 def getType(self): """ Get the key locator type. If KeyLocatorType.KEYNAME, you may also getKeyName(). If KeyLocatorType.KEY_LOCATOR_DIGEST, you may also getKeyData() to get the digest. :return: The key locator type, or None if not specified. :rtype: an int from KeyLocatorType """ return self._type def getKeyName(self): """ Get the key name. This is meaningful if getType() is KeyLocatorType.KEYNAME. :return: The key name. If not specified, the Name is empty. :rtype: Name """ return self._keyName.get() def getKeyData(self): """ Get the key data. This is the digest bytes if getType() is KeyLocatorType.KEY_LOCATOR_DIGEST. :return: The key data as a Blob, which isNull() if unspecified. :rtype: Blob """ return self._keyData def setType(self, type): """ Set the key locator type. If KeyLocatorType.KEYNAME, you must also setKeyName(). If KeyLocatorType.KEY_LOCATOR_DIGEST, you must also setKeyData() to set the digest. :param type: The key locator type. If None, the type is unspecified. :type type: an int from KeyLocatorType """ self._type = None if type == None or type < 0 else type self._changeCount += 1 def setKeyName(self, keyName): """ Set key name to a copy of the given Name. This is the name if getType() is KeyLocatorType.KEYNAME. :param Name keyName: The key name which is copied. """ self._keyName.set(keyName if type(keyName) is Name else Name(keyName)) self._changeCount += 1 def setKeyData(self, keyData): """ Set the key data to the given value. This is the digest bytes if getType() is KeyLocatorType.KEY_LOCATOR_DIGEST. :param keyData: The array with the key data bytes. If keyData is not a Blob, then create a new Blob to copy the bytes (otherwise take another pointer to the same Blob). :type keyData: A Blob or an array type with int elements """ self._keyData = keyData if type(keyData) is Blob else Blob(keyData) self._changeCount += 1 def clear(self): """ Clear the fields and set the type to None. """ self._type = None self._keyName.get().clear() self._keyData = Blob() self._changeCount += 1 def getChangeCount(self): """ Get the change count, which is incremented each time this object (or a child object) is changed. :return: The change count. :rtype: int """ # Make sure each of the checkChanged is called. changed = self._keyName.checkChanged() if changed: # A child object has changed, so update the change count. self._changeCount += 1 return self._changeCount # Create managed properties for read/write properties of the class for more pythonic syntax. type = property(getType, setType) keyName = property(getKeyName, setKeyName) keyData = property(getKeyData, setKeyData) # Support property-based equivalence check # TODO: Desired syntax? def equals(self, other): if self is None and other is None: return True if other is None: return False if self._type != other._type: return False if self._keyName.get() != None and not self._keyName.get().equals(other._keyName.get()): return False if self._keyData != None and not self._keyData.equals(other._keyData): return False return True
def test_constructor(self): # Check default settings. content = EncryptedContent() self.assertEqual(content.getAlgorithmType(), None) self.assertTrue(content.getPayload().isNull()) self.assertTrue(content.getInitialVector().isNull()) self.assertEqual(content.getKeyLocator().getType(), None) # Check an encrypted content with IV. keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.getKeyName().set("/test/key/locator") rsaOaepContent = EncryptedContent() rsaOaepContent.setAlgorithmType(EncryptAlgorithmType.RsaOaep).setKeyLocator( keyLocator).setPayload(Blob(message, False)).setInitialVector(Blob(iv, False)) self.assertEqual(rsaOaepContent.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContent.getPayload().equals(Blob(message, False))) self.assertTrue(rsaOaepContent.getInitialVector().equals(Blob(iv, False))) self.assertTrue(rsaOaepContent.getKeyLocator().getType() != None) self.assertTrue(rsaOaepContent.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) # Encoding. encryptedBlob = Blob(encrypted, False) encoded = rsaOaepContent.wireEncode() self.assertTrue(encryptedBlob.equals(encoded)) # Decoding. rsaOaepContent2 = EncryptedContent() rsaOaepContent2.wireDecode(encryptedBlob) self.assertEqual(rsaOaepContent2.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContent2.getPayload().equals(Blob(message, False))) self.assertTrue(rsaOaepContent2.getInitialVector().equals(Blob(iv, False))) self.assertTrue(rsaOaepContent2.getKeyLocator().getType() != None) self.assertTrue(rsaOaepContent2.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) # Check the no IV case. rsaOaepContentNoIv = EncryptedContent() rsaOaepContentNoIv.setAlgorithmType(EncryptAlgorithmType.RsaOaep).setKeyLocator( keyLocator).setPayload(Blob(message, False)) self.assertEqual(rsaOaepContentNoIv.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContentNoIv.getPayload().equals(Blob(message, False))) self.assertTrue(rsaOaepContentNoIv.getInitialVector().isNull()) self.assertTrue(rsaOaepContentNoIv.getKeyLocator().getType() != None) self.assertTrue(rsaOaepContentNoIv.getKeyLocator().getKeyName().equals( Name("/test/key/locator"))) # Encoding. encryptedBlob2 = Blob(encryptedNoIv, False) encodedNoIv = rsaOaepContentNoIv.wireEncode() self.assertTrue(encryptedBlob2.equals(encodedNoIv)) # Decoding. rsaOaepContentNoIv2 = EncryptedContent() rsaOaepContentNoIv2.wireDecode(encryptedBlob2) self.assertEqual(rsaOaepContentNoIv2.getAlgorithmType(), EncryptAlgorithmType.RsaOaep) self.assertTrue(rsaOaepContentNoIv2.getPayload().equals(Blob(message, False))) self.assertTrue(rsaOaepContentNoIv2.getInitialVector().isNull()) self.assertTrue(rsaOaepContentNoIv2.getKeyLocator().getType() != None) self.assertTrue(rsaOaepContentNoIv2.getKeyLocator().getKeyName().equals( Name("/test/key/locator")))
def test_content_asymmetric_encrypt_large(self): for input in encryptorRsaTestInputs: largeContent = Blob(bytearray([ 0x73, 0x5a, 0xbd, 0x47, 0x0c, 0xfe, 0xf8, 0x7d, 0x2e, 0x17, 0xaa, 0x11, 0x6f, 0x23, 0xc5, 0x10, 0x23, 0x36, 0x88, 0xc4, 0x2a, 0x0f, 0x9a, 0x72, 0x54, 0x31, 0xa8, 0xb3, 0x51, 0x18, 0x9f, 0x0e, 0x1b, 0x93, 0x62, 0xd9, 0xc4, 0xf5, 0xf4, 0x3d, 0x61, 0x9a, 0xca, 0x05, 0x65, 0x6b, 0xc6, 0x41, 0xf9, 0xd5, 0x1c, 0x67, 0xc1, 0xd0, 0xd5, 0x6f, 0x7b, 0x70, 0xb8, 0x8f, 0xdb, 0x19, 0x68, 0x7c, 0xe0, 0x2d, 0x04, 0x49, 0xa9, 0xa2, 0x77, 0x4e, 0xfc, 0x60, 0x0d, 0x7c, 0x1b, 0x93, 0x6c, 0xd2, 0x61, 0xc4, 0x6b, 0x01, 0xe9, 0x12, 0x28, 0x6d, 0xf5, 0x78, 0xe9, 0x99, 0x0b, 0x9c, 0x4f, 0x90, 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f, 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48, 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5, 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde, 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9, 0x22, 0xf1, 0x67, 0x76, 0x71, 0x0c, 0xff, 0x99, 0x7b, 0x94, 0x9b, 0x24, 0x20, 0x80, 0xe3, 0xcc, 0x06, 0x4a, 0xed, 0xdf, 0xec, 0x50, 0xd5, 0x87, 0x3d, 0xa0, 0x7d, 0x9c, 0xe5, 0x13, 0x10, 0x98, 0x14, 0xc3, 0x90, 0x10, 0xd9, 0x25, 0x9a, 0x59, 0xe9, 0x37, 0x26, 0xfd, 0x87, 0xd7, 0xf4, 0xf9, 0x11, 0x91, 0xad, 0x5c, 0x00, 0x95, 0xf5, 0x2b, 0x37, 0xf7, 0x4e, 0xb4, 0x4b, 0x42, 0x7c, 0xb3, 0xad, 0xd6, 0x33, 0x5f, 0x0b, 0x84, 0x57, 0x7f, 0xa7, 0x07, 0x73, 0x37, 0x4b, 0xab, 0x2e, 0xfb, 0xfe, 0x1e, 0xcb, 0xb6, 0x4a, 0xc1, 0x21, 0x5f, 0xec, 0x92, 0xb7, 0xac, 0x97, 0x75, 0x20, 0xc9, 0xd8, 0x9e, 0x93, 0xd5, 0x12, 0x7a, 0x64, 0xb9, 0x4c, 0xed, 0x49, 0x87, 0x44, 0x5b, 0x4f, 0x90, 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f, 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48, 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5, 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde, 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9 ]), False) data = Data() rsaParams = RsaKeyParams(1024) keyName = Name("test") decryptKey = RsaAlgorithm.generateKey(rsaParams) encryptKey = RsaAlgorithm.deriveEncryptKey(decryptKey.getKeyBits()) eKey = encryptKey.getKeyBits() dKey = decryptKey.getKeyBits() encryptParams = EncryptParams(input.type) Encryptor.encryptData(data, largeContent, keyName, eKey, encryptParams) self.assertTrue(data.getName().equals(Name("/FOR").append(keyName)), input.testName) largeDataContent = data.getContent() # largeDataContent is a sequence of the two EncryptedContent. encryptedNonce = EncryptedContent() encryptedNonce.wireDecode(largeDataContent) self.assertTrue(keyName.equals(encryptedNonce.getKeyLocator().getKeyName()), input.testName) self.assertEqual(encryptedNonce.getInitialVector().size(), 0, input.testName) self.assertEqual(encryptedNonce.getAlgorithmType(), input.type, input.testName) # Use the size of encryptedNonce to find the start of encryptedPayload. payloadContent = largeDataContent.buf()[encryptedNonce.wireEncode().size():] encryptedPayload = EncryptedContent() encryptedPayload.wireDecode(payloadContent) nonceKeyName = Name(keyName) nonceKeyName.append("nonce") self.assertTrue(nonceKeyName.equals(encryptedPayload.getKeyLocator().getKeyName()), input.testName) self.assertEqual(encryptedPayload.getInitialVector().size(), 16, input.testName) self.assertEqual(encryptedPayload.getAlgorithmType(), EncryptAlgorithmType.AesCbc, input.testName) self.assertEqual( largeDataContent.size(), encryptedNonce.wireEncode().size() + encryptedPayload.wireEncode().size(), input.testName) blobNonce = encryptedNonce.getPayload() nonce = RsaAlgorithm.decrypt(dKey, blobNonce, encryptParams) encryptParams.setAlgorithmType(EncryptAlgorithmType.AesCbc) encryptParams.setInitialVector(encryptedPayload.getInitialVector()) bufferPayload = encryptedPayload.getPayload() largePayload = AesAlgorithm.decrypt(nonce, bufferPayload, encryptParams) self.assertTrue(largeContent.equals(largePayload), input.testName)
class Component(object): """ Create a new Name.Component. :param value: (optional) If value is already a Blob or Name.Component, then take another pointer to the value. Otherwise, create a new Blob with a copy of the value. If omitted, create an empty component. :type value: Blob or Name.Component or value for Blob constructor """ def __init__(self, value = None): if type(value) is Name.Component: # Use the existing Blob in the other Component. self._value = value._value elif value == None: self._value = Blob([]) else: # Blob will make a copy. self._value = value if isinstance(value, Blob) else Blob(value) def getValue(self): """ Get the value of the component. :return: The component value. :rtype: Blob """ return self._value def toEscapedString(self, result = None): """ Convert this component to a string, escaping characters according to the NDN URI Scheme. This also adds "..." to a value with zero or more ".". :param BytesIO result: (optional) The BytesIO stream to write to. If omitted, return a str with the result. :return: The result as a string (only if result is omitted). :rtype: str """ if result == None: return Name.toEscapedString(self._value.buf()) else: Name.toEscapedString(self._value.buf(), result) def toNumber(self): """ Interpret this name component as a network-ordered number and return an integer. :return: The integer number. :rtype: int """ result = 0 for i in range(self._value.size()): result *= 256 result += self._value.buf()[i] return result def toNumberWithMarker(self, marker): """ Interpret this name component as a network-ordered number with a marker and return an integer. :param int marker: The required first byte of the component. :return: The integer number. :rtype: int :raises RuntimeError: If the first byte of the component does not equal the marker. """ if self._value.size() <= 0 or self._value.buf()[0] != marker: raise RuntimeError( "Name component does not begin with the expected marker") result = 0 for i in range(1, self._value.size()): result *= 256 result += self._value.buf()[i] return result def toSegment(self): """ Interpret this name component as a segment number according to NDN name conventions (a network-ordered number where the first byte is the marker 0x00). :return: The integer segment number. :rtype: int :raises RuntimeError: If the first byte of the component is not the expected marker. """ return self.toNumberWithMarker(0x00) def toVersion(self): """ Interpret this name component as a version number according to NDN name conventions (a network-ordered number where the first byte is the marker 0xFD). Note that this returns the exact number from the component without converting it to a time representation. :return: The integer version number. :rtype: int :raises RuntimeError: If the first byte of the component is not the expected marker. """ return self.toNumberWithMarker(0xFD) def equals(self, other): """ Check if this is the same component as other. :param Name.Component other: The other Component to compare with. :return: True if the components are equal, otherwise False. :rtype: bool """ return self._value.equals(other._value) def compare(self, other): """ Compare this to the other Component using NDN canonical ordering. :param Name.Component other: The other Component to compare with. :return: 0 If they compare equal, -1 if self comes before other in the canonical ordering, or 1 if self comes after other in the canonical ordering. :rtype: int :see: http://named-data.net/doc/0.2/technical/CanonicalOrder.html """ if self._value.size() < other._value.size(): return -1 if self._value.size() > other._value.size(): return 1 # The components are equal length. Just do a byte compare. return self._value.compare(other._value) @staticmethod def fromNumber(number): """ Create a component whose value is the network-ordered encoding of the number. Note: if the number is zero, the result is empty. :param int number: The number to be encoded. :return: The component value. :rtype: Name.Component """ value = [] # First encode in little endian. while number != 0: value.append(number & 0xff) number >>= 8 # Make it big endian. value.reverse() return Name.Component(Blob(value, False)) @staticmethod def fromNumberWithMarker(number, marker): """ Create a component whose value is the marker appended with the network-ordered encoding of the number. Note: if the number is zero, no bytes are used for the number - the result will have only the marker. :param int number: The number to be encoded. :param int marker: The marker to use as the first byte of the component. :return: The component value. :rtype: Name.Component """ value = [] # First encode in little endian. while number != 0: value.append(number & 0xff) number >>= 8 # Make it big endian. value.reverse() # Prepend the leading marker. value.insert(0, marker) return Name.Component(Blob(value, False)) # Python operators def __eq__(self, other): return type(other) is Name.Component and self.equals(other) def __ne__(self, other): return not self == other def __le__(self, other): return self.compare(other) <= 0 def __lt__(self, other): return self.compare(other) < 0 def __ge__(self, other): return self.compare(other) >= 0 def __gt__(self, other): return self.compare(other) > 0