Ejemplo n.º 1
0
    def generateKeyPair(self, keyName, params):
        """
        Generate a pair of asymmetric keys.

        :param Name keyName: The name of the key pair.
        :param KeyParams params: The parameters of the key.
        """
        if self.doesKeyExist(keyName, KeyClass.PUBLIC):
            raise SecurityException("Public key already exists")
        if self.doesKeyExist(keyName, KeyClass.PRIVATE):
            raise SecurityException("Private key already exists")

        publicKeyDer = None
        privateKeyDer = None

        if params.getKeyType() == KeyType.RSA:
            key = RSA.generate(params.getKeySize())
            publicKeyDer = key.publickey().exportKey(format='DER')
            privateKeyDer = key.exportKey(format='DER', pkcs=8)
        else:
            raise SecurityException("Unsupported key type")

        keyUri = keyName.toUri()
        publicKeyFilePath = self.nameTransform(keyUri, ".pub")
        privateKeyFilePath = self.nameTransform(keyUri, ".pri")

        with open(publicKeyFilePath, 'w') as keyFile:
            keyFile.write(
                Blob(base64.b64encode(publicKeyDer), False).toRawStr())
        with open(privateKeyFilePath, 'w') as keyFile:
            keyFile.write(
                Blob(base64.b64encode(privateKeyDer), False).toRawStr())

        os.chmod(publicKeyFilePath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
        os.chmod(privateKeyFilePath, stat.S_IRUSR)
Ejemplo n.º 2
0
    def addCertificate(self, certificate):
        """
        Add a certificate to the identity storage.

        :param IdentityCertificate certificate: The certificate to be added.
          This makes a copy of the certificate.
        """
        certificateName = certificate.getName()
        keyName = certificate.getPublicKeyName()

        if not self.doesKeyExist(keyName):
            raise SecurityException(
                "No corresponding Key record for certificate! " +
                keyName.toUri() + " " + certificateName.toUri())

        # Check if the certificate already exists.
        if self.doesCertificateExist(certificateName):
            raise SecurityException("Certificate has already been installed!")

        # Check if the public key of certificate is the same as the key record.
        keyBlob = self.getKey(keyName)
        if (keyBlob.isNull() or
                # Note: In Python, != should do a byte-by-byte comparison.
                keyBlob.toBuffer() !=
                certificate.getPublicKeyInfo().getKeyDer().toBuffer()):
            raise SecurityException(
                "Certificate does not match the public key!")

        # Insert the certificate.
        # wireEncode returns the cached encoding if available.
        self._certificateStore[certificateName.toUri()] = (
            certificate.wireEncode())
Ejemplo n.º 3
0
    def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256):
        """
        Fetch the private key for keyName and sign the data, returning a
        signature Blob.

        :param data: Pointer the input byte buffer to sign.
        :type data: An array type with int elements
        :param Name keyName: The name of the signing key.
        :param digestAlgorithm: (optional) the digest algorithm. If omitted,
          use DigestAlgorithm.SHA256.
        :type digestAlgorithm: int from DigestAlgorithm
        :return: The signature Blob.
        :rtype: Blob
        """
        keyURI = keyName.toUri()

        if not self.doesKeyExist(keyName, KeyClass.PRIVATE):
            raise SecurityException(
                "FilePrivateKeyStorage.sign: private key doesn't exist")

        # Read the private key.
        base64Content = None
        with open(self.nameTransform(keyURI, ".pri")) as keyFile:
            base64Content = keyFile.read()
        pkcs8Der = base64.b64decode(base64Content)

        privateKey = TpmPrivateKey()
        try:
            privateKey.loadPkcs8(pkcs8Der)
            return privateKey.sign(
                Blob(data, False).toBytes(), digestAlgorithm)
        except Exception as ex:
            raise SecurityException("Error in sign: " + str(ex))
Ejemplo n.º 4
0
    def getPublicKey(self, keyName):
        """
        Get the public key with the keyName.

        :param Name keyName: The name of public key.
        :return: The public key.
        :rtype: PublicKey
        """
        publicKey = self._getKey(keyName, KeyClass.PUBLIC)
        if publicKey == None:
            raise SecurityException("The requested public key [" +
                                    keyName.toUri() +
                                    "] does not exist in the OSX Keychain")

        exportedKey = None

        try:
            exportedKey = c_void_p()
            res = self._security.SecItemExport(publicKey,
                                               self._kSecFormatOpenSSL, 0,
                                               None, pointer(exportedKey))
            if res != None:
                raise SecurityException(
                    "Cannot export the requested public key from the OSX Keychain"
                )

            blob = self._CFDataToBlob(exportedKey)

            return PublicKey(blob)
        finally:
            if publicKey != None:
                cf.CFRelease(publicKey)
            if exportedKey != None:
                cf.CFRelease(exportedKey)
