File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libtpmtss / plugins / tpm / tpm_private_key.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 3 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    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>