From: Nikos Mavrogiannopoulos Date: Wed, 11 Jul 2012 21:34:57 +0000 (+0200) Subject: Added the option to register a key X-Git-Tag: gnutls_3_1_0pre0~79 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e441e4bbf444e85ff69e69022c0f81b0b9a812ae;p=thirdparty%2Fgnutls.git Added the option to register a key --- diff --git a/lib/includes/gnutls/tpm.h b/lib/includes/gnutls/tpm.h index 9eb3c92b73..cfed07ed27 100644 --- a/lib/includes/gnutls/tpm.h +++ b/lib/includes/gnutls/tpm.h @@ -31,8 +31,8 @@ extern "C" { #endif -#define GNUTLS_TPM_SIG_PKCS1V15 1 -#define GNUTLS_TPM_SIG_PKCS1V15_SHA1 2 +#define GNUTLS_TPM_KEY_SIGNING (1<<2) +#define GNUTLS_TPM_REGISTER_KEY (1<<3) int gnutls_tpm_privkey_generate (gnutls_pk_algorithm_t pk, unsigned int bits, diff --git a/lib/tpm.c b/lib/tpm.c index 6f03f53fa5..9740d49d92 100644 --- a/lib/tpm.c +++ b/lib/tpm.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -477,6 +478,46 @@ unescape_string (char *output, const char *input, size_t * size, return ret; } +#define UUID_SIZE 16 + +static int randomize_uuid(TSS_UUID* uuid) +{ + uint8_t raw_uuid[16]; + int ret; + + ret = _gnutls_rnd (GNUTLS_RND_NONCE, raw_uuid, sizeof(raw_uuid)); + if (ret < 0) + return gnutls_assert_val(ret); + + memcpy(&uuid->ulTimeLow, raw_uuid, 4); + memcpy(&uuid->usTimeMid, &raw_uuid[4], 2); + memcpy(&uuid->usTimeHigh, &raw_uuid[6], 2); + uuid->bClockSeqHigh = raw_uuid[8]; + uuid->bClockSeqLow = raw_uuid[9]; + memcpy(&uuid->rgbNode, &raw_uuid[10], 6); + + return 0; +} + +static int encode_tpmkey_url(char** url, TSS_UUID* uuid) +{ +size_t size = UUID_SIZE*2+4+32; + + *url = gnutls_malloc(size); + if (*url == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + snprintf(*url, size, "tpmkey:uuid=%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x", + (unsigned int)uuid->ulTimeLow, (unsigned int)uuid->usTimeMid, + (unsigned int)uuid->usTimeHigh, (unsigned int)uuid->bClockSeqHigh, + (unsigned int)uuid->bClockSeqLow, (unsigned int)uuid->rgbNode[0], + (unsigned int)uuid->rgbNode[1], (unsigned int)uuid->rgbNode[2], + (unsigned int)uuid->rgbNode[3], (unsigned int)uuid->rgbNode[4], + (unsigned int)uuid->rgbNode[5]); + + return 0; +} + static int decode_tpmkey_url(const char* url, struct tpmkey_url_st *s) { char* p; @@ -787,7 +828,12 @@ out_blob: * is not one of the allowed values, then it will be quantized to * one of 512, 1024, 2048, 4096, 8192 and 16384. * - * Allowed flags are %GNUTLS_TPM_SIG_PKCS1V15 and %GNUTLS_TPM_SIG_PKCS1V15_SHA1. + * Allowed flags are: + * + * %GNUTLS_TPM_KEY_SIGNING: Generate a signing key instead of a legacy, + + * %GNUTLS_TPM_REGISTER_KEY: Register the generate key in TPM. In that + * case @privkey would contain a URL with the UUID. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. @@ -803,7 +849,7 @@ gnutls_tpm_privkey_generate (gnutls_pk_algorithm_t pk, unsigned int bits, gnutls_datum_t* pubkey, unsigned int flags) { -TSS_FLAG tpm_flags = TSS_KEY_TYPE_LEGACY | TSS_KEY_VOLATILE; +TSS_FLAG tpm_flags = TSS_KEY_VOLATILE; TSS_HKEY key_ctx; TSS_RESULT tssret; int ret; @@ -811,10 +857,14 @@ void* tdata; UINT32 tint; gnutls_datum_t tmpkey; TSS_HPOLICY key_policy; -unsigned int sig; gnutls_pubkey_t pub; struct tpm_ctx_st s; + if (flags & GNUTLS_TPM_KEY_SIGNING) + tpm_flags |= TSS_KEY_TYPE_SIGNING; + else + tpm_flags |= TSS_KEY_TYPE_LEGACY; + if (bits <= 512) tpm_flags |= TSS_KEY_SIZE_512; else if (bits <= 1024) @@ -840,13 +890,8 @@ struct tpm_ctx_st s; goto err_cc; } - if (flags & GNUTLS_TPM_SIG_PKCS1V15_SHA1) - sig = TSS_SS_RSASSAPKCS1V15_SHA1; - else - sig = TSS_SS_RSASSAPKCS1V15_DER; - tssret = Tspi_SetAttribUint32(key_ctx, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME, - sig); + TSS_SS_RSASSAPKCS1V15_DER); if (tssret != 0) { gnutls_assert(); @@ -883,36 +928,72 @@ struct tpm_ctx_st s; goto err_sa; } - tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_KEY_BLOB, - TSS_TSPATTRIB_KEYBLOB_BLOB, &tint, (void*)&tdata); - if (tssret != 0) + if (flags & GNUTLS_TPM_REGISTER_KEY) { - gnutls_assert(); - ret = tss_err(tssret); - goto err_sa; - } + TSS_UUID key_uuid; + + ret = randomize_uuid(&key_uuid); + if (ret < 0) + { + gnutls_assert(); + goto err_sa; + } + + tssret = Tspi_Context_RegisterKey(s.tpm_ctx, key_ctx, TSS_PS_TYPE_SYSTEM, + key_uuid, TSS_PS_TYPE_SYSTEM, srk_uuid); + if (tssret != 0) + { + gnutls_assert(); + ret = tss_err(tssret); + goto err_sa; + } + + ret = encode_tpmkey_url((char**)&privkey->data, &key_uuid); + if (ret < 0) + { + TSS_HKEY tkey; + + Tspi_Context_UnregisterKey(s.tpm_ctx, TSS_PS_TYPE_SYSTEM, key_uuid, &tkey); + gnutls_assert(); + goto err_sa; + } + privkey->size = strlen((char*)privkey->data); - ret = _gnutls_x509_encode_octet_string(tdata, tint, &tmpkey); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; } - - if (format == GNUTLS_X509_FMT_PEM) + else /* get the key as blob */ { - ret = _gnutls_fbase64_encode ("TSS KEY BLOB", tmpkey.data, tmpkey.size, privkey); + + tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_KEY_BLOB, + TSS_TSPATTRIB_KEYBLOB_BLOB, &tint, (void*)&tdata); + if (tssret != 0) + { + gnutls_assert(); + ret = tss_err(tssret); + goto err_sa; + } + + ret = _gnutls_x509_encode_octet_string(tdata, tint, &tmpkey); if (ret < 0) { gnutls_assert(); goto cleanup; } - } - else - { - privkey->data = tmpkey.data; - privkey->size = tmpkey.size; - tmpkey.data = NULL; + + if (format == GNUTLS_X509_FMT_PEM) + { + ret = _gnutls_fbase64_encode ("TSS KEY BLOB", tmpkey.data, tmpkey.size, privkey); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + } + else + { + privkey->data = tmpkey.data; + privkey->size = tmpkey.size; + tmpkey.data = NULL; + } } /* read the public key */