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