libtpmtss: Load X.509 certificates from TPM 2.0 NV RAM
[strongswan.git] / src / libtpmtss / plugins / tpm / tpm_cert.c
1 /*
2 * Copyright (C) 2017 Andreas Steffen
3 * HSR Hochschule für Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tpm_cert.h"
17
18 #include <tpm_tss.h>
19
20 #include <utils/debug.h>
21
22
23 /**
24 * See header.
25 */
26 certificate_t *tpm_cert_load(certificate_type_t type, va_list args)
27 {
28 tpm_tss_t *tpm;
29 chunk_t keyid = chunk_empty, pin = chunk_empty, data = chunk_empty;
30 certificate_t *cert;
31 char handle_str[4];
32 size_t len;
33 uint32_t hierarchy = 0x40000001; /* TPM_RH_OWNER */
34 uint32_t handle;
35 bool success;
36
37 while (TRUE)
38 {
39 switch (va_arg(args, builder_part_t))
40 {
41 case BUILD_PKCS11_KEYID:
42 keyid = va_arg(args, chunk_t);
43 continue;
44 case BUILD_PKCS11_SLOT:
45 hierarchy = va_arg(args, int);
46 continue;
47 case BUILD_PKCS11_MODULE:
48 va_arg(args, char*);
49 continue;
50 case BUILD_END:
51 break;
52 default:
53 return NULL;
54 }
55 break;
56 }
57
58 /* convert keyid into 32 bit TPM key object handle */
59 if (!keyid.len)
60 {
61 return NULL;
62 }
63 len = min(keyid.len, 4);
64 memset(handle_str, 0x00, 4);
65 memcpy(handle_str + 4 - len, keyid.ptr + keyid.len - len, len);
66 handle = untoh32(handle_str);
67
68 /* try to find a TPM 2.0 */
69 tpm = tpm_tss_probe(TPM_VERSION_2_0);
70 if (!tpm)
71 {
72 DBG1(DBG_LIB, "no TPM 2.0 found");
73 return NULL;
74 }
75 success = tpm->get_data(tpm, hierarchy, handle, pin, &data);
76 tpm->destroy(tpm);
77
78 if (!success)
79 {
80 DBG1(DBG_LIB, "loading certificate from TPM NV index 0x%08x failed",
81 handle);
82 return NULL;
83 }
84 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
85 BUILD_BLOB_ASN1_DER, data, BUILD_END);
86 free(data.ptr);
87
88 if (!cert)
89 {
90 DBG1(DBG_LIB, "parsing certificate from TPM NV index 0x%08x failed",
91 handle);
92 return NULL;
93 }
94 DBG1(DBG_LIB, "loaded certificate from TPM NV index 0x%08x", handle);
95
96 return cert;
97 }