Annotation of embedaddon/strongswan/src/libtpmtss/plugins/tpm/tpm_private_key.c, revision 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>