Ejemplo n.º 5
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.
        """
        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"
            )
Ejemplo n.º 6
0
    def generateKeyPair(self, keyName, params):
        """
        Generate a pair of asymmetric keys.

        :param Name keyName: The name of the key pair.
        :param KeyParams params: The parameters of the key.
        """
        if self.doesKeyExist(keyName, KeyClass.PUBLIC):
            raise SecurityException("Public key already exists")
        if self.doesKeyExist(keyName, KeyClass.PRIVATE):
            raise SecurityException("Private key already exists")

        try:
            privateKey = TpmPrivateKey.generatePrivateKey(params)
            privateKeyDer = privateKey.toPkcs8().toBytes()
            publicKeyDer = privateKey.derivePublicKey().toBytes()
        except Exception as ex:
            raise SecurityException("Error in generatePrivateKey: " + str(ex))

        keyUri = keyName.toUri()
        keyFilePathNoExtension = self.maintainMapping(keyUri)
        publicKeyFilePath = keyFilePathNoExtension + ".pub"
        privateKeyFilePath = keyFilePathNoExtension + ".pri"

        with open(publicKeyFilePath, 'w') as keyFile:
            keyFile.write(Common.base64Encode(publicKeyDer, True))
        with open(privateKeyFilePath, 'w') as keyFile:
            keyFile.write(Common.base64Encode(privateKeyDer, True))

        os.chmod(publicKeyFilePath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
        os.chmod(privateKeyFilePath, stat.S_IRUSR)
Ejemplo n.º 7
0
    def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256):
        """
        Fetch the private key for keyName and sign the data, returning a
        signature Blob.

        :param data: The input byte buffer to sign.
        :type data: an array which implements the buffer protocol
        :param Name keyName: The name of the signing key.
        :param digestAlgorithm: (optional) the digest algorithm. If omitted,
          use DigestAlgorithm.SHA256.
        :type digestAlgorithm: int from DigestAlgorithm
        :return: The signature Blob.
        :rtype: Blob
        :raises SecurityException: if can't find the private key with keyName.
        """
        if digestAlgorithm != DigestAlgorithm.SHA256:
            raise SecurityException(
                "MemoryPrivateKeyStorage.sign: Unsupported digest algorithm")

        # Find the private key.
        keyUri = keyName.toUri()
        if not keyUri in self._privateKeyStore:
            raise SecurityException(
                "MemoryPrivateKeyStorage: Cannot find private key " + keyUri)
        privateKey = self._privateKeyStore[keyUri]

        # Sign the hash of the data.
        if sys.version_info[0] == 2:
            # In Python 2.x, we need a str.  Use Blob to convert data.
            data = Blob(data, False).toRawStr()
        signature = PKCS1_v1_5.new(privateKey.getPrivateKey()).sign(
            SHA256.new(data))
        # Convert the string to a Blob.
        return Blob(bytearray(signature), False)
Ejemplo n.º 8
0
    def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256):
        """
        Fetch the private key for keyName and sign the data, returning a
        signature Blob.

        :param data: The input byte buffer to sign.
        :type data: an array which implements the buffer protocol
        :param Name keyName: The name of the signing key.
        :param digestAlgorithm: (optional) the digest algorithm. If omitted,
          use DigestAlgorithm.SHA256.
        :type digestAlgorithm: int from DigestAlgorithm
        :return: The signature Blob.
        :rtype: Blob
        :raises SecurityException: if can't find the private key with keyName.
        """
        # Find the private key.
        keyUri = keyName.toUri()
        if not keyUri in self._privateKeyStore:
            raise SecurityException(
                "MemoryPrivateKeyStorage: Cannot find private key " + keyUri)
        privateKey = self._privateKeyStore[keyUri]

        try:
            return privateKey.sign(
                Blob(data, False).toBytes(), digestAlgorithm)
        except Exception as ex:
            raise SecurityException("Error in sign: " + str(ex))
Ejemplo n.º 9
0
    def generateKeyPair(self, keyName, params):
        """
        Generate a pair of asymmetric keys.

        :param Name keyName: The name of the key pair.
        :param KeyParams params: The parameters of the key.
        """
        if self.doesKeyExist(keyName, KeyClass.PUBLIC):
            raise SecurityException("keyName already exists")

        keyLabel = None
        attrDict = None
        cfKeySize = None
        publicKey = None
        privateKey = None

        try:
            keyNameUri = self._toInternalKeyName(keyName, KeyClass.PUBLIC)

            keyLabel = CFSTR(keyNameUri)

            attrDict = c_void_p(cf.CFDictionaryCreateMutable(
              None, 3, cf.kCFTypeDictionaryKeyCallBacks, None))

            if params.getKeyType() == KeyType.RSA:
                keySize = params.getKeySize()
            elif params.getKeyType() == KeyType.EC:
                keySize = params.getKeySize()
            else:
                raise SecurityException("generateKeyPair: Unsupported key type ")

            cfKeySize = c_void_p(cf.CFNumberCreate(
              None, kCFNumberIntType, byref(c_int(keySize))))

            cf.CFDictionaryAddValue(
              attrDict, self._kSecAttrKeyType,
              self._getAsymmetricKeyType(params.getKeyType()))
            cf.CFDictionaryAddValue(
              attrDict, self._kSecAttrKeySizeInBits, cfKeySize)
            cf.CFDictionaryAddValue(
              attrDict, self._kSecAttrLabel, keyLabel)

            publicKey = c_void_p()
            privateKey = c_void_p()
            res = self._security.SecKeyGeneratePair(
              attrDict, pointer(publicKey), pointer(privateKey))

            if res != 0:
                raise SecurityException("Fail to create a key pair")
        finally:
            if keyLabel != None:
                cf.CFRelease(keyLabel)
            if attrDict != None:
                cf.CFRelease(attrDict)
            if cfKeySize != None:
                cf.CFRelease(cfKeySize)
            if publicKey != None:
                cf.CFRelease(publicKey)
            if privateKey != None:
                cf.CFRelease(privateKey)
Ejemplo n.º 10
0
    def getKey(self, keyName):
        """
        Get the public key DER blob from the identity storage.

        :param Name keyName: The name of the requested public key.
        :return: The DER Blob.
        :rtype: Blob
        :raises SecurityException: if the key doesn't exist.
        """
        if keyName.size() == 0:
            raise SecurityException(
                "BasicIdentityStorage::getKey: Empty keyName")

        identityUri = keyName[:-1].toUri()
        keyId = keyName[-1].toEscapedString()

        cursor = self._database.cursor()
        cursor.execute(
            "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?",
            (identityUri, keyId))
        row = cursor.fetchone()
        if row != None:
            (keyData, ) = row
            cursor.close()
            return Blob(bytearray(keyData), False)
        else:
            cursor.close()
            raise SecurityException(
                "BasicIdentityStorage::getKey: The key does not exist")
Ejemplo n.º 11
0
    def signByIdentity(self, target, identityName=None, wireFormat=None):
        """
        Sign the target. If it is a Data object, set its signature.
        If it is an array, return a signature object.

        :param target: If this is a Data object, wire encode for signing,
          update its signature and key locator field and wireEncoding. If it is
          an array, sign it and return a Signature object.
        :type target: Data or an array which implements the buffer protocol
        :param Name identityName: (optional) The identity name for the key to
          use for signing. If omitted, infer the signing identity from the data
          packet name.
        :param wireFormat: (optional) A WireFormat object used to encode the
           input. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :return: The Signature object (only if the target is an array).
        :rtype: An object of a subclass of Signature
        """
        if identityName == None:
            identityName = Name()

        if isinstance(target, Data):
            if identityName.size() == 0:
                inferredIdentity = self._policyManager.inferSigningIdentity(
                    target.getName())
                if inferredIdentity.size() == 0:
                    signingCertificateName = self._identityManager.getDefaultCertificateName(
                    )
                else:
                    signingCertificateName = \
                      self._identityManager.getDefaultCertificateNameForIdentity(inferredIdentity)
            else:
                signingCertificateName = \
                  self._identityManager.getDefaultCertificateNameForIdentity(identityName)

            if signingCertificateName.size() == 0:
                raise SecurityException("No qualified certificate name found!")

            if not self._policyManager.checkSigningPolicy(
                    target.getName(), signingCertificateName):
                raise SecurityException(
                    "Signing Cert name does not comply with signing policy")

            self._identityManager.signByCertificate(target,
                                                    signingCertificateName,
                                                    wireFormat)
        else:
            signingCertificateName = \
              self._identityManager.getDefaultCertificateNameForIdentity(identityName)

            if signingCertificateName.size() == 0:
                raise SecurityException("No qualified certificate name found!")

            return self._identityManager.signByCertificate(
                target, signingCertificateName)
Ejemplo n.º 12
0
    def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256):
        """
        Fetch the private key for keyName and sign the data, returning a
        signature Blob.

        :param data: Pointer the input byte buffer to sign.
        :type data: An array type with int elements
        :param Name keyName: The name of the signing key.
        :param digestAlgorithm: (optional) the digest algorithm. If omitted,
          use DigestAlgorithm.SHA256.
        :type digestAlgorithm: int from DigestAlgorithm
        :return: The signature Blob.
        :rtype: Blob
        """
        keyURI = keyName.toUri()

        if not self.doesKeyExist(keyName, KeyClass.PRIVATE):
            raise SecurityException(
                "FilePrivateKeyStorage.sign: private key doesn't exist")

        if digestAlgorithm != DigestAlgorithm.SHA256:
            raise SecurityException(
                "FilePrivateKeyStorage.sign: Unsupported digest algorithm")

        # Read the private key.
        base64Content = None
        with open(self.nameTransform(keyURI, ".pri")) as keyFile:
            base64Content = keyFile.read()
        der = Blob(base64.b64decode(base64Content), False)

        # Decode the PKCS #8 key to get the algorithm OID.
        parsedNode = DerNode.parse(der.buf(), 0)
        pkcs8Children = parsedNode.getChildren()
        algorithmIdChildren = DerNode.getSequence(pkcs8Children,
                                                  1).getChildren()
        oidString = algorithmIdChildren[0].toVal()

        privateKey = serialization.load_der_private_key(
            der.toBytes(), password=None, backend=default_backend())

        # Sign the data.
        data = Blob(data, False).toBytes()
        if (oidString == PublicKey.RSA_ENCRYPTION_OID
                or oidString == PublicKey.EC_ENCRYPTION_OID):
            if oidString == PublicKey.RSA_ENCRYPTION_OID:
                signer = privateKey.signer(padding.PKCS1v15(), hashes.SHA256())
            else:
                signer = privateKey.signer(ec.ECDSA(hashes.SHA256()))

            signer.update(data)
            signature = signer.finalize()
            return Blob(bytearray(signature), False)
        else:
            raise SecurityException(
                "FilePrivateKeyStorage.sign: Unrecognized private key type")
Ejemplo n.º 13
0
    def generateKeyPair(self, keyName, params):
        """
        Generate a pair of asymmetric keys.

        :param Name keyName: The name of the key pair.
        :param KeyParams params: The parameters of the key.
        """
        if self.doesKeyExist(keyName, KeyClass.PUBLIC):
            raise SecurityException("Public key already exists")
        if self.doesKeyExist(keyName, KeyClass.PRIVATE):
            raise SecurityException("Private key already exists")

        publicKeyDer = None
        privateKeyDer = None

        if (params.getKeyType() == KeyType.RSA
                or params.getKeyType() == KeyType.ECDSA):
            if params.getKeyType() == KeyType.RSA:
                privateKey = rsa.generate_private_key(
                    public_exponent=65537,
                    key_size=params.getKeySize(),
                    backend=default_backend())
            else:
                privateKey = ec.generate_private_key(
                    PrivateKeyStorage.getEcCurve(params.getKeySize()),
                    default_backend())

            publicKeyDer = privateKey.public_key().public_bytes(
                encoding=serialization.Encoding.DER,
                format=serialization.PublicFormat.SubjectPublicKeyInfo)
            privateKeyDer = privateKey.private_bytes(
                encoding=serialization.Encoding.DER,
                format=serialization.PrivateFormat.PKCS8,
                encryption_algorithm=serialization.NoEncryption())
        else:
            raise SecurityException("Unsupported key type")

        keyUri = keyName.toUri()
        keyFilePathNoExtension = self.maintainMapping(keyUri)
        publicKeyFilePath = keyFilePathNoExtension + ".pub"
        privateKeyFilePath = keyFilePathNoExtension + ".pri"

        with open(publicKeyFilePath, 'w') as keyFile:
            keyFile.write(
                Blob(base64.b64encode(publicKeyDer), False).toRawStr())
        with open(privateKeyFilePath, 'w') as keyFile:
            keyFile.write(
                Blob(base64.b64encode(privateKeyDer), False).toRawStr())

        os.chmod(publicKeyFilePath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
        os.chmod(privateKeyFilePath, stat.S_IRUSR)
Ejemplo n.º 14
0
    def signWithHmacWithSha256(target, key, wireFormat = None):
        """
        Wire encode the target, compute an HmacWithSha256 and update the
        signature value.
        Note: This method is an experimental feature. The API may change.

        :param target: If this is a Data object, update its signature and wire
          encoding.
        :type target: Data
        :param Blob key: The key for the HmacWithSha256.
        :param wireFormat: (optional) The WireFormat for calling encodeData,
          etc., or WireFormat.getDefaultWireFormat() if omitted.
        :type wireFormat: A subclass of WireFormat
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        if isinstance(target, Data):
            data = target
            # Encode once to get the signed portion.
            encoding = data.wireEncode(wireFormat)

            signer = hmac.HMAC(key.toBytes(), hashes.SHA256(),
              backend = default_backend())
            signer.update(encoding.toSignedBytes())
            data.getSignature().setSignature(
              Blob(bytearray(signer.finalize()), False))
        else:
            raise SecurityException("signWithHmacWithSha256: Unrecognized target type")
