Return to openssl_util.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / openssl |
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: 32: /** 33: * Described in header. 34: */ 35: bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash) 36: { 37: EVP_MD_CTX *ctx; 38: bool ret = FALSE; 39: const EVP_MD *hasher = EVP_get_digestbynid(hash_type); 40: if (!hasher) 41: { 42: return FALSE; 43: } 44: 45: ctx = EVP_MD_CTX_create(); 46: if (!ctx) 47: { 48: goto error; 49: } 50: 51: if (!EVP_DigestInit_ex(ctx, hasher, NULL)) 52: { 53: goto error; 54: } 55: 56: if (!EVP_DigestUpdate(ctx, data.ptr, data.len)) 57: { 58: goto error; 59: } 60: 61: *hash = chunk_alloc(EVP_MD_size(hasher)); 62: if (!EVP_DigestFinal_ex(ctx, hash->ptr, NULL)) 63: { 64: chunk_free(hash); 65: goto error; 66: } 67: 68: ret = TRUE; 69: error: 70: if (ctx) 71: { 72: EVP_MD_CTX_destroy(ctx); 73: } 74: return ret; 75: } 76: 77: /** 78: * Described in header. 79: */ 80: bool openssl_bn_cat(const int len, const BIGNUM *a, const BIGNUM *b, 81: chunk_t *chunk) 82: { 83: int offset; 84: 85: chunk->len = len + (b ? len : 0); 86: chunk->ptr = malloc(chunk->len); 87: memset(chunk->ptr, 0, chunk->len); 88: 89: /* convert a */ 90: offset = len - BN_num_bytes(a); 91: if (!BN_bn2bin(a, chunk->ptr + offset)) 92: { 93: goto error; 94: } 95: 96: /* optionally convert and concatenate b */ 97: if (b) 98: { 99: offset = len - BN_num_bytes(b); 100: if (!BN_bn2bin(b, chunk->ptr + len + offset)) 101: { 102: goto error; 103: } 104: } 105: 106: return TRUE; 107: error: 108: chunk_free(chunk); 109: return FALSE; 110: } 111: 112: /** 113: * Described in header. 114: */ 115: bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b) 116: { 117: int len; 118: 119: if ((chunk.len % 2) != 0) 120: { 121: return FALSE; 122: } 123: 124: len = chunk.len / 2; 125: 126: if (!BN_bin2bn(chunk.ptr, len, a) || 127: !BN_bin2bn(chunk.ptr + len, len, b)) 128: { 129: return FALSE; 130: } 131: 132: return TRUE; 133: } 134: 135: /** 136: * Described in header. 137: */ 138: bool openssl_bn2chunk(const BIGNUM *bn, chunk_t *chunk) 139: { 140: *chunk = chunk_alloc(BN_num_bytes(bn)); 141: if (BN_bn2bin(bn, chunk->ptr) == chunk->len) 142: { 143: if (chunk->len && chunk->ptr[0] & 0x80) 144: { /* if MSB is set, prepend a zero to make it non-negative */ 145: *chunk = chunk_cat("cm", chunk_from_chars(0x00), *chunk); 146: } 147: return TRUE; 148: } 149: chunk_free(chunk); 150: return FALSE; 151: } 152: 153: /** 154: * Described in header. 155: */ 156: chunk_t openssl_asn1_obj2chunk(const ASN1_OBJECT *asn1) 157: { 158: if (asn1) 159: { 160: return chunk_create((u_char*)OBJ_get0_data(asn1), OBJ_length(asn1)); 161: } 162: return chunk_empty; 163: } 164: 165: /** 166: * Described in header. 167: */ 168: chunk_t openssl_asn1_str2chunk(const ASN1_STRING *asn1) 169: { 170: if (asn1) 171: { 172: return chunk_create((u_char*)ASN1_STRING_get0_data(asn1), 173: ASN1_STRING_length(asn1)); 174: } 175: return chunk_empty; 176: } 177: 178: /** 179: * Convert a X509 name to a ID_DER_ASN1_DN identification_t 180: */ 181: identification_t *openssl_x509_name2id(X509_NAME *name) 182: { 183: if (name) 184: { 185: identification_t *id; 186: chunk_t chunk; 187: 188: chunk = openssl_i2chunk(X509_NAME, name); 189: if (chunk.len) 190: { 191: id = identification_create_from_encoding(ID_DER_ASN1_DN, chunk); 192: free(chunk.ptr); 193: return id; 194: } 195: } 196: return NULL; 197: } 198: 199: /** 200: * We can't include <asn1/asn1.h>, as the ASN1_ definitions would clash 201: * with OpenSSL. Redeclare what we need. 202: */ 203: int asn1_known_oid(chunk_t); 204: time_t asn1_to_time(chunk_t *,int); 205: 206: /** 207: * Described in header. 208: */ 209: int openssl_asn1_known_oid(const ASN1_OBJECT *obj) 210: { 211: return asn1_known_oid(openssl_asn1_obj2chunk(obj)); 212: } 213: 214: /** 215: * Described in header. 216: */ 217: time_t openssl_asn1_to_time(const ASN1_TIME *time) 218: { 219: chunk_t chunk; 220: 221: if (time) 222: { 223: chunk = openssl_asn1_str2chunk(time); 224: switch (time->type) 225: { 226: case V_ASN1_UTCTIME: 227: case V_ASN1_GENERALIZEDTIME: 228: return asn1_to_time(&chunk, time->type); 229: default: 230: break; 231: } 232: } 233: DBG1(DBG_LIB, "invalid ASN1 time"); 234: return 0; 235: }