def __init__(self, value=None): if type(value) is Interest: # Copy the values. self._name = ChangeCounter(Name(value.getName())) self._minSuffixComponents = value._minSuffixComponents self._maxSuffixComponents = value._maxSuffixComponents self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._exclude = ChangeCounter(Exclude(value.getExclude())) self._childSelector = value._childSelector self._mustBeFresh = value._mustBeFresh self._nonce = value.getNonce() self._scope = value._scope self._interestLifetimeMilliseconds = value._interestLifetimeMilliseconds else: self._name = ChangeCounter( Name(value) if type(value) is Name else Name()) self._minSuffixComponents = None self._maxSuffixComponents = None self._keyLocator = ChangeCounter(KeyLocator()) self._exclude = ChangeCounter(Exclude()) self._childSelector = None self._mustBeFresh = True self._nonce = Blob() self._scope = None self._interestLifetimeMilliseconds = None self._getNonceChangeCount = 0 self._changeCount = 0
def _encryptSymmetric(payload, key, keyName, params): """ Encrypt the payload using the symmetric key according to params, and return an EncryptedContent. :param Blob payload: The data to encrypt. :param Blob key: The key value. :param Name keyName: The key name for the EncryptedContent key locator. :param EncryptParams params: The parameters for encryption. :return: A new EncryptedContent. :rtype: EncryptedContent """ algorithmType = params.getAlgorithmType() initialVector = params.getInitialVector() keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.setKeyName(keyName) if (algorithmType == EncryptAlgorithmType.AesCbc or algorithmType == EncryptAlgorithmType.AesEcb): if (algorithmType == EncryptAlgorithmType.AesCbc): if initialVector.size() != AesAlgorithm.BLOCK_SIZE: raise RuntimeError("incorrect initial vector size") encryptedPayload = AesAlgorithm.encrypt(key, payload, params) result = EncryptedContent() result.setAlgorithmType(algorithmType) result.setKeyLocator(keyLocator) result.setPayload(encryptedPayload) result.setInitialVector(initialVector) return result else: raise RuntimeError("Unsupported encryption method")
def _verify(self, signatureInfo, signedBlob, failureReason): """ Check the type of signatureInfo to get the KeyLocator. Look in the IdentityStorage for the public key with the name in the KeyLocator and use it to verify the signedBlob. If the public key can't be found, return false. (This is a generalized method which can verify both a Data packet and an interest.) :param Signature signatureInfo: An object of a subclass of Signature, e.g. Sha256WithRsaSignature. :param SignedBlob signedBlob: the SignedBlob with the signed portion to verify. :param Array<str> failureReason: If verification fails, set failureReason[0] to the failure reason string. :return: True if the signature verifies, False if not. :rtype: boolean """ publicKeyDer = None if KeyLocator.canGetFromSignature(signatureInfo): publicKeyDer = self._getPublicKeyDer( KeyLocator.getFromSignature(signatureInfo), failureReason) if publicKeyDer.isNull(): return False if self.verifySignature( signatureInfo, signedBlob, publicKeyDer): return True else: failureReason[0] = ( "The signature did not verify with the given public key") return False
def _encryptAsymmetric(payload, key, keyName, params): """ Encrypt the payload using the asymmetric key according to params, and return an EncryptedContent. :param Blob payload: The data to encrypt. The size should be within range of the key. :param Blob key: The key value. :param Name keyName: The key name for the EncryptedContent key locator. :param EncryptParams params: The parameters for encryption. :return: A new EncryptedContent. :rtype: EncryptedContent """ algorithmType = params.getAlgorithmType() keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.setKeyName(keyName) if (algorithmType == EncryptAlgorithmType.RsaPkcs or algorithmType == EncryptAlgorithmType.RsaOaep): encryptedPayload = RsaAlgorithm.encrypt(key, payload, params) result = EncryptedContent() result.setAlgorithmType(algorithmType) result.setKeyLocator(keyLocator) result.setPayload(encryptedPayload) return result else: raise RuntimeError("Unsupported encryption method")
def _verify(self, signatureInfo, signedBlob, failureReason): """ Check the type of signatureInfo to get the KeyLocator. Look in the IdentityStorage for the public key with the name in the KeyLocator and use it to verify the signedBlob. If the public key can't be found, return false. (This is a generalized method which can verify both a Data packet and an interest.) :param Signature signatureInfo: An object of a subclass of Signature, e.g. Sha256WithRsaSignature. :param SignedBlob signedBlob: the SignedBlob with the signed portion to verify. :param Array<str> failureReason: If verification fails, set failureReason[0] to the failure reason string. :return: True if the signature verifies, False if not. :rtype: boolean """ publicKeyDer = None if KeyLocator.canGetFromSignature(signatureInfo): publicKeyDer = self._getPublicKeyDer( KeyLocator.getFromSignature(signatureInfo), failureReason) if publicKeyDer.isNull(): return False if self.verifySignature(signatureInfo, signedBlob, publicKeyDer): return True else: failureReason[0] = ( "The signature did not verify with the given public key") return False
def clear(self): """ Set all the fields to indicate unspecified values. """ self._algorithmType = None self._keyLocator = KeyLocator() self._initialVector = Blob() self._payload = Blob() self._payloadKey = Blob()
def __init__(self, value=None): if isinstance(value, EncryptedContent): # Make a deep copy. self._algorithmType = value._algorithmType self._keyLocator = KeyLocator(value._keyLocator) self._initialVector = value._initialVector self._payload = value._payload self._payloadKey = value._payloadKey else: self.clear()
def setKeyLocator(self, keyLocator): """ Set this interest to use a copy of the given keyLocator. Note: You can also change this interest's key locator modifying the object from getKeyLocator(). :param KeyLocator keyLocator: The KeyLocator that is copied. """ self._keyLocator.set(keyLocator if type(keyLocator) is KeyLocator( keyLocator) else KeyLocator()) self._changeCount += 1
def __init__(self, value=None): if type(value) is EncryptedContent: # Make a deep copy. self._algorithmType = value._algorithmType self._keyLocator = KeyLocator(value._keyLocator) self._initialVector = value._initialVector self._payload = value._payload else: self._algorithmType = None self._keyLocator = KeyLocator() self._initialVector = Blob() self._payload = Blob()
def setKeyLocator(self, keyLocator): """ Set the key locator. :param KeyLocator keyLocator: The key locator. This makes a copy of the object. If not specified, set to the default KeyLocator(). :return: This EncryptedContent so that you can chain calls to update values. :rtype: EncryptedContent """ self._keyLocator = (KeyLocator(keyLocator) if type(keyLocator) is KeyLocator else KeyLocator()) return self
def __init__(self, value=None): if isinstance(value, Interest): # Copy the values. self._name = ChangeCounter(Name(value.getName())) self._minSuffixComponents = value._minSuffixComponents self._maxSuffixComponents = value._maxSuffixComponents self._didSetCanBePrefix = value._didSetCanBePrefix self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._exclude = ChangeCounter(Exclude(value.getExclude())) self._childSelector = value._childSelector self._mustBeFresh = value._mustBeFresh self._nonce = value.getNonce() self._interestLifetimeMilliseconds = value._interestLifetimeMilliseconds self._forwardingHint = ChangeCounter( DelegationSet(value.getForwardingHint())) self._applicationParameters = value._applicationParameters self._linkWireEncoding = value._linkWireEncoding self._linkWireEncodingFormat = value._linkWireEncodingFormat self._link = ChangeCounter(None) if value._link.get() != None: self._link.set(Link(value._link.get())) self._selectedDelegationIndex = value._selectedDelegationIndex self._defaultWireEncoding = value.getDefaultWireEncoding() self._defaultWireEncodingFormat = value._defaultWireEncodingFormat else: self._name = ChangeCounter(Name(value)) self._minSuffixComponents = None self._maxSuffixComponents = None if Interest._defaultCanBePrefix else 1 # _didSetCanBePrefix is True if the app already called setDefaultCanBePrefix(). self._didSetCanBePrefix = Interest._didSetDefaultCanBePrefix self._keyLocator = ChangeCounter(KeyLocator()) self._exclude = ChangeCounter(Exclude()) self._childSelector = None self._mustBeFresh = False self._nonce = Blob() self._interestLifetimeMilliseconds = None self._forwardingHint = ChangeCounter(DelegationSet()) self._applicationParameters = Blob() self._linkWireEncoding = Blob() self._linkWireEncodingFormat = None self._link = ChangeCounter(None) self._selectedDelegationIndex = None self._defaultWireEncoding = SignedBlob() self._defaultWireEncodingFormat = None self._getNonceChangeCount = 0 self._getDefaultWireEncodingChangeCount = 0 self._changeCount = 0 self._lpPacket = None
def __init__(self, value=None): if value == None: self._keyLocator = ChangeCounter(KeyLocator()) self._signature = Blob() elif type(value) is Sha256WithRsaSignature: # Copy its values. self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._signature = value._signature else: raise RuntimeError( "Unrecognized type for Sha256WithRsaSignature constructor: " + str(type(value))) self._changeCount = 0
def _makeSelfSignedCertificate(keyName, privateKeyBag, publicKeyEncoding, password, digestAlgorithm, wireFormat): certificate = CertificateV2() # Set the name. now = Common.getNowMilliseconds() certificateName = Name(keyName) certificateName.append("self").appendVersion(int(now)) certificate.setName(certificateName) # Set the MetaInfo. certificate.getMetaInfo().setType(ContentType.KEY) # Set a one-hour freshness period. certificate.getMetaInfo().setFreshnessPeriod(3600 * 1000.0) # Set the content. publicKey = PublicKey(publicKeyEncoding) certificate.setContent(publicKey.getKeyDer()) # Create a temporary in-memory Tpm and import the private key. tpm = Tpm("", "", TpmBackEndMemory()) tpm._importPrivateKey(keyName, privateKeyBag.toBytes(), password) # Set the signature info. if publicKey.getKeyType() == KeyType.RSA: certificate.setSignature(Sha256WithRsaSignature()) elif publicKey.getKeyType() == KeyType.EC: certificate.setSignature(Sha256WithEcdsaSignature()) else: raise ValueError("Unsupported key type") signatureInfo = certificate.getSignature() KeyLocator.getFromSignature(signatureInfo).setType( KeyLocatorType.KEYNAME) KeyLocator.getFromSignature(signatureInfo).setKeyName(keyName) # Set a 20-year validity period. ValidityPeriod.getFromSignature(signatureInfo).setPeriod( now, now + 20 * 365 * 24 * 3600 * 1000.0) # Encode once to get the signed portion. encoding = certificate.wireEncode(wireFormat) signatureBytes = tpm.sign(encoding.toSignedBytes(), keyName, digestAlgorithm) signatureInfo.setSignature(signatureBytes) # Encode again to include the signature. certificate.wireEncode(wireFormat) return certificate
def _makeSelfSignedCertificate( keyName, privateKeyBag, publicKeyEncoding, password, digestAlgorithm, wireFormat): certificate = CertificateV2() # Set the name. now = Common.getNowMilliseconds() certificateName = Name(keyName) certificateName.append("self").appendVersion(int(now)) certificate.setName(certificateName) # Set the MetaInfo. certificate.getMetaInfo().setType(ContentType.KEY) # Set a one-hour freshness period. certificate.getMetaInfo().setFreshnessPeriod(3600 * 1000.0) # Set the content. publicKey = PublicKey(publicKeyEncoding) certificate.setContent(publicKey.getKeyDer()) # Create a temporary in-memory Tpm and import the private key. tpm = Tpm("", "", TpmBackEndMemory()) tpm._importPrivateKey(keyName, privateKeyBag.toBytes(), password) # Set the signature info. if publicKey.getKeyType() == KeyType.RSA: certificate.setSignature(Sha256WithRsaSignature()) elif publicKey.getKeyType() == KeyType.EC: certificate.setSignature(Sha256WithEcdsaSignature()) else: raise ValueError("Unsupported key type") signatureInfo = certificate.getSignature() KeyLocator.getFromSignature(signatureInfo).setType(KeyLocatorType.KEYNAME) KeyLocator.getFromSignature(signatureInfo).setKeyName(keyName) # Set a 20-year validity period. ValidityPeriod.getFromSignature(signatureInfo).setPeriod( now, now + 20 * 365 * 24 * 3600 * 1000.0) # Encode once to get the signed portion. encoding = certificate.wireEncode(wireFormat) signatureBytes = tpm.sign(encoding.toSignedBytes(), keyName, digestAlgorithm) signatureInfo.setSignature(signatureBytes) # Encode again to include the signature. certificate.wireEncode(wireFormat) return certificate
def __init__(self, value=None): if type(value) is Interest: # Copy the values. self._name = ChangeCounter(Name(value.getName())) self._minSuffixComponents = value._minSuffixComponents self._maxSuffixComponents = value._maxSuffixComponents self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._exclude = ChangeCounter(Exclude(value.getExclude())) self._childSelector = value._childSelector self._mustBeFresh = value._mustBeFresh self._nonce = value.getNonce() self._interestLifetimeMilliseconds = value._interestLifetimeMilliseconds self._forwardingHint = ChangeCounter( DelegationSet(value.getForwardingHint())) self._linkWireEncoding = value._linkWireEncoding self._linkWireEncodingFormat = value._linkWireEncodingFormat self._link = ChangeCounter(None) if value._link.get() != None: self._link.set(Link(value._link.get())) self._selectedDelegationIndex = value._selectedDelegationIndex self._defaultWireEncoding = value.getDefaultWireEncoding() self._defaultWireEncodingFormat = value._defaultWireEncodingFormat self._content = value._content else: self._name = ChangeCounter( Name(value) if type(value) is Name else Name()) self._minSuffixComponents = None self._maxSuffixComponents = None self._keyLocator = ChangeCounter(KeyLocator()) self._exclude = ChangeCounter(Exclude()) self._childSelector = None self._mustBeFresh = True self._nonce = Blob() self._interestLifetimeMilliseconds = None self._forwardingHint = ChangeCounter(DelegationSet()) self._linkWireEncoding = Blob() self._linkWireEncodingFormat = None self._link = ChangeCounter(None) self._selectedDelegationIndex = None self._defaultWireEncoding = SignedBlob() self._defaultWireEncodingFormat = None self._content = Blob() self._getNonceChangeCount = 0 self._getDefaultWireEncodingChangeCount = 0 self._changeCount = 0 self._lpPacket = None
def setKeyLocator(self, keyLocator): """ Set this interest to use a copy of the given KeyLocator object. :note: You can also call getKeyLocator and change the key locator directly. :param KeyLocator keyLocator: The KeyLocator object. This makes a copy of the object. If no key locator is specified, set to a new default KeyLocator(), or to a KeyLocator with an unspecified type. :return: This Interest so that you can chain calls to update values. :rtype: Interest """ self._keyLocator.set( KeyLocator(keyLocator ) if type(keyLocator) is KeyLocator else KeyLocator()) self._changeCount += 1 return self
def __str__(self): """ Get a string representation of this certificate. :return: The string representation. :rtype: str """ result = "" result += "Certificate name:\n" result += " " + self.getName().toUri() + "\n" result += "Validity:\n" result += " NotBefore: " + Schedule.toIsoString( self.getValidityPeriod().getNotBefore()) + "\n" result += " NotAfter: " + Schedule.toIsoString( self.getValidityPeriod().getNotAfter()) + "\n" # TODO: Print the extension. result += "Public key bits:\n" try: result += Common.base64Encode(self.getPublicKey().toBytes(), True) except: # No public key. pass result += "Signature Information:\n" result += " Signature Type: " if type(self.getSignature()) is Sha256WithEcdsaSignature: result += "SignatureSha256WithEcdsa\n" elif type(self.getSignature()) is Sha256WithRsaSignature: result += "SignatureSha256WithRsa\n" else: result += "<unknown>\n" if KeyLocator.canGetFromSignature(self.getSignature()): result += " Key Locator: " keyLocator = KeyLocator.getFromSignature(self.getSignature()) if keyLocator.getType() == KeyLocatorType.KEYNAME: if keyLocator.getKeyName().equals(self.getKeyName()): result += "Self-Signed " result += "Name=" + keyLocator.getKeyName().toUri() + "\n" else: result += "<no KeyLocator key name>\n" return result
def __init__(self, value=None): if value == None: self._keyLocator = ChangeCounter(KeyLocator()) self._validityPeriod = ChangeCounter(ValidityPeriod()) self._signature = Blob() elif isinstance(value, Sha256WithEcdsaSignature): # Copy its values. self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._validityPeriod = ChangeCounter( ValidityPeriod(value.getValidityPeriod())) self._signature = value._signature else: raise RuntimeError( "Unrecognized type for Sha256WithEcdsaSignature constructor: " + str(type(value))) self._changeCount = 0
def setKeyLocator(self, keyLocator): """ Set the key locator to a copy of the given keyLocator. :param KeyLocator keyLocator: The KeyLocator to copy. """ self._keyLocator.set(KeyLocator(keyLocator)) self._changeCount += 1
def __str__(self): """ Get a string representation of this certificate. :return: The string representation. :rtype: str """ result = "" result += "Certificate name:\n" result += " " + self.getName().toUri() + "\n" result += "Validity:\n" result += " NotBefore: " + Schedule.toIsoString( self.getValidityPeriod().getNotBefore()) + "\n" result += " NotAfter: " + Schedule.toIsoString( self.getValidityPeriod().getNotAfter()) + "\n" # TODO: Print the extension. result += "Public key bits:\n" try: result += Common.base64Encode(self.getPublicKey().toBytes(), True) except: # No public key. pass result += "Signature Information:\n" result += " Signature Type: " if isinstance(self.getSignature(), Sha256WithEcdsaSignature): result += "SignatureSha256WithEcdsa\n" elif isinstance(self.getSignature(), Sha256WithRsaSignature): result += "SignatureSha256WithRsa\n" else: result += "<unknown>\n" if KeyLocator.canGetFromSignature(self.getSignature()): result += " Key Locator: " keyLocator = KeyLocator.getFromSignature(self.getSignature()) if keyLocator.getType() == KeyLocatorType.KEYNAME: if keyLocator.getKeyName().equals(self.getKeyName()): result += "Self-Signed " result += "Name=" + keyLocator.getKeyName().toUri() + "\n" else: result += "<no KeyLocator key name>\n" return result
def __init__(self, value=None): if isinstance(value, Interest): # Copy the values. self._name = ChangeCounter(Name(value.getName())) self._canBePrefix = value._canBePrefix self._hopLimit = value._hopLimit self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._mustBeFresh = value._mustBeFresh self._nonce = value.getNonce() self._interestLifetimeMilliseconds = value._interestLifetimeMilliseconds self._forwardingHint = ChangeCounter( DelegationSet(value.getForwardingHint())) self._applicationParameters = value._applicationParameters self._linkWireEncoding = value._linkWireEncoding self._linkWireEncodingFormat = value._linkWireEncodingFormat self._link = ChangeCounter(None) if value._link.get() != None: self._link.set(Link(value._link.get())) self._selectedDelegationIndex = value._selectedDelegationIndex self._defaultWireEncoding = value.getDefaultWireEncoding() self._defaultWireEncodingFormat = value._defaultWireEncodingFormat else: self._name = ChangeCounter(Name(value)) self._canBePrefix = Interest._defaultCanBePrefix self._hopLimit = Interest._defaultHopLimit self._keyLocator = ChangeCounter(KeyLocator()) self._mustBeFresh = False self._nonce = Blob() self._interestLifetimeMilliseconds = None self._forwardingHint = ChangeCounter(DelegationSet()) self._applicationParameters = Blob() self._linkWireEncoding = Blob() self._linkWireEncodingFormat = None self._link = ChangeCounter(None) self._selectedDelegationIndex = None self._defaultWireEncoding = SignedBlob() self._defaultWireEncodingFormat = None self._getNonceChangeCount = 0 self._getDefaultWireEncodingChangeCount = 0 self._changeCount = 0 self._lpPacket = None
def __init__(self, value = None): if value == None: self._keyLocator = ChangeCounter(KeyLocator()) # self._validityPeriod = ChangeCounter(ValidityPeriod()) self._signature = Blob() elif isinstance(value, Sha256WithAbsSignature): # Copy its values. self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) # self._validityPeriod = ChangeCounter(ValidityPeriod(value.getValidityPeriod())) self._signature = value._signature elif isinstance(value, GenericSignature): self.wireDecode(value.getSignatureInfoEncoding().toBuffer()) self._signature = value.getSignature() else: raise RuntimeError( "Unrecognized type for Sha256WithAbsSignature constructor: " + str(type(value))) self._changeCount = 0
def __init__(self, value = None): if isinstance(value, EncryptedContent): # Make a deep copy. self._algorithmType = value._algorithmType self._keyLocator = KeyLocator(value._keyLocator) self._initialVector = value._initialVector self._payload = value._payload self._payloadKey = value._payloadKey else: self.clear()
def _getKeyLocatorNameFromSignature(signatureInfo, state): """ A helper method for getKeyLocatorName. :param Signature signatureInfo: :param ValidationState state: :rtype: Name """ if not KeyLocator.canGetFromSignature(signatureInfo): state.fail(ValidationError (ValidationError.INVALID_KEY_LOCATOR, "KeyLocator is missing")) return Name() keyLocator = KeyLocator.getFromSignature(signatureInfo) if keyLocator.getType() != KeyLocatorType.KEYNAME: state.fail(ValidationError (ValidationError.INVALID_KEY_LOCATOR, "KeyLocator type is not Name")) return Name() return keyLocator.getKeyName()
def _verify(self, signatureInfo, signedBlob): """ Check the type of signatureInfo to get the KeyLocator. Look in the IdentityStorage for the public key with the name in the KeyLocator and use it to verify the signedBlob. If the public key can't be found, return false. (This is a generalized method which can verify both a Data packet and an interest.) :param Signature signatureInfo: An object of a subclass of Signature, e.g. Sha256WithRsaSignature. :param SignedBlob signedBlob: the SignedBlob with the signed portion to verify. :return: True if the signature verifies, False if not. :rtype: boolean """ publicKeyDer = None if KeyLocator.canGetFromSignature(signatureInfo): publicKeyDer = self._getPublicKeyDer(KeyLocator.getFromSignature(signatureInfo)) if publicKeyDer.isNull(): return False return self.verifySignature(signatureInfo, signedBlob, publicKeyDer)
def _getKeyLocatorNameFromSignature(signatureInfo, state): """ A helper method for getKeyLocatorName. :param Signature signatureInfo: :param ValidationState state: :rtype: Name """ if not KeyLocator.canGetFromSignature(signatureInfo): state.fail( ValidationError(ValidationError.INVALID_KEY_LOCATOR, "KeyLocator is missing")) return Name() keyLocator = KeyLocator.getFromSignature(signatureInfo) if keyLocator.getType() != KeyLocatorType.KEYNAME: state.fail( ValidationError(ValidationError.INVALID_KEY_LOCATOR, "KeyLocator type is not Name")) return Name() return keyLocator.getKeyName()
def _verify(self, signatureInfo, signedBlob): """ Check the type of signatureInfo to get the KeyLocator. Look in the IdentityStorage for the public key with the name in the KeyLocator and use it to verify the signedBlob. If the public key can't be found, return false. (This is a generalized method which can verify both a Data packet and an interest.) :param Signature signatureInfo: An object of a subclass of Signature, e.g. Sha256WithRsaSignature. :param SignedBlob signedBlob: the SignedBlob with the signed portion to verify. :return: True if the signature verifies, False if not. :rtype: boolean """ publicKeyDer = None if KeyLocator.canGetFromSignature(signatureInfo): publicKeyDer = self._getPublicKeyDer( KeyLocator.getFromSignature(signatureInfo)) if publicKeyDer.isNull(): return False return self.verifySignature(signatureInfo, signedBlob, publicKeyDer)
def _verify(self, signatureInfo, signedBlob, failureReason): """ Check the type of signatureInfo to get the KeyLocator. Look in the IdentityStorage for the public key with the name in the KeyLocator and use it to verify the signedBlob. If the public key can't be found, return false. (This is a generalized method which can verify both a Data packet and an interest.) :param Signature signatureInfo: An object of a subclass of Signature, e.g. Sha256WithRsaSignature. :param SignedBlob signedBlob: the SignedBlob with the signed portion to verify. :param Array<str> failureReason: If verification fails, set failureReason[0] to the failure reason string. :return: True if the signature verifies, False if not. :rtype: boolean """ # We have already checked once that there is a key locator. keyLocator = KeyLocator.getFromSignature(signatureInfo) if (keyLocator.getType() == KeyLocatorType.KEYNAME): # Assume the key name is a certificate name. signatureName = keyLocator.getKeyName() certificate = self._refreshManager.getCertificate(signatureName) if certificate is None: certificate = self._certificateCache.getCertificate( signatureName) if certificate is None: failureReason[0] = ("Cannot find a certificate with name " + signatureName.toUri()) return False publicKeyDer = certificate.getPublicKeyInfo().getKeyDer() if publicKeyDer.isNull(): # We don't expect this to happen. failureReason[0] = ( "There is no public key in the certificate with name " + certificate.getName().toUri()) return False if self.verifySignature(signatureInfo, signedBlob, publicKeyDer): return True else: failureReason[0] = ( "The signature did not verify with the given public key") return False else: failureReason[0] = "The KeyLocator does not have a key name" return False
def _verify(self, signatureInfo, signedBlob, failureReason): """ Check the type of signatureInfo to get the KeyLocator. Look in the IdentityStorage for the public key with the name in the KeyLocator and use it to verify the signedBlob. If the public key can't be found, return false. (This is a generalized method which can verify both a Data packet and an interest.) :param Signature signatureInfo: An object of a subclass of Signature, e.g. Sha256WithRsaSignature. :param SignedBlob signedBlob: the SignedBlob with the signed portion to verify. :param Array<str> failureReason: If verification fails, set failureReason[0] to the failure reason string. :return: True if the signature verifies, False if not. :rtype: boolean """ # We have already checked once that there is a key locator. keyLocator = KeyLocator.getFromSignature(signatureInfo) if (keyLocator.getType() == KeyLocatorType.KEYNAME): # Assume the key name is a certificate name. signatureName = keyLocator.getKeyName() certificate = self._refreshManager.getCertificate(signatureName) if certificate is None: certificate = self._certificateCache.getCertificate(signatureName) if certificate is None: failureReason[0] = ("Cannot find a certificate with name " + signatureName.toUri()) return False publicKeyDer = certificate.getPublicKeyInfo().getKeyDer() if publicKeyDer.isNull(): # We don't expect this to happen. failureReason[0] = ( "There is no public key in the certificate with name " + certificate.getName().toUri()) return False if self.verifySignature(signatureInfo, signedBlob, publicKeyDer): return True else: failureReason[0] = ( "The signature did not verify with the given public key") return False else: failureReason[0] = "The KeyLocator does not have a key name" return False
def wireDecode(self, wire): decoder = TlvDecoder(wire) beginOffset = decoder.getOffset() endOffset = decoder.readNestedTlvsStart(Tlv.SignatureInfo) signatureType = decoder.readNonNegativeIntegerTlv(Tlv.SignatureType) if signatureType != Tlv.SignatureType_Sha256WithAbsSignature: raise RuntimeError("Invalid SignatureType code: expected %d, got %d" % (Tlv.SignatureType_Sha256WithAbsSignature, signatureType)) keyLocator = KeyLocator() Tlv0_2WireFormat._decodeKeyLocator(Tlv.KeyLocator, keyLocator, decoder, True) self._keyLocator = ChangeCounter(keyLocator) # if decoder.peekType(Tlv.ValidityPeriod_ValidityPeriod, endOffset): # Tlv0_2WireFormat._decodeValidityPeriod( # signatureInfo.getValidityPeriod(), decoder) decoder.finishNestedTlvs(endOffset)
def addCertificate(self, certificate): """ Add a certificate to the identity storage. Also call addKey to ensure that the certificate key exists. If the certificate is already installed, don't replace it. :param IdentityCertificate certificate: The certificate to be added. This makes a copy of the certificate. """ certificateName = certificate.getName() keyName = certificate.getPublicKeyName() self.addKey(keyName, certificate.getPublicKeyInfo().getKeyType(), certificate.getPublicKeyInfo().getKeyDer()) if self.doesCertificateExist(certificateName): return keyId = keyName.get(-1).toEscapedString() identity = keyName[:-1] # Insert the certificate. signature = certificate.getSignature() signerName = KeyLocator.getFromSignature(signature).getKeyName() # Convert from milliseconds to seconds since 1/1/1970. notBefore = int(math.floor(certificate.getNotBefore() / 1000.0)) notAfter = int(math.floor(certificate.getNotAfter() / 1000.0)) encodedCert = sqlite3.Binary(bytearray(certificate.wireEncode().buf())) cursor = self._database.cursor() cursor.execute( "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data) " + "VALUES (?,?,?,?,?,?,?)", (certificateName.toUri(), signerName.toUri(), identity.toUri(), keyId, notBefore, notAfter, encodedCert)) self._database.commit() cursor.close()
def _verify(self, signatureInfo, signedBlob): """ Check the type of signatureInfo to get the KeyLocator. Look in the IdentityStorage for the public key with the name in the KeyLocator and use it to verify the signedBlob. If the public key can't be found, return false. (This is a generalized method which can verify both a Data packet and an interest.) :param Signature signatureInfo: An object of a subclass of Signature, e.g. Sha256WithRsaSignature. :param SignedBlob signedBlob: the SignedBlob with the signed portion to verify. :return: True if the signature verifies, False if not. :rtype: boolean """ # We have already checked once that there is a key locator. keyLocator = KeyLocator.getFromSignature(signatureInfo) if (keyLocator.getType() == KeyLocatorType.KEYNAME): # Assume the key name is a certificate name. signatureName = keyLocator.getKeyName() certificate = self._refreshManager.getCertificate(signatureName) if certificate is None: certificate = self._certificateCache.getCertificate( signatureName) if certificate is None: return False publicKeyDer = certificate.getPublicKeyInfo().getKeyDer() if publicKeyDer.isNull(): # Can't find the public key with the name. return False return self.verifySignature(signatureInfo, signedBlob, publicKeyDer) else: # Can't find a key to verify. return False
def requestIdentityBasedPrivateKey(self): """ Setup a local PKG only for this Device to be able to do initialization with a PKG. Set the KeyLocator to the ID of the requesting Device. Append the TemporaryMasterPublicKey to the Interest. Interest: Name: /ndn/no/ntnu/initDevice/<nonce>/<tempMasterPublicKey> Selector: KeyLocator = ID Send the Interest """ self.initRequestStart = time.clock() ID = self.deviceName.toUri() # Make each init unique with a session self.initSession = str(int(round(util.getNowMilliseconds() / 1000.0))) a = SymmetricCryptoAbstraction(self.presharedKey) message = {"ID": ID, "nonce": self.initSession} cipher = a.encrypt(str(message)) cipherEncoded = base64.b64encode(cipher) logging.info("Cipher encoded: " + str(cipherEncoded)) name = Name(self.baseName).append("pkg").append("initDevice").append( self.initSession) interest = Interest(name) # interest.setMinSuffixComponents(6) keyLocator = KeyLocator() keyLocator.setType(KeyLocatorType.KEYNAME) keyLocator.setKeyName(Name(self.deviceName).append(cipherEncoded)) interest.setKeyLocator(keyLocator) logging.info("Expressing interest name: " + name.toUri()) self.face.expressInterest(interest, self.onInitData, self.onTimeout)
# All boolean, so use shortcut below # from pyndn.forwarding_flags import ForwardingFlags for p in ["active", "childInherit", "advertise", "last", "capture", "local", "tap", "captureOk"]: res = testPropertyRW( ForwardingFlags(), p, [True, False] ) if not res[0]: print(res) # Interest # TODO: We do not check exclude because there is no equals() for it yet. # TODO: When passing None as the KeyLocator, it generates a blank KeyLocator object, so equivalence checks fail. Don't check None. # from pyndn.name import Name from pyndn.key_locator import KeyLocator from pyndn.exclude import Exclude from pyndn.interest import Interest for p in [("name", Name("yes"), Name("another")), ("minSuffixComponents", 4, None), ("maxSuffixComponents", 1, None), ("keyLocator", KeyLocator(), KeyLocator()),("childSelector", 1, 0), ("mustBeFresh", 0, 1), ("nonce", Blob(), Blob()), ("interestLifetimeMilliseconds", 49, None)]: res = testPropertyRW( Interest(), p[0], [p[1],p[2]]) if not res[0]: print(res) # KeyLocator # from pyndn.name import Name from pyndn.util.blob import Blob from pyndn.key_locator import KeyLocator, KeyLocatorType for p in [("type", KeyLocatorType.KEYNAME, KeyLocatorType.KEY_LOCATOR_DIGEST), ("keyName", Name("yes"), Name("another")), ("keyData", Blob(), Blob())]: res = testPropertyRW( KeyLocator(), p[0], [p[1],p[2]]) if not res[0]: print(res) # MetaInfo # TODO: Support FinalBlockId of None. #
def checkVerificationPolicy(self, dataOrInterest, stepCount, onVerified, onValidationFailed, wireFormat = None): """ If there is a rule matching the data or interest, and the matching certificate is missing, download it. If there is no matching rule, verification fails. Otherwise, verify the signature using the public key in the IdentityStorage. :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). NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onVerified: function object :param onValidationFailed: If the signature check fails, this calls onValidationFailed(dataOrInterest, reason). NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onValidationFailed: function object :return: None for no further step for looking up a certificate chain. :rtype: ValidationRequest """ if stepCount > self._maxDepth: try: onValidationFailed( dataOrInterest, "The verification stepCount " + stepCount + " exceeded the maxDepth " + self._maxDepth) except: logging.exception("Error in onValidationFailed") return None signature = self._extractSignature(dataOrInterest, wireFormat) # no signature -> fail if signature is None: try: onValidationFailed( dataOrInterest, "Cannot extract the signature from " + dataOrInterest.getName().toUri()) except: logging.exception("Error in onValidationFailed") return None if not KeyLocator.canGetFromSignature(signature): # We only support signature types with key locators. try: onValidationFailed( dataOrInterest, "The signature type does not support a KeyLocator") except: logging.exception("Error in onValidationFailed") return None keyLocator = None try: keyLocator = KeyLocator.getFromSignature(signature) except Exception as ex: # No key locator -> fail. try: onValidationFailed( dataOrInterest, "Error in KeyLocator.getFromSignature: " + str(ex)) except: logging.exception("Error in onValidationFailed") return None signatureName = keyLocator.getKeyName() # no key name in KeyLocator -> fail if signatureName.size() == 0: try: onValidationFailed( dataOrInterest, "The signature KeyLocator doesn't have a key name") except: logging.exception("Error in onValidationFailed") return None objectName = dataOrInterest.getName() matchType = "data" #for command interests, we need to ignore the last 4 components when matching the name if isinstance(dataOrInterest, Interest): objectName = objectName.getPrefix(-4) matchType = "interest" # first see if we can find a rule to match this packet try: matchedRule = self._findMatchingRule(objectName, matchType) except: matchedRule = None # no matching rule -> fail if matchedRule is None: try: onValidationFailed( dataOrInterest, "No matching rule found for " + objectName.toUri()) except: logging.exception("Error in onValidationFailed") return None failureReason = ["unknown"] signatureMatches = self._checkSignatureMatch( signatureName, objectName, matchedRule, failureReason) if not signatureMatches: try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed") return None # before we look up keys, refresh any certificate directories self._refreshManager.refreshAnchors() # now finally check that the data or interest was signed correctly # if we don't actually have the certificate yet, create a # ValidationRequest for it foundCert = self._refreshManager.getCertificate(signatureName) if foundCert is None: foundCert = self._certificateCache.getCertificate(signatureName) if foundCert is None: certificateInterest = Interest(signatureName) def onCertificateDownloadComplete(data): try: certificate = IdentityCertificate(data) except: try: onValidationFailed( dataOrInterest, "Cannot decode certificate " + data.getName().toUri()) except: logging.exception("Error in onValidationFailed") return None self._certificateCache.insertCertificate(certificate) self.checkVerificationPolicy(dataOrInterest, stepCount+1, onVerified, onValidationFailed) nextStep = ValidationRequest(certificateInterest, onCertificateDownloadComplete, onValidationFailed, 2, stepCount+1) return nextStep # for interests, we must check that the timestamp is fresh enough # I do this after (possibly) downloading the certificate to avoid # filling the cache with bad keys if isinstance(dataOrInterest, Interest): keyName = foundCert.getPublicKeyName() timestamp = dataOrInterest.getName().get(-4).toNumber() if not self._interestTimestampIsFresh( keyName, timestamp, failureReason): try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed") return None # certificate is known, verify the signature if self._verify(signature, dataOrInterest.wireEncode(), failureReason): try: onVerified(dataOrInterest) except: logging.exception("Error in onVerified") if isinstance(dataOrInterest, Interest): self._updateTimestampForKey(keyName, timestamp) else: try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed")
def matchesData(self, data, wireFormat = None): """ Check if the given Data packet can satisfy this Interest. This method considers the Name, MinSuffixComponents, MaxSuffixComponents, PublisherPublicKeyLocator, and Exclude. It does not consider the ChildSelector or MustBeFresh. This uses the given wireFormat to get the Data packet encoding for the full Name. :param Data data: The Data packet to check. :param wireFormat: (optional) A WireFormat object used to encode the Data packet to get its full Name. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat :return: True if the given Data packet can satisfy this Interest. :rtype: bool """ # Imitate ndn-cxx Interest::matchesData. interestNameLength = self.getName().size() dataName = data.getName() fullNameLength = dataName.size() + 1 # Check MinSuffixComponents. hasMinSuffixComponents = (self.getMinSuffixComponents() != None) minSuffixComponents = (self.getMinSuffixComponents() if hasMinSuffixComponents else 0) if not (interestNameLength + minSuffixComponents <= fullNameLength): return False # Check MaxSuffixComponents. hasMaxSuffixComponents = (self.getMaxSuffixComponents() != None) if (hasMaxSuffixComponents and not (interestNameLength + self.getMaxSuffixComponents() >= fullNameLength)): return False # Check the prefix. if interestNameLength == fullNameLength: if self.getName().get(-1).isImplicitSha256Digest(): if not self.getName().equals(data.getFullName(wireFormat)): return False else: # The Interest Name is the same length as the Data full Name, # but the last component isn't a digest so there's no # possibility of matching. return False else: # The Interest Name should be a strict prefix of the Data full Name. if not self.getName().isPrefixOf(dataName): return False # Check the Exclude. # The Exclude won't be violated if the Interest Name is the same as the # Data full Name. if self.getExclude().size() > 0 and fullNameLength > interestNameLength: if interestNameLength == fullNameLength - 1: # The component to exclude is the digest. if self.getExclude().matches( data.getFullName(wireFormat).get(interestNameLength)): return False else: # The component to exclude is not the digest. if self.getExclude().matches(dataName.get(interestNameLength)): return False # Check the KeyLocator. publisherPublicKeyLocator = self.getKeyLocator() if publisherPublicKeyLocator.getType() != None: signature = data.getSignature() if not KeyLocator.canGetFromSignature(signature): # No KeyLocator in the Data packet. return False if not publisherPublicKeyLocator.equals( (KeyLocator.getFromSignature(signature))): return False return True
def checkVerificationPolicy(self, dataOrInterest, stepCount, onVerified, onValidationFailed, wireFormat = None): """ If there is a rule matching the data or interest, and the matching certificate is missing, download it. If there is no matching rule, verification fails. Otherwise, verify the signature using the public key in the IdentityStorage. :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). NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onVerified: function object :param onValidationFailed: If the signature check fails, this calls onValidationFailed(dataOrInterest, reason). NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onValidationFailed: function object :return: None for no further step for looking up a certificate chain. :rtype: ValidationRequest """ objectName = dataOrInterest.getName() matchType = "data" # For command interests, we need to ignore the last 4 components when # matching the name. if isinstance(dataOrInterest, Interest): objectName = objectName.getPrefix(-4) matchType = "interest" signature = self._extractSignature(dataOrInterest, wireFormat) # no signature -> fail if signature is None: try: onValidationFailed( dataOrInterest, "Cannot extract the signature from " + dataOrInterest.getName().toUri()) except: logging.exception("Error in onValidationFailed") return None failureReason = ["unknown"] certificateInterest = self._getCertificateInterest( stepCount, matchType, objectName, signature, failureReason) if certificateInterest is None: try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed") return None if certificateInterest.getName().size() > 0: def onCertificateDownloadComplete(data): if self._isSecurityV1: try: certificate = IdentityCertificate(data) except: try: onValidationFailed( dataOrInterest, "Cannot decode certificate " + data.getName().toUri()) except: logging.exception("Error in onValidationFailed") return None self._certificateCache.insertCertificate(certificate) else: try: certificate = CertificateV2(data) except: try: onValidationFailed( dataOrInterest, "Cannot decode certificate " + data.getName().toUri()) except: logging.exception("Error in onValidationFailed") return None self._certificateCacheV2.insert(certificate) self.checkVerificationPolicy(dataOrInterest, stepCount+1, onVerified, onValidationFailed) return ValidationRequest(certificateInterest, onCertificateDownloadComplete, onValidationFailed, 2, stepCount+1) # For interests, we must check that the timestamp is fresh enough. # This is done after (possibly) downloading the certificate to avoid # filling the cache with bad keys. if isinstance(dataOrInterest, Interest): signatureName = KeyLocator.getFromSignature(signature).getKeyName() if self._isSecurityV1: keyName = IdentityCertificate.certificateNameToPublicKeyName( signatureName) else: keyName = signatureName timestamp = dataOrInterest.getName().get(-4).toNumber() if not self._interestTimestampIsFresh( keyName, timestamp, failureReason): try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed") return None # Certificate is known. Verify the signature. # wireEncode returns the cached encoding if available. if self._verify(signature, dataOrInterest.wireEncode(), failureReason): try: onVerified(dataOrInterest) except: logging.exception("Error in onVerified") if isinstance(dataOrInterest, Interest): self._updateTimestampForKey(keyName, timestamp) else: try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed")
def checkVerificationPolicy(self, dataOrInterest, stepCount, onVerified, onValidationFailed, wireFormat=None): """ If there is a rule matching the data or interest, and the matching certificate is missing, download it. If there is no matching rule, verification fails. Otherwise, verify the signature using the public key in the IdentityStorage. :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). NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onVerified: function object :param onValidationFailed: If the signature check fails, this calls onValidationFailed(dataOrInterest, reason). NOTE: The library will log any exceptions raised by this callback, but for better error handling the callback should catch and properly handle any exceptions. :type onValidationFailed: function object :return: None for no further step for looking up a certificate chain. :rtype: ValidationRequest """ if stepCount > self._maxDepth: try: onValidationFailed( dataOrInterest, "The verification stepCount " + stepCount + " exceeded the maxDepth " + self._maxDepth) except: logging.exception("Error in onValidationFailed") return None signature = self._extractSignature(dataOrInterest, wireFormat) # no signature -> fail if signature is None: try: onValidationFailed( dataOrInterest, "Cannot extract the signature from " + dataOrInterest.getName().toUri()) except: logging.exception("Error in onValidationFailed") return None if not KeyLocator.canGetFromSignature(signature): # We only support signature types with key locators. try: onValidationFailed( dataOrInterest, "The signature type does not support a KeyLocator") except: logging.exception("Error in onValidationFailed") return None keyLocator = None try: keyLocator = KeyLocator.getFromSignature(signature) except Exception as ex: # No key locator -> fail. try: onValidationFailed( dataOrInterest, "Error in KeyLocator.getFromSignature: " + str(ex)) except: logging.exception("Error in onValidationFailed") return None signatureName = keyLocator.getKeyName() # no key name in KeyLocator -> fail if signatureName.size() == 0: try: onValidationFailed( dataOrInterest, "The signature KeyLocator doesn't have a key name") except: logging.exception("Error in onValidationFailed") return None objectName = dataOrInterest.getName() matchType = "data" #for command interests, we need to ignore the last 4 components when matching the name if isinstance(dataOrInterest, Interest): objectName = objectName.getPrefix(-4) matchType = "interest" # first see if we can find a rule to match this packet try: matchedRule = self._findMatchingRule(objectName, matchType) except: matchedRule = None # no matching rule -> fail if matchedRule is None: try: onValidationFailed( dataOrInterest, "No matching rule found for " + objectName.toUri()) except: logging.exception("Error in onValidationFailed") return None failureReason = ["unknown"] signatureMatches = self._checkSignatureMatch(signatureName, objectName, matchedRule, failureReason) if not signatureMatches: try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed") return None # before we look up keys, refresh any certificate directories self._refreshManager.refreshAnchors() # now finally check that the data or interest was signed correctly # if we don't actually have the certificate yet, create a # ValidationRequest for it foundCert = self._refreshManager.getCertificate(signatureName) if foundCert is None: foundCert = self._certificateCache.getCertificate(signatureName) if foundCert is None: certificateInterest = Interest(signatureName) def onCertificateDownloadComplete(data): try: certificate = IdentityCertificate(data) except: try: onValidationFailed( dataOrInterest, "Cannot decode certificate " + data.getName().toUri()) except: logging.exception("Error in onValidationFailed") return None self._certificateCache.insertCertificate(certificate) self.checkVerificationPolicy(dataOrInterest, stepCount + 1, onVerified, onValidationFailed) nextStep = ValidationRequest(certificateInterest, onCertificateDownloadComplete, onValidationFailed, 2, stepCount + 1) return nextStep # for interests, we must check that the timestamp is fresh enough # I do this after (possibly) downloading the certificate to avoid # filling the cache with bad keys if isinstance(dataOrInterest, Interest): keyName = foundCert.getPublicKeyName() timestamp = dataOrInterest.getName().get(-4).toNumber() if not self._interestTimestampIsFresh(keyName, timestamp, failureReason): try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed") return None # certificate is known, verify the signature if self._verify(signature, dataOrInterest.wireEncode(), failureReason): try: onVerified(dataOrInterest) except: logging.exception("Error in onVerified") if isinstance(dataOrInterest, Interest): self._updateTimestampForKey(keyName, timestamp) else: try: onValidationFailed(dataOrInterest, failureReason[0]) except: logging.exception("Error in onValidationFailed")
def _getCertificateInterest(self, stepCount, matchType, objectName, signature, failureReason): """ This is a helper for checkVerificationPolicy to verify the rule and return a certificate interest to fetch the next certificate in the hierarchy if needed. :param int stepCount: The number of verification steps that have been done, used to track the verification progress. :param str matchType: Either "data" or "interest". :param Name objectName: The name of the data or interest packet. :param Signature signature: The Signature object for the data or interest packet. :param Array<str> failureReason: If can't determine the interest, set failureReason[0] to the failure reason. :return: None if can't determine the interest, otherwise the interest for the ValidationRequest to fetch the next certificate. However, if the interest has an empty name, the validation succeeded and no need to fetch a certificate. :rtype: Interest """ if stepCount > self._maxDepth: failureReason[0] = ("The verification stepCount " + stepCount + " exceeded the maxDepth " + self._maxDepth) return None # First see if we can find a rule to match this packet. try: matchedRule = self._findMatchingRule(objectName, matchType) except: matchedRule = None # No matching rule -> fail. if matchedRule is None: failureReason[0] = "No matching rule found for " + objectName.toUri() return None if not KeyLocator.canGetFromSignature(signature): # We only support signature types with key locators. failureReason[0] = "The signature type does not support a KeyLocator" return None keyLocator = KeyLocator.getFromSignature(signature) signatureName = keyLocator.getKeyName() # No key name in KeyLocator -> fail. if signatureName.size() == 0: failureReason[0] = "The signature KeyLocator doesn't have a key name" return None signatureMatches = self._checkSignatureMatch( signatureName, objectName, matchedRule, failureReason) if not signatureMatches: return None # Before we look up keys, refresh any certificate directories. self._refreshManager.refreshAnchors() # If we don't actually have the certificate yet, return a # certificateInterest for it. if self._isSecurityV1: foundCert = self._refreshManager.getCertificate(signatureName) if foundCert is None: foundCert = self._certificateCache.getCertificate(signatureName) if foundCert is None: return Interest(signatureName) else: foundCert = self._refreshManager.getCertificateV2(signatureName) if foundCert is None: foundCert = self._certificateCacheV2.find(signatureName) if foundCert is None: return Interest(signatureName) return Interest()
def _getCertificateInterest(self, stepCount, matchType, objectName, signature, failureReason): """ This is a helper for checkVerificationPolicy to verify the rule and return a certificate interest to fetch the next certificate in the hierarchy if needed. :param int stepCount: The number of verification steps that have been done, used to track the verification progress. :param str matchType: Either "data" or "interest". :param Name objectName: The name of the data or interest packet. :param Signature signature: The Signature object for the data or interest packet. :param Array<str> failureReason: If can't determine the interest, set failureReason[0] to the failure reason. :return: None if can't determine the interest, otherwise the interest for the ValidationRequest to fetch the next certificate. However, if the interest has an empty name, the validation succeeded and no need to fetch a certificate. :rtype: Interest """ if stepCount > self._maxDepth: failureReason[0] = ("The verification stepCount " + stepCount + " exceeded the maxDepth " + self._maxDepth) return None # First see if we can find a rule to match this packet. try: matchedRule = self._findMatchingRule(objectName, matchType) except: matchedRule = None # No matching rule -> fail. if matchedRule is None: failureReason[ 0] = "No matching rule found for " + objectName.toUri() return None if not KeyLocator.canGetFromSignature(signature): # We only support signature types with key locators. failureReason[ 0] = "The signature type does not support a KeyLocator" return None keyLocator = KeyLocator.getFromSignature(signature) signatureName = keyLocator.getKeyName() # No key name in KeyLocator -> fail. if signatureName.size() == 0: failureReason[ 0] = "The signature KeyLocator doesn't have a key name" return None signatureMatches = self._checkSignatureMatch(signatureName, objectName, matchedRule, failureReason) if not signatureMatches: return None # Before we look up keys, refresh any certificate directories. self._refreshManager.refreshAnchors() # If we don't actually have the certificate yet, return a # certificateInterest for it. if self._isSecurityV1: foundCert = self._refreshManager.getCertificate(signatureName) if foundCert is None: foundCert = self._certificateCache.getCertificate( signatureName) if foundCert is None: return Interest(signatureName) else: foundCert = self._refreshManager.getCertificateV2(signatureName) if foundCert is None: foundCert = self._certificateCacheV2.find(signatureName) if foundCert is None: return Interest(signatureName) return Interest()
def matchesData(self, data, wireFormat=None): """ Check if the given Data packet can satisfy this Interest. This method considers the Name, MinSuffixComponents, MaxSuffixComponents, PublisherPublicKeyLocator, and Exclude. It does not consider the ChildSelector or MustBeFresh. This uses the given wireFormat to get the Data packet encoding for the full Name. :param Data data: The Data packet to check. :param wireFormat: (optional) A WireFormat object used to encode the Data packet to get its full Name. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat :return: True if the given Data packet can satisfy this Interest. :rtype: bool """ # Imitate ndn-cxx Interest::matchesData. interestNameLength = self.getName().size() dataName = data.getName() fullNameLength = dataName.size() + 1 # Check MinSuffixComponents. hasMinSuffixComponents = (self.getMinSuffixComponents() != None) minSuffixComponents = (self.getMinSuffixComponents() if hasMinSuffixComponents else 0) if not (interestNameLength + minSuffixComponents <= fullNameLength): return False # Check MaxSuffixComponents. hasMaxSuffixComponents = (self.getMaxSuffixComponents() != None) if (hasMaxSuffixComponents and not (interestNameLength + self.getMaxSuffixComponents() >= fullNameLength)): return False # Check the prefix. if interestNameLength == fullNameLength: if self.getName().get(-1).isImplicitSha256Digest(): if not self.getName().equals(data.getFullName(wireFormat)): return False else: # The Interest Name is the same length as the Data full Name, # but the last component isn't a digest so there's no # possibility of matching. return False else: # The Interest Name should be a strict prefix of the Data full Name. if not self.getName().isPrefixOf(dataName): return False # Check the Exclude. # The Exclude won't be violated if the Interest Name is the same as the # Data full Name. if self.getExclude().size( ) > 0 and fullNameLength > interestNameLength: if interestNameLength == fullNameLength - 1: # The component to exclude is the digest. if self.getExclude().matches( data.getFullName(wireFormat).get(interestNameLength)): return False else: # The component to exclude is not the digest. if self.getExclude().matches(dataName.get(interestNameLength)): return False # Check the KeyLocator. publisherPublicKeyLocator = self.getKeyLocator() if publisherPublicKeyLocator.getType() != None: signature = data.getSignature() if not KeyLocator.canGetFromSignature(signature): # No KeyLocator in the Data packet. return False if not publisherPublicKeyLocator.equals( (KeyLocator.getFromSignature(signature))): return False return True
class EncryptedContent(object): """ Create an EncryptedContent. :param value: (optional) If value is another EncryptedContent then copy it. If value is omitted then create an EncryptedContent with unspecified values. :type value: EncryptedContent """ def __init__(self, value = None): if isinstance(value, EncryptedContent): # Make a deep copy. self._algorithmType = value._algorithmType self._keyLocator = KeyLocator(value._keyLocator) self._initialVector = value._initialVector self._payload = value._payload self._payloadKey = value._payloadKey else: self.clear() def getAlgorithmType(self): """ Get the algorithm type from EncryptAlgorithmType. :return: The algorithm type from EncryptAlgorithmType, or None if not specified. :rtype: int """ return self._algorithmType def getKeyLocator(self): """ Get the key locator. :return: The key locator. If not specified, getType() is None. :rtype: KeyLocator """ return self._keyLocator def getKeyLocatorName(self): """ Check that the key locator type is KEYNAME and return the key Name. :return: The key Name. :rtype: Name :raises: RuntimeError if the key locator type is not KEYNAME. """ if self._keyLocator.getType() != KeyLocatorType.KEYNAME: raise RuntimeError("getKeyLocatorName: The KeyLocator type must be KEYNAME") return self._keyLocator.getKeyName() def hasInitialVector(self): """ Check if the initial vector is specified. :return: True if the initial vector is specified. :rtype: bool """ return not self._initialVector.isNull() def getInitialVector(self): """ Get the initial vector. :return: The initial vector. If not specified, isNull() is True. :rtype: Blob """ return self._initialVector def getPayload(self): """ Get the payload. :return: The payload. If not specified, isNull() is True. :rtype: Blob """ return self._payload def getPayloadKey(self): """ Get the encrypted payload key. :return: The encrypted payload key. If not specified, isNull() is true. :rtype: Blob """ return self._payloadKey def setAlgorithmType(self, algorithmType): """ Set the algorithm type. :param int algorithmType: The algorithm type from EncryptAlgorithmType. If not specified, set to None. :return: This EncryptedContent so that you can chain calls to update values. :rtype: EncryptedContent """ self._algorithmType = algorithmType return self def setKeyLocator(self, keyLocator): """ Set the key locator. :param KeyLocator keyLocator: The key locator. This makes a copy of the object. If not specified, set to the default KeyLocator(). :return: This EncryptedContent so that you can chain calls to update values. :rtype: EncryptedContent """ self._keyLocator = (KeyLocator(keyLocator) if isinstance(keyLocator, KeyLocator) else KeyLocator()) return self def setKeyLocatorName(self, keyName): """ Set the key locator type to KeyLocatorType.KEYNAME and set the key Name. :param Name keyName: The key locator Name, which is copied. :return: This EncryptedContent so that you can chain calls to update values. :rtype: EncryptedContent """ self._keyLocator.setType(KeyLocatorType.KEYNAME) self._keyLocator.setKeyName(keyName) return self def setInitialVector(self, initialVector): """ Set the initial vector. :param Blob initialVector: The initial vector. If not specified, set to the default Blob() where isNull() is True. :return: This EncryptedContent so that you can chain calls to update values. :rtype: EncryptedContent """ self._initialVector = (initialVector if isinstance(initialVector, Blob) else Blob(initialVector)) return self def setPayload(self, payload): """ Set the encrypted payload. :param Blob payload: The payload. If not specified, set to the default Blob() where isNull() is True. :return: This EncryptedContent so that you can chain calls to update values. :rtype: EncryptedContent """ self._payload = payload if isinstance(payload, Blob) else Blob(payload) return self def setPayloadKey(self, payloadKey): """ Set the encrypted payload key. :param Blob payloadKey: The encrypted payload key. If not specified, set to the default Blob() where isNull() is True. :return: This EncryptedContent so that you can chain calls to update values. :rtype: EncryptedContent """ self._payloadKey = (payloadKey if isinstance(payloadKey, Blob) else Blob(payloadKey)) return self def clear(self): """ Set all the fields to indicate unspecified values. """ self._algorithmType = None self._keyLocator = KeyLocator() self._initialVector = Blob() self._payload = Blob() self._payloadKey = Blob() def wireEncode(self, wireFormat = None): """ Encode this to an EncryptedContent v1 for a particular wire format. :param wireFormat: (optional) A WireFormat object used to encode this EncryptedContent. 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.encodeEncryptedContent(self) def wireEncodeV2(self, wireFormat = None): """ Encode this to an EncryptedContent v2 for a particular wire format. :param wireFormat: (optional) A WireFormat object used to encode this EncryptedContent. 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.encodeEncryptedContentV2(self) def wireDecode(self, input, wireFormat = None): """ Decode the input as an EncryptedContent v1 using a particular wire format and update this EncryptedContent. :param input: The array with the bytes to decode. :type input: A Blob or an array type with int elements :param wireFormat: (optional) A WireFormat object used to decode this EncryptedContent. 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 isinstance(input, Blob): # Input is a blob, so get its buf() and set copy False. wireFormat.decodeEncryptedContent(self, input.buf(), False) else: wireFormat.decodeEncryptedContent(self, input, True) def wireDecodeV2(self, input, wireFormat = None): """ Decode the input as an EncryptedContent v2 using a particular wire format and update this EncryptedContent. :param input: The array with the bytes to decode. :type input: A Blob or an array type with int elements :param wireFormat: (optional) A WireFormat object used to decode this EncryptedContent. 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 isinstance(input, Blob): # Input is a blob, so get its buf() and set copy False. wireFormat.decodeEncryptedContentV2(self, input.buf(), False) else: wireFormat.decodeEncryptedContentV2(self, input, True)