Ejemplo n.º 15
0
    def addKey(self, keyName, keyType, publicKeyDer):    
        """
        Add a public key to the identity storage.
        
        :param Name keyName: The name of the public key to be added.
        :param keyType: Type of the public key to be added.
        :type keyType: int from KeyType
        :param Blob publicKeyDer: A blob of the public key DER to be added.
        """
        if self.doesKeyExist(keyName):
            raise SecurityException("A key with the same name already exists!")

        identityName = keyName.getPrefix(-1)
        identityUri = identityName.toUri()
        makeDefault = 0
        if not self.doesIdentityExist(identityName):
            self.addIdentity(identityName)
            makeDefault = 1

        keyId = keyName.get(-1).toEscapedString()
        keyBuffer = buffer(bytearray (publicKeyDer.buf()))

        cursor = self._database.cursor()
        cursor.execute("INSERT INTO Key VALUES(?,?,?,?,?, ?)", 
            (identityUri, keyId, keyType, keyBuffer, makeDefault, 1))
        self._database.commit()
        cursor.close()
Ejemplo n.º 16
0
    def setDefaultIdentity(self, identityName):    
        """
        Set the default identity. If the identityName does not exist,  
        raises a SecurityException.
        
        :param Name identityName: The default identity name.
        """
        if not self.doesIdentityExist(identityName):
            raise SecurityException("Identity does not exist")
        
        try:
            cursor = None
            currentDefault = self.getDefaultIdentity().toUri()
        except SecurityException:
            # no default, no need to remove default flag
            pass
        else:
            cursor = self._database.cursor()
            cursor.execute("UPDATE Identity SET default_identity=0 WHERE identity_name=?", (currentDefault,))

        if cursor is None:
            cursor = self._database.cursor()

        # now set this identity as default
        cursor.execute("UPDATE Identity SET default_identity=1 WHERE identity_name=?", (identityName.toUri(), ))

        self._database.commit()
        cursor.close()
