示例#1
0
    def _doExportKey(self, keyName, password):
        """
        A protected method to get the encoded private key with name keyName in
        PKCS #8 format, possibly password-encrypted.

        :param Name keyName: The name of the key in the TPM.
        :param password: The password for encrypting the private key, which
          should have characters in the range of 1 to 127. If the password is
          supplied, use it to return a PKCS #8 EncryptedPrivateKeyInfo. If the
          password is None, return an unencrypted PKCS #8 PrivateKeyInfo.
        :type password: an array which implements the buffer protocol
        :return: The encoded private key.
        :rtype: Blob
        :raises TpmBackEnd.Error: If the key does not exist or if the key cannot
          be exported, e.g., insufficient privileges.
        """
        if not self.hasKey(keyName):
            raise TpmBackEnd.Error("exportKey: The key does not exist")

        try:
            if password != None:
                return self._keys[keyName].toEncryptedPkcs8(password)
            else:
                return self._keys[keyName].toPkcs8()
        except TpmPrivateKey.Error as ex:
            raise TpmBackEnd.Error("Error in TpmPrivateKey.toPkcs8: " +
                                   str(ex))
示例#2
0
    def _doImportKey(self, keyName, pkcs8, password):
        """
        A protected method to import an encoded private key with name keyName in
          PKCS #8 format, possibly passwprd-encrypted.

        :param Name keyName: The name of the key to use in the TPM.
        :param pkcs8: The input byte buffer. If the password is supplied, this
          is a PKCS #8 EncryptedPrivateKeyInfo. If the password is none, this is
          an unencrypted PKCS #8 PrivateKeyInfo.
        :type pkcs8: an array which implements the buffer protocol
        :param password: The password for decrypting the private key. If the
          password is supplied, use it to decrypt the PKCS #8
          EncryptedPrivateKeyInfo. If the password is None, import an
          unencrypted PKCS #8 PrivateKeyInfo.
        :type password: an array which implements the buffer protocol
        :raises TpmBackEnd.Error: For an error importing the key.
        """
        try:
            if password != None:
                raise TpmBackEnd.Error(
                    "Private key password-encryption is not implemented")
            else:
                key = TpmPrivateKey()
                key.loadPkcs8(pkcs8)
                # Copy the Name.
                self._keys[Name(keyName)] = key
        except TpmPrivateKey.Error as ex:
            raise TpmBackEnd.Error("Cannot import private key: " + str(ex))
示例#3
0
    def _doDerivePublicKey(self):
        """
        A protected method to do the work of derivePublicKey().

        :return: The public key encoding Blob.
        :rtype: Blob
        """
        try:
            return self._key.derivePublicKey()
        except TpmPrivateKey.Error as ex:
            raise TpmBackEnd.Error("Error in TpmPrivateKey.derivePublicKey: " +
                                   str(ex))
示例#4
0
    def _doDecrypt(self, cipherText):
        """
        A protected method to do the work of decrypt().

        :param cipherText: The cipher text byte buffer.
        :type cipherText: an array which implements the buffer protocol
        :return: The decrypted data.
        :rtype: Blob
        """
        try:
            return self._key.decrypt(cipherText)
        except TpmPrivateKey.Error as ex:
            raise TpmBackEnd.Error("Error in TpmPrivateKey.decrypt: " +
                                   str(ex))
示例#5
0
    def _doCreateKey(self, identityName, params):
        """
        Create a key for identityName according to params. The created key is
        named as: /<identityName>/[keyId]/KEY . The key name is set in the
        returned TpmKeyHandle.

        :param Name identityName: The name if the identity.
        :param KeyParams params: The KeyParams for creating the key.
        :return: The handle of the created key.
        :rtype: TpmKeyHandle
        :raises TpmBackEnd.Error: If the key cannot be created.
        """
        try:
            key = TpmPrivateKey.generatePrivateKey(params)
        except Exception as ex:
            raise TpmBackEndFile.Error(
                "Error in TpmPrivateKey.generatePrivateKey: " + str(ex))
        keyHandle = TpmKeyHandleMemory(key)

        TpmBackEnd.setKeyName(keyHandle, identityName, params)

        self._saveKey(keyHandle.getKeyName(), key)
        return keyHandle
