diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-07-14 10:38:27 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-07-14 10:38:27 +0200 |
commit | 9a931a9de38e7ef29b33e04258fde243a28bda52 (patch) | |
tree | 3db92c580bb812f96150f76ed411887256bfae5c /lib/tpm.c | |
parent | 61e04c3e3f0ca09eacbe9f7a44d40dc52c7aebb4 (diff) | |
download | gnutls-9a931a9de38e7ef29b33e04258fde243a28bda52.tar.gz |
Allow handling of user and system keys.
Diffstat (limited to 'lib/tpm.c')
-rw-r--r-- | lib/tpm.c | 108 |
1 files changed, 51 insertions, 57 deletions
@@ -53,7 +53,7 @@ struct tpm_ctx_st struct tpm_key_list_st { UINT32 size; - TSS_KM_KEYINFO * ki; + TSS_KM_KEYINFO2 * ki; TSS_HCONTEXT tpm_ctx; }; @@ -62,9 +62,10 @@ static int import_tpm_key (gnutls_privkey_t pkey, const gnutls_datum_t * fdata, gnutls_x509_crt_fmt_t format, TSS_UUID *uuid, + TSS_FLAG storage_type, const char *srk_password, const char *key_password); -static int encode_tpmkey_url(char** url, const TSS_UUID* uuid, const TSS_UUID* parent); +static int encode_tpmkey_url(char** url, const TSS_UUID* uuid, TSS_FLAG storage); /* TPM URL format: * @@ -174,8 +175,8 @@ static const unsigned char nullpass[20]; static const gnutls_datum_t nulldata = {(void*)nullpass, 20}; const TSS_UUID srk_uuid = TSS_UUID_SRK; -static int tpm_pin(const TSS_UUID* uuid, char* pin, unsigned int pin_size, - unsigned int attempts) +static int tpm_pin(const TSS_UUID* uuid, TSS_FLAG storage, char* pin, + unsigned int pin_size, unsigned int attempts) { unsigned int flags = 0; const char* label; @@ -191,7 +192,7 @@ int ret; label = "SRK"; else { - ret = encode_tpmkey_url(&url, uuid, NULL); + ret = encode_tpmkey_url(&url, uuid, storage); if (ret < 0) return gnutls_assert_val(ret); @@ -310,6 +311,7 @@ import_tpm_key_cb (gnutls_privkey_t pkey, const gnutls_datum_t * fdata, gnutls_x509_crt_fmt_t format, TSS_UUID *uuid, + TSS_FLAG storage, const char *srk_password, const char *key_password) { @@ -320,14 +322,14 @@ int ret, ret2; do { - ret = import_tpm_key(pkey, fdata, format, uuid, srk_password, key_password); + ret = import_tpm_key(pkey, fdata, format, uuid, storage, srk_password, key_password); if (attempts > 3 || _gnutls_pin_func == NULL) break; if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR) { - ret2 = tpm_pin(&srk_uuid, pin1, sizeof(pin1), attempts++); + ret2 = tpm_pin(&srk_uuid, storage, pin1, sizeof(pin1), attempts++); if (ret2 < 0) { gnutls_assert(); @@ -338,7 +340,7 @@ int ret, ret2; if (ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR) { - ret2 = tpm_pin(uuid, pin2, sizeof(pin2), attempts++); + ret2 = tpm_pin(uuid, storage, pin2, sizeof(pin2), attempts++); if (ret2 < 0) { gnutls_assert(); @@ -360,6 +362,7 @@ import_tpm_key (gnutls_privkey_t pkey, const gnutls_datum_t * fdata, gnutls_x509_crt_fmt_t format, TSS_UUID *uuid, + TSS_FLAG storage, const char *srk_password, const char *key_password) { @@ -416,8 +419,9 @@ import_tpm_key (gnutls_privkey_t pkey, else if (uuid) { err = - Tspi_Context_LoadKeyByUUID (s->tpm_ctx, TSS_PS_TYPE_SYSTEM, - *uuid, &s->tpm_key); + Tspi_Context_LoadKeyByUUID (s->tpm_ctx, storage, + *uuid, &s->tpm_key); + if (err) { gnutls_assert (); @@ -528,15 +532,16 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey, unsigned int flags) { if (flags & GNUTLS_PRIVKEY_DISABLE_CALLBACKS) - return import_tpm_key(pkey, fdata, format, NULL, srk_password, key_password); + return import_tpm_key(pkey, fdata, format, NULL, 0, srk_password, key_password); else - return import_tpm_key_cb(pkey, fdata, format, NULL, srk_password, key_password); + return import_tpm_key_cb(pkey, fdata, format, NULL, 0, srk_password, key_password); } struct tpmkey_url_st { char* filename; TSS_UUID uuid; + TSS_FLAG storage; unsigned int uuid_set; }; @@ -613,7 +618,7 @@ static int randomize_uuid(TSS_UUID* uuid) return 0; } -static int encode_tpmkey_url(char** url, const TSS_UUID* uuid, const TSS_UUID* parent) +static int encode_tpmkey_url(char** url, const TSS_UUID* uuid, TSS_FLAG storage) { size_t size = (UUID_SIZE*2+4)*2+32; uint8_t u1[UUID_SIZE]; @@ -652,35 +657,12 @@ int ret; goto cleanup; } -#if 0 - if (parent) + ret = _gnutls_buffer_append_printf(&buf, ";storage=%s", (storage==TSS_PS_TYPE_USER)?"user":"system"); + if (ret < 0) { - memcpy(u1, &parent->ulTimeLow, 4); - memcpy(&u1[4], &parent->usTimeMid, 2); - memcpy(&u1[6], &parent->usTimeHigh, 2); - u1[8] = parent->bClockSeqHigh; - u1[9] = parent->bClockSeqLow; - memcpy(&u1[10], parent->rgbNode, 6); - - ret = _gnutls_buffer_append_str(&buf, ";parent="); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_buffer_append_printf(&buf, "%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x", - (unsigned int)u1[0], (unsigned int)u1[1], (unsigned int)u1[2], (unsigned int)u1[3], - (unsigned int)u1[4], (unsigned int)u1[5], (unsigned int)u1[6], (unsigned int)u1[7], - (unsigned int)u1[8], (unsigned int)u1[9], (unsigned int)u1[10], (unsigned int)u1[11], - (unsigned int)u1[12], (unsigned int)u1[13], (unsigned int)u1[14], (unsigned int)u1[15]); - if (ret < 0) - { - gnutls_assert(); - goto cleanup; - } + gnutls_assert(); + goto cleanup; } -#endif ret = _gnutls_buffer_to_datum(&buf, &dret); if (ret < 0) @@ -765,6 +747,11 @@ static int decode_tpmkey_url(const char* url, struct tpmkey_url_st *s) return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); } + if ((p = strstr(url, "storage=user")) != NULL) + s->storage = TSS_PS_TYPE_USER; + else + s->storage = TSS_PS_TYPE_SYSTEM; + return 0; cleanup: @@ -833,9 +820,9 @@ int ret; else if (durl.uuid_set) { if (flags & GNUTLS_PRIVKEY_DISABLE_CALLBACKS) - ret = import_tpm_key (pkey, NULL, 0, &durl.uuid, srk_password, key_password); + ret = import_tpm_key (pkey, NULL, 0, &durl.uuid, durl.storage, srk_password, key_password); else - ret = import_tpm_key_cb (pkey, NULL, 0, &durl.uuid, srk_password, key_password); + ret = import_tpm_key_cb (pkey, NULL, 0, &durl.uuid, durl.storage, srk_password, key_password); if (ret < 0) { gnutls_assert(); @@ -908,6 +895,7 @@ import_tpm_pubkey (gnutls_pubkey_t pkey, const gnutls_datum_t * fdata, gnutls_x509_crt_fmt_t format, TSS_UUID *uuid, + TSS_FLAG storage, const char *srk_password) { gnutls_datum_t asn1 = {NULL, 0}; @@ -951,8 +939,8 @@ struct tpm_ctx_st s; else if (uuid) { err = - Tspi_Context_LoadKeyByUUID (s.tpm_ctx, TSS_PS_TYPE_SYSTEM, - *uuid, &s.tpm_key); + Tspi_Context_LoadKeyByUUID (s.tpm_ctx, storage, + *uuid, &s.tpm_key); if (err) { gnutls_assert (); @@ -987,23 +975,23 @@ import_tpm_pubkey_cb (gnutls_pubkey_t pkey, const gnutls_datum_t * fdata, gnutls_x509_crt_fmt_t format, TSS_UUID *uuid, + TSS_FLAG storage, const char *srk_password) { unsigned int attempts = 0; char pin1[GNUTLS_PKCS11_MAX_PIN_LEN]; int ret; - do { - ret = import_tpm_pubkey(pkey, fdata, format, uuid, srk_password); + ret = import_tpm_pubkey(pkey, fdata, format, uuid, storage, srk_password); if (attempts > 3 || _gnutls_pin_func == NULL) break; if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR) { - ret = tpm_pin(&srk_uuid, pin1, sizeof(pin1), attempts++); + ret = tpm_pin(&srk_uuid, storage, pin1, sizeof(pin1), attempts++); if (ret < 0) { gnutls_assert(); @@ -1048,9 +1036,9 @@ gnutls_pubkey_import_tpm_raw (gnutls_pubkey_t pkey, unsigned int flags) { if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS) - return import_tpm_pubkey_cb(pkey, fdata, format, NULL, srk_password); + return import_tpm_pubkey_cb(pkey, fdata, format, NULL, 0, srk_password); else - return import_tpm_pubkey(pkey, fdata, format, NULL, srk_password); + return import_tpm_pubkey(pkey, fdata, format, NULL, 0, srk_password); } /** @@ -1110,9 +1098,9 @@ int ret; else if (durl.uuid_set) { if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS) - ret = import_tpm_pubkey (pkey, NULL, 0, &durl.uuid, srk_password); + ret = import_tpm_pubkey (pkey, NULL, 0, &durl.uuid, durl.storage, srk_password); else - ret = import_tpm_pubkey_cb (pkey, NULL, 0, &durl.uuid, srk_password); + ret = import_tpm_pubkey_cb (pkey, NULL, 0, &durl.uuid, durl.storage, srk_password); if (ret < 0) { gnutls_assert(); @@ -1179,12 +1167,18 @@ gnutls_datum_t tmpkey = {NULL, 0}; TSS_HPOLICY key_policy; gnutls_pubkey_t pub; struct tpm_ctx_st s; +TSS_FLAG storage_type; if (flags & GNUTLS_TPM_KEY_SIGNING) tpm_flags |= TSS_KEY_TYPE_SIGNING; else tpm_flags |= TSS_KEY_TYPE_LEGACY; + if (flags & GNUTLS_TPM_KEY_USER) + storage_type = TSS_PS_TYPE_USER; + else + storage_type = TSS_PS_TYPE_SYSTEM; + if (bits <= 512) tpm_flags |= TSS_KEY_SIZE_512; else if (bits <= 1024) @@ -1259,7 +1253,7 @@ struct tpm_ctx_st s; goto err_sa; } - tssret = Tspi_Context_RegisterKey(s.tpm_ctx, key_ctx, TSS_PS_TYPE_SYSTEM, + tssret = Tspi_Context_RegisterKey(s.tpm_ctx, key_ctx, storage_type, key_uuid, TSS_PS_TYPE_SYSTEM, srk_uuid); if (tssret != 0) { @@ -1268,12 +1262,12 @@ struct tpm_ctx_st s; goto err_sa; } - ret = encode_tpmkey_url((char**)&privkey->data, &key_uuid, &srk_uuid); + ret = encode_tpmkey_url((char**)&privkey->data, &key_uuid, storage_type); if (ret < 0) { TSS_HKEY tkey; - Tspi_Context_UnregisterKey(s.tpm_ctx, TSS_PS_TYPE_SYSTEM, key_uuid, &tkey); + Tspi_Context_UnregisterKey(s.tpm_ctx, storage_type, key_uuid, &tkey); gnutls_assert(); goto err_sa; } @@ -1414,7 +1408,7 @@ gnutls_tpm_key_list_get_url (gnutls_tpm_key_list_t list, unsigned int idx, char* if (idx >= list->size) return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); - return encode_tpmkey_url(url, &list->ki[idx].keyUUID, &list->ki[idx].parentKeyUUID); + return encode_tpmkey_url(url, &list->ki[idx].keyUUID, list->ki[idx].persistentStorageType); } /** @@ -1457,7 +1451,7 @@ int ret; } tssret = - Tspi_Context_GetRegisteredKeysByUUID((*list)->tpm_ctx, TSS_PS_TYPE_SYSTEM, + Tspi_Context_GetRegisteredKeysByUUID2((*list)->tpm_ctx, TSS_PS_TYPE_SYSTEM, NULL, &(*list)->size, &(*list)->ki); if (tssret) { @@ -1506,7 +1500,7 @@ int ret; if (ret < 0) return gnutls_assert_val(ret); - tssret = Tspi_Context_UnregisterKey(s.tpm_ctx, TSS_PS_TYPE_SYSTEM, durl.uuid, &tkey); + tssret = Tspi_Context_UnregisterKey(s.tpm_ctx, durl.storage, durl.uuid, &tkey); if (tssret != 0) { gnutls_assert(); |