Ejemplo n.º 17
0
    def addKey(self, keyName, keyType, publicKeyDer):
        """
        Add a public key to the identity storage. Also call addIdentity to ensure
        that the identityName for the key exists.

        :param Name keyName: The name of the public key to be added.
        :param keyType: Type of the public key to be added.
        :type keyType: int from KeyType
        :param Blob publicKeyDer: A blob of the public key DER to be added.
        """
        if keyName.size() == 0:
            return

        if self.doesKeyExist(keyName):
            raise SecurityException("A key with the same name already exists!")

        identityName = keyName[:-1]
        identityUri = identityName.toUri()

        self.addIdentity(identityName)

        keyId = keyName[-1].toEscapedString()
        keyBuffer = sqlite3.Binary(bytearray(publicKeyDer.buf()))

        cursor = self._database.cursor()
        cursor.execute(
            "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) VALUES(?,?,?,?)",
            (identityUri, keyId, keyType, keyBuffer))
        self._database.commit()
        cursor.close()
Ejemplo n.º 18
0
    def getKeyType(self, keyName):
        """
        Get the KeyType of the public key with the given keyName.
        
        :param Name keyName: The name of the requested public key.
        :return: The KeyType, for example KeyType.RSA.
        :rtype: an int from KeyType
        """
        keyId = keyName.get(keyName.size() - 1).toEscapedString()
        identityName = keyName.getSubName(0, keyName.size() - 1)

        cursor = self._database.cursor()
        cursor.execute(
            "SELECT key_type FROM Key WHERE identity_name=? AND key_identifier=?",
            (identityName.toUri(), keyId))
        row = cursor.fetchone()

        if row != None:
            (keyType, ) = row
            cursor.close()
            return keyType
        else:
            cursor.close()
            raise SecurityException(
                "Cannot get public key type because the keyName doesn't exist")
