Preliminary support for reason code CRL extension.
[openssl.git] / crypto / x509v3 / v3_utl.c
1 /* v3_utl.c */
2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3  * project 1999.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer. 
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 /* X509 v3 extension utilities */
59
60 #include <stdlib.h>
61 #include <string.h>
62 #include <ctype.h>
63 #include <pem.h>
64 #include <conf.h>
65 #include <err.h>
66 #include "x509v3.h"
67
68 static char *strip_spaces(char *name);
69
70 char *str_dup(str)
71 char *str;
72 {
73         char *tmp;
74         if(!(tmp = Malloc(strlen(str) + 1))) return NULL;
75         strcpy(tmp, str);
76         return tmp;
77 }
78
79 /* Add a CONF_VALUE name value pair to stack */
80
81 int X509V3_add_value(name, value, extlist)
82 char *name;
83 char *value;
84 STACK **extlist;
85 {
86         CONF_VALUE *vtmp = NULL;
87         char *tname = NULL, *tvalue = NULL;
88         if(name && !(tname = str_dup(name))) goto err;
89         if(value && !(tvalue = str_dup(value))) goto err;;
90         if(!(vtmp = (CONF_VALUE *)Malloc(sizeof(CONF_VALUE)))) goto err;
91         if(!*extlist && !(*extlist = sk_new(NULL))) goto err;
92         vtmp->section = NULL;
93         vtmp->name = tname;
94         vtmp->value = tvalue;
95         if(!sk_push(*extlist, (char *)vtmp)) goto err;
96         return 1;
97         err:
98         X509V3err(X509V3_F_X509V3_ADD_VALUE,ERR_R_MALLOC_FAILURE);
99         if(vtmp) Free(vtmp);
100         if(tname) Free(tname);
101         if(tvalue) Free(tvalue);
102         return 0;
103 }
104
105 /* Free function for STACK of CONF_VALUE */
106
107 void X509V3_conf_free(conf)
108 CONF_VALUE *conf;
109 {
110         if(!conf) return;
111         if(conf->name) Free(conf->name);
112         if(conf->value) Free(conf->value);
113         if(conf->section) Free(conf->section);
114         Free((char *)conf);
115 }
116
117 int X509V3_add_value_bool(name, asn1_bool, extlist)
118 char *name;
119 int asn1_bool;
120 STACK **extlist;
121 {
122         if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
123         return X509V3_add_value(name, "FALSE", extlist);
124 }
125
126 int X509V3_add_value_bool_nf(name, asn1_bool, extlist)
127 char *name;
128 int asn1_bool;
129 STACK **extlist;
130 {
131         if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
132         return 1;
133 }
134
135
136 char *i2s_ASN1_ENUMERATED(method, a)
137 X509V3_EXT_METHOD *method;
138 ASN1_ENUMERATED *a;
139 {
140         BIGNUM *bntmp = NULL;
141         char *strtmp = NULL;
142         if(!a) return NULL;
143         if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
144             !(strtmp = BN_bn2dec(bntmp)) )
145                 X509V3err(X509V3_F_I2S_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
146         BN_free(bntmp);
147         return strtmp;
148 }
149
150 char *i2s_ASN1_INTEGER(method, a)
151 X509V3_EXT_METHOD *method;
152 ASN1_INTEGER *a;
153 {
154         BIGNUM *bntmp = NULL;
155         char *strtmp = NULL;
156         if(!a) return NULL;
157         if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
158             !(strtmp = BN_bn2dec(bntmp)) )
159                 X509V3err(X509V3_F_I2S_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
160         BN_free(bntmp);
161         return strtmp;
162 }
163
164 int X509V3_add_value_int(name, aint, extlist)
165 char *name;
166 ASN1_INTEGER *aint;
167 STACK **extlist;
168 {
169         char *strtmp;
170         int ret;
171         if(!aint) return 1;
172         if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0;
173         ret = X509V3_add_value(name, strtmp, extlist);
174         Free(strtmp);
175         return ret;
176 }
177
178 int X509V3_get_value_bool(value, asn1_bool)
179 CONF_VALUE *value;
180 int *asn1_bool;
181 {
182         char *btmp;
183         if(!(btmp = value->value)) goto err;
184         if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
185                  || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
186                 || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
187                 *asn1_bool = 0xff;
188                 return 1;
189         } else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
190                  || !strcmp(btmp, "N") || !strcmp(btmp, "n")
191                 || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
192                 *asn1_bool = 0;
193                 return 1;
194         }
195         err:
196         X509V3err(X509V3_F_X509V3_VALUE_GET_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
197         X509V3_conf_err(value);
198         return 0;
199 }
200
201 int X509V3_get_value_int(value, aint)
202 CONF_VALUE *value;
203 ASN1_INTEGER **aint;
204 {
205         BIGNUM *bn = NULL;
206         bn = BN_new();
207         if(!value->value) {
208                 X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_INVALID_NULL_VALUE);
209                 X509V3_conf_err(value);
210                 return 0;
211         }
212         if(!BN_dec2bn(&bn, value->value)) {
213                 X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_DEC2BN_ERROR);
214                 X509V3_conf_err(value);
215                 return 0;
216         }
217
218         if(!(*aint = BN_to_ASN1_INTEGER(bn, NULL))) {
219                 X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
220                 X509V3_conf_err(value);
221                 return 0;
222         }
223         BN_free(bn);
224         return 1;
225 }
226
227 #define HDR_NAME        1
228 #define HDR_VALUE       2
229
230 /*#define DEBUG*/
231
232 STACK *X509V3_parse_list(line)
233 char *line;
234 {
235         char *p, *q, c;
236         char *ntmp, *vtmp;
237         STACK *values = NULL;
238         char *linebuf;
239         int state;
240         /* We are going to modify the line so copy it first */
241         linebuf = str_dup(line);
242         state = HDR_NAME;
243         ntmp = NULL;
244         /* Go through all characters */
245         for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
246
247                 switch(state) {
248                         case HDR_NAME:
249                         if(c == ':') {
250                                 state = HDR_VALUE;
251                                 *p = 0;
252                                 ntmp = strip_spaces(q);
253                                 if(!ntmp) {
254                                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
255                                         goto err;
256                                 }
257                                 q = p + 1;
258                         } else if(c == ',') {
259                                 *p = 0;
260                                 ntmp = strip_spaces(q);
261                                 q = p + 1;
262 #ifdef DEBUG
263                                 printf("%s\n", ntmp);
264 #endif
265                                 if(!ntmp) {
266                                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
267                                         goto err;
268                                 }
269                                 X509V3_add_value(ntmp, NULL, &values);
270                         }
271                         break ;
272
273                         case HDR_VALUE:
274                         if(c == ',') {
275                                 state = HDR_NAME;
276                                 *p = 0;
277                                 vtmp = strip_spaces(q);
278 #ifdef DEBUG
279                                 printf("%s\n", ntmp);
280 #endif
281                                 if(!vtmp) {
282                                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
283                                         goto err;
284                                 }
285                                 X509V3_add_value(ntmp, vtmp, &values);
286                                 ntmp = NULL;
287                                 q = p + 1;
288                         }
289
290                 }
291         }
292
293         if(state == HDR_VALUE) {
294                 vtmp = strip_spaces(q);
295 #ifdef DEBUG
296                 printf("%s=%s\n", ntmp, vtmp);
297 #endif
298                 if(!vtmp) {
299                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
300                         goto err;
301                 }
302                 X509V3_add_value(ntmp, vtmp, &values);
303         } else {
304                 ntmp = strip_spaces(q);
305 #ifdef DEBUG
306                 printf("%s\n", ntmp);
307 #endif
308                 if(!ntmp) {
309                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
310                         goto err;
311                 }
312                 X509V3_add_value(ntmp, NULL, &values);
313         }
314 Free(linebuf);
315 return values;
316
317 err:
318 Free(linebuf);
319 sk_pop_free(values, X509V3_conf_free);
320 return NULL;
321
322 }
323
324 /* Delete leading and trailing spaces from a string */
325 static char *strip_spaces(name)
326 char *name;
327 {
328         char *p, *q;
329         /* Skip over leading spaces */
330         p = name;
331         while(*p && isspace(*p)) p++;
332         if(!*p) return NULL;
333         q = p + strlen(p) - 1;
334         while((q != p) && isspace(*q)) q--;
335         if(p != q) q[1] = 0;
336         if(!*p) return NULL;
337         return p;
338 }
339
340 /* hex string utilities */
341
342 /* Given a buffer of length 'len' return a Malloc'ed string with its
343  * hex representation
344  */
345
346 char *hex_to_string(buffer, len)
347 unsigned char *buffer;
348 long len;
349 {
350         char *tmp, *q;
351         unsigned char *p;
352         int i;
353         static char hexdig[] = "0123456789ABCDEF";
354         if(!buffer || !len) return NULL;
355         if(!(tmp = Malloc(len * 3 + 1))) {
356                 X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
357                 return NULL;
358         }
359         q = tmp;
360         for(i = 0, p = buffer; i < len; i++,p++) {
361                 *q++ = hexdig[(*p >> 4) & 0xf];
362                 *q++ = hexdig[*p & 0xf];
363                 *q++ = ':';
364         }
365         q[-1] = 0;
366         return tmp;
367 }
368
369 /* Give a string of hex digits convert to
370  * a buffer
371  */
372
373 unsigned char *string_to_hex(str, len)
374 char *str;
375 long *len;
376 {
377         unsigned char *hexbuf, *q;
378         unsigned char ch, cl, *p;
379         if(!str) {
380                 X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT);
381                 return NULL;
382         }
383         if(!(hexbuf = Malloc(strlen(str) >> 1))) goto err;
384         for(p = (unsigned char *)str, q = hexbuf; *p;) {
385                 ch = *p++;
386                 if(ch == ':') continue;
387                 cl = *p++;
388                 if(!cl) {
389                         X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS);
390                         Free(hexbuf);
391                         return NULL;
392                 }
393                 if(isupper(ch)) ch = tolower(ch);
394                 if(isupper(cl)) cl = tolower(cl);
395
396                 if((ch >= '0') && (ch <= '9')) ch -= '0';
397                 else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
398                 else goto badhex;
399
400                 if((cl >= '0') && (cl <= '9')) cl -= '0';
401                 else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
402                 else goto badhex;
403
404                 *q++ = (ch << 4) | cl;
405         }
406
407         if(len) *len = q - hexbuf;
408
409         return hexbuf;
410
411         err:
412         if(hexbuf) Free(hexbuf);
413         X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE);
414         return NULL;
415
416         badhex:
417         Free(hexbuf);
418         X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT);
419         return NULL;
420
421 }
422
423 /* V2I name comparison function: returns zero if 'name' matches
424  * cmp or cmp.*
425  */
426
427 int name_cmp(name, cmp)
428 char *name;
429 char *cmp;
430 {
431         int len, ret;
432         char c;
433         len = strlen(cmp);
434         if((ret = strncmp(name, cmp, len))) return ret;
435         c = name[len];
436         if(!c || (c=='.')) return 0;
437         return 1;
438 }