Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_util.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * Copyright (C) 2009 Martin Willi
                      3:  * Copyright (C) 2008 Tobias Brunner
                      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 "openssl_util.h"
                     18: 
                     19: #include <utils/debug.h>
                     20: 
                     21: #include <openssl/bn.h>
                     22: #include <openssl/evp.h>
                     23: #include <openssl/x509.h>
                     24: 
                     25: /* these were added with 1.1.0 when ASN1_OBJECT was made opaque */
                     26: #if OPENSSL_VERSION_NUMBER < 0x10100000L
                     27: #define OBJ_get0_data(o) ((o)->data)
                     28: #define OBJ_length(o) ((o)->length)
                     29: #define ASN1_STRING_get0_data(a) ASN1_STRING_data((ASN1_STRING*)a)
                     30: #endif
                     31: 
1.1.1.2 ! misho      32: /*
        !            33:  * Described in header
        !            34:  */
        !            35: bool openssl_compute_shared_key(EVP_PKEY *priv, EVP_PKEY *pub, chunk_t *shared)
        !            36: {
        !            37:        EVP_PKEY_CTX *ctx;
        !            38:        bool success = FALSE;
        !            39: 
        !            40:        ctx = EVP_PKEY_CTX_new(priv, NULL);
        !            41:        if (!ctx)
        !            42:        {
        !            43:                return FALSE;
        !            44:        }
        !            45: 
        !            46:        if (EVP_PKEY_derive_init(ctx) <= 0)
        !            47:        {
        !            48:                goto error;
        !            49:        }
        !            50: 
        !            51:        if (EVP_PKEY_derive_set_peer(ctx, pub) <= 0)
        !            52:        {
        !            53:                goto error;
        !            54:        }
        !            55: 
        !            56:        if (EVP_PKEY_derive(ctx, NULL, &shared->len) <= 0)
        !            57:        {
        !            58:                goto error;
        !            59:        }
        !            60: 
        !            61:        *shared = chunk_alloc(shared->len);
        !            62: 
        !            63:        if (EVP_PKEY_derive(ctx, shared->ptr, &shared->len) <= 0)
        !            64:        {
        !            65:                goto error;
        !            66:        }
        !            67: 
        !            68:        success = TRUE;
        !            69: 
        !            70: error:
        !            71:        EVP_PKEY_CTX_free(ctx);
        !            72:        return success;
        !            73: }
        !            74: 