Ejemplo n.º 19
0
    def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256):
        """
        Fetch the private key for keyName and sign the data, returning a 
        signature Blob.

        :param data: Pointer the input byte buffer to sign.
        :type data: An array type with int elements
        :param Name keyName: The name of the signing key.
        :param digestAlgorithm: (optional) the digest algorithm. If omitted,
          use DigestAlgorithm.SHA256.
        :type digestAlgorithm: int from DigestAlgorithm
        :return: The signature, or an isNull() Blob pointer if signing fails.
        :rtype: Blob
        """
        if digestAlgorithm != DigestAlgorithm.SHA256:
            raise SecurityException(
                "FilePrivateKeyStorage.sign: Unsupported digest algorithm")

        der = self.getPrivateKey(keyName)
        privateKey = RSA.importKey(der.toRawStr())

        # Sign the hash of the data.
        if sys.version_info[0] == 2:
            # In Python 2.x, we need a str.  Use Blob to convert data.
            data = Blob(data, False).toRawStr()
        signature = PKCS1_v1_5.new(privateKey).sign(SHA256.new(data))
        # Convert the string to a Blob.
        return Blob(bytearray(signature), False)
Ejemplo n.º 20
0
    def getNewKeyName(self, identityName, useKsk):
        """
        Generate a name for a new key belonging to the identity.

        :param Name identityName: The identity name.
        :param bool useKsk: If True, generate a KSK name, otherwise a DSK name.
        :return: The generated key name.
        :rtype: Name
        """
        timestamp = math.floor(Common.getNowMilliseconds() / 1000.0)
        while timestamp <= self._lastTimestamp:
            # Make the timestamp unique.
            timestamp += 1
        self._lastTimestamp = timestamp

        nowString = repr(timestamp).replace(".0", "")
        if useKsk:
            keyIdStr = "ksk-" + nowString
        else:
            keyIdStr = "dsk-" + nowString

        keyName = Name(identityName).append(keyIdStr)

        if self.doesKeyExist(keyName):
            raise SecurityException("Key name already exists")

        return keyName