示例#6
0
    def _doCreateKey(self, identityName, params):
        """
        Create a key for identityName according to params. The created key is
        named as: /<identityName>/[keyId]/KEY . The key name is set in the
        returned TpmKeyHandle.

        :param Name identityName: The name if the identity.
        :param KeyParams params: The KeyParams for creating the key.
        :return: The handle of the created key.
        :rtype: TpmKeyHandle
        :raises TpmBackEnd.Error: If the key cannot be created.
        """
        try:
            key = TpmPrivateKey.generatePrivateKey(params)
        except Exception as ex:
            raise TpmBackEndFile.Error(
              "Error in TpmPrivateKey.generatePrivateKey: " + str(ex))
        keyHandle = TpmKeyHandleMemory(key)

        TpmBackEnd.setKeyName(keyHandle, identityName, params)

        self._saveKey(keyHandle.getKeyName(), key)
        return keyHandle
示例#7
0
    def _doSign(self, digestAlgorithm, data):
        """
        A protected method to do the work of sign().

        :param digestAlgorithm: The digest algorithm.
        :type digestAlgorithm: int from DigestAlgorithm
        :param data: The input byte buffer.
        :type data: an array which implements the buffer protocol
        :return: The signature Blob, or an isNull Blob for an unrecognized
          digestAlgorithm.
        :rtype: Blob
        """
        if digestAlgorithm == DigestAlgorithm.SHA256:
            try:
                return self._key.sign(data, digestAlgorithm)
            except TpmPrivateKey.Error as ex:
                raise TpmBackEnd.Error("Error in TpmPrivateKey.sign: " +
                                       str(ex))
        else:
            return Blob()
示例#8
0
    def _doCreateKey(self, identityName, params):
        """
        A protected method to create a key for identityName according to params.
        The created key is named as: /<identityName>/[keyId]/KEY . The key name
        is set in the returned TpmKeyHandle.

        :param Name identityName: The name if the identity.
        :param KeyParams params: The KeyParams for creating the key.
        :return: The handle of the created key.
        :rtype: TpmKeyHandle
        :raises TpmBackEnd.Error: If the key cannot be created.
        """
        osx = Osx.get()
        keyLabel = None
        attrDict = None
        cfKeySize = None
        publicKey = None

        try:
            keyType = params.getKeyType()
            if keyType == KeyType.RSA:
                keySize = params.getKeySize()
            elif keyType == KeyType.EC:
                keySize = params.getKeySize()
            else:
                raise TpmBackEndOsx.Error(
                    "Failed to create a key pair: Unsupported key type")
            cfKeySize = c_void_p(
                cf.CFNumberCreate(None, kCFNumberIntType,
                                  byref(c_int(keySize))))

            attrDict = c_void_p(
                cf.CFDictionaryCreateMutable(None, 2,
                                             cf.kCFTypeDictionaryKeyCallBacks,
                                             None))
            cf.CFDictionaryAddValue(
                attrDict, osx._kSecAttrKeyType,
                TpmBackEndOsx._getAsymmetricKeyType(keyType))
            cf.CFDictionaryAddValue(attrDict, osx._kSecAttrKeySizeInBits,
                                    cfKeySize)

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

            if res != 0:
                # TODO: check for errSecAuthFailed
                raise TpmBackEndOsx.Error("Failed to create a key pair")

            keyHandle = TpmKeyHandleOsx(privateKey)
            TpmBackEnd.setKeyName(keyHandle, identityName, params)

            keyUri = keyHandle.getKeyName().toUri()
            # There is only one attr, so we don't need to make a C array.
            attr = SecKeychainAttribute(osx._kSecKeyPrintName, len(keyUri),
                                        keyUri.encode('utf-8'))
            attrList = SecKeychainAttributeList(1, pointer(attr))

            osx._security.SecKeychainItemModifyAttributesAndData(
                privateKey, byref(attrList), 0, None)
            osx._security.SecKeychainItemModifyAttributesAndData(
                publicKey, byref(attrList), 0, None)

            return keyHandle
        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)
