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>