Ejemplo n.º 21
0
    def setDefaultCertificateNameForKey(self, keyName, certificateName):        
        """
        Set the default certificate name for the corresponding key
                
        :param Name keyName: not used
        :param Name certificateName: The certificate name.
        """
        
        if not self.doesCertificateExist(certificateName):
            raise SecurityException("Certificate does not exist")

        keyName = IdentityCertificate.certificateNameToPublicKeyName(certificateName)
        identityUri = keyName.getPrefix(-1).toUri()
        keyId = keyName.get(-1).toEscapedString()

        try:
            cursor = None
            currentDefault = self.getDefaultCertificateNameForKey(keyName)
        except SecurityException:
            pass
        else:
            cursor = self._database.cursor()
            cursor.execute("UPDATE Certificate SET default_cert=0 WHERE cert_name=? AND identity_name=? AND key_identifier=?",
                (currentDefault.toUri(), identityUri, keyId))

        if cursor is None:
            cursor = self._database.cursor()
        
        cursor.execute("UPDATE Certificate SET default_cert=1 WHERE cert_name=? AND identity_name=? AND key_identifier=?",
                (certificateName.toUri(), identityUri, keyId))

        self._database.commit()
        cursor.close()
Ejemplo n.º 22
0
    def verifySignature(signature, signedBlob, publicKeyDer):
        """
        Check the type of signature and use the publicKeyDer to verify the
        signedBlob using the appropriate signature algorithm.

        :param Blob signature: An object of a subclass of Signature, e.g.
          Sha256WithRsaSignature.
        :param SignedBlob signedBlob: the SignedBlob with the signed portion to
          verify.
        :param Blob publicKeyDer: The DER-encoded public key used to verify the
          signature. This is ignored if the signature type does not require a
          public key.
        :return: True if the signature verifies, False if not.
        :rtype: bool
        :raises: SecurityException if the signature type is not recognized or if
          publicKeyDer can't be decoded.
        """
        if isinstance(signature, Sha256WithRsaSignature):
            if publicKeyDer.isNull():
                return False
            return PolicyManager._verifySha256WithRsaSignature(
              signature.getSignature(), signedBlob, publicKeyDer)
        elif isinstance(signature, Sha256WithEcdsaSignature):
            if publicKeyDer.isNull():
                return False
            return PolicyManager._verifySha256WithEcdsaSignature(
              signature.getSignature(), signedBlob, publicKeyDer)
        elif isinstance(signature, DigestSha256Signature):
            return PolicyManager._verifyDigestSha256Signature(
              signature.getSignature(), signedBlob)
        else:
            raise SecurityException(
              "PolicyManager.verify: Signature type is unknown")
