/** * gnutls_privkey_import_ext: * @pkey: The private key * @pk: The public key algorithm * @userdata: private data to be provided to the callbacks * @sign_func: callback for signature operations * @decrypt_func: callback for decryption operations * @flags: Flags for the import * * This function will associate the given callbacks with the * #gnutls_privkey_t type. At least one of the two callbacks * must be non-null. * * Note that the signing function is supposed to "raw" sign data, i.e., * without any hashing or preprocessing. In case of RSA the DigestInfo * will be provided, and the signing function is expected to do the PKCS #1 * 1.5 padding and the exponentiation. * * See also gnutls_privkey_import_ext3(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.0 **/ int gnutls_privkey_import_ext(gnutls_privkey_t pkey, gnutls_pk_algorithm_t pk, void *userdata, gnutls_privkey_sign_func sign_func, gnutls_privkey_decrypt_func decrypt_func, unsigned int flags) { return gnutls_privkey_import_ext2(pkey, pk, userdata, sign_func, decrypt_func, NULL, flags); }
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; }