Example #1
0
    def _processValidCertificate(self, data):
        # unpack the cert from the HMAC signed packet and verify
        try:
            newCert = IdentityCertificate()
            newCert.wireDecode(data.getContent())
            self.log.info("Received certificate from controller")
            self.log.debug(str(newCert))

            # NOTE: we download and install the root certificate without verifying it (!)
            # otherwise our policy manager will reject it.
            # we may need a static method on KeyChain to allow verifying before adding
    
            rootCertName = newCert.getSignature().getKeyLocator().getKeyName()
            # update trust rules so we trust the controller
            self._policyManager.setDeviceIdentity(self._configureIdentity) 
            self._policyManager.updateTrustRules()

            def onRootCertificateDownload(interest, data):
                try:
                    self._identityStorage.addCertificate(data)
                except SecurityException:
                    # already exists
                    pass
                self._keyChain.verifyData(newCert, self._finalizeCertificateDownload, self._certificateValidationFailed)

            def onRootCertificateTimeout(interest):
                # TODO: limit number of tries, then revert trust root + network prefix
                # reset salt, create new Hmac key
                self.face.expressInterest(rootCertName, onRootCertificateDownload, onRootCertificateTimeout)

            self.face.expressInterest(rootCertName, onRootCertificateDownload, onRootCertificateTimeout)

        except Exception as e:
            self.log.exception("Could not import new certificate", exc_info=True)