示例#9
0
    def _doCreateKey(self, identityName, params):
        """
        A protected method to create a key for identityName according to params.
        The created key is named as: /<identityName>/[keyId]/KEY . The key name
        is set in the returned TpmKeyHandle.

        :param Name identityName: The name if the identity.
        :param KeyParams params: The KeyParams for creating the key.
        :return: The handle of the created key.
        :rtype: TpmKeyHandle
        :raises TpmBackEnd.Error: If the key cannot be created.
        """
        osx = Osx.get()
        keyLabel = None
        attrDict = None
        cfKeySize = None
        publicKey = None

        try:
            keyType = params.getKeyType()
            if keyType == KeyType.RSA:
                keySize = params.getKeySize()
            elif keyType == KeyType.EC:
                keySize = params.getKeySize()
            else:
                raise TpmBackEndOsx.Error(
                    "Failed to create a key pair: Unsupported key type")
            cfKeySize = c_void_p(
                cf.CFNumberCreate(None, kCFNumberIntType,
                                  byref(c_int(keySize))))

            attrDict = c_void_p(
                cf.CFDictionaryCreateMutable(None, 3,
                                             cf.kCFTypeDictionaryKeyCallBacks,
                                             None))
            cf.CFDictionaryAddValue(
                attrDict, osx._kSecAttrKeyType,
                TpmBackEndOsx._getAsymmetricKeyType(keyType))
            cf.CFDictionaryAddValue(attrDict, osx._kSecAttrKeySizeInBits,
                                    cfKeySize)
            # TODO: Use TpmBackEnd.setKeyName after generating like in ndn-cpp
            # because constructKeyName doesn't support KeyIdType.SHA256 .
            # This requires calling SecKeychainItemModifyAttributesAndData.
            keyName = TpmBackEnd.constructKeyName(identityName, params)
            keyLabel = CFSTR(keyName.toUri())
            cf.CFDictionaryAddValue(attrDict, osx._kSecAttrLabel, keyLabel)

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

            if res != 0:
                # TODO: check for errSecAuthFailed
                raise TpmBackEndOsx.Error("Failed to create a key pair")

            keyHandle = TpmKeyHandleOsx(privateKey)
            keyHandle.setKeyName(keyName)
            return keyHandle
        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)
示例#10
0
    def _doCreateKey(self, identityName, params):
        """
        A protected method to create a key for identityName according to params.
        The created key is named as: /<identityName>/[keyId]/KEY . The key name
        is set in the returned TpmKeyHandle.

        :param Name identityName: The name if the identity.
        :param KeyParams params: The KeyParams for creating the key.
        :return: The handle of the created key.
        :rtype: TpmKeyHandle
        :raises TpmBackEnd.Error: If the key cannot be created.
        """
        osx = Osx.get()
        keyLabel = None
        attrDict = None
        cfKeySize = None
        publicKey = None

        try:
            keyType = params.getKeyType()
            if keyType == KeyType.RSA:
                keySize = params.getKeySize()
            elif keyType == KeyType.EC:
                keySize = params.getKeySize()
            else:
                raise TpmBackEndOsx.Error(
                  "Failed to create a key pair: Unsupported key type")
            cfKeySize = c_void_p(cf.CFNumberCreate(
              None, kCFNumberIntType, byref(c_int(keySize))))

            attrDict = c_void_p(cf.CFDictionaryCreateMutable(
              None, 2, cf.kCFTypeDictionaryKeyCallBacks, None))
            cf.CFDictionaryAddValue(
              attrDict, osx._kSecAttrKeyType,
              TpmBackEndOsx._getAsymmetricKeyType(keyType))
            cf.CFDictionaryAddValue(
              attrDict, osx._kSecAttrKeySizeInBits, cfKeySize)

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

            if res != 0:
                # TODO: check for errSecAuthFailed
                raise TpmBackEndOsx.Error("Failed to create a key pair")

            keyHandle = TpmKeyHandleOsx(privateKey)
            TpmBackEnd.setKeyName(keyHandle, identityName, params)

            keyUri = keyHandle.getKeyName().toUri()
            # There is only one attr, so we don't need to make a C array.
            attr = SecKeychainAttribute(
              osx._kSecKeyPrintName, len(keyUri), keyUri.encode('utf-8'))
            attrList = SecKeychainAttributeList(1, pointer(attr))

            osx._security.SecKeychainItemModifyAttributesAndData(
              privateKey, byref(attrList), 0, None)
            osx._security.SecKeychainItemModifyAttributesAndData(
              publicKey, byref(attrList), 0, None)

            return keyHandle
        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)