Add OAEP.
[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 * str_dup(char *str);
69 static char *strip_spaces(char *name);
70
71 static char *str_dup(str)
72 char *str;
73 {
74         char *tmp;
75         if(!(tmp = Malloc(strlen(str) + 1))) return NULL;
76         strcpy(tmp, str);
77         return tmp;
78 }
79
80 /* Add a CONF_VALUE name value pair to stack */
81
82 int X509V3_add_value(name, value, extlist)
83 char *name;
84 char *value;
85 STACK **extlist;
86 {
87         CONF_VALUE *vtmp = NULL;
88         char *tname = NULL, *tvalue = NULL;
89         if(name && !(tname = str_dup(name))) goto err;
90         if(value && !(tvalue = str_dup(value))) goto err;;
91         if(!(vtmp = (CONF_VALUE *)Malloc(sizeof(CONF_VALUE)))) goto err;
92         if(!*extlist && !(*extlist = sk_new(NULL))) goto err;
93         vtmp->section = NULL;
94         vtmp->name = tname;
95         vtmp->value = tvalue;
96         if(!sk_push(*extlist, (char *)vtmp)) goto err;
97         return 1;
98         err:
99         X509V3err(X509V3_F_X509V3_ADD_VALUE,ERR_R_MALLOC_FAILURE);
100         if(vtmp) Free(vtmp);
101         if(tname) Free(tname);
102         if(tvalue) Free(tvalue);
103         return 0;
104 }
105
106 /* Free function for STACK of CONF_VALUE */
107
108 void X509V3_conf_free(conf)
109 CONF_VALUE *conf;
110 {
111         if(!conf) return;
112         if(conf->name) Free(conf->name);
113         if(conf->value) Free(conf->value);
114         if(conf->section) Free(conf->section);
115         Free((char *)conf);
116 }
117
118 int X509V3_add_value_bool(name, asn1_bool, extlist)
119 char *name;
120 int asn1_bool;
121 STACK **extlist;
122 {
123         if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
124         return X509V3_add_value(name, "FALSE", extlist);
125 }
126
127 int X509V3_add_value_bool_nf(name, asn1_bool, extlist)
128 char *name;
129 int asn1_bool;
130 STACK **extlist;
131 {
132         if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
133         return 1;
134 }
135
136 int X509V3_add_value_int(name, aint, extlist)
137 char *name;
138 ASN1_INTEGER *aint;
139 STACK **extlist;
140 {
141         BIGNUM *bntmp;
142         char *strtmp;
143         int ret;
144         if(!aint) return 1;
145         bntmp = ASN1_INTEGER_to_BN(aint, NULL);
146         strtmp = BN_bn2dec(bntmp);
147         ret = X509V3_add_value(name, strtmp, extlist);
148         BN_free(bntmp);
149         Free(strtmp);
150         return ret;
151 }
152
153 int X509V3_get_value_bool(value, asn1_bool)
154 CONF_VALUE *value;
155 int *asn1_bool;
156 {
157         char *btmp;
158         if(!(btmp = value->value)) goto err;
159         if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
160                  || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
161                 || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
162                 *asn1_bool = 0xff;
163                 return 1;
164         } else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
165                  || !strcmp(btmp, "N") || !strcmp(btmp, "n")
166                 || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
167                 *asn1_bool = 0;
168                 return 1;
169         }
170         err:
171         X509V3err(X509V3_F_X509V3_VALUE_GET_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
172         X509V3_conf_err(value);
173         return 0;
174 }
175
176 int X509V3_get_value_int(value, aint)
177 CONF_VALUE *value;
178 ASN1_INTEGER **aint;
179 {
180         BIGNUM *bn = NULL;
181         bn = BN_new();
182         if(!value->value) {
183                 X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_INVALID_NULL_VALUE);
184                 X509V3_conf_err(value);
185                 return 0;
186         }
187         if(!BN_dec2bn(&bn, value->value)) {
188                 X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_DEC2BN_ERROR);
189                 X509V3_conf_err(value);
190                 return 0;
191         }
192
193         if(!(*aint = BN_to_ASN1_INTEGER(bn, NULL))) {
194                 X509V3err(X509V3_F_X509V3_GET_VALUE_INT,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
195                 X509V3_conf_err(value);
196                 return 0;
197         }
198         BN_free(bn);
199         return 1;
200 }
201
202 #define HDR_NAME        1
203 #define HDR_VALUE       2
204
205 /*#define DEBUG*/
206
207 STACK *X509V3_parse_list(line)
208 char *line;
209 {
210         char *p, *q, c;
211         char *ntmp, *vtmp;
212         STACK *values = NULL;
213         char *linebuf;
214         int state;
215         /* We are going to modify the line so copy it first */
216         linebuf = str_dup(line);
217         state = HDR_NAME;
218         ntmp = NULL;
219         /* Go through all characters */
220         for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
221
222                 switch(state) {
223                         case HDR_NAME:
224                         if(c == ':') {
225                                 state = HDR_VALUE;
226                                 *p = 0;
227                                 ntmp = strip_spaces(q);
228                                 if(!ntmp) {
229                                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
230                                         goto err;
231                                 }
232                                 q = p + 1;
233                         } else if(c == ',') {
234                                 *p = 0;
235                                 ntmp = strip_spaces(q);
236                                 q = p + 1;
237 #ifdef DEBUG
238                                 printf("%s\n", ntmp);
239 #endif
240                                 if(!ntmp) {
241                                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
242                                         goto err;
243                                 }
244                                 X509V3_add_value(ntmp, NULL, &values);
245                         }
246                         break ;
247
248                         case HDR_VALUE:
249                         if(c == ',') {
250                                 state = HDR_NAME;
251                                 *p = 0;
252                                 vtmp = strip_spaces(q);
253 #ifdef DEBUG
254                                 printf("%s\n", ntmp);
255 #endif
256                                 if(!vtmp) {
257                                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
258                                         goto err;
259                                 }
260                                 X509V3_add_value(ntmp, vtmp, &values);
261                                 ntmp = NULL;
262                                 q = p + 1;
263                         }
264
265                 }
266         }
267
268         if(state == HDR_VALUE) {
269                 vtmp = strip_spaces(q);
270 #ifdef DEBUG
271                 printf("%s=%s\n", ntmp, vtmp);
272 #endif
273                 if(!vtmp) {
274                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
275                         goto err;
276                 }
277                 X509V3_add_value(ntmp, vtmp, &values);
278         } else {
279                 ntmp = strip_spaces(q);
280 #ifdef DEBUG
281                 printf("%s\n", ntmp);
282 #endif
283                 if(!ntmp) {
284                         X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
285                         goto err;
286                 }
287                 X509V3_add_value(ntmp, NULL, &values);
288         }
289 Free(linebuf);
290 return values;
291
292 err:
293 Free(linebuf);
294 sk_pop_free(values, X509V3_conf_free);
295 return NULL;
296
297 }
298
299 /* Delete leading and trailing spaces from a string */
300 static char *strip_spaces(name)
301 char *name;
302 {
303         char *p, *q;
304         /* Skip over leading spaces */
305         p = name;
306         while(*p && isspace(*p)) p++;
307         if(!*p) return NULL;
308         q = p + strlen(p) - 1;
309         while((q != p) && isspace(*q)) q--;
310         if(p != q) q[1] = 0;
311         if(!*p) return NULL;
312         return p;
313 }
314
315 /* hex string utilities */
316
317 /* Given a buffer of length 'len' return a Malloc'ed string with its
318  * hex representation
319  */
320
321 char *hex_to_string(buffer, len)
322 unsigned char *buffer;
323 long len;
324 {
325         char *tmp, *q;
326         unsigned char *p;
327         int i;
328         static char hexdig[] = "0123456789ABCDEF";
329         if(!buffer || !len) return NULL;
330         if(!(tmp = Malloc(len * 3 + 1))) {
331                 X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
332                 return NULL;
333         }
334         q = tmp;
335         for(i = 0, p = buffer; i < len; i++,p++) {
336                 *q++ = hexdig[(*p >> 4) & 0xf];
337                 *q++ = hexdig[*p & 0xf];
338                 *q++ = ':';
339         }
340         q[-1] = 0;
341         return tmp;
342 }
343
344 /* Give a string of hex digits convert to
345  * a buffer
346  */
347
348 unsigned char *string_to_hex(str, len)
349 char *str;
350 long *len;
351 {
352         unsigned char *hexbuf, *q;
353         unsigned char ch, cl, *p;
354         if(!str) {
355                 X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT);
356                 return NULL;
357         }
358         if(!(hexbuf = Malloc(strlen(str) >> 1))) goto err;
359         for(p = (unsigned char *)str, q = hexbuf; *p;) {
360                 ch = *p++;
361                 if(ch == ':') continue;
362                 cl = *p++;
363                 if(!cl) {
364                         X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS);
365                         Free(hexbuf);
366                         return NULL;
367                 }
368                 if(isupper(ch)) ch = tolower(ch);
369                 if(isupper(cl)) cl = tolower(cl);
370
371                 if((ch >= '0') && (ch <= '9')) ch -= '0';
372                 else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
373                 else goto badhex;
374
375                 if((cl >= '0') && (cl <= '9')) cl -= '0';
376                 else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
377                 else goto badhex;
378
379                 *q++ = (ch << 4) | cl;
380         }
381
382         if(len) *len = q - hexbuf;
383
384         return hexbuf;
385
386         err:
387         if(hexbuf) Free(hexbuf);
388         X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE);
389         return NULL;
390
391         badhex:
392         Free(hexbuf);
393         X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT);
394         return NULL;
395
396 }
397
398 /* V2I name comparison function: returns zero if 'name' matches
399  * cmp or cmp.*
400  */
401
402 int name_cmp(name, cmp)
403 char *name;
404 char *cmp;
405 {
406         int len, ret;
407         char c;
408         len = strlen(cmp);
409         if((ret = strncmp(name, cmp, len))) return ret;
410         c = name[len];
411         if(!c || (c=='.')) return 0;
412         return 1;
413 }