Example #2
0
    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: Data
        """
        chosenCert = None
        certificateUri = certificateName.toUri()
        cursor = self._database.cursor()

        #if not allowAny:
        #    validityClause = " AND valid_flag=1"
        #else:
        validityClause = ""

        # use LIKE because key locators chop off timestamps
        # need to escape any percent signs in the certificate uri for sql's
        # sake, but still append % for LIKE
        escapedUri = certificateUri.replace('%', '\\%')
        full_statement = "SELECT certificate_data FROM Certificate WHERE cert_name LIKE ?"+validityClause+" ESCAPE '\\' ORDER BY cert_name DESC"
        #full_statement = "SELECT certificate_data FROM Certificate WHERE cert_name=?"+validityClause
        cursor.execute(full_statement, (escapedUri+'%', ))
        try:
            (certData, ) = cursor.fetchone()
        except TypeError:
            pass
        else:
            chosenCert = IdentityCertificate()
            chosenCert.wireDecode(bytearray(certData))
        return chosenCert 
Example #3
0
    def _processValidCertificate(self, data):
        # unpack the cert from the HMAC signed packet and verify
        try:
            newCert = IdentityCertificate()
            newCert.wireDecode(data.getContent())
            self.log.info("Received certificate from controller")

            # NOTE: we download and install the root certificate without verifying it (!)
            # otherwise our policy manager will reject it.
            # we may need a static method on KeyChain to allow verifying before adding
    
            rootCertName = newCert.getSignature().getKeyLocator().getKeyName()
            # update trust rules so we trust the controller
            self._policyManager.setDeviceIdentity(self._configureIdentity) 
            self._policyManager.updateTrustRules()

            def onRootCertificateDownload(interest, data):
                try:
                    # zhehao: the root cert is downloaded and installed without verifying; should the root cert be preconfigured?
                    # Insert root certificate so that we can verify newCert
                    self._policyManager._certificateCache.insertCertificate(data)

                    # Set the root cert as default for root identity
                    try:
                        self._identityManager.addCertificateAsIdentityDefault(IdentityCertificate(data))
                    except SecurityException as e:
                        print("Error when addCertificateAsIdentityDefault for root: " + data.getName().toUri())
                        print(str(e))

                    self._rootCertificate = data
                    try:
                        # use the default configuration where possible
                        # TODO: use environment variable for this, fall back to default
                        fileName = os.path.expanduser('~/.ndn/.iot.root.cert')
                        rootCertFile = open(fileName, "w")
                        rootCertFile.write(Blob(b64encode(self._rootCertificate.wireEncode().toBytes()), False).toRawStr())
                        rootCertFile.close()
                    except IOError as e:
                        self.log.error("Cannot write to root certificate file: " + rootCertFile)
                        print "Cannot write to root certificate file: " + rootCertFile

                except SecurityException as e:
                    print(str(e))
                    # already exists, or got certificate in wrong format
                    pass
                self._keyChain.verifyData(newCert, self._finalizeCertificateDownload, self._certificateValidationFailed)

            def onRootCertificateTimeout(interest):
                # TODO: limit number of tries, then revert trust root + network prefix
                # reset salt, create new Hmac key
                self.face.expressInterest(rootCertName, onRootCertificateDownload, onRootCertificateTimeout)

            self.face.expressInterest(rootCertName, onRootCertificateDownload, onRootCertificateTimeout)

        except Exception as e:
            self.log.exception("Could not import new certificate", exc_info=True)
Example #4
0
    def test_refresh_10s(self):
        with open('policy_config/testData', 'r') as dataFile:
            encodedData = dataFile.read()
            data = Data()
            dataBlob = Blob(b64decode(encodedData))
            data.wireDecode(dataBlob)

        # needed, since the KeyChain will express interests in unknown
        # certificates
        vr = doVerify(self.policyManager, data)

        self.assertTrue(vr.hasFurtherSteps,
                "ConfigPolicyManager did not create ValidationRequest for unknown certificate")
        self.assertEqual(vr.successCount, 0,
                "ConfigPolicyManager called success callback with pending ValidationRequest")
        self.assertEqual(vr.failureCount, 0,
                "ConfigPolicyManager called failure callback with pending ValidationRequest")

        # now save the cert data to our anchor directory, and wait
        # we have to sign it with the current identity or the
        # policy manager will create an interest for the signing certificate

        with open(self.testCertFile, 'w') as certFile:
            cert = IdentityCertificate()
            certData = b64decode(CERT_DUMP)
            cert.wireDecode(Blob(certData, False))
            self.keyChain.signByIdentity(cert, self.identityName)
            encodedCert = b64encode(cert.wireEncode().toBuffer())
            certFile.write(Blob(encodedCert, False).toRawStr())

        # still too early for refresh to pick it up
        vr = doVerify(self.policyManager, data)

        self.assertTrue(vr.hasFurtherSteps,
                "ConfigPolicyManager refresh occured sooner than specified")
        self.assertEqual(vr.successCount, 0,
                "ConfigPolicyManager called success callback with pending ValidationRequest")
        self.assertEqual(vr.failureCount, 0,
                "ConfigPolicyManager called failure callback with pending ValidationRequest")
        time.sleep(6)

        # now we should find it
        vr  = doVerify(self.policyManager, data)

        self.assertFalse(vr.hasFurtherSteps,
                "ConfigPolicyManager did not refresh certificate store")
        self.assertEqual(vr.successCount, 1,
                "Verification success called {} times instead of 1".format(
                    vr.successCount))
        self.assertEqual(vr.failureCount, 0,
                "ConfigPolicyManager did not verify valid signed data")
    def test_refresh_10s(self):
        with open('policy_config/testData', 'r') as dataFile:
            encodedData = dataFile.read()
            data = Data()
            dataBlob = Blob(b64decode(encodedData))
            data.wireDecode(dataBlob)

        # needed, since the KeyChain will express interests in unknown
        # certificates
        vr = doVerify(self.policyManager, data)

        self.assertTrue(vr.hasFurtherSteps,
                "ConfigPolicyManager did not create ValidationRequest for unknown certificate")
        self.assertEqual(vr.successCount, 0,
                "ConfigPolicyManager called success callback with pending ValidationRequest")
        self.assertEqual(vr.failureCount, 0,
                "ConfigPolicyManager called failure callback with pending ValidationRequest")

        # now save the cert data to our anchor directory, and wait
        # we have to sign it with the current identity or the
        # policy manager will create an interest for the signing certificate

        with open(self.testCertFile, 'w') as certFile:
            cert = IdentityCertificate()
            certData = b64decode(CERT_DUMP)
            cert.wireDecode(Blob(certData, False))
            self.keyChain.signByIdentity(cert, self.identityName)
            encodedCert = b64encode(cert.wireEncode().toBytes())
            certFile.write(Blob(encodedCert, False).toRawStr())

        # still too early for refresh to pick it up
        vr = doVerify(self.policyManager, data)

        self.assertTrue(vr.hasFurtherSteps,
                "ConfigPolicyManager refresh occured sooner than specified")
        self.assertEqual(vr.successCount, 0,
                "ConfigPolicyManager called success callback with pending ValidationRequest")
        self.assertEqual(vr.failureCount, 0,
                "ConfigPolicyManager called failure callback with pending ValidationRequest")
        time.sleep(6)

        # now we should find it
        vr  = doVerify(self.policyManager, data)

        self.assertFalse(vr.hasFurtherSteps,
                "ConfigPolicyManager did not refresh certificate store")
        self.assertEqual(vr.successCount, 1,
                "Verification success called {} times instead of 1".format(
                    vr.successCount))
        self.assertEqual(vr.failureCount, 0,
                "ConfigPolicyManager did not verify valid signed data")
Example #6
0
    def test_create_d_key_data(self):
        # Create the group manager.
        manager = GroupManager(
            Name("Alice"), Name("data_type"),
            Sqlite3GroupManagerDb(self.dKeyDatabaseFilePath), 2048, 1,
            self.keyChain)

        newCertificateBlob = self.certificate.wireEncode()
        newCertificate = IdentityCertificate()
        newCertificate.wireDecode(newCertificateBlob)

        # Encrypt the D-KEY.
        data = manager._createDKeyData(
            "20150825T000000", "20150827T000000", Name("/ndn/memberA/KEY"),
            self.decryptKeyBlob,
            newCertificate.getPublicKeyInfo().getKeyDer())

        # Verify the encrypted D-KEY.
        dataContent = data.getContent()

        # Get the nonce key.
        # dataContent is a sequence of the two EncryptedContent.
        encryptedNonce = EncryptedContent()
        encryptedNonce.wireDecode(dataContent)
        self.assertEqual(0, encryptedNonce.getInitialVector().size())
        self.assertEqual(EncryptAlgorithmType.RsaOaep,
                         encryptedNonce.getAlgorithmType())

        blobNonce = encryptedNonce.getPayload()
        decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep)
        nonce = RsaAlgorithm.decrypt(self.decryptKeyBlob, blobNonce,
                                     decryptParams)

        # Get the D-KEY.
        # Use the size of encryptedNonce to find the start of encryptedPayload.
        payloadContent = dataContent.buf()[encryptedNonce.wireEncode().size():]
        encryptedPayload = EncryptedContent()
        encryptedPayload.wireDecode(payloadContent)
        self.assertEqual(16, encryptedPayload.getInitialVector().size())
        self.assertEqual(EncryptAlgorithmType.AesCbc,
                         encryptedPayload.getAlgorithmType())

        decryptParams.setAlgorithmType(EncryptAlgorithmType.AesCbc)
        decryptParams.setInitialVector(encryptedPayload.getInitialVector())
        blobPayload = encryptedPayload.getPayload()
        largePayload = AesAlgorithm.decrypt(nonce, blobPayload, decryptParams)

        self.assertTrue(largePayload.equals(self.decryptKeyBlob))
Example #7
0
    def test_create_d_key_data(self):
        # Create the group manager.
        manager = GroupManager(
          Name("Alice"), Name("data_type"),
          Sqlite3GroupManagerDb(self.dKeyDatabaseFilePath), 2048, 1,
          self.keyChain)

        newCertificateBlob = self.certificate.wireEncode()
        newCertificate = IdentityCertificate()
        newCertificate.wireDecode(newCertificateBlob)

        # Encrypt the D-KEY.
        data = manager._createDKeyData(
          "20150825T000000", "20150827T000000", Name("/ndn/memberA/KEY"),
          self.decryptKeyBlob, newCertificate.getPublicKeyInfo().getKeyDer())

        # Verify the encrypted D-KEY.
        dataContent = data.getContent()

        # Get the nonce key.
        # dataContent is a sequence of the two EncryptedContent.
        encryptedNonce = EncryptedContent()
        encryptedNonce.wireDecode(dataContent)
        self.assertEqual(0, encryptedNonce.getInitialVector().size())
        self.assertEqual(EncryptAlgorithmType.RsaOaep, encryptedNonce.getAlgorithmType())

        blobNonce = encryptedNonce.getPayload()
        decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep)
        nonce = RsaAlgorithm.decrypt(self.decryptKeyBlob, blobNonce, decryptParams)

        # Get the D-KEY.
        # Use the size of encryptedNonce to find the start of encryptedPayload.
        payloadContent = dataContent.buf()[encryptedNonce.wireEncode().size():]
        encryptedPayload = EncryptedContent()
        encryptedPayload.wireDecode(payloadContent)
        self.assertEqual(16, encryptedPayload.getInitialVector().size())
        self.assertEqual(EncryptAlgorithmType.AesCbc, encryptedPayload.getAlgorithmType())

        decryptParams.setAlgorithmType(EncryptAlgorithmType.AesCbc)
        decryptParams.setInitialVector(encryptedPayload.getInitialVector())
        blobPayload = encryptedPayload.getPayload()
        largePayload = AesAlgorithm.decrypt(nonce, blobPayload, decryptParams)

        self.assertTrue(largePayload.equals(self.decryptKeyBlob))
Example #8
0
    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
        """
        certificateNameUri = certificateName.toUri()
        if not (certificateNameUri in self._certificateStore):
            # Not found.  Silently return None.
            return None

        certificate = IdentityCertificate()
        certificate.wireDecode(self._certificateStore[certificateNameUri])
        return certificate
