Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_util.c, revision 1.1.1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>