Annotation of embedaddon/strongswan/src/libtpmtss/plugins/tpm/tpm_private_key.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2018 Tobias Brunner
3: * Copyright (C) 2017-2018 Andreas Steffen
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include "tpm_private_key.h"
18:
19: #include <tpm_tss.h>
20: #include <utils/debug.h>
21:
22: typedef struct private_tpm_private_key_t private_tpm_private_key_t;
23:
24: /**
25: * Private data of an tpm_private_key_t object.
26: */
27: struct private_tpm_private_key_t {
28:
29: /**
30: * Public tpm_private_key_t interface.
31: */
32: tpm_private_key_t public;
33:
34: /**
35: * Token keyid used to reference optional PIN for TPM key
36: */
37: identification_t *keyid;
38:
39: /**
40: * Trusted Platform Module
41: */
42: tpm_tss_t *tpm;
43:
44: /**
45: * TPM key object handle
46: */
47: uint32_t handle;
48:
49: /**
50: * Hierarchy the TPM key object is attached to
51: */
52: uint32_t hierarchy;
53:
54: /**
55: * Associated public key
56: */
57: public_key_t *pubkey;
58:
59: /**
60: * References to this key
61: */
62: refcount_t ref;
63:
64: };
65:
66:
67: METHOD(private_key_t, get_type, key_type_t,
68: private_tpm_private_key_t *this)
69: {
70: return this->pubkey->get_type(this->pubkey);
71: }
72:
73: METHOD(private_key_t, get_keysize, int,
74: private_tpm_private_key_t *this)
75: {
76: return this->pubkey->get_keysize(this->pubkey);
77: }
78:
79: METHOD(private_key_t, supported_signature_schemes, enumerator_t*,
80: private_tpm_private_key_t *this)
81: {
82: return this->tpm->supported_signature_schemes(this->tpm, this->handle);
83: }
84:
85: METHOD(private_key_t, sign, bool,
86: private_tpm_private_key_t *this, signature_scheme_t scheme, void *params,
87: chunk_t data, chunk_t *signature)
88: {
89: chunk_t pin = chunk_empty;
90: shared_key_t *shared;
91: enumerator_t *enumerator;
92:
93: /* check for optional PIN */
94: enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
95: SHARED_PIN, this->keyid, NULL);
96: if (enumerator->enumerate(enumerator, &shared, NULL, NULL))
97: {
98: pin = shared->get_key(shared);
99: }
100: enumerator->destroy(enumerator);
101:
102: return this->tpm->sign(this->tpm, this->hierarchy, this->handle, scheme,
103: params, data, pin, signature);
104: }
105:
106: METHOD(private_key_t, decrypt, bool,
107: private_tpm_private_key_t *this, encryption_scheme_t scheme,
108: chunk_t crypt, chunk_t *plain)
109: {
110: return FALSE;
111: }
112:
113: METHOD(private_key_t, get_public_key, public_key_t*,
114: private_tpm_private_key_t *this)
115: {
116: return this->pubkey->get_ref(this->pubkey);
117: }
118:
119: METHOD(private_key_t, get_fingerprint, bool,
120: private_tpm_private_key_t *this, cred_encoding_type_t type,
121: chunk_t *fingerprint)
122: {
123: return this->pubkey->get_fingerprint(this->pubkey, type, fingerprint);
124: }
125:
126: METHOD(private_key_t, get_encoding, bool,
127: private_tpm_private_key_t *this, cred_encoding_type_t type,
128: chunk_t *encoding)
129: {
130: return FALSE;
131: }
132:
133: METHOD(private_key_t, get_ref, private_key_t*,
134: private_tpm_private_key_t *this)
135: {
136: ref_get(&this->ref);
137: return &this->public.key;
138: }
139:
140: METHOD(private_key_t, destroy, void,
141: private_tpm_private_key_t *this)
142: {
143: if (ref_put(&this->ref))
144: {
145: DESTROY_IF(this->pubkey);
146: this->tpm->destroy(this->tpm);
147: this->keyid->destroy(this->keyid);
148: free(this);
149: }
150: }
151:
152: /**
153: * See header.
154: */
155: tpm_private_key_t *tpm_private_key_connect(key_type_t type, va_list args)
156: {
157: private_tpm_private_key_t *this;
158: tpm_tss_t *tpm;
159: chunk_t keyid = chunk_empty, pubkey_blob = chunk_empty;
160: char handle_str[4];
161: size_t len;
162: uint32_t hierarchy = 0x4000000B; /* TPM_RH_ENDORSEMENT */
163: uint32_t handle;
164:
165: while (TRUE)
166: {
167: switch (va_arg(args, builder_part_t))
168: {
169: case BUILD_PKCS11_KEYID:
170: keyid = va_arg(args, chunk_t);
171: continue;
172: case BUILD_PKCS11_SLOT:
173: hierarchy = va_arg(args, int);
174: continue;
175: case BUILD_PKCS11_MODULE:
176: va_arg(args, char*);
177: continue;
178: case BUILD_END:
179: break;
180: default:
181: return NULL;
182: }
183: break;
184: }
185:
186: /* convert keyid into 32 bit TPM key object handle */
187: if (!keyid.len)
188: {
189: return NULL;
190: }
191: len = min(keyid.len, 4);
192: memset(handle_str, 0x00, 4);
193: memcpy(handle_str + 4 - len, keyid.ptr + keyid.len - len, len);
194: handle = untoh32(handle_str);
195:
196: /* try to find a TPM 2.0 */
197: tpm = tpm_tss_probe(TPM_VERSION_2_0);
198: if (!tpm)
199: {
200: DBG1(DBG_LIB, "no TPM 2.0 found");
201: return NULL;
202: }
203:
204: INIT(this,
205: .public = {
206: .key = {
207: .get_type = _get_type,
208: .sign = _sign,
209: .decrypt = _decrypt,
210: .get_keysize = _get_keysize,
211: .supported_signature_schemes = _supported_signature_schemes,
212: .get_public_key = _get_public_key,
213: .equals = private_key_equals,
214: .belongs_to = private_key_belongs_to,
215: .get_fingerprint = _get_fingerprint,
216: .has_fingerprint = private_key_has_fingerprint,
217: .get_encoding = _get_encoding,
218: .get_ref = _get_ref,
219: .destroy = _destroy,
220: },
221: },
222: .tpm = tpm,
223: .keyid = identification_create_from_encoding(ID_KEY_ID, keyid),
224: .handle = handle,
225: .hierarchy = hierarchy,
226: .ref = 1,
227: );
228:
229: /* get public key from TPM */
230: pubkey_blob = tpm->get_public(tpm, handle);
231: if (!pubkey_blob.len)
232: {
233: destroy(this);
234: return NULL;
235: }
236: this->pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
237: BUILD_BLOB_ASN1_DER, pubkey_blob, BUILD_END);
238: chunk_free(&pubkey_blob);
239:
240: if (!this->pubkey)
241: {
242: destroy(this);
243: return NULL;
244: }
245:
246: return &this->public;
247: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>