|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* OpenConnect (SSL + DTLS) VPN client
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Copyright © 2012 Free Software Foundation.
|
|
Packit Service |
4684c1 |
* Copyright © 2008-2012 Intel Corporation.
|
|
Packit Service |
4684c1 |
* Copyright © 2015-2016 Red Hat, Inc.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Author: David Woodhouse <dwmw2@infradead.org>
|
|
Packit Service |
4684c1 |
* Author: Nikos Mavrogiannopoulos
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* GnuTLS is free software; you can redistribute it and/or
|
|
Packit Service |
4684c1 |
* modify it under the terms of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* as published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
4684c1 |
* the License, or (at your option) any later version.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This library is distributed in the hope that it will be useful, but
|
|
Packit Service |
4684c1 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4684c1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4684c1 |
* Lesser General Public License for more details.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* TPM code based on client-tpm.c from
|
|
Packit Service |
4684c1 |
* Carolin Latze <latze@angry-red-pla.net> and Tobias Soder
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include <config.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/gnutls.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/abstract.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/tpm.h>
|
|
Packit Service |
4684c1 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef HAVE_TROUSERS
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include <pkcs11_int.h>
|
|
Packit Service |
4684c1 |
#include <x509/common.h>
|
|
Packit Service |
4684c1 |
#include <x509_b64.h>
|
|
Packit Service |
4684c1 |
#include <random.h>
|
|
Packit Service |
4684c1 |
#include <pin.h>
|
|
Packit Service |
4684c1 |
#include <c-ctype.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include <dlfcn.h>
|
|
Packit Service |
4684c1 |
#include <trousers/tss.h>
|
|
Packit Service |
4684c1 |
#include <trousers/trousers.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
typedef char *(*Trspi_Error_Layer_func)(TSS_RESULT);
|
|
Packit Service |
4684c1 |
typedef char *(*Trspi_Error_String_func)(TSS_RESULT);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Trspi_Error_Code_func)(TSS_RESULT);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_CloseObject_func)(TSS_HCONTEXT, TSS_HOBJECT);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_Close_func)(TSS_HCONTEXT);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_CreateObject_func)(TSS_HCONTEXT, TSS_FLAG, TSS_FLAG, TSS_HOBJECT*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_FreeMemory_func)(TSS_HCONTEXT, BYTE*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_GetTpmObject_func)(TSS_HCONTEXT, TSS_HTPM*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_LoadKeyByUUID_func)(TSS_HCONTEXT, TSS_FLAG, TSS_UUID, TSS_HKEY*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_RegisterKey_func)(TSS_HCONTEXT, TSS_HKEY, TSS_FLAG, TSS_UUID, TSS_FLAG, TSS_UUID);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_UnregisterKey_func)(TSS_HCONTEXT, TSS_FLAG, TSS_UUID, TSS_HKEY*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Key_CreateKey_func)(TSS_HKEY, TSS_HKEY, TSS_HPCRS);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Hash_SetHashValue_func)(TSS_HHASH, UINT32, BYTE*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Hash_Sign_func)(TSS_HHASH, TSS_HKEY, UINT32*, BYTE**);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Policy_SetSecret_func)(TSS_HPOLICY, TSS_FLAG, UINT32, BYTE*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_Create_func)(TSS_HCONTEXT*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_Connect_func)(TSS_HCONTEXT, TSS_UNICODE*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_GetPolicyObject_func)(TSS_HOBJECT, TSS_FLAG, TSS_HPOLICY*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_DecodeBER_TssBlob_func)(UINT32, BYTE*, UINT32*, UINT32*, BYTE*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_LoadKeyByBlob_func)(TSS_HCONTEXT, TSS_HKEY, UINT32, BYTE*, TSS_HKEY*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Policy_AssignToObject_func)(TSS_HPOLICY, TSS_HOBJECT);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_GetAttribData_func)(TSS_HOBJECT, TSS_FLAG, TSS_FLAG, UINT32*, BYTE**);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_GetAttribUint32_func)(TSS_HOBJECT, TSS_FLAG, TSS_FLAG, UINT32*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_TPM_StirRandom_func)(TSS_HTPM, UINT32, BYTE*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_SetAttribUint32_func)(TSS_HOBJECT, TSS_FLAG, TSS_FLAG, UINT32);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_EncodeDER_TssBlob_func)(UINT32, BYTE*, UINT32, UINT32*, BYTE*);
|
|
Packit Service |
4684c1 |
typedef TSS_RESULT (*Tspi_Context_GetRegisteredKeysByUUID2_func)(TSS_HCONTEXT, TSS_FLAG, TSS_UUID*, UINT32*, TSS_KM_KEYINFO2**);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static Tspi_Context_CloseObject_func pTspi_Context_CloseObject;
|
|
Packit Service |
4684c1 |
static Tspi_Context_Close_func pTspi_Context_Close;
|
|
Packit Service |
4684c1 |
static Tspi_Context_CreateObject_func pTspi_Context_CreateObject;
|
|
Packit Service |
4684c1 |
static Tspi_Context_FreeMemory_func pTspi_Context_FreeMemory;
|
|
Packit Service |
4684c1 |
static Tspi_Context_GetTpmObject_func pTspi_Context_GetTpmObject;
|
|
Packit Service |
4684c1 |
static Tspi_Context_LoadKeyByUUID_func pTspi_Context_LoadKeyByUUID;
|
|
Packit Service |
4684c1 |
static Tspi_Context_RegisterKey_func pTspi_Context_RegisterKey;
|
|
Packit Service |
4684c1 |
static Tspi_Context_UnregisterKey_func pTspi_Context_UnregisterKey;
|
|
Packit Service |
4684c1 |
static Tspi_Key_CreateKey_func pTspi_Key_CreateKey;
|
|
Packit Service |
4684c1 |
static Tspi_Hash_SetHashValue_func pTspi_Hash_SetHashValue;
|
|
Packit Service |
4684c1 |
static Tspi_Hash_Sign_func pTspi_Hash_Sign;
|
|
Packit Service |
4684c1 |
static Tspi_Policy_SetSecret_func pTspi_Policy_SetSecret;
|
|
Packit Service |
4684c1 |
static Tspi_Context_Create_func pTspi_Context_Create;
|
|
Packit Service |
4684c1 |
static Tspi_Context_Connect_func pTspi_Context_Connect;
|
|
Packit Service |
4684c1 |
static Tspi_GetPolicyObject_func pTspi_GetPolicyObject;
|
|
Packit Service |
4684c1 |
static Tspi_DecodeBER_TssBlob_func pTspi_DecodeBER_TssBlob;
|
|
Packit Service |
4684c1 |
static Tspi_Context_LoadKeyByBlob_func pTspi_Context_LoadKeyByBlob;
|
|
Packit Service |
4684c1 |
static Tspi_Policy_AssignToObject_func pTspi_Policy_AssignToObject;
|
|
Packit Service |
4684c1 |
static Tspi_GetAttribData_func pTspi_GetAttribData;
|
|
Packit Service |
4684c1 |
static Tspi_GetAttribUint32_func pTspi_GetAttribUint32;
|
|
Packit Service |
4684c1 |
static Tspi_Context_GetTpmObject_func pTspi_Context_GetTpmObject;
|
|
Packit Service |
4684c1 |
static Tspi_TPM_StirRandom_func pTspi_TPM_StirRandom;
|
|
Packit Service |
4684c1 |
static Tspi_SetAttribUint32_func pTspi_SetAttribUint32;
|
|
Packit Service |
4684c1 |
static Tspi_EncodeDER_TssBlob_func pTspi_EncodeDER_TssBlob;
|
|
Packit Service |
4684c1 |
static Tspi_Context_GetRegisteredKeysByUUID2_func pTspi_Context_GetRegisteredKeysByUUID2;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static Trspi_Error_Layer_func pTrspi_Error_Layer;
|
|
Packit Service |
4684c1 |
static Trspi_Error_String_func pTrspi_Error_String;
|
|
Packit Service |
4684c1 |
static Trspi_Error_Code_func pTrspi_Error_Code;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void *tpm_dl = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define _DLSYM(dl, sym) \
|
|
Packit Service |
4684c1 |
p##sym = dlsym(dl, #sym); \
|
|
Packit Service |
4684c1 |
if (p##sym == NULL) { \
|
|
Packit Service |
4684c1 |
dlclose(dl); \
|
|
Packit Service |
4684c1 |
dl = NULL; \
|
|
Packit Service |
4684c1 |
return -1; \
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int check_init(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (tpm_dl == NULL) {
|
|
Packit Service |
4684c1 |
tpm_dl = dlopen(TROUSERS_LIB, RTLD_LAZY);
|
|
Packit Service |
4684c1 |
if (tpm_dl == NULL) {
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("couldn't open %s\n", TROUSERS_LIB);
|
|
Packit Service |
4684c1 |
return -1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_CloseObject);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_Close);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_CreateObject);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_FreeMemory);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_GetTpmObject);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_LoadKeyByUUID);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_RegisterKey);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_UnregisterKey);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Key_CreateKey);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Hash_SetHashValue);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Hash_Sign);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Policy_SetSecret);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_Create);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_Connect);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_GetPolicyObject);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_DecodeBER_TssBlob);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_LoadKeyByBlob);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Policy_AssignToObject);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_GetAttribData);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_GetAttribUint32);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_GetTpmObject);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_TPM_StirRandom);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_SetAttribUint32);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_EncodeDER_TssBlob);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Tspi_Context_GetRegisteredKeysByUUID2);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Trspi_Error_Layer);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Trspi_Error_String);
|
|
Packit Service |
4684c1 |
_DLSYM(tpm_dl,Trspi_Error_Code);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define CHECK_INIT \
|
|
Packit Service |
4684c1 |
if (check_init() < 0) return gnutls_assert_val(GNUTLS_E_TPM_NO_LIB)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define CHECK_INIT_VOID \
|
|
Packit Service |
4684c1 |
if (check_init() < 0) return
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void _gnutls_tpm_global_deinit(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (tpm_dl) {
|
|
Packit Service |
4684c1 |
dlclose(tpm_dl);
|
|
Packit Service |
4684c1 |
tpm_dl = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
struct tpm_ctx_st {
|
|
Packit Service |
4684c1 |
TSS_HCONTEXT tpm_ctx;
|
|
Packit Service |
4684c1 |
TSS_HKEY tpm_key;
|
|
Packit Service |
4684c1 |
TSS_HPOLICY tpm_key_policy;
|
|
Packit Service |
4684c1 |
TSS_HKEY srk;
|
|
Packit Service |
4684c1 |
TSS_HPOLICY srk_policy;
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
struct tpm_key_list_st {
|
|
Packit Service |
4684c1 |
UINT32 size;
|
|
Packit Service |
4684c1 |
TSS_KM_KEYINFO2 *ki;
|
|
Packit Service |
4684c1 |
TSS_HCONTEXT tpm_ctx;
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void tpm_close_session(struct tpm_ctx_st *s);
|
|
Packit Service |
4684c1 |
static int import_tpm_key(gnutls_privkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage_type,
|
|
Packit Service |
4684c1 |
const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password);
|
|
Packit Service |
4684c1 |
static int encode_tpmkey_url(char **url, const TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* TPM URL format: (draft-mavrogiannopoulos-tpmuri-01)
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* tpmkey:file=/path/to/file
|
|
Packit Service |
4684c1 |
* tpmkey:uuid=7f468c16-cb7f-11e1-824d-b3a4f4b20343;storage=user
|
|
Packit Service |
4684c1 |
* tpmkey:uuid=7f468c16-cb7f-11e1-824d-b3a4f4b20343;storage=system
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int tss_err_pwd(TSS_RESULT err, int pwd_error)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("TPM (%s) error: %s (%x)\n",
|
|
Packit Service |
4684c1 |
pTrspi_Error_Layer(err), pTrspi_Error_String(err),
|
|
Packit Service |
4684c1 |
(unsigned int) pTrspi_Error_Code(err));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
switch (ERROR_LAYER(err)) {
|
|
Packit Service |
4684c1 |
case TSS_LAYER_TPM:
|
|
Packit Service |
4684c1 |
switch (ERROR_CODE(err)) {
|
|
Packit Service |
4684c1 |
case TPM_E_AUTHFAIL:
|
|
Packit Service |
4684c1 |
return pwd_error;
|
|
Packit Service |
4684c1 |
case TPM_E_NOSRK:
|
|
Packit Service |
4684c1 |
return GNUTLS_E_TPM_UNINITIALIZED;
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_TPM_ERROR);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
case TSS_LAYER_TCS:
|
|
Packit Service |
4684c1 |
case TSS_LAYER_TSP:
|
|
Packit Service |
4684c1 |
switch (ERROR_CODE(err)) {
|
|
Packit Service |
4684c1 |
case TSS_E_COMM_FAILURE:
|
|
Packit Service |
4684c1 |
case TSS_E_NO_CONNECTION:
|
|
Packit Service |
4684c1 |
case TSS_E_CONNECTION_FAILED:
|
|
Packit Service |
4684c1 |
case TSS_E_CONNECTION_BROKEN:
|
|
Packit Service |
4684c1 |
return GNUTLS_E_TPM_SESSION_ERROR;
|
|
Packit Service |
4684c1 |
case TSS_E_PS_KEY_NOTFOUND:
|
|
Packit Service |
4684c1 |
return GNUTLS_E_TPM_KEY_NOT_FOUND;
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_TPM_ERROR);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_TPM_ERROR);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define tss_err(x) tss_err_pwd(x, GNUTLS_E_TPM_SRK_PASSWORD_ERROR)
|
|
Packit Service |
4684c1 |
#define tss_err_key(x) tss_err_pwd(x, GNUTLS_E_TPM_KEY_PASSWORD_ERROR)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void tpm_deinit_fn(gnutls_privkey_t key, void *_s)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct tpm_ctx_st *s = _s;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->tpm_key_policy);
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->tpm_key);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tpm_close_session(s);
|
|
Packit Service |
4684c1 |
gnutls_free(s);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
tpm_sign_fn(gnutls_privkey_t key, void *_s,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * data, gnutls_datum_t * sig)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct tpm_ctx_st *s = _s;
|
|
Packit Service |
4684c1 |
TSS_HHASH hash;
|
|
Packit Service |
4684c1 |
int err;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("TPM sign function called for %u bytes.\n",
|
|
Packit Service |
4684c1 |
data->size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err =
|
|
Packit Service |
4684c1 |
pTspi_Context_CreateObject(s->tpm_ctx,
|
|
Packit Service |
4684c1 |
TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER,
|
|
Packit Service |
4684c1 |
&hash);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("Failed to create TPM hash object: %s\n",
|
|
Packit Service |
4684c1 |
pTrspi_Error_String(err));
|
|
Packit Service |
4684c1 |
return GNUTLS_E_PK_SIGN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
err = pTspi_Hash_SetHashValue(hash, data->size, data->data);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_debug_log
|
|
Packit Service |
4684c1 |
("Failed to set value in TPM hash object: %s\n",
|
|
Packit Service |
4684c1 |
pTrspi_Error_String(err));
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, hash);
|
|
Packit Service |
4684c1 |
return GNUTLS_E_PK_SIGN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
err = pTspi_Hash_Sign(hash, s->tpm_key, &sig->size, &sig->data);
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, hash);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
if (s->tpm_key_policy || err != TPM_E_AUTHFAIL)
|
|
Packit Service |
4684c1 |
_gnutls_debug_log
|
|
Packit Service |
4684c1 |
("TPM hash signature failed: %s\n",
|
|
Packit Service |
4684c1 |
pTrspi_Error_String(err));
|
|
Packit Service |
4684c1 |
if (err == TPM_E_AUTHFAIL)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_TPM_KEY_PASSWORD_ERROR;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
return GNUTLS_E_PK_SIGN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const unsigned char nullpass[20];
|
|
Packit Service |
4684c1 |
static const gnutls_datum_t nulldata = { (void *) nullpass, 20 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
const TSS_UUID srk_uuid = TSS_UUID_SRK;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int tpm_pin(struct pin_info_st *pin_info, const TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage, char *pin, unsigned int pin_size,
|
|
Packit Service |
4684c1 |
unsigned int attempts)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned int flags = 0;
|
|
Packit Service |
4684c1 |
const char *label;
|
|
Packit Service |
4684c1 |
char *url = NULL;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (attempts > 0)
|
|
Packit Service |
4684c1 |
flags |= GNUTLS_PIN_WRONG;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (uuid) {
|
|
Packit Service |
4684c1 |
if (memcmp(uuid, &srk_uuid, sizeof(TSS_UUID)) == 0) {
|
|
Packit Service |
4684c1 |
label = "SRK";
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = encode_tpmkey_url(&url, uuid, storage);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
label = "TPM";
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = encode_tpmkey_url(&url, uuid, storage);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
label = "unknown";
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_retrieve_pin(pin_info, url, label, flags, pin, pin_size);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
gnutls_free(url);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static TSS_RESULT myTspi_Policy_SetSecret(TSS_HPOLICY hPolicy,
|
|
Packit Service |
4684c1 |
UINT32 ulSecretLength,
|
|
Packit Service |
4684c1 |
BYTE * rgbSecret)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (rgbSecret == NULL) {
|
|
Packit Service |
4684c1 |
/* Well known NULL key */
|
|
Packit Service |
4684c1 |
return pTspi_Policy_SetSecret(hPolicy,
|
|
Packit Service |
4684c1 |
TSS_SECRET_MODE_SHA1,
|
|
Packit Service |
4684c1 |
sizeof(nullpass),
|
|
Packit Service |
4684c1 |
(BYTE *) nullpass);
|
|
Packit Service |
4684c1 |
} else { /* key is given */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return pTspi_Policy_SetSecret(hPolicy,
|
|
Packit Service |
4684c1 |
TSS_SECRET_MODE_PLAIN,
|
|
Packit Service |
4684c1 |
ulSecretLength, rgbSecret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define SAFE_LEN(x) (x==NULL?0:strlen(x))
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int tpm_open_session(struct tpm_ctx_st *s, const char *_srk_password, unsigned allow_invalid_pass)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int err, ret;
|
|
Packit Service |
4684c1 |
char *password = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err = pTspi_Context_Create(&s->tpm_ctx);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return tss_err(err);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (_srk_password != NULL) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t pout;
|
|
Packit Service |
4684c1 |
ret = _gnutls_utf8_password_normalize(_srk_password, strlen(_srk_password), &pout, allow_invalid_pass);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_tspi_ctx;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
password = (char*)pout.data;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err = pTspi_Context_Connect(s->tpm_ctx, NULL);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_tspi_ctx;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err =
|
|
Packit Service |
4684c1 |
pTspi_Context_LoadKeyByUUID(s->tpm_ctx, TSS_PS_TYPE_SYSTEM,
|
|
Packit Service |
4684c1 |
srk_uuid, &s->srk);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_tspi_ctx;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err =
|
|
Packit Service |
4684c1 |
pTspi_GetPolicyObject(s->srk, TSS_POLICY_USAGE, &s->srk_policy);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_srk;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err = myTspi_Policy_SetSecret(s->srk_policy,
|
|
Packit Service |
4684c1 |
SAFE_LEN(password),
|
|
Packit Service |
4684c1 |
(BYTE *) password);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_srkpol;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
gnutls_free(password);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
out_srkpol:
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->srk_policy);
|
|
Packit Service |
4684c1 |
s->srk_policy = 0;
|
|
Packit Service |
4684c1 |
out_srk:
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->srk);
|
|
Packit Service |
4684c1 |
s->srk = 0;
|
|
Packit Service |
4684c1 |
out_tspi_ctx:
|
|
Packit Service |
4684c1 |
pTspi_Context_Close(s->tpm_ctx);
|
|
Packit Service |
4684c1 |
s->tpm_ctx = 0;
|
|
Packit Service |
4684c1 |
gnutls_free(password);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void tpm_close_session(struct tpm_ctx_st *s)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->srk_policy);
|
|
Packit Service |
4684c1 |
s->srk_policy = 0;
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->srk);
|
|
Packit Service |
4684c1 |
s->srk = 0;
|
|
Packit Service |
4684c1 |
pTspi_Context_Close(s->tpm_ctx);
|
|
Packit Service |
4684c1 |
s->tpm_ctx = 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
import_tpm_key_cb(gnutls_privkey_t pkey, const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format, TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage, const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned int attempts = 0;
|
|
Packit Service |
4684c1 |
char pin1[GNUTLS_PKCS11_MAX_PIN_LEN];
|
|
Packit Service |
4684c1 |
char pin2[GNUTLS_PKCS11_MAX_PIN_LEN];
|
|
Packit Service |
4684c1 |
int ret, ret2;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
import_tpm_key(pkey, fdata, format, uuid, storage,
|
|
Packit Service |
4684c1 |
srk_password, key_password);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (attempts > 3)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR) {
|
|
Packit Service |
4684c1 |
ret2 =
|
|
Packit Service |
4684c1 |
tpm_pin(&pkey->pin, &srk_uuid, storage, pin1,
|
|
Packit Service |
4684c1 |
sizeof(pin1), attempts++);
|
|
Packit Service |
4684c1 |
if (ret2 < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_TPM_SRK_PASSWORD_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
srk_password = pin1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR) {
|
|
Packit Service |
4684c1 |
ret2 =
|
|
Packit Service |
4684c1 |
tpm_pin(&pkey->pin, uuid, storage, pin2,
|
|
Packit Service |
4684c1 |
sizeof(pin2), attempts++);
|
|
Packit Service |
4684c1 |
if (ret2 < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_TPM_KEY_PASSWORD_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
key_password = pin2;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
while (ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR
|
|
Packit Service |
4684c1 |
|| ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int load_key(TSS_HCONTEXT tpm_ctx, TSS_HKEY srk,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format, TSS_HKEY * tpm_key)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret, err;
|
|
Packit Service |
4684c1 |
gnutls_datum_t asn1 = { NULL, 0 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (format == GNUTLS_TPMKEY_FMT_CTK_PEM) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t td;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_pem_base64_decode2("TSS KEY BLOB", fdata,
|
|
Packit Service |
4684c1 |
&asn1);
|
|
Packit Service |
4684c1 |
if (ret) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_debug_log
|
|
Packit Service |
4684c1 |
("Error decoding TSS key blob: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
|
|
Packit Service |
4684c1 |
asn1.data, asn1.size, &td, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
gnutls_free(asn1.data);
|
|
Packit Service |
4684c1 |
asn1.data = td.data;
|
|
Packit Service |
4684c1 |
asn1.size = td.size;
|
|
Packit Service |
4684c1 |
} else { /* DER */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
UINT32 tint2;
|
|
Packit Service |
4684c1 |
UINT32 type;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
asn1.size = fdata->size;
|
|
Packit Service |
4684c1 |
asn1.data = gnutls_malloc(asn1.size);
|
|
Packit Service |
4684c1 |
if (asn1.data == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tint2 = asn1.size;
|
|
Packit Service |
4684c1 |
err =
|
|
Packit Service |
4684c1 |
pTspi_DecodeBER_TssBlob(fdata->size, fdata->data, &type,
|
|
Packit Service |
4684c1 |
&tint2, asn1.data);
|
|
Packit Service |
4684c1 |
if (err != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
asn1.size = tint2;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* ... we get it here instead. */
|
|
Packit Service |
4684c1 |
err = pTspi_Context_LoadKeyByBlob(tpm_ctx, srk,
|
|
Packit Service |
4684c1 |
asn1.size, asn1.data, tpm_key);
|
|
Packit Service |
4684c1 |
if (err != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
gnutls_free(asn1.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
import_tpm_key(gnutls_privkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage,
|
|
Packit Service |
4684c1 |
const char *srk_password, const char *_key_password)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int err, ret;
|
|
Packit Service |
4684c1 |
struct tpm_ctx_st *s;
|
|
Packit Service |
4684c1 |
gnutls_datum_t tmp_sig;
|
|
Packit Service |
4684c1 |
char *key_password = NULL;
|
|
Packit Service |
4684c1 |
uint32_t authusage;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
s = gnutls_malloc(sizeof(*s));
|
|
Packit Service |
4684c1 |
if (s == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (_key_password != NULL) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t pout;
|
|
Packit Service |
4684c1 |
ret = _gnutls_utf8_password_normalize(_key_password, strlen(_key_password), &pout, 1);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_ctx;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
key_password = (char*)pout.data;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* normalization of srk_password happens in tpm_open_session() */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = tpm_open_session(s, srk_password, 1);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_ctx;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (fdata != NULL) {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
load_key(s->tpm_ctx, s->srk, fdata, format,
|
|
Packit Service |
4684c1 |
&s->tpm_key);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (uuid) {
|
|
Packit Service |
4684c1 |
err =
|
|
Packit Service |
4684c1 |
pTspi_Context_LoadKeyByUUID(s->tpm_ctx, storage,
|
|
Packit Service |
4684c1 |
*uuid, &s->tpm_key);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err = pTspi_GetAttribUint32(s->tpm_key, TSS_TSPATTRIB_KEY_INFO,
|
|
Packit Service |
4684c1 |
TSS_TSPATTRIB_KEYINFO_AUTHUSAGE,
|
|
Packit Service |
4684c1 |
&authusage);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (authusage) {
|
|
Packit Service |
4684c1 |
if (!_key_password) {
|
|
Packit Service |
4684c1 |
ret = GNUTLS_E_TPM_KEY_PASSWORD_ERROR;
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err = pTspi_Context_CreateObject(s->tpm_ctx,
|
|
Packit Service |
4684c1 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit Service |
4684c1 |
TSS_POLICY_USAGE,
|
|
Packit Service |
4684c1 |
&s->tpm_key_policy);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_key;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err = pTspi_Policy_AssignToObject(s->tpm_key_policy,
|
|
Packit Service |
4684c1 |
s->tpm_key);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_key_policy;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
err = myTspi_Policy_SetSecret(s->tpm_key_policy,
|
|
Packit Service |
4684c1 |
SAFE_LEN(key_password),
|
|
Packit Service |
4684c1 |
(void *) key_password);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err_key(err);
|
|
Packit Service |
4684c1 |
goto out_key_policy;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_privkey_import_ext2(pkey, GNUTLS_PK_RSA, s,
|
|
Packit Service |
4684c1 |
tpm_sign_fn, NULL, tpm_deinit_fn,
|
|
Packit Service |
4684c1 |
0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA1, 0, &nulldata,
|
|
Packit Service |
4684c1 |
&tmp_sig);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(key_password);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
out_key_policy:
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->tpm_key_policy);
|
|
Packit Service |
4684c1 |
s->tpm_key_policy = 0;
|
|
Packit Service |
4684c1 |
out_key:
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s->tpm_ctx, s->tpm_key);
|
|
Packit Service |
4684c1 |
s->tpm_key = 0;
|
|
Packit Service |
4684c1 |
out_session:
|
|
Packit Service |
4684c1 |
_gnutls_privkey_cleanup(pkey);
|
|
Packit Service |
4684c1 |
tpm_close_session(s);
|
|
Packit Service |
4684c1 |
out_ctx:
|
|
Packit Service |
4684c1 |
gnutls_free(s);
|
|
Packit Service |
4684c1 |
gnutls_free(key_password);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_privkey_import_tpm_raw:
|
|
Packit Service |
4684c1 |
* @pkey: The private key
|
|
Packit Service |
4684c1 |
* @fdata: The TPM key to be imported
|
|
Packit Service |
4684c1 |
* @format: The format of the private key
|
|
Packit Service |
4684c1 |
* @srk_password: The password for the SRK key (optional)
|
|
Packit Service |
4684c1 |
* @key_password: A password for the key (optional)
|
|
Packit Service |
4684c1 |
* @flags: should be zero
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will import the given private key to the abstract
|
|
Packit Service |
4684c1 |
* #gnutls_privkey_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* With respect to passwords the same as in gnutls_privkey_import_tpm_url() apply.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_privkey_import_tpm_raw(gnutls_privkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (flags & GNUTLS_PRIVKEY_DISABLE_CALLBACKS)
|
|
Packit Service |
4684c1 |
return import_tpm_key(pkey, fdata, format, NULL, 0,
|
|
Packit Service |
4684c1 |
srk_password, key_password);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
return import_tpm_key_cb(pkey, fdata, format, NULL, 0,
|
|
Packit Service |
4684c1 |
srk_password, key_password);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
struct tpmkey_url_st {
|
|
Packit Service |
4684c1 |
char *filename;
|
|
Packit Service |
4684c1 |
TSS_UUID uuid;
|
|
Packit Service |
4684c1 |
TSS_FLAG storage;
|
|
Packit Service |
4684c1 |
unsigned int uuid_set;
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void clear_tpmkey_url(struct tpmkey_url_st *s)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_free(s->filename);
|
|
Packit Service |
4684c1 |
memset(s, 0, sizeof(*s));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
unescape_string(char *output, const char *input, size_t * size,
|
|
Packit Service |
4684c1 |
char terminator)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st str;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
char *p;
|
|
Packit Service |
4684c1 |
int len;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_buffer_init(&str);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* find terminator */
|
|
Packit Service |
4684c1 |
p = strchr(input, terminator);
|
|
Packit Service |
4684c1 |
if (p != NULL)
|
|
Packit Service |
4684c1 |
len = p - input;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
len = strlen(input);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_append_data(&str, input, len);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_unescape(&str);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_append_data(&str, "", 1);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_pop_data(&str, output, str.length);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&str);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define UUID_SIZE 16
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int randomize_uuid(TSS_UUID * uuid)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
uint8_t raw_uuid[16];
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_rnd(GNUTLS_RND_NONCE, raw_uuid, sizeof(raw_uuid));
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* mark it as random uuid */
|
|
Packit Service |
4684c1 |
raw_uuid[6] &= 0x0f;
|
|
Packit Service |
4684c1 |
raw_uuid[6] |= 0x40;
|
|
Packit Service |
4684c1 |
raw_uuid[8] &= 0x0f;
|
|
Packit Service |
4684c1 |
raw_uuid[8] |= 0x80;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memcpy(&uuid->ulTimeLow, raw_uuid, 4);
|
|
Packit Service |
4684c1 |
memcpy(&uuid->usTimeMid, &raw_uuid[4], 2);
|
|
Packit Service |
4684c1 |
memcpy(&uuid->usTimeHigh, &raw_uuid[6], 2);
|
|
Packit Service |
4684c1 |
uuid->bClockSeqHigh = raw_uuid[8];
|
|
Packit Service |
4684c1 |
uuid->bClockSeqLow = raw_uuid[9];
|
|
Packit Service |
4684c1 |
memcpy(&uuid->rgbNode, &raw_uuid[10], 6);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int encode_tpmkey_url(char **url, const TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
uint8_t u1[UUID_SIZE];
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
gnutls_datum_t dret;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_buffer_init(&buf;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memcpy(u1, &uuid->ulTimeLow, 4);
|
|
Packit Service |
4684c1 |
memcpy(&u1[4], &uuid->usTimeMid, 2);
|
|
Packit Service |
4684c1 |
memcpy(&u1[6], &uuid->usTimeHigh, 2);
|
|
Packit Service |
4684c1 |
u1[8] = uuid->bClockSeqHigh;
|
|
Packit Service |
4684c1 |
u1[9] = uuid->bClockSeqLow;
|
|
Packit Service |
4684c1 |
memcpy(&u1[10], uuid->rgbNode, 6);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_append_str(&buf, "tpmkey:uuid=");
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_buffer_append_printf(&buf,
|
|
Packit Service |
4684c1 |
"%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
|
|
Packit Service |
4684c1 |
(unsigned int) u1[0],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[1],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[2],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[3],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[4],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[5],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[6],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[7],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[8],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[9],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[10],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[11],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[12],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[13],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[14],
|
|
Packit Service |
4684c1 |
(unsigned int) u1[15]);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_buffer_append_printf(&buf, ";storage=%s",
|
|
Packit Service |
4684c1 |
(storage ==
|
|
Packit Service |
4684c1 |
TSS_PS_TYPE_USER) ? "user" :
|
|
Packit Service |
4684c1 |
"system");
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_to_datum(&buf, &dret, 1);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
*url = (char *) dret.data;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int decode_tpmkey_url(const char *url, struct tpmkey_url_st *s)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
char *p;
|
|
Packit Service |
4684c1 |
size_t size;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
unsigned int i, j;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (strstr(url, "tpmkey:") == NULL)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(s, 0, sizeof(*s));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
p = strstr(url, "file=");
|
|
Packit Service |
4684c1 |
if (p != NULL) {
|
|
Packit Service |
4684c1 |
p += sizeof("file=") - 1;
|
|
Packit Service |
4684c1 |
size = strlen(p);
|
|
Packit Service |
4684c1 |
s->filename = gnutls_malloc(size + 1);
|
|
Packit Service |
4684c1 |
if (s->filename == NULL)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = unescape_string(s->filename, p, &size, ';');
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
s->filename[size] = 0;
|
|
Packit Service |
4684c1 |
} else if ((p = strstr(url, "uuid=")) != NULL) {
|
|
Packit Service |
4684c1 |
char tmp_uuid[33];
|
|
Packit Service |
4684c1 |
uint8_t raw_uuid[16];
|
|
Packit Service |
4684c1 |
gnutls_datum_t tmp;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
p += sizeof("uuid=") - 1;
|
|
Packit Service |
4684c1 |
size = strlen(p);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (j = i = 0; i < size; i++) {
|
|
Packit Service |
4684c1 |
if (j == sizeof(tmp_uuid) - 1) {
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (c_isalnum(p[i]))
|
|
Packit Service |
4684c1 |
tmp_uuid[j++] = p[i];
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
tmp_uuid[j] = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tmp.data = (void*)tmp_uuid;
|
|
Packit Service |
4684c1 |
tmp.size = strlen(tmp_uuid);
|
|
Packit Service |
4684c1 |
size = sizeof(raw_uuid);
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_hex_decode(&tmp, raw_uuid,
|
|
Packit Service |
4684c1 |
&size);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memcpy(&s->uuid.ulTimeLow, raw_uuid, 4);
|
|
Packit Service |
4684c1 |
memcpy(&s->uuid.usTimeMid, &raw_uuid[4], 2);
|
|
Packit Service |
4684c1 |
memcpy(&s->uuid.usTimeHigh, &raw_uuid[6], 2);
|
|
Packit Service |
4684c1 |
s->uuid.bClockSeqHigh = raw_uuid[8];
|
|
Packit Service |
4684c1 |
s->uuid.bClockSeqLow = raw_uuid[9];
|
|
Packit Service |
4684c1 |
memcpy(&s->uuid.rgbNode, &raw_uuid[10], 6);
|
|
Packit Service |
4684c1 |
s->uuid_set = 1;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (strstr(url, "storage=user") != NULL)
|
|
Packit Service |
4684c1 |
s->storage = TSS_PS_TYPE_USER;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
s->storage = TSS_PS_TYPE_SYSTEM;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
clear_tpmkey_url(s);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_privkey_import_tpm_url:
|
|
Packit Service |
4684c1 |
* @pkey: The private key
|
|
Packit Service |
4684c1 |
* @url: The URL of the TPM key to be imported
|
|
Packit Service |
4684c1 |
* @srk_password: The password for the SRK key (optional)
|
|
Packit Service |
4684c1 |
* @key_password: A password for the key (optional)
|
|
Packit Service |
4684c1 |
* @flags: One of the GNUTLS_PRIVKEY_* flags
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will import the given private key to the abstract
|
|
Packit Service |
4684c1 |
* #gnutls_privkey_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that unless %GNUTLS_PRIVKEY_DISABLE_CALLBACKS
|
|
Packit Service |
4684c1 |
* is specified, if incorrect (or NULL) passwords are given
|
|
Packit Service |
4684c1 |
* the PKCS11 callback functions will be used to obtain the
|
|
Packit Service |
4684c1 |
* correct passwords. Otherwise if the SRK password is wrong
|
|
Packit Service |
4684c1 |
* %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned and if the key password
|
|
Packit Service |
4684c1 |
* is wrong or not provided then %GNUTLS_E_TPM_KEY_PASSWORD_ERROR
|
|
Packit Service |
4684c1 |
* is returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_privkey_import_tpm_url(gnutls_privkey_t pkey,
|
|
Packit Service |
4684c1 |
const char *url,
|
|
Packit Service |
4684c1 |
const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct tpmkey_url_st durl;
|
|
Packit Service |
4684c1 |
gnutls_datum_t fdata = { NULL, 0 };
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = decode_tpmkey_url(url, &durl);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (durl.filename) {
|
|
Packit Service |
4684c1 |
ret = gnutls_load_file(durl.filename, &fdata);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("Error loading %s\n",
|
|
Packit Service |
4684c1 |
durl.filename);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_privkey_import_tpm_raw(pkey, &fdata,
|
|
Packit Service |
4684c1 |
GNUTLS_TPMKEY_FMT_CTK_PEM,
|
|
Packit Service |
4684c1 |
srk_password,
|
|
Packit Service |
4684c1 |
key_password, flags);
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_privkey_import_tpm_raw(pkey, &fdata,
|
|
Packit Service |
4684c1 |
GNUTLS_TPMKEY_FMT_RAW,
|
|
Packit Service |
4684c1 |
srk_password,
|
|
Packit Service |
4684c1 |
key_password,
|
|
Packit Service |
4684c1 |
flags);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (durl.uuid_set) {
|
|
Packit Service |
4684c1 |
if (flags & GNUTLS_PRIVKEY_DISABLE_CALLBACKS)
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
import_tpm_key(pkey, NULL, 0, &durl.uuid,
|
|
Packit Service |
4684c1 |
durl.storage, srk_password,
|
|
Packit Service |
4684c1 |
key_password);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
import_tpm_key_cb(pkey, NULL, 0, &durl.uuid,
|
|
Packit Service |
4684c1 |
durl.storage, srk_password,
|
|
Packit Service |
4684c1 |
key_password);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
gnutls_free(fdata.data);
|
|
Packit Service |
4684c1 |
clear_tpmkey_url(&durl);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* reads the RSA public key from the given TSS key.
|
|
Packit Service |
4684c1 |
* If psize is non-null it contains the total size of the parameters
|
|
Packit Service |
4684c1 |
* in bytes */
|
|
Packit Service |
4684c1 |
static int read_pubkey(gnutls_pubkey_t pub, TSS_HKEY key_ctx,
|
|
Packit Service |
4684c1 |
size_t * psize)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
void *tdata;
|
|
Packit Service |
4684c1 |
UINT32 tint;
|
|
Packit Service |
4684c1 |
TSS_RESULT tssret;
|
|
Packit Service |
4684c1 |
gnutls_datum_t m, e;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* read the public key */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret = pTspi_GetAttribData(key_ctx, TSS_TSPATTRIB_RSAKEY_INFO,
|
|
Packit Service |
4684c1 |
TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
|
|
Packit Service |
4684c1 |
&tint, (void *) &tdata);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return tss_err(tssret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
m.data = tdata;
|
|
Packit Service |
4684c1 |
m.size = tint;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret = pTspi_GetAttribData(key_ctx, TSS_TSPATTRIB_RSAKEY_INFO,
|
|
Packit Service |
4684c1 |
TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT,
|
|
Packit Service |
4684c1 |
&tint, (void *) &tdata);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
pTspi_Context_FreeMemory(key_ctx, m.data);
|
|
Packit Service |
4684c1 |
return tss_err(tssret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
e.data = tdata;
|
|
Packit Service |
4684c1 |
e.size = tint;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_pubkey_import_rsa_raw(pub, &m, &e);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
pTspi_Context_FreeMemory(key_ctx, m.data);
|
|
Packit Service |
4684c1 |
pTspi_Context_FreeMemory(key_ctx, e.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (psize)
|
|
Packit Service |
4684c1 |
*psize = e.size + m.size;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
import_tpm_pubkey(gnutls_pubkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage, const char *srk_password)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int err, ret;
|
|
Packit Service |
4684c1 |
struct tpm_ctx_st s;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = tpm_open_session(&s, srk_password, 1);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (fdata != NULL) {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
load_key(s.tpm_ctx, s.srk, fdata, format, &s.tpm_key);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (uuid) {
|
|
Packit Service |
4684c1 |
err =
|
|
Packit Service |
4684c1 |
pTspi_Context_LoadKeyByUUID(s.tpm_ctx, storage,
|
|
Packit Service |
4684c1 |
*uuid, &s.tpm_key);
|
|
Packit Service |
4684c1 |
if (err) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(err);
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = read_pubkey(pkey, s.tpm_key, NULL);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto out_session;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
out_session:
|
|
Packit Service |
4684c1 |
tpm_close_session(&s);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
import_tpm_pubkey_cb(gnutls_pubkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
TSS_UUID * uuid,
|
|
Packit Service |
4684c1 |
TSS_FLAG storage, const char *srk_password)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned int attempts = 0;
|
|
Packit Service |
4684c1 |
char pin1[GNUTLS_PKCS11_MAX_PIN_LEN];
|
|
Packit Service |
4684c1 |
int ret, sret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
import_tpm_pubkey(pkey, fdata, format, uuid, storage,
|
|
Packit Service |
4684c1 |
srk_password);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (attempts > 3)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR) {
|
|
Packit Service |
4684c1 |
sret =
|
|
Packit Service |
4684c1 |
tpm_pin(&pkey->pin, &srk_uuid, storage, pin1,
|
|
Packit Service |
4684c1 |
sizeof(pin1), attempts++);
|
|
Packit Service |
4684c1 |
if (sret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_TPM_SRK_PASSWORD_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
srk_password = pin1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
while (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_pubkey_import_tpm_raw:
|
|
Packit Service |
4684c1 |
* @pkey: The public key
|
|
Packit Service |
4684c1 |
* @fdata: The TPM key to be imported
|
|
Packit Service |
4684c1 |
* @format: The format of the private key
|
|
Packit Service |
4684c1 |
* @srk_password: The password for the SRK key (optional)
|
|
Packit Service |
4684c1 |
* @flags: One of the GNUTLS_PUBKEY_* flags
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will import the public key from the provided TPM key
|
|
Packit Service |
4684c1 |
* structure.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* With respect to passwords the same as in
|
|
Packit Service |
4684c1 |
* gnutls_pubkey_import_tpm_url() apply.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_pubkey_import_tpm_raw(gnutls_pubkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
const char *srk_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS)
|
|
Packit Service |
4684c1 |
return import_tpm_pubkey_cb(pkey, fdata, format, NULL, 0,
|
|
Packit Service |
4684c1 |
srk_password);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
return import_tpm_pubkey(pkey, fdata, format, NULL, 0,
|
|
Packit Service |
4684c1 |
srk_password);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_pubkey_import_tpm_url:
|
|
Packit Service |
4684c1 |
* @pkey: The public key
|
|
Packit Service |
4684c1 |
* @url: The URL of the TPM key to be imported
|
|
Packit Service |
4684c1 |
* @srk_password: The password for the SRK key (optional)
|
|
Packit Service |
4684c1 |
* @flags: should be zero
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will import the given private key to the abstract
|
|
Packit Service |
4684c1 |
* #gnutls_privkey_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that unless %GNUTLS_PUBKEY_DISABLE_CALLBACKS
|
|
Packit Service |
4684c1 |
* is specified, if incorrect (or NULL) passwords are given
|
|
Packit Service |
4684c1 |
* the PKCS11 callback functions will be used to obtain the
|
|
Packit Service |
4684c1 |
* correct passwords. Otherwise if the SRK password is wrong
|
|
Packit Service |
4684c1 |
* %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_pubkey_import_tpm_url(gnutls_pubkey_t pkey,
|
|
Packit Service |
4684c1 |
const char *url,
|
|
Packit Service |
4684c1 |
const char *srk_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct tpmkey_url_st durl;
|
|
Packit Service |
4684c1 |
gnutls_datum_t fdata = { NULL, 0 };
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = decode_tpmkey_url(url, &durl);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (durl.filename) {
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_load_file(durl.filename, &fdata);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_pubkey_import_tpm_raw(pkey, &fdata,
|
|
Packit Service |
4684c1 |
GNUTLS_TPMKEY_FMT_CTK_PEM,
|
|
Packit Service |
4684c1 |
srk_password, flags);
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_pubkey_import_tpm_raw(pkey, &fdata,
|
|
Packit Service |
4684c1 |
GNUTLS_TPMKEY_FMT_RAW,
|
|
Packit Service |
4684c1 |
srk_password,
|
|
Packit Service |
4684c1 |
flags);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (durl.uuid_set) {
|
|
Packit Service |
4684c1 |
if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS)
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
import_tpm_pubkey(pkey, NULL, 0, &durl.uuid,
|
|
Packit Service |
4684c1 |
durl.storage, srk_password);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
import_tpm_pubkey_cb(pkey, NULL, 0, &durl.uuid,
|
|
Packit Service |
4684c1 |
durl.storage,
|
|
Packit Service |
4684c1 |
srk_password);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
gnutls_free(fdata.data);
|
|
Packit Service |
4684c1 |
clear_tpmkey_url(&durl);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_tpm_privkey_generate:
|
|
Packit Service |
4684c1 |
* @pk: the public key algorithm
|
|
Packit Service |
4684c1 |
* @bits: the security bits
|
|
Packit Service |
4684c1 |
* @srk_password: a password to protect the exported key (optional)
|
|
Packit Service |
4684c1 |
* @key_password: the password for the TPM (optional)
|
|
Packit Service |
4684c1 |
* @format: the format of the private key
|
|
Packit Service |
4684c1 |
* @pub_format: the format of the public key
|
|
Packit Service |
4684c1 |
* @privkey: the generated key
|
|
Packit Service |
4684c1 |
* @pubkey: the corresponding public key (may be null)
|
|
Packit Service |
4684c1 |
* @flags: should be a list of GNUTLS_TPM_* flags
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will generate a private key in the TPM
|
|
Packit Service |
4684c1 |
* chip. The private key will be generated within the chip
|
|
Packit Service |
4684c1 |
* and will be exported in a wrapped with TPM's master key
|
|
Packit Service |
4684c1 |
* form. Furthermore the wrapped key can be protected with
|
|
Packit Service |
4684c1 |
* the provided @password.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that bits in TPM is quantized value. If the input value
|
|
Packit Service |
4684c1 |
* is not one of the allowed values, then it will be quantized to
|
|
Packit Service |
4684c1 |
* one of 512, 1024, 2048, 4096, 8192 and 16384.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Allowed flags are:
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* %GNUTLS_TPM_KEY_SIGNING: Generate a signing key instead of a legacy,
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* %GNUTLS_TPM_REGISTER_KEY: Register the generate key in TPM. In that
|
|
Packit Service |
4684c1 |
* case @privkey would contain a URL with the UUID.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_tpm_privkey_generate(gnutls_pk_algorithm_t pk, unsigned int bits,
|
|
Packit Service |
4684c1 |
const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_fmt_t pub_format,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * privkey,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * pubkey, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
TSS_FLAG tpm_flags = TSS_KEY_VOLATILE;
|
|
Packit Service |
4684c1 |
TSS_HKEY key_ctx;
|
|
Packit Service |
4684c1 |
TSS_RESULT tssret;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
void *tdata;
|
|
Packit Service |
4684c1 |
UINT32 tint;
|
|
Packit Service |
4684c1 |
gnutls_datum_t tmpkey = { NULL, 0 };
|
|
Packit Service |
4684c1 |
TSS_HPOLICY key_policy;
|
|
Packit Service |
4684c1 |
gnutls_pubkey_t pub;
|
|
Packit Service |
4684c1 |
struct tpm_ctx_st s;
|
|
Packit Service |
4684c1 |
TSS_FLAG storage_type;
|
|
Packit Service |
4684c1 |
TSS_HTPM htpm;
|
|
Packit Service |
4684c1 |
uint8_t buf[32];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
privkey->data = NULL;
|
|
Packit Service |
4684c1 |
if (pubkey != NULL)
|
|
Packit Service |
4684c1 |
pubkey->data = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (flags & GNUTLS_TPM_KEY_SIGNING)
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_TYPE_SIGNING;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_TYPE_LEGACY;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (flags & GNUTLS_TPM_KEY_USER)
|
|
Packit Service |
4684c1 |
storage_type = TSS_PS_TYPE_USER;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
storage_type = TSS_PS_TYPE_SYSTEM;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (bits <= 512)
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_SIZE_512;
|
|
Packit Service |
4684c1 |
else if (bits <= 1024)
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_SIZE_1024;
|
|
Packit Service |
4684c1 |
else if (bits <= 2048)
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_SIZE_2048;
|
|
Packit Service |
4684c1 |
else if (bits <= 4096)
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_SIZE_4096;
|
|
Packit Service |
4684c1 |
else if (bits <= 8192)
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_SIZE_8192;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
tpm_flags |= TSS_KEY_SIZE_16384;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = tpm_open_session(&s, srk_password, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* put some randomness into TPM.
|
|
Packit Service |
4684c1 |
* Let's not trust it completely.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
tssret = pTspi_Context_GetTpmObject(s.tpm_ctx, &htpm);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_cc;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_rnd(GNUTLS_RND_RANDOM, buf, sizeof(buf));
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto err_cc;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret = pTspi_TPM_StirRandom(htpm, sizeof(buf), buf);
|
|
Packit Service |
4684c1 |
if (tssret) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_Context_CreateObject(s.tpm_ctx, TSS_OBJECT_TYPE_RSAKEY,
|
|
Packit Service |
4684c1 |
tpm_flags, &key_ctx);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_cc;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_SetAttribUint32(key_ctx, TSS_TSPATTRIB_KEY_INFO,
|
|
Packit Service |
4684c1 |
TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
|
|
Packit Service |
4684c1 |
TSS_SS_RSASSAPKCS1V15_DER);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* set the password of the actual key */
|
|
Packit Service |
4684c1 |
if (key_password) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t pout;
|
|
Packit Service |
4684c1 |
char *password = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_GetPolicyObject(key_ctx, TSS_POLICY_USAGE,
|
|
Packit Service |
4684c1 |
&key_policy);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_utf8_password_normalize(key_password, strlen(key_password), &pout, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
password = (char*)pout.data;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret = myTspi_Policy_SetSecret(key_policy,
|
|
Packit Service |
4684c1 |
SAFE_LEN(password),
|
|
Packit Service |
4684c1 |
(void *)password);
|
|
Packit Service |
4684c1 |
gnutls_free(password);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret = pTspi_Key_CreateKey(key_ctx, s.srk, 0);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (flags & GNUTLS_TPM_REGISTER_KEY) {
|
|
Packit Service |
4684c1 |
TSS_UUID key_uuid;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = randomize_uuid(&key_uuid);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_Context_RegisterKey(s.tpm_ctx, key_ctx,
|
|
Packit Service |
4684c1 |
storage_type, key_uuid,
|
|
Packit Service |
4684c1 |
TSS_PS_TYPE_SYSTEM, srk_uuid);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
encode_tpmkey_url((char **) &privkey->data, &key_uuid,
|
|
Packit Service |
4684c1 |
storage_type);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
TSS_HKEY tkey;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
pTspi_Context_UnregisterKey(s.tpm_ctx, storage_type,
|
|
Packit Service |
4684c1 |
key_uuid, &tkey);
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
privkey->size = strlen((char *) privkey->data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
} else { /* get the key as blob */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_GetAttribData(key_ctx, TSS_TSPATTRIB_KEY_BLOB,
|
|
Packit Service |
4684c1 |
TSS_TSPATTRIB_KEYBLOB_BLOB, &tint,
|
|
Packit Service |
4684c1 |
(void *) &tdata);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_sa;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (format == GNUTLS_TPMKEY_FMT_CTK_PEM) {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_x509_encode_string
|
|
Packit Service |
4684c1 |
(ASN1_ETYPE_OCTET_STRING, tdata, tint,
|
|
Packit Service |
4684c1 |
&tmpkey);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_fbase64_encode("TSS KEY BLOB",
|
|
Packit Service |
4684c1 |
tmpkey.data,
|
|
Packit Service |
4684c1 |
tmpkey.size, privkey);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
UINT32 tint2;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tmpkey.size = tint + 32; /* spec says no more than 20 */
|
|
Packit Service |
4684c1 |
tmpkey.data = gnutls_malloc(tmpkey.size);
|
|
Packit Service |
4684c1 |
if (tmpkey.data == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tint2 = tmpkey.size;
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_EncodeDER_TssBlob(tint, tdata,
|
|
Packit Service |
4684c1 |
TSS_BLOB_TYPE_PRIVATEKEY,
|
|
Packit Service |
4684c1 |
&tint2, tmpkey.data);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tmpkey.size = tint2;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
privkey->data = tmpkey.data;
|
|
Packit Service |
4684c1 |
privkey->size = tmpkey.size;
|
|
Packit Service |
4684c1 |
tmpkey.data = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* read the public key */
|
|
Packit Service |
4684c1 |
if (pubkey != NULL) {
|
|
Packit Service |
4684c1 |
size_t psize = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_pubkey_init(&pub;;
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto privkey_cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = read_pubkey(pub, key_ctx, &psize);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto privkey_cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
psize += 512;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
pubkey->data = gnutls_malloc(psize);
|
|
Packit Service |
4684c1 |
if (pubkey->data == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
goto pubkey_cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_pubkey_export(pub, pub_format, pubkey->data,
|
|
Packit Service |
4684c1 |
&psize);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto pubkey_cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
pubkey->size = psize;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pubkey_deinit(pub);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
pubkey_cleanup:
|
|
Packit Service |
4684c1 |
gnutls_pubkey_deinit(pub);
|
|
Packit Service |
4684c1 |
privkey_cleanup:
|
|
Packit Service |
4684c1 |
gnutls_free(privkey->data);
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
gnutls_free(tmpkey.data);
|
|
Packit Service |
4684c1 |
err_sa:
|
|
Packit Service |
4684c1 |
pTspi_Context_CloseObject(s.tpm_ctx, key_ctx);
|
|
Packit Service |
4684c1 |
err_cc:
|
|
Packit Service |
4684c1 |
tpm_close_session(&s);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_tpm_key_list_deinit:
|
|
Packit Service |
4684c1 |
* @list: a list of the keys
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will deinitialize the list of stored keys in the TPM.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void gnutls_tpm_key_list_deinit(gnutls_tpm_key_list_t list)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
CHECK_INIT_VOID;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (list->tpm_ctx != 0)
|
|
Packit Service |
4684c1 |
pTspi_Context_Close(list->tpm_ctx);
|
|
Packit Service |
4684c1 |
gnutls_free(list);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_tpm_key_list_get_url:
|
|
Packit Service |
4684c1 |
* @list: a list of the keys
|
|
Packit Service |
4684c1 |
* @idx: The index of the key (starting from zero)
|
|
Packit Service |
4684c1 |
* @url: The URL to be returned
|
|
Packit Service |
4684c1 |
* @flags: should be zero
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will return for each given index a URL of
|
|
Packit Service |
4684c1 |
* the corresponding key.
|
|
Packit Service |
4684c1 |
* If the provided index is out of bounds then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
|
|
Packit Service |
4684c1 |
* is returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_tpm_key_list_get_url(gnutls_tpm_key_list_t list, unsigned int idx,
|
|
Packit Service |
4684c1 |
char **url, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (idx >= list->size)
|
|
Packit Service |
4684c1 |
return
|
|
Packit Service |
4684c1 |
gnutls_assert_val
|
|
Packit Service |
4684c1 |
(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return encode_tpmkey_url(url, &list->ki[idx].keyUUID,
|
|
Packit Service |
4684c1 |
list->ki[idx].persistentStorageType);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_tpm_get_registered:
|
|
Packit Service |
4684c1 |
* @list: a list to store the keys
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will get a list of stored keys in the TPM. The uuid
|
|
Packit Service |
4684c1 |
* of those keys
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int gnutls_tpm_get_registered(gnutls_tpm_key_list_t * list)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
TSS_RESULT tssret;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
*list = gnutls_calloc(1, sizeof(struct tpm_key_list_st));
|
|
Packit Service |
4684c1 |
if (*list == NULL)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret = pTspi_Context_Create(&(*list)->tpm_ctx);
|
|
Packit Service |
4684c1 |
if (tssret) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret = pTspi_Context_Connect((*list)->tpm_ctx, NULL);
|
|
Packit Service |
4684c1 |
if (tssret) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_Context_GetRegisteredKeysByUUID2((*list)->tpm_ctx,
|
|
Packit Service |
4684c1 |
TSS_PS_TYPE_SYSTEM, NULL,
|
|
Packit Service |
4684c1 |
&(*list)->size,
|
|
Packit Service |
4684c1 |
&(*list)->ki);
|
|
Packit Service |
4684c1 |
if (tssret) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
gnutls_tpm_key_list_deinit(*list);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_tpm_privkey_delete:
|
|
Packit Service |
4684c1 |
* @url: the URL describing the key
|
|
Packit Service |
4684c1 |
* @srk_password: a password for the SRK key
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will unregister the private key from the TPM
|
|
Packit Service |
4684c1 |
* chip.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int gnutls_tpm_privkey_delete(const char *url, const char *srk_password)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct tpm_ctx_st s;
|
|
Packit Service |
4684c1 |
struct tpmkey_url_st durl;
|
|
Packit Service |
4684c1 |
TSS_RESULT tssret;
|
|
Packit Service |
4684c1 |
TSS_HKEY tkey;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = decode_tpmkey_url(url, &durl);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (durl.uuid_set == 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = tpm_open_session(&s, srk_password, 1);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
tssret =
|
|
Packit Service |
4684c1 |
pTspi_Context_UnregisterKey(s.tpm_ctx, durl.storage, durl.uuid,
|
|
Packit Service |
4684c1 |
&tkey);
|
|
Packit Service |
4684c1 |
if (tssret != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = tss_err(tssret);
|
|
Packit Service |
4684c1 |
goto err_cc;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
err_cc:
|
|
Packit Service |
4684c1 |
tpm_close_session(&s);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#else /* HAVE_TROUSERS */
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_privkey_import_tpm_raw(gnutls_privkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_privkey_import_tpm_url(gnutls_privkey_t pkey,
|
|
Packit Service |
4684c1 |
const char *url,
|
|
Packit Service |
4684c1 |
const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_pubkey_import_tpm_raw(gnutls_pubkey_t pkey,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * fdata,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
const char *srk_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_pubkey_import_tpm_url(gnutls_pubkey_t pkey,
|
|
Packit Service |
4684c1 |
const char *url,
|
|
Packit Service |
4684c1 |
const char *srk_password, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_tpm_privkey_generate(gnutls_pk_algorithm_t pk, unsigned int bits,
|
|
Packit Service |
4684c1 |
const char *srk_password,
|
|
Packit Service |
4684c1 |
const char *key_password,
|
|
Packit Service |
4684c1 |
gnutls_tpmkey_fmt_t format,
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_fmt_t pub_format,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * privkey,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * pubkey, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void gnutls_tpm_key_list_deinit(gnutls_tpm_key_list_t list)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_tpm_key_list_get_url(gnutls_tpm_key_list_t list, unsigned int idx,
|
|
Packit Service |
4684c1 |
char **url, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int gnutls_tpm_get_registered(gnutls_tpm_key_list_t * list)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int gnutls_tpm_privkey_delete(const char *url, const char *srk_password)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif /* HAVE_TROUSERS */
|