def wireDecode(self, input, wireFormat=None): """ Decode the input using a particular wire format and update this Interest. If wireFormat is the default wire format, also set the defaultWireEncoding to another pointer to the input. :param input: The array with the bytes to decode. If input is not a Blob, then copy the bytes to save the defaultWireEncoding (otherwise take another pointer to the same Blob). :type input: A Blob or an array type with int elements :param wireFormat: (optional) A WireFormat object used to decode this Interest. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() # If input is a Blob, get its buf(). decodeBuffer = input.buf() if isinstance(input, Blob) else input (signedPortionBeginOffset, signedPortionEndOffset) = wireFormat.decodeInterest(self, decodeBuffer) if wireFormat == WireFormat.getDefaultWireFormat(): # This is the default wire encoding. In the Blob constructor, set # copy true, but if input is already a Blob, it won't copy. self._setDefaultWireEncoding( SignedBlob(Blob(input, True), signedPortionBeginOffset, signedPortionEndOffset), WireFormat.getDefaultWireFormat(), ) else: self._setDefaultWireEncoding(SignedBlob(), None)
def wireEncode(self, wireFormat=None): """ Encode this Interest for a particular wire format. If wireFormat is the default wire format, also set the defaultWireEncoding field to the encoded result. :param wireFormat: (optional) A WireFormat object used to encode this Interest. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat :return: The encoded buffer. :rtype: Blob """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() if not self.getDefaultWireEncoding().isNull() and self.getDefaultWireEncodingFormat() == wireFormat: # We already have an encoding in the desired format. return self.getDefaultWireEncoding() (encoding, signedPortionBeginOffset, signedPortionEndOffset) = wireFormat.encodeInterest(self) wireEncoding = SignedBlob(encoding, signedPortionBeginOffset, signedPortionEndOffset) if wireFormat == WireFormat.getDefaultWireFormat(): # This is the default wire encoding. self._setDefaultWireEncoding(wireEncoding, WireFormat.getDefaultWireFormat()) return wireEncoding
def signByCertificate(self, data, certificateName, wireFormat = None): """ Sign data packet based on the certificate name. :param Data data: The Data object to sign and update its signature. :param Name certificateName: The Name identifying the certificate which identifies the signing key. :param wireFormat: (optional) The WireFormat for calling encodeData, or WireFormat.getDefaultWireFormat() if omitted. :type wireFormat: A subclass of WireFormat """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() keyName = self.certificateNameToPublicKeyName(certificateName) publicKey = self._privateKeyStorage.getPublicKey(keyName) # For temporary usage, we support RSA + SHA256 only, but will support more. data.setSignature(Sha256WithRsaSignature()) # Get a pointer to the clone which Data made. signature = data.getSignature() signature.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)) # Encode once to get the signed portion. encoding = data.wireEncode(wireFormat) signature.setSignature(self._privateKeyStorage.sign (encoding.toSignedBuffer(), keyName)) # Encode again to include the signature. data.wireEncode(wireFormat)
def signInterest(self, interest, keyName=None, wireFormat=None): # Adds the nonce and timestamp here, because there is no # 'makeCommandInterest' call for this yet nonceValue = bytearray(8) for i in range(8): nonceValue[i] = self.random.randint(0, 0xff) timestampValue = bytearray(8) ts = int(timestamp() * 1000) for i in range(8): byte = ts & 0xff timestampValue[-(i + 1)] = byte ts = ts >> 8 if wireFormat is None: wireFormat = WireFormat.getDefaultWireFormat() s = HmacWithSha256Signature() s.getKeyLocator().setType(KeyLocatorType.KEYNAME) s.getKeyLocator().setKeyName(keyName) interestName = interest.getName() interestName.append(nonceValue).append(timestampValue) interestName.append(wireFormat.encodeSignatureInfo(s)) interestName.append(Name.Component()) encoding = interest.wireEncode(wireFormat) signer = hmac.new(self.key, encoding.toSignedBuffer(), sha256) s.setSignature(Blob(signer.digest())) interest.setName( interestName.getPrefix(-1).append( wireFormat.encodeSignatureValue(s)))
def signInterest(self, interest, keyName=None, wireFormat=None): # Adds the nonce and timestamp here, because there is no # 'makeCommandInterest' call for this yet nonceValue = bytearray(8) for i in range(8): nonceValue[i] = self.random.randint(0,0xff) timestampValue = bytearray(8) ts = int(timestamp()*1000) for i in range(8): byte = ts & 0xff timestampValue[-(i+1)] = byte ts = ts >> 8 if wireFormat is None: wireFormat = WireFormat.getDefaultWireFormat() s = Sha256HmacSignature() s.getKeyLocator().setType(KeyLocatorType.KEYNAME) s.getKeyLocator().setKeyName(keyName) interestName = interest.getName() interestName.append(nonceValue).append(timestampValue) interestName.append(wireFormat.encodeSignatureInfo(s)) interestName.append(Name.Component()) encoding = interest.wireEncode(wireFormat) signer = hmac.new(self.key, encoding.toSignedBuffer(), sha256) s.setSignature(Blob(signer.digest())) interest.setName(interestName.getPrefix(-1).append( wireFormat.encodeSignatureValue(s)))
def __init__(self, raw_key, wireFormat=None): super(HmacHelper, self).__init__() self.key = sha256(raw_key).digest() self.random = SystemRandom() if wireFormat is None: self.wireFormat = WireFormat.getDefaultWireFormat() else: self.wireFormat = wireFormat
def verifyInterest(self, interest, wireFormat=None): if wireFormat is None: wireFormat = WireFormat.getDefaultWireFormat() signature = self.extractInterestSignature(interest, wireFormat) encoding = interest.wireEncode(wireFormat) hasher = hmac.new(self.key, encoding.toSignedBuffer(), sha256) return signature.getSignature().toRawStr() == hasher.digest()
def verifyData(self, data, wireFormat=None): # clear out old signature so encoding does not include it if wireFormat is None: wireFormat = WireFormat.getDefaultWireFormat() encoded = data.wireEncode(wireFormat) hasher = hmac.new(self.key, bytearray(encoded.toSignedBuffer()), sha256) sigBytes = data.getSignature().getSignature() return sigBytes.toRawStr() == hasher.digest()
def signByCertificate(self, target, certificateName, wireFormat=None): """ Sign the target based on the certificateName. If it is a Data object, set its signature. If it is an array, return a signature object. :param target: If this is a Data object, wire encode for signing, update its signature and key locator field and wireEncoding. If it is an array, sign it and return a Signature object. :param Name certificateName: The Name identifying the certificate which identifies the signing key. :param wireFormat: (optional) The WireFormat for calling encodeData, or WireFormat.getDefaultWireFormat() if omitted. :type wireFormat: A subclass of WireFormat :return: The Signature object (only if the target is an array). :rtype: An object of a subclass of Signature """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() if isinstance(target, Data): data = target keyName = self.certificateNameToPublicKeyName(certificateName) # For temporary usage, we support RSA + SHA256 only, but will support more. data.setSignature(Sha256WithRsaSignature()) # Get a pointer to the clone which Data made. signature = data.getSignature() signature.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)) # Encode once to get the signed portion. encoding = data.wireEncode(wireFormat) signature.setSignature( self._privateKeyStorage.sign(encoding.toSignedBuffer(), keyName)) # Encode again to include the signature. data.wireEncode(wireFormat) else: keyName = self.certificateNameToPublicKeyName(certificateName) # For temporary usage, we support RSA + SHA256 only, but will support more. signature = Sha256WithRsaSignature() signature.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)) signature.setSignature( self._privateKeyStorage.sign(target, keyName)) return signature
def extractInterestSignature(cls, interest, wireFormat=None): if wireFormat is None: wireFormat = WireFormat.getDefaultWireFormat() try: signature = wireFormat.decodeSignatureInfoAndValue( interest.getName().get(-2).getValue().buf(), interest.getName().get(-1).getValue().buf()) except: signature = None return signature
def signByCertificate(self, target, certificateName, wireFormat = None): """ Sign the target based on the certificateName. If it is a Data object, set its signature. If it is an array, return a signature object. :param target: If this is a Data object, wire encode for signing, update its signature and key locator field and wireEncoding. If it is an array, sign it and return a Signature object. :param Name certificateName: The Name identifying the certificate which identifies the signing key. :param wireFormat: (optional) The WireFormat for calling encodeData, or WireFormat.getDefaultWireFormat() if omitted. :type wireFormat: A subclass of WireFormat :return: The Signature object (only if the target is an array). :rtype: An object of a subclass of Signature """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() if isinstance(target, Data): data = target keyName = self.certificateNameToPublicKeyName(certificateName) # For temporary usage, we support RSA + SHA256 only, but will support more. data.setSignature(Sha256WithRsaSignature()) # Get a pointer to the clone which Data made. signature = data.getSignature() signature.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)) # Encode once to get the signed portion. encoding = data.wireEncode(wireFormat) signature.setSignature(self._privateKeyStorage.sign (encoding.toSignedBuffer(), keyName)) # Encode again to include the signature. data.wireEncode(wireFormat) else: keyName = self.certificateNameToPublicKeyName(certificateName) # For temporary usage, we support RSA + SHA256 only, but will support more. signature = Sha256WithRsaSignature() signature.getKeyLocator().setType(KeyLocatorType.KEYNAME) signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)) signature.setSignature( self._privateKeyStorage.sign(target, keyName)) return signature
def signData(self, data, keyName=None, wireFormat=None): data.setSignature(Sha256HmacSignature()) s = data.getSignature() s.getKeyLocator().setType(KeyLocatorType.KEYNAME) s.getKeyLocator().setKeyName(keyName) if wireFormat is None: wireFormat = WireFormat.getDefaultWireFormat() encoded = data.wireEncode(wireFormat) signer = hmac.new(self.key, bytearray(encoded.toSignedBuffer()), sha256) s.setSignature(Blob(signer.digest())) data.wireEncode(wireFormat)
def checkVerificationPolicy(self, dataOrInterest, stepCount, onVerified, onVerifyFailed, wireFormat = None): """ Look in the IdentityStorage for the public key with the name in the KeyLocator (if available) and use it to verify the data packet or signed interest. If the public key can't be found, call onVerifyFailed. :param dataOrInterest: The Data object or interest with the signature to check. :type dataOrInterest: Data or Interest :param int stepCount: The number of verification steps that have been done, used to track the verification progress. :param onVerified: If the signature is verified, this calls onVerified(dataOrInterest). :type onVerified: function object :param onVerifyFailed: If the signature check fails, this calls onVerifyFailed(dataOrInterest). :type onVerifyFailed: function object :return: None for no further step for looking up a certificate chain. :rtype: ValidationRequest """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() if isinstance(dataOrInterest, Data): data = dataOrInterest # wireEncode returns the cached encoding if available. if self._verify(data.getSignature(), data.wireEncode()): onVerified(data) else: onVerifyFailed(data) elif isinstance(dataOrInterest, Interest): interest = dataOrInterest # Decode the last two name components of the signed interest signature = wireFormat.decodeSignatureInfoAndValue( interest.getName().get(-2).getValue().buf(), interest.getName().get(-1).getValue().buf()) # wireEncode returns the cached encoding if available. if self._verify(signature, interest.wireEncode()): onVerified(interest) else: onVerifyFailed(interest) else: raise RuntimeError( "checkVerificationPolicy: unrecognized type for dataOrInterest") # No more steps, so return a None. return None
def signData(self, data, keyName=None, wireFormat=None): data.setSignature(HmacWithSha256Signature()) s = data.getSignature() s.getKeyLocator().setType(KeyLocatorType.KEYNAME) s.getKeyLocator().setKeyName(keyName) if wireFormat is None: wireFormat = WireFormat.getDefaultWireFormat() encoded = data.wireEncode(wireFormat) signer = hmac.new(self.key, bytearray(encoded.toSignedBuffer()), sha256) s.setSignature(Blob(signer.digest())) data.wireEncode(wireFormat)
def wireEncode(self, wireFormat=None): """ Encode this ControlParameters for a particular wire format. :param wireFormat: (optional) A WireFormat object used to encode this ControlParameters. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat :return: The encoded buffer. :rtype: Blob """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() return wireFormat.encodeControlParameters(self)
def wireEncode(self, wireFormat = None): """ Encode this ForwardingEntry for a particular wire format. :param wireFormat: (optional) A WireFormat object used to encode this ForwardingEntry. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat :return: The encoded buffer. :rtype: Blob """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() return wireFormat.encodeForwardingEntry(self)
def wireEncode(self, wireFormat=None): """ Encode this Interest for a particular wire format. :param wireFormat: (optional) A WireFormat object used to encode this Interest. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat :return: The encoded buffer. :rtype: Blob """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() (encoding, signedPortionBeginOffset, signedPortionEndOffset) = wireFormat.encodeInterest(self) return SignedBlob(encoding, signedPortionBeginOffset, signedPortionEndOffset)
def wireDecode(self, input, wireFormat=None): """ Decode the input using a particular wire format and update this Interest. :param input: The array with the bytes to decode. :type input: An array type with int elements :param wireFormat: (optional) A WireFormat object used to decode this Interest. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() # If input is a blob, get its buf(). decodeBuffer = input.buf() if isinstance(input, Blob) else input wireFormat.decodeInterest(self, decodeBuffer)
def wireDecode(self, input, wireFormat = None): """ Decode the input using a particular wire format and update this Interest. :param input: The array with the bytes to decode. :type input: An array type with int elements :param wireFormat: (optional) A WireFormat object used to decode this Interest. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() # If input is a blob, get its buf(). decodeBuffer = input.buf() if isinstance(input, Blob) else input wireFormat.decodeInterest(self, decodeBuffer)
def wireEncode(self, wireFormat=None): """ Encode this Interest for a particular wire format. :param wireFormat: (optional) A WireFormat object used to encode this Interest. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat :return: The encoded buffer. :rtype: Blob """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() (encoding, signedPortionBeginOffset, signedPortionEndOffset) = \ wireFormat.encodeInterest(self) return SignedBlob(encoding, signedPortionBeginOffset, signedPortionEndOffset)
def _extractSignature(dataOrInterest, wireFormat=None): """ Extract the signature information from the interest name or from the data packet. :param dataOrInterest: The object whose signature is needed. :type dataOrInterest: Data or Interest :param WireFormat wireFormat: (optional) The wire format used to decode signature information from the interest name. """ if isinstance(dataOrInterest, Data): return dataOrInterest.getSignature() elif isinstance(dataOrInterest, Interest): if wireFormat is None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() try: signature = wireFormat.decodeSignatureInfoAndValue( dataOrInterest.getName().get(-2).getValue().buf(), dataOrInterest.getName().get(-1).getValue().buf()) except (IndexError, ValueError): return None return signature return None