Example #9
0
    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
        """
        certificateNameUri = certificateName.toUri()
        if not (certificateNameUri in self._certificateStore):
            # Not found.  Silently return None.
            return None

        certificate = IdentityCertificate()
        certificate.wireDecode(self._certificateStore[certificateNameUri])
        return certificate
Example #10
0
    def _processValidCertificate(self, data):
        # unpack the cert from the HMAC signed packet and verify
        try:
            newCert = IdentityCertificate()
            newCert.wireDecode(data.getContent())
            self.log.info("Received certificate from controller")
            self.log.debug(str(newCert))

            # NOTE: we download and install the root certificate without verifying it (!)
            # otherwise our policy manager will reject it.
            # we may need a static method on KeyChain to allow verifying before adding

            rootCertName = newCert.getSignature().getKeyLocator().getKeyName()
            # update trust rules so we trust the controller
            self._policyManager.setDeviceIdentity(self._configureIdentity)
            self._policyManager.updateTrustRules()

            def onRootCertificateDownload(interest, data):
                try:
                    self._identityStorage.addCertificate(data)
                except SecurityException:
                    # already exists
                    pass
                self._keyChain.verifyData(newCert,
                                          self._finalizeCertificateDownload,
                                          self._certificateValidationFailed)

            def onRootCertificateTimeout(interest):
                # TODO: limit number of tries, then revert trust root + network prefix
                # reset salt, create new Hmac key
                self.face.expressInterest(rootCertName,
                                          onRootCertificateDownload,
                                          onRootCertificateTimeout)

            self.face.expressInterest(rootCertName, onRootCertificateDownload,
                                      onRootCertificateTimeout)

        except Exception as e:
            self.log.exception("Could not import new certificate",
                               exc_info=True)
Example #11
0
    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.
        """
        certificateNameUri = certificateName.toUri()
        if not (certificateNameUri in self._certificateStore):
            raise SecurityException(
              "MemoryIdentityStorage::getCertificate: The certificate does not exist")

        certificate = IdentityCertificate()
        try:
            certificate.wireDecode(self._certificateStore[certificateNameUri])
        except ValueError:
            raise SecurityException(
              "MemoryIdentityStorage::getCertificate: The certificate cannot be decoded")

        return certificate