Ejemplo n.º 23
0
    def _makeSignatureByCertificate(self, certificateName, digestAlgorithm):
        """
        Return a new Signature object based on the signature algorithm of the
        public key with keyName (derived from certificateName).

        :param Name certificateName: The full certificate name.
        :param Array digestAlgorithm: Set digestAlgorithm[0] to the signature
          algorithm's digest algorithm, e.g. DigestAlgorithm.SHA256 .
        :return: The related public key name.
        :rtype: Signature
        """
        keyName = IdentityCertificate.certificateNameToPublicKeyName(
            certificateName)
        publicKey = self._privateKeyStorage.getPublicKey(keyName)
        keyType = publicKey.getKeyType()

        if keyType == KeyType.RSA:
            signature = Sha256WithRsaSignature()
            digestAlgorithm[0] = DigestAlgorithm.SHA256

            signature.getKeyLocator().setType(KeyLocatorType.KEYNAME)
            signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1))

            return signature
        elif keyType == KeyType.ECDSA:
            signature = Sha256WithEcdsaSignature()
            digestAlgorithm[0] = DigestAlgorithm.SHA256

            signature.getKeyLocator().setType(KeyLocatorType.KEYNAME)
            signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1))

            return signature
        else:
            raise SecurityException("Key type is not recognized")
Ejemplo n.º 24
0
    def _verifySha256WithEcdsaSignature(signature, signedBlob, publicKeyDer):
        """
        Verify the ECDSA signature on the SignedBlob using the given public key.

        :param Blob signature: The signature bits.
        :param SignedBlob signedBlob: the SignedBlob with the signed portion to
          verify.
        :param Blob publicKeyDer: The DER-encoded public key used to verify the
          signature.
        :return: True if the signature verifies, False if not.
        :rtype: bool
        """
        # Get the public key.
        publicKeyDerBytes = publicKeyDer.toBytes()
        try:
            publicKey = load_der_public_key(
              publicKeyDerBytes, backend = default_backend())
        except:
            raise SecurityException("Cannot decode the ECDSA public key")

        # Verify.
        verifier = publicKey.verifier(
          signature.toBytes(), ec.ECDSA(hashes.SHA256()))
        verifier.update(signedBlob.toSignedBytes())
        try:
            verifier.verify()
            return True
        except InvalidSignature:
            return False
