static int import_tpm_key(gnutls_privkey_t pkey, const gnutls_datum_t * fdata, gnutls_tpmkey_fmt_t format, TSS_UUID * uuid, TSS_FLAG storage, const char *srk_password, const char *key_password) { int err, ret; struct tpm_ctx_st *s; gnutls_datum_t tmp_sig; s = gnutls_malloc(sizeof(*s)); if (s == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } ret = tpm_open_session(s, srk_password); if (ret < 0) { gnutls_assert(); goto out_ctx; } if (fdata != NULL) { ret = load_key(s->tpm_ctx, s->srk, fdata, format, &s->tpm_key); if (ret < 0) { gnutls_assert(); goto out_session; } } else if (uuid) { err = Tspi_Context_LoadKeyByUUID(s->tpm_ctx, storage, *uuid, &s->tpm_key); if (err) { gnutls_assert(); ret = tss_err(err); goto out_session; } } else { gnutls_assert(); ret = GNUTLS_E_INVALID_REQUEST; goto out_session; } ret = gnutls_privkey_import_ext2(pkey, GNUTLS_PK_RSA, s, tpm_sign_fn, NULL, tpm_deinit_fn, 0); if (ret < 0) { gnutls_assert(); goto out_session; } ret = gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA1, 0, &nulldata, &tmp_sig); if (ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR) { if (!s->tpm_key_policy) { err = Tspi_Context_CreateObject(s->tpm_ctx, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &s-> tpm_key_policy); if (err) { gnutls_assert(); ret = tss_err(err); goto out_key; } err = Tspi_Policy_AssignToObject(s->tpm_key_policy, s->tpm_key); if (err) { gnutls_assert(); ret = tss_err(err); goto out_key_policy; } } err = myTspi_Policy_SetSecret(s->tpm_key_policy, SAFE_LEN(key_password), (void *) key_password); if (err) { gnutls_assert(); ret = tss_err_key(err); goto out_key_policy; } } else if (ret < 0) { gnutls_assert(); goto out_session; } return 0; out_key_policy: Tspi_Context_CloseObject(s->tpm_ctx, s->tpm_key_policy); s->tpm_key_policy = 0; out_key: Tspi_Context_CloseObject(s->tpm_ctx, s->tpm_key); s->tpm_key = 0; out_session: tpm_close_session(s); out_ctx: gnutls_free(s); return ret; }
static int import_tpm_key(gnutls_privkey_t pkey, const gnutls_datum_t * fdata, gnutls_tpmkey_fmt_t format, TSS_UUID * uuid, TSS_FLAG storage, const char *srk_password, const char *_key_password) { int err, ret; struct tpm_ctx_st *s; gnutls_datum_t tmp_sig; char *key_password = NULL; uint32_t authusage; s = gnutls_malloc(sizeof(*s)); if (s == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } if (_key_password != NULL) { gnutls_datum_t pout; ret = _gnutls_utf8_password_normalize(_key_password, strlen(_key_password), &pout, 1); if (ret < 0) { gnutls_assert(); goto out_ctx; } key_password = (char*)pout.data; } /* normalization of srk_password happens in tpm_open_session() */ ret = tpm_open_session(s, srk_password, 1); if (ret < 0) { gnutls_assert(); goto out_ctx; } if (fdata != NULL) { ret = load_key(s->tpm_ctx, s->srk, fdata, format, &s->tpm_key); if (ret < 0) { gnutls_assert(); goto out_session; } } else if (uuid) { err = pTspi_Context_LoadKeyByUUID(s->tpm_ctx, storage, *uuid, &s->tpm_key); if (err) { gnutls_assert(); ret = tss_err(err); goto out_session; } } else { gnutls_assert(); ret = GNUTLS_E_INVALID_REQUEST; goto out_session; } err = pTspi_GetAttribUint32(s->tpm_key, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &authusage); if (err) { gnutls_assert(); ret = tss_err(err); goto out_session; } if (authusage) { if (!_key_password) { ret = GNUTLS_E_TPM_KEY_PASSWORD_ERROR; goto out_session; } err = pTspi_Context_CreateObject(s->tpm_ctx, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &s->tpm_key_policy); if (err) { gnutls_assert(); ret = tss_err(err); goto out_key; } err = pTspi_Policy_AssignToObject(s->tpm_key_policy, s->tpm_key); if (err) { gnutls_assert(); ret = tss_err(err); goto out_key_policy; } err = myTspi_Policy_SetSecret(s->tpm_key_policy, SAFE_LEN(key_password), (void *) key_password); if (err) { gnutls_assert(); ret = tss_err_key(err); goto out_key_policy; } } ret = gnutls_privkey_import_ext2(pkey, GNUTLS_PK_RSA, s, tpm_sign_fn, NULL, tpm_deinit_fn, 0); if (ret < 0) { gnutls_assert(); goto out_session; } ret = gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA1, 0, &nulldata, &tmp_sig); if (ret < 0) { gnutls_assert(); goto out_session; } gnutls_free(key_password); return 0; out_key_policy: pTspi_Context_CloseObject(s->tpm_ctx, s->tpm_key_policy); s->tpm_key_policy = 0; out_key: pTspi_Context_CloseObject(s->tpm_ctx, s->tpm_key); s->tpm_key = 0; out_session: _gnutls_privkey_cleanup(pkey); tpm_close_session(s); out_ctx: gnutls_free(s); gnutls_free(key_password); return ret; }