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>