Ejemplo n.º 25
0
    def _lookupCertificateV2(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 CertificateV2, or None if not found.
        :rtype: CertificateV2
        """
        if self._isSecurityV1:
            raise SecurityException(
                "lookupCertificateV2: For security v1, use lookupCertificate()"
            )

        try:
            certUri = self._fixedCertificateCache[certID]
        except KeyError:
            if isPath:
                # load the certificate data (base64 encoded IdentityCertificate)
                cert = TrustAnchorRefreshManager.loadCertificateV2FromFile(
                    certID)
            else:
                certData = b64decode(certID)
                cert = CertificateV2()
                cert.wireDecode(Blob(certData, False))

            certUri = cert.getName()[:-1].toUri()
            self._fixedCertificateCache[certID] = certUri
            self._certificateCacheV2.insert(cert)
        else:
            cert = self._certificateCacheV2.find(Name(certUri))

        return cert
Ejemplo n.º 26
0
    def setDefaultKeyNameForIdentity(self, keyName, identityNameCheck=None):
        """
        Set a key as the default key of an identity. The identity name is
        inferred from keyName.

        :param Name keyName: The name of the key.
        :param Name identityNameCheck: (optional) The identity name to check
          that the keyName contains the same identity name. If an empty name, it
          is ignored.
        """
        keyId = keyName[-1].toEscapedString()
        identityName = keyName[:-1]

        if (not (identityNameCheck is None) and identityNameCheck.size() != 0
                and not identityNameCheck.equals(identityName)):
            raise SecurityException(
                "Specified identity name does not match the key name")

        # Reset the previous default key.
        identityUri = identityName.toUri()
        cursor = self._database.cursor()
        cursor.execute(
            "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?",
            (identityUri, ))

        # Set the current default Key.
        cursor.execute(
            "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?",
            (identityUri, keyId))

        self._database.commit()
        cursor.close()
Ejemplo n.º 27
0
    def getDefaultCertificateNameForKey(self, keyName):
        """
        Get the default certificate name for the specified key.

        :param Name keyName: The key name.
        :return: The default certificate name.
        :rtype: Name
        :raises SecurityException: if the default certificate name for the key
          name is not set.
        """
        keyId = keyName[-1].toEscapedString()
        identityName = keyName[:-1]

        cursor = self._database.cursor()
        cursor.execute(
            "SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1",
            (identityName.toUri(), keyId))
        row = cursor.fetchone()

        if row != None:
            (certName, ) = row
            cursor.close()
            return Name(certName)
        else:
            cursor.close()
            raise SecurityException(
                "BasicIdentityStorage::getDefaultCertificateNameForKey: The default certificate for the key name is not defined"
            )
Ejemplo n.º 28
0
    def getDefaultKeyNameForIdentity(self, identityName):
        """
        Get the default key name for the specified identity.

        :param Name identityName: The identity name.
        :return: The default key name.
        :rtype: Name
        :raises SecurityException: if the default key name for the identity is
          not set.
        """
        cursor = self._database.cursor()
        cursor.execute(
            "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1",
            (identityName.toUri(), ))
        row = cursor.fetchone()

        if row != None:
            (keyName, ) = row
            cursor.close()
            return Name(identityName).append(keyName)
        else:
            cursor.close()
            raise SecurityException(
                "BasicIdentityStorage::getDefaultKeyNameForIdentity: The default key for the identity is not defined"
            )
    def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256):
        """
        Fetch the private key for keyName and sign the data, returning a 
        signature Blob.

        :param data: Pointer the input byte buffer to sign.
        :type data: An array type with int elements
        :param Name keyName: The name of the signing key.
        :param digestAlgorithm: (optional) the digest algorithm. If omitted,
          use DigestAlgorithm.SHA256.
        :type digestAlgorithm: int from DigestAlgorithm
        :return: The signature, or an isNull() Blob pointer if signing fails.
        :rtype: Blob
        """
        keyURI = keyName.toUri()

        if not self.doesKeyExist(keyName, KeyClass.PRIVATE):
            raise SecurityException(
                "FilePrivateKeyStorage.sign: private key doesn't exist")

        if digestAlgorithm != DigestAlgorithm.SHA256:
            raise SecurityException(
                "FilePrivateKeyStorage.sign: Unsupported digest algorithm")

        # Read the private key.
        base64Content = None
        with open(self.nameTransform(keyURI, ".pri")) as keyFile:
            base64Content = keyFile.read()
        der = base64.b64decode(base64Content)
        if not type(der) is str:
            der = "".join(map(chr, der))

        # The private key is generated by NFD which stores as PKCS #8.
        # This hack skips the PKCS #8 preamble because PyCryoto decodes as PKCS #1.
        # TODO: Use proper PKCS #8 decoding instead of this hack.
        pkcs8PreambleSize = 26
        privateKey = RSA.importKey(der[pkcs8PreambleSize:])

        # Sign the hash of the data.
        if sys.version_info[0] == 2:
            # In Python 2.x, we need a str.  Use Blob to convert data.
            data = Blob(data, False).toRawStr()
        signature = PKCS1_v1_5.new(privateKey).sign(SHA256.new(data))
        # Convert the string to a Blob.
        return Blob(bytearray(signature), False)
Ejemplo n.º 30
0
    def addCertificate(self, certificate):
        """
        Add a certificate to the identity storage.

        :param IdentityCertificate certificate: The certificate to be added.
          This makes a copy of the certificate.
        """
        certificateName = certificate.getName()
        keyName = certificate.getPublicKeyName()

        if not self.doesKeyExist(keyName):
            raise SecurityException(
                "No corresponding Key record for certificate! " +
                keyName.toUri() + " " + certificateName.toUri())

        # Check if the certificate already exists.
        if self.doesCertificateExist(certificateName):
            raise SecurityException("Certificate has already been installed!")

        keyId = keyName.get(-1).toEscapedString()
        identity = keyName[:-1]

        # Check if the public key of the certificate is the same as the key record.
        keyBlob = self.getKey(keyName)
        if (keyBlob.isNull() or not keyBlob.equals(
                certificate.getPublicKeyInfo().getKeyDer())):
            raise SecurityException("Certificate does not match public key")

        # 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()