def _lookupCertificate(self, certID, isPath): """ This looks up certificates specified as base64-encoded data or file names. These are cached by filename or encoding to avoid repeated reading of files or decoding. :return: The certificate object, or None if not found. :rtype: IdentityCertificate """ if not self._isSecurityV1: raise SecurityException( "lookupCertificate: For security v2, use lookupCertificateV2()") try: certUri = self._fixedCertificateCache[certID] except KeyError: if isPath: # load the certificate data (base64 encoded IdentityCertificate) cert = TrustAnchorRefreshManager.loadIdentityCertificateFromFile( certID) else: certData = b64decode(certID) cert = IdentityCertificate() cert.wireDecode(Blob(certData, False)) certUri = cert.getName()[:-1].toUri() self._fixedCertificateCache[certID] = certUri self._certificateCache.insertCertificate(cert) else: cert = self._certificateCache.getCertificate(Name(certUri)) return cert
def _lookupCertificate(self, certID, isPath): """ This looks up certificates specified as base64-encoded data or file names. These are cached by filename or encoding to avoid repeated reading of files or decoding. :return: The certificate object, or None if not found. :rtype: IdentityCertificate """ try: certUri = self._fixedCertificateCache[certID] except KeyError: if isPath: # load the certificate data (base64 encoded IdentityCertificate) cert = TrustAnchorRefreshManager.loadIdentityCertificateFromFile( certID) else: certData = b64decode(certID) cert = IdentityCertificate() cert.wireDecode(Blob(certData, False)) certUri = cert.getName()[:-1].toUri() self._fixedCertificateCache[certID] = certUri self._certificateCache.insertCertificate(cert) else: cert = self._certificateCache.getCertificate(Name(certUri)) return cert
def loadIdentityCertificateFromFile(filename): with open(filename, 'r') as certFile: encodedData = certFile.read() decodedData = b64decode(encodedData) cert = IdentityCertificate() cert.wireDecode(Blob(decodedData, False)) return cert
def getCertificate(self, certificateName): """ Get a certificate from the identity storage. :param Name certificateName: The name of the requested certificate. :return: The requested certificate. :rtype: IdentityCertificate :raises SecurityException: if the certificate doesn't exist. """ cursor = self._database.cursor() cursor.execute("SELECT certificate_data FROM Certificate WHERE cert_name=?", (certificateName.toUri(), )) row = cursor.fetchone() if row != None: (certData, ) = row cursor.close() certificate = IdentityCertificate() try: certificate.wireDecode(bytearray(certData)) except ValueError: raise SecurityException( "BasicIdentityStorage.getCertificate: The certificate cannot be decoded") return certificate else: cursor.close() raise SecurityException( "BasicIdentityStorage.getCertificate: The certificate does not exist")
def getCertificate(self, certificateName): """ Get a certificate from the identity storage. :param Name certificateName: The name of the requested certificate. :return: The requested certificate. :rtype: IdentityCertificate :raises SecurityException: if the certificate doesn't exist. """ cursor = self._database.cursor() cursor.execute( "SELECT certificate_data FROM Certificate WHERE cert_name=?", (certificateName.toUri(), )) row = cursor.fetchone() if row != None: (certData, ) = row cursor.close() certificate = IdentityCertificate() try: certificate.wireDecode(bytearray(certData)) except ValueError: raise SecurityException( "BasicIdentityStorage::getCertificate: The certificate cannot be decoded" ) return certificate else: cursor.close() raise SecurityException( "BasicIdentityStorage::getCertificate: The certificate does not exist" )
def getCertificate(self, certificateName, allowAny=False): """ Get a certificate from the identity storage. :param Name certificateName: The name of the requested certificate. :param bool allowAny: (optional) If False, only a valid certificate will be returned, otherwise validity is disregarded. If omitted, allowAny is False. :return: The requested certificate. If not found, return None. :rtype: IdentityCertificate """ if not self.doesCertificateExist(certificateName): return None if not allowAny: raise RuntimeError( "BasicIdentityStorage.getCertificate for not allowAny is not implemented" ) cursor = self._database.cursor() cursor.execute( "SELECT certificate_data FROM Certificate WHERE cert_name=?", (certificateName.toUri())) (certData, ) = cursor.fetchone() cursor.close() certificate = IdentityCertificate() certificate.wireDecode(bytearray(certData)) return certificate
def _lookupCertificate(self, certID, isPath): """ This looks up certificates specified as base64-encoded data or file names. These are cached by filename or encoding to avoid repeated reading of files or decoding. """ try: certUri = self._fixedCertificateCache[certID] except KeyError: if isPath: # load the certificate data (base64 encoded IdentityCertificate) cert = TrustAnchorRefreshManager.loadIdentityCertificateFromFile( certID) else: certData = b64decode(certID) cert = IdentityCertificate() cert.wireDecode(certData) certUri = cert.getName()[:-1].toUri() self._fixedCertificateCache[certID] = certUri self._certificateCache.insertCertificate(cert) else: cert = self._certificateCache.getCertificate(Name(certUri)) return cert
def getCertificate(self, certificateName, allowAny = False): """ Get a certificate from the identity storage. :param Name certificateName: The name of the requested certificate. :param bool allowAny: (optional) If False, only a valid certificate will be returned, otherwise validity is disregarded. If omitted, allowAny is False. :return: The requested certificate. If not found, return None. :rtype: IdentityCertificate """ if not self.doesCertificateExist(certificateName): return None if not allowAny: raise RuntimeError( "BasicIdentityStorage.getCertificate for not allowAny is not implemented") cursor = self._database.cursor() cursor.execute("SELECT certificate_data FROM Certificate WHERE cert_name=?", (certificateName.toUri(), )) (certData, ) = cursor.fetchone() cursor.close() certificate = IdentityCertificate() certificate.wireDecode(bytearray(certData)) return certificate
def insertCertificate(self, certificate): """ Insert the certificate into the cache. Assumes the timestamp is not yet removed. :param IdentityCertificate certificate: The certificate to insert. """ certificate = IdentityCertificate(certificate) certName = certificate.getName()[:-1] self._cache[certName.toUri()] = certificate.wireEncode()
def getCertificate(self, certificateName): """ Fetch a certificate from the cache. :param Name certificateName: The name of the certificate to remove. Assumes there is no timestamp in the name. """ try: cert = IdentityCertificate() certData = self._cache[certificateName.toUri()] cert.wireDecode(certData) return cert except KeyError: return None
def _getPublicKeyDer(self, keyLocator, failureReason): """ Look in the IdentityStorage for the public key with the name in the KeyLocator. If the public key can't be found, return and empty Blob. :param KeyLocator keyLocator: The KeyLocator. :param Array<str> failureReason: If can't find the public key, set failureReason[0] to the failure reason string. :return: The public key DER or an empty Blob if not found. :rtype: Blob """ if (keyLocator.getType() == KeyLocatorType.KEYNAME and self._identityStorage != None): try: # Assume the key name is a certificate name. keyName = IdentityCertificate.certificateNameToPublicKeyName( keyLocator.getKeyName()) except Exception: failureReason[0] = ( "Cannot get a public key name from the certificate named: " + keyLocator.getKeyName().toUri()) return Blob() try: return self._identityStorage.getKey(keyName) except SecurityException: failureReason[0] = ( "The identityStorage doesn't have the key named " + keyName.toUri()) return Blob() else: # Can't find a key to verify. failureReason[ 0] = "The signature KeyLocator doesn't have a key name" return Blob()
def test_identity_create_delete(self): identityName = Name('/TestIdentityStorage/Identity').appendVersion( int(time.time())) certificateName = self.keyChain.createIdentityAndCertificate( identityName) keyName = IdentityCertificate.certificateNameToPublicKeyName( certificateName) self.assertTrue(self.identityStorage.doesIdentityExist(identityName), "Identity was not added to IdentityStorage") self.assertIsNotNone(keyName, "New identity has no key") self.assertTrue(self.identityStorage.doesKeyExist(keyName), "Key was not added to IdentityStorage") self.assertIsNotNone(certificateName, "Certificate was not added to IdentityStorage") self.keyChain.deleteIdentity(identityName) self.assertFalse(self.identityStorage.doesIdentityExist(identityName), "Identity still in IdentityStorage after revoking") self.assertFalse( self.identityStorage.doesKeyExist(keyName), "Key still in IdentityStorage after identity was deletedInfo") self.assertFalse( self.identityStorage.doesCertificateExist(certificateName), "Certificate still in IdentityStorage after identity was deletedInfo" ) with self.assertRaises(SecurityException): self.identityManager.getDefaultCertificateNameForIdentity( identityName)
def test_identity_create_delete(self): identityName = Name('/TestIdentityStorage/Identity').appendVersion( int(time.time())) certificateName = self.keyChain.createIdentityAndCertificate(identityName) keyName = IdentityCertificate.certificateNameToPublicKeyName(certificateName) self.assertTrue(self.identityStorage.doesIdentityExist(identityName), "Identity was not added to IdentityStorage") self.assertIsNotNone(keyName, "New identity has no key") self.assertTrue(self.identityStorage.doesKeyExist(keyName), "Key was not added to IdentityStorage") self.assertIsNotNone(certificateName, "Certificate was not added to IdentityStorage") self.keyChain.deleteIdentity(identityName) self.assertFalse(self.identityStorage.doesIdentityExist(identityName), "Identity still in IdentityStorage after identity was deleted") self.assertFalse(self.identityStorage.doesKeyExist(keyName), "Key still in IdentityStorage after identity was deleted") self.assertFalse(self.identityStorage.doesCertificateExist(certificateName), "Certificate still in IdentityStorage after identity was deleted") with self.assertRaises(SecurityException): self.identityManager.getDefaultCertificateNameForIdentity(identityName)
def _getPublicKeyDer(self, keyLocator, failureReason): """ Look in the IdentityStorage for the public key with the name in the KeyLocator. If the public key can't be found, return and empty Blob. :param KeyLocator keyLocator: The KeyLocator. :param Array<str> failureReason: If can't find the public key, set failureReason[0] to the failure reason string. :return: The public key DER or an empty Blob if not found. :rtype: Blob """ if (keyLocator.getType() == KeyLocatorType.KEYNAME and self._identityStorage != None): try: # Assume the key name is a certificate name. keyName = IdentityCertificate.certificateNameToPublicKeyName( keyLocator.getKeyName()) except Exception: failureReason[0] = ( "Cannot get a public key name from the certificate named: " + keyLocator.getKeyName().toUri()) return Blob() try: return self._identityStorage.getKey(keyName) except SecurityException: failureReason[0] = ( "The identityStorage doesn't have the key named " + keyName.toUri()) return Blob() else: # Can't find a key to verify. failureReason[0] = "The signature KeyLocator doesn't have a key name" return Blob()
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)
def addMember(self, scheduleName, memberCertificate): """ Add a new member with the given memberCertificate into a schedule named scheduleName. If cert is an IdentityCertificate made from memberCertificate, then the member's identity name is cert.getPublicKeyName().getPrefix(-1). :param str scheduleName: The schedule name. :param Data memberCertificate: The member's certificate. :raises GroupManagerDb.Error: If there's no schedule named scheduleName, if the member's identity name already exists, or other database error. :raises DerDecodingException: for error decoding memberCertificate as a certificate. """ cert = IdentityCertificate(memberCertificate) self._database.addMember(scheduleName, cert.getPublicKeyName(), cert.getPublicKeyInfo().getKeyDer())
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 """ signature = signatureInfo if not isinstance(signature, Sha256WithRsaSignature): raise SecurityException( "SelfVerifyPolicyManager: Signature is not Sha256WithRsaSignature.") if (signature.getKeyLocator().getType() == KeyLocatorType.KEYNAME and self._identityStorage != None): # Assume the key name is a certificate name. publicKeyDer = self._identityStorage.getKey( IdentityCertificate.certificateNameToPublicKeyName( signature.getKeyLocator().getKeyName())) if publicKeyDer.isNull(): # Can't find the public key with the name. return False return self._verifySha256WithRsaSignature( signature, signedBlob, publicKeyDer) else: # Can't find a key to verify. return False
def test_stress(self): # ndn-cxx/tests/unit-tests/security/test-sec-public-info-sqlite3.cpp identityName = Name("/TestSecPublicInfoSqlite3/Delete").appendVersion( int(time.time())) # ndn-cxx returns the cert name, but the IndentityManager docstring # specifies a key certName1 = self.keyChain.createIdentityAndCertificate(identityName) keyName1 = IdentityCertificate.certificateNameToPublicKeyName( certName1) keyName2 = self.keyChain.generateRSAKeyPairAsDefault(identityName) cert2 = self.identityManager.selfSign(keyName2) certName2 = cert2.getName() self.identityManager.addCertificateAsDefault(cert2) keyName3 = self.keyChain.generateRSAKeyPairAsDefault(identityName) cert3 = self.identityManager.selfSign(keyName3) certName3 = cert3.getName() self.identityManager.addCertificateAsDefault(cert3) cert4 = self.identityManager.selfSign(keyName3) self.identityManager.addCertificateAsDefault(cert4) certName4 = cert4.getName() cert5 = self.identityManager.selfSign(keyName3) self.identityManager.addCertificateAsDefault(cert5) certName5 = cert5.getName() self.assertTrue(self.identityStorage.doesIdentityExist(identityName)) self.assertTrue(self.identityStorage.doesKeyExist(keyName1)) self.assertTrue(self.identityStorage.doesKeyExist(keyName2)) self.assertTrue(self.identityStorage.doesKeyExist(keyName3)) self.assertTrue(self.identityStorage.doesCertificateExist(certName1)) self.assertTrue(self.identityStorage.doesCertificateExist(certName2)) self.assertTrue(self.identityStorage.doesCertificateExist(certName3)) self.assertTrue(self.identityStorage.doesCertificateExist(certName4)) self.assertTrue(self.identityStorage.doesCertificateExist(certName5)) self.identityStorage.deleteCertificateInfo(certName5) self.assertFalse(self.identityStorage.doesCertificateExist(certName5)) self.assertTrue(self.identityStorage.doesCertificateExist(certName4)) self.assertTrue(self.identityStorage.doesCertificateExist(certName3)) self.assertTrue(self.identityStorage.doesKeyExist(keyName2)) self.identityStorage.deletePublicKeyInfo(keyName3) self.assertFalse(self.identityStorage.doesCertificateExist(certName4)) self.assertFalse(self.identityStorage.doesCertificateExist(certName3)) self.assertFalse(self.identityStorage.doesKeyExist(keyName3)) self.assertTrue(self.identityStorage.doesKeyExist(keyName2)) self.assertTrue(self.identityStorage.doesKeyExist(keyName1)) self.assertTrue(self.identityStorage.doesIdentityExist(identityName)) self.keyChain.deleteIdentity(identityName) self.assertFalse(self.identityStorage.doesCertificateExist(certName2)) self.assertFalse(self.identityStorage.doesKeyExist(keyName2)) self.assertFalse(self.identityStorage.doesCertificateExist(certName1)) self.assertFalse(self.identityStorage.doesKeyExist(keyName1)) self.assertFalse(self.identityStorage.doesIdentityExist(identityName))
def test_stress(self): # ndn-cxx/tests/unit-tests/security/test-sec-public-info-sqlite3.cpp identityName = Name("/TestSecPublicInfoSqlite3/Delete").appendVersion( int(time.time())) # ndn-cxx returns the cert name, but the IndentityManager docstring # specifies a key certName1 = self.keyChain.createIdentityAndCertificate(identityName) keyName1 = IdentityCertificate.certificateNameToPublicKeyName(certName1) keyName2 = self.keyChain.generateRSAKeyPairAsDefault(identityName) cert2 = self.identityManager.selfSign(keyName2) certName2 = cert2.getName() self.identityManager.addCertificateAsDefault(cert2) keyName3 = self.keyChain.generateRSAKeyPairAsDefault(identityName) cert3 = self.identityManager.selfSign(keyName3) certName3 = cert3.getName() self.identityManager.addCertificateAsDefault(cert3) cert4 = self.identityManager.selfSign(keyName3) self.identityManager.addCertificateAsDefault(cert4) certName4 = cert4.getName() cert5 = self.identityManager.selfSign(keyName3) self.identityManager.addCertificateAsDefault(cert5) certName5 = cert5.getName() self.assertTrue(self.identityStorage.doesIdentityExist(identityName)) self.assertTrue(self.identityStorage.doesKeyExist(keyName1)) self.assertTrue(self.identityStorage.doesKeyExist(keyName2)) self.assertTrue(self.identityStorage.doesKeyExist(keyName3)) self.assertTrue(self.identityStorage.doesCertificateExist(certName1)) self.assertTrue(self.identityStorage.doesCertificateExist(certName2)) self.assertTrue(self.identityStorage.doesCertificateExist(certName3)) self.assertTrue(self.identityStorage.doesCertificateExist(certName4)) self.assertTrue(self.identityStorage.doesCertificateExist(certName5)) self.identityStorage.deleteCertificateInfo(certName5) self.assertFalse(self.identityStorage.doesCertificateExist(certName5)) self.assertTrue(self.identityStorage.doesCertificateExist(certName4)) self.assertTrue(self.identityStorage.doesCertificateExist(certName3)) self.assertTrue(self.identityStorage.doesKeyExist(keyName2)) self.identityStorage.deletePublicKeyInfo(keyName3) self.assertFalse(self.identityStorage.doesCertificateExist(certName4)) self.assertFalse(self.identityStorage.doesCertificateExist(certName3)) self.assertFalse(self.identityStorage.doesKeyExist(keyName3)) self.assertTrue(self.identityStorage.doesKeyExist(keyName2)) self.assertTrue(self.identityStorage.doesKeyExist(keyName1)) self.assertTrue(self.identityStorage.doesIdentityExist(identityName)) self.keyChain.deleteIdentity(identityName) self.assertFalse(self.identityStorage.doesCertificateExist(certName2)) self.assertFalse(self.identityStorage.doesKeyExist(keyName2)) self.assertFalse(self.identityStorage.doesCertificateExist(certName1)) self.assertFalse(self.identityStorage.doesKeyExist(keyName1)) self.assertFalse(self.identityStorage.doesIdentityExist(identityName))
def _getPublicKeyDer(self, keyLocator): """ Look in the IdentityStorage for the public key with the name in the KeyLocator. If the public key can't be found, return and empty Blob. :param KeyLocator keyLocator: The KeyLocator. :return: The public key DER or an empty Blob if not found. :rtype: Blob """ if keyLocator.getType() == KeyLocatorType.KEYNAME and self._identityStorage != None: # Assume the key name is a certificate name. return self._identityStorage.getKey( IdentityCertificate.certificateNameToPublicKeyName(keyLocator.getKeyName()) ) else: return Blob()
def _getPublicKeyDer(self, keyLocator): """ Look in the IdentityStorage for the public key with the name in the KeyLocator. If the public key can't be found, return and empty Blob. :param KeyLocator keyLocator: The KeyLocator. :return: The public key DER or an empty Blob if not found. :rtype: Blob """ if (keyLocator.getType() == KeyLocatorType.KEYNAME and self._identityStorage != None): # Assume the key name is a certificate name. return self._identityStorage.getKey( IdentityCertificate.certificateNameToPublicKeyName( keyLocator.getKeyName())) else: return Blob()
def checkVerificationPolicy(self, data, stepCount, onVerified, onVerifyFailed): """ Look in the IdentityStorage for the public key with the name in the KeyLocator (if available) and use it to verify the data packet. If the public key can't be found, call onVerifyFailed. :param Data data: The Data object with the signature to check. :param int stepCount: The number of verification steps that have been done, used to track the verification progress. (stepCount is ignored.) :param onVerified: If the signature is verified, this calls onVerified(data). :type onVerified: function object :param onVerifyFailed: If the signature check fails or can't find the public key, this calls onVerifyFailed(data). :type onVerifyFailed: function object :return: None for no further step for looking up a certificate chain. :rtype: ValidationRequest """ signature = data.getSignature() if not isinstance(signature, Sha256WithRsaSignature): raise SecurityException( "SelfVerifyPolicyManager: Signature is not Sha256WithRsaSignature." ) if (signature.getKeyLocator().getType() == KeyLocatorType.KEYNAME and self._identityStorage != None): # Assume the key name is a certificate name. publicKeyDer = self._identityStorage.getKey( IdentityCertificate.certificateNameToPublicKeyName( signature.getKeyLocator().getKeyName())) if publicKeyDer.isNull(): # Can't find the public key with the name. onVerifyFailed(data) if self._verifySha256WithRsaSignature(data, publicKeyDer): onVerified(data) else: onVerifyFailed(data) else: # Can't find a key to verify. onVerifyFailed(data) # No more steps, so return a None. return None
def createIdentity(self, identityName, params = None): """ Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK. If a key pair or certificate for the identity already exists, use it. :deprecated: Use createIdentityAndCertificate which returns the certificate name instead of the key name. You can use IdentityCertificate.certificateNameToPublicKeyName to convert the certificate name to the key name. :param Name identityName: The name of the identity. :param KeyParams params: (optional) The key parameters if a key needs to be generated for the identity. If omitted, use DEFAULT_KEY_PARAMS. :return: The key name of the auto-generated KSK of the identity. :rtype: Name """ return IdentityCertificate.certificateNameToPublicKeyName( self.createIdentityAndCertificate(identityName, params))
def checkVerificationPolicy(self, data, stepCount, onVerified, onVerifyFailed): """ Look in the IdentityStorage for the public key with the name in the KeyLocator (if available) and use it to verify the data packet. If the public key can't be found, call onVerifyFailed. :param Data data: The Data object with the signature to check. :param int stepCount: The number of verification steps that have been done, used to track the verification progress. (stepCount is ignored.) :param onVerified: If the signature is verified, this calls onVerified(data). :type onVerified: function object :param onVerifyFailed: If the signature check fails or can't find the public key, this calls onVerifyFailed(data). :type onVerifyFailed: function object :return: None for no further step for looking up a certificate chain. :rtype: ValidationRequest """ signature = data.getSignature() if not isinstance(signature, Sha256WithRsaSignature): raise SecurityException( "SelfVerifyPolicyManager: Signature is not Sha256WithRsaSignature.") if (signature.getKeyLocator().getType() == KeyLocatorType.KEYNAME and self._identityStorage != None): # Assume the key name is a certificate name. publicKeyDer = self._identityStorage.getKey( IdentityCertificate.certificateNameToPublicKeyName( signature.getKeyLocator().getKeyName())) if publicKeyDer.isNull(): # Can't find the public key with the name. onVerifyFailed(data) if self._verifySha256WithRsaSignature(data, publicKeyDer): onVerified(data) else: onVerifyFailed(data) else: # Can't find a key to verify. onVerifyFailed(data) # No more steps, so return a None. return 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 """ 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 onCertificateDownloadComplete(certificate): certificate = IdentityCertificate(certificate) self._certificateCache.insertCertificate(certificate) self.checkVerificationPolicy(dataOrInterest, stepCount + 1, onVerified, onVerifyFailed)
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")