Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2011 Tobias Brunner
                      3:  * HSR Hochschule fuer 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 "pkcs11_rng.h"
                     17: 
                     18: #include <utils/debug.h>
                     19: 
                     20: #include "pkcs11_manager.h"
                     21: 
                     22: typedef struct private_pkcs11_rng_t private_pkcs11_rng_t;
                     23: 
                     24: /**
                     25:  * Private data of an pkcs11_rng_t object.
                     26:  */
                     27: struct private_pkcs11_rng_t {
                     28: 
                     29:        /**
                     30:         * Public interface.
                     31:         */
                     32:        pkcs11_rng_t public;
                     33: 
                     34:        /**
                     35:         * PKCS#11 library
                     36:         */
                     37:        pkcs11_library_t *lib;
                     38: 
                     39:        /**
                     40:         * Mechanism for this rng
                     41:         */
                     42:        CK_SESSION_HANDLE session;
                     43: 
                     44: };
                     45: 
                     46: METHOD(rng_t, get_bytes, bool,
                     47:        private_pkcs11_rng_t *this, size_t bytes, uint8_t *buffer)
                     48: {
                     49:        CK_RV rv;
                     50:        rv = this->lib->f->C_GenerateRandom(this->session, buffer, bytes);
                     51:        if (rv != CKR_OK)
                     52:        {
                     53:                DBG1(DBG_CFG, "C_GenerateRandom() failed: %N", ck_rv_names, rv);
                     54:                return FALSE;
                     55:        }
                     56:        return TRUE;
                     57: }
                     58: 
                     59: METHOD(rng_t, allocate_bytes, bool,
                     60:        private_pkcs11_rng_t *this, size_t bytes, chunk_t *chunk)
                     61: {
                     62:        *chunk = chunk_alloc(bytes);
                     63:        if (!get_bytes(this, chunk->len, chunk->ptr))
                     64:        {
                     65:                chunk_clear(chunk);
                     66:                return FALSE;
                     67:        }
                     68:        return TRUE;
                     69: }
                     70: 
                     71: METHOD(rng_t, destroy, void,
                     72:        private_pkcs11_rng_t *this)
                     73: {
                     74:        this->lib->f->C_CloseSession(this->session);
                     75:        free(this);
                     76: }
                     77: 
                     78: /**
                     79:  * Find a token with its own RNG
                     80:  */
                     81: static pkcs11_library_t *find_token(CK_SESSION_HANDLE *session)
                     82: {
                     83:        enumerator_t *tokens;
                     84:        pkcs11_manager_t *manager;
                     85:        pkcs11_library_t *current, *found = NULL;
                     86:        CK_SLOT_ID slot;
                     87: 
                     88:        manager = lib->get(lib, "pkcs11-manager");
                     89:        if (!manager)
                     90:        {
                     91:                return NULL;
                     92:        }
                     93:        tokens = manager->create_token_enumerator(manager);
                     94:        while (tokens->enumerate(tokens, &current, &slot))
                     95:        {
                     96:                CK_TOKEN_INFO info;
                     97:                CK_RV rv;
                     98:                rv = current->f->C_GetTokenInfo(slot, &info);
                     99:                if (rv != CKR_OK)
                    100:                {
                    101:                        continue;
                    102:                }
                    103:                if (info.flags & CKF_RNG)
                    104:                {
                    105:                        if (current->f->C_OpenSession(slot, CKF_SERIAL_SESSION,
                    106:                                                                                  NULL, NULL, session) == CKR_OK)
                    107:                        {
                    108:                                found = current;
                    109:                                break;
                    110:                        }
                    111:                }
                    112:        }
                    113:        tokens->destroy(tokens);
                    114:        return found;
                    115: }
                    116: 
                    117: /*
                    118:  * Described in header.
                    119:  */
                    120: pkcs11_rng_t *pkcs11_rng_create(rng_quality_t quality)
                    121: {
                    122:        private_pkcs11_rng_t *this;
                    123: 
                    124:        INIT(this,
                    125:                .public = {
                    126:                        .rng = {
                    127:                                .get_bytes = _get_bytes,
                    128:                                .allocate_bytes = _allocate_bytes,
                    129:                                .destroy = _destroy,
                    130:                        },
                    131:                },
                    132:        );
                    133: 
                    134:        this->lib = find_token(&this->session);
                    135:        if (!this->lib)
                    136:        {
                    137:                free(this);
                    138:                return NULL;
                    139:        }
                    140: 
                    141:        return &this->public;
                    142: }
                    143: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>