1.1       misho      75: /**
                     76:  * Described in header.
                     77:  */
                     78: bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
                     79: {
                     80:        EVP_MD_CTX *ctx;
                     81:        bool ret = FALSE;
                     82:        const EVP_MD *hasher = EVP_get_digestbynid(hash_type);
                     83:        if (!hasher)
                     84:        {
                     85:                return FALSE;
                     86:        }
                     87: 
                     88:        ctx = EVP_MD_CTX_create();
                     89:        if (!ctx)
                     90:        {
                     91:                goto error;
                     92:        }
                     93: 
                     94:        if (!EVP_DigestInit_ex(ctx, hasher, NULL))
                     95:        {
                     96:                goto error;
                     97:        }
                     98: 
                     99:        if (!EVP_DigestUpdate(ctx, data.ptr, data.len))
                    100:        {
                    101:                goto error;
                    102:        }
                    103: 
                    104:        *hash = chunk_alloc(EVP_MD_size(hasher));
                    105:        if (!EVP_DigestFinal_ex(ctx, hash->ptr, NULL))
                    106:        {
                    107:                chunk_free(hash);
                    108:                goto error;
                    109:        }
                    110: 
                    111:        ret = TRUE;
                    112: error:
                    113:        if (ctx)
                    114:        {
                    115:                EVP_MD_CTX_destroy(ctx);
                    116:        }
                    117:        return ret;
                    118: }
                    119: 
                    120: /**
                    121:  * Described in header.
                    122:  */
                    123: bool openssl_bn_cat(const int len, const BIGNUM *a, const BIGNUM *b,
                    124:                                        chunk_t *chunk)
                    125: {
                    126:        int offset;
                    127: 
                    128:        chunk->len = len + (b ? len : 0);
                    129:        chunk->ptr = malloc(chunk->len);
                    130:        memset(chunk->ptr, 0, chunk->len);
                    131: 
                    132:        /* convert a */
                    133:        offset = len - BN_num_bytes(a);
                    134:        if (!BN_bn2bin(a, chunk->ptr + offset))
                    135:        {
                    136:                goto error;
                    137:        }
                    138: 
                    139:        /* optionally convert and concatenate b */
                    140:        if (b)
                    141:        {
                    142:                offset = len - BN_num_bytes(b);
                    143:                if (!BN_bn2bin(b, chunk->ptr + len + offset))
                    144:                {
                    145:                        goto error;
                    146:                }
                    147:        }
                    148: 
                    149:        return TRUE;
                    150: error:
                    151:        chunk_free(chunk);
                    152:        return FALSE;
                    153: }
                    154: 
                    155: /**
                    156:  * Described in header.
                    157:  */
                    158: bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b)
                    159: {
                    160:        int len;
                    161: 
                    162:        if ((chunk.len % 2) != 0)
                    163:        {
                    164:                return FALSE;
                    165:        }
                    166: 
                    167:        len = chunk.len / 2;
                    168: 
                    169:        if (!BN_bin2bn(chunk.ptr, len, a) ||
                    170:                !BN_bin2bn(chunk.ptr + len, len, b))
                    171:        {
                    172:                return FALSE;
                    173:        }
                    174: 
                    175:        return TRUE;
                    176: }
                    177: 
                    178: /**
                    179:  * Described in header.
                    180:  */
                    181: bool openssl_bn2chunk(const BIGNUM *bn, chunk_t *chunk)
                    182: {
                    183:        *chunk = chunk_alloc(BN_num_bytes(bn));
                    184:        if (BN_bn2bin(bn, chunk->ptr) == chunk->len)
                    185:        {
                    186:                if (chunk->len && chunk->ptr[0] & 0x80)
                    187:                {       /* if MSB is set, prepend a zero to make it non-negative */
                    188:                        *chunk = chunk_cat("cm", chunk_from_chars(0x00), *chunk);
                    189:                }
                    190:                return TRUE;
                    191:        }
                    192:        chunk_free(chunk);
                    193:        return FALSE;
                    194: }
                    195: 
                    196: /**
                    197:  * Described in header.
                    198:  */
                    199: chunk_t openssl_asn1_obj2chunk(const ASN1_OBJECT *asn1)
                    200: {
                    201:        if (asn1)
                    202:        {
                    203:                return chunk_create((u_char*)OBJ_get0_data(asn1), OBJ_length(asn1));
                    204:        }
                    205:        return chunk_empty;
                    206: }
                    207: 
                    208: /**
                    209:  * Described in header.
                    210:  */
                    211: chunk_t openssl_asn1_str2chunk(const ASN1_STRING *asn1)
                    212: {
                    213:        if (asn1)
                    214:        {
                    215:                return chunk_create((u_char*)ASN1_STRING_get0_data(asn1),
                    216:                                                        ASN1_STRING_length(asn1));
                    217:        }
                    218:        return chunk_empty;
                    219: }
                    220: 
                    221: /**
                    222:  * Convert a X509 name to a ID_DER_ASN1_DN identification_t
                    223:  */
                    224: identification_t *openssl_x509_name2id(X509_NAME *name)
                    225: {
                    226:        if (name)
                    227:        {
                    228:                identification_t *id;
                    229:                chunk_t chunk;
                    230: 
                    231:                chunk = openssl_i2chunk(X509_NAME, name);
                    232:                if (chunk.len)
                    233:                {
                    234:                        id = identification_create_from_encoding(ID_DER_ASN1_DN, chunk);
                    235:                        free(chunk.ptr);
                    236:                        return id;
                    237:                }
                    238:        }
                    239:        return NULL;
                    240: }
                    241: 
                    242: /**
                    243:  * We can't include <asn1/asn1.h>, as the ASN1_ definitions would clash
                    244:  * with OpenSSL. Redeclare what we need.
                    245:  */
                    246: int asn1_known_oid(chunk_t);
                    247: time_t asn1_to_time(chunk_t *,int);
                    248: 
                    249: /**
                    250:  * Described in header.
                    251:  */
                    252: int openssl_asn1_known_oid(const ASN1_OBJECT *obj)
                    253: {
                    254:        return asn1_known_oid(openssl_asn1_obj2chunk(obj));
                    255: }
                    256: 
                    257: /**
                    258:  * Described in header.
                    259:  */
                    260: time_t openssl_asn1_to_time(const ASN1_TIME *time)
                    261: {
                    262:        chunk_t chunk;
                    263: 
                    264:        if (time)
                    265:        {
                    266:                chunk = openssl_asn1_str2chunk(time);
                    267:                switch (time->type)
                    268:                {
                    269:                        case V_ASN1_UTCTIME:
                    270:                        case V_ASN1_GENERALIZEDTIME:
                    271:                                return asn1_to_time(&chunk, time->type);
                    272:                        default:
                    273:                                break;
                    274:                }
                    275:        }
                    276:        DBG1(DBG_LIB, "invalid ASN1 time");
                    277:        return 0;
                    278: }

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