Example #12
0
    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.
        """
        certificateNameUri = certificateName.toUri()
        if not (certificateNameUri in self._certificateStore):
            raise SecurityException(
                "MemoryIdentityStorage.getCertificate: The certificate does not exist"
            )

        certificate = IdentityCertificate()
        try:
            certificate.wireDecode(self._certificateStore[certificateNameUri])
        except ValueError:
            raise SecurityException(
                "MemoryIdentityStorage.getCertificate: The certificate cannot be decoded"
            )

        return certificate
Example #13
0
    def _processValidCertificate(self, data):
        # unpack the cert from the HMAC signed packet and verify
        try:
            newCert = IdentityCertificate()
            newCert.wireDecode(data.getContent())
            self.log.info("Received certificate from controller")

            # NOTE: we download and install the root certificate without verifying it (!)
            # otherwise our policy manager will reject it.
            # we may need a static method on KeyChain to allow verifying before adding

            rootCertName = newCert.getSignature().getKeyLocator().getKeyName()
            # update trust rules so we trust the controller
            self._policyManager.setDeviceIdentity(self._configureIdentity)
            self._policyManager.updateTrustRules()

            def onRootCertificateDownload(interest, data):
                try:
                    # zhehao: the root cert is downloaded and installed without verifying; should the root cert be preconfigured?
                    # Insert root certificate so that we can verify newCert
                    self._policyManager._certificateCache.insertCertificate(
                        data)

                    # Set the root cert as default for root identity
                    try:
                        self._identityManager.addCertificateAsIdentityDefault(
                            IdentityCertificate(data))
                    except SecurityException as e:
                        print(
                            "Error when addCertificateAsIdentityDefault for root: "
                            + data.getName().toUri())
                        print(str(e))

                    self._rootCertificate = data
                    try:
                        # use the default configuration where possible
                        # TODO: use environment variable for this, fall back to default
                        fileName = os.path.expanduser('~/.ndn/.iot.root.cert')
                        rootCertFile = open(fileName, "w")
                        rootCertFile.write(
                            Blob(
                                b64encode(self._rootCertificate.wireEncode().
                                          toBytes()), False).toRawStr())
                        rootCertFile.close()
                    except IOError as e:
                        self.log.error(
                            "Cannot write to root certificate file: " +
                            rootCertFile)
                        print "Cannot write to root certificate file: " + rootCertFile

                except SecurityException as e:
                    print(str(e))
                    # already exists, or got certificate in wrong format
                    pass
                self._keyChain.verifyData(newCert,
                                          self._finalizeCertificateDownload,
                                          self._certificateValidationFailed)

            def onRootCertificateTimeout(interest):
                # TODO: limit number of tries, then revert trust root + network prefix
                # reset salt, create new Hmac key
                self.face.expressInterest(rootCertName,
                                          onRootCertificateDownload,
                                          onRootCertificateTimeout)

            self.face.expressInterest(rootCertName, onRootCertificateDownload,
                                      onRootCertificateTimeout)

        except Exception as e:
            self.log.exception("Could not import new certificate",
                               exc_info=True)