def test_rsa_signing(self): for tpm in self.backEndList: # Create an RSA key. identityName = Name("/Test/KeyName") key = tpm.createKey(identityName, RsaKeyParams()) keyName = key.getKeyName() content = Blob([0x01, 0x02, 0x03, 0x04]) signature = key.sign(DigestAlgorithm.SHA256, content.toBytes()) publicKey = key.derivePublicKey() # TODO: Move verify to PublicKey? result = PolicyManager._verifySha256WithRsaSignature( signature, SignedBlob(content, 0, content.size()), publicKey) self.assertEquals(True, result) tpm.deleteKey(keyName) self.assertEquals(False, tpm.hasKey(keyName))
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()
class ContentMetaInfo(object): """ Create a new ContentMetaInfo object, possibly copying values from another object. :param ContentMetaInfo value: (optional) If value is a ContentMetaInfo, copy its values. If value is omitted, set all the fields to their default unspecified values. """ def __init__(self, value=None): if value == None: self.clear() elif isinstance(value, ContentMetaInfo): # Copy its values. self._contentType = value._contentType self._timestamp = value._timestamp self._hasSegments = value._hasSegments self._other = value._other else: raise RuntimeError( "Unrecognized type for ContentMetaInfo constructor: " + str(type(value))) def getContentType(self): """ Get the content type. :return: The content type. If not specified, return an empty string. :rtype: str """ return self._contentType def getTimestamp(self): """ Get the time stamp. :return: The time stamp as milliseconds since Jan 1, 1970 UTC. If not specified, return None. :rtype: float """ return self._timestamp def getHasSegments(self): """ Get the hasSegments flag. :return: The hasSegments flag. :rtype: bool """ return self._hasSegments def getOther(self): """ Get the Blob containing the optional other info. :return: The other info. If not specified, return an isNull Blob. :rtype: Blob """ return self._other def setContentType(self, contentType): """ Set the content type. :param str contentType: The content type. :return: This ContentMetaInfo so that you can chain calls to update values. :rtype: ContentMetaInfo """ self._contentType = contentType return self def setTimestamp(self, timestamp): """ Set the time stamp. :param float timestamp: The time stamp. :return: This ContentMetaInfo so that you can chain calls to update values. :rtype: ContentMetaInfo """ self._timestamp = Common.nonNegativeFloatOrNone(timestamp) return self def setHasSegments(self, hasSegments): """ Set the hasSegments flag. :param bool hasSegments: The hasSegments flag. :return: This ContentMetaInfo so that you can chain calls to update values. :rtype: ContentMetaInfo """ self._hasSegments = hasSegments return self def setOther(self, other): """ Set the Blob containing the optional other info. :param Blob other: The other info, or a default null Blob() if not specified. :return: This ContentMetaInfo so that you can chain calls to update values. :rtype: ContentMetaInfo """ self._other = other if isinstance(other, Blob) else Blob(other) return self def clear(self): """ Set all the fields to their default unspecified values. """ self._contentType = "" self._timestamp = None self._hasSegments = False self._other = Blob() def wireEncode(self): """ Encode this ContentMetaInfo. :return: The encoding Blob. :rtype: Blob """ if self._timestamp == None: raise RuntimeError( "The ContentMetaInfo timestamp is not specified") meta = ContentMetaInfoMessage() meta.content_meta_info.content_type = self._contentType meta.content_meta_info.timestamp = int(round(self._timestamp)) meta.content_meta_info.has_segments = self._hasSegments if not self._other.isNull() and self._other.size() > 0: meta.content_meta_info.other = self._other.toBytes() return ProtobufTlv.encode(meta) def wireDecode(self, input): """ Decode the input and update this ContentMetaInfo. :param input: The array with the bytes to decode. :type input: An array type with int elements """ meta = ContentMetaInfoMessage() ProtobufTlv.decode(meta, input) self.clear() self._contentType = meta.content_meta_info.content_type self._timestamp = float(meta.content_meta_info.timestamp) self._hasSegments = meta.content_meta_info.has_segments if len(meta.content_meta_info.other) > 0: self._other = Blob(bytearray(meta.content_meta_info.other), False) # Create managed properties for read/write properties of the class for more pythonic syntax. contentType = property(getContentType, setContentType) timestamp = property(getTimestamp, setTimestamp) hasSegments = property(getHasSegments, setHasSegments) other = property(getOther, setOther)
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