Rid the world of yet more evil casts.
[openssl.git] / crypto / x509 / v3_x509.c
1 /* crypto/x509/v3_x509.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #include <stdio.h>
60 #include <ctype.h>
61 #include "stack.h"
62 #include "cryptlib.h"
63 #include "bio.h"
64 #include "asn1.h"
65 #include "objects.h"
66 #include "x509.h"
67
68 #if 0
69 static int i2a_key_usage(BIO *bp, X509 *x);
70 static int a2i_key_usage(X509 *x, char *str, int len);
71 #endif
72
73 int X509v3_get_key_usage(X509 *x);
74 int X509v3_set_key_usage(X509 *x,unsigned int use);
75 int i2a_X509v3_key_usage(BIO *bp, unsigned int use);
76 unsigned int a2i_X509v3_key_usage(char *p);
77
78 #define STD_X509_EXT_NUM        9
79
80 #if 0
81 static X509_OBJECTS std_x509_ext[STD_X509_EXT_NUM]={
82 {NID_subject_key_identifier,    NULL,NULL},
83 {NID_key_usage,                 a2i_key_usage,i2a_key_usage}, /**/
84 {NID_private_key_usage_period,  NULL,NULL},
85 {NID_subject_alt_name,          NULL,NULL},
86 {NID_issuer_alt_name,           NULL,NULL},
87 {NID_basic_constraints,         NULL,NULL},
88 {NID_crl_number,                NULL,NULL},
89 {NID_certificate_policies,      NULL,NULL},
90 {NID_authority_key_identifier,  NULL,NULL},
91         };
92 #endif
93
94 int X509v3_add_standard_extensions()
95         {
96
97 #if 0
98         for (i=0; i<STD_X509_EXT_NUM; i++)
99                 if (!X509v3_add_extension(&(std_x509_ext[i])))
100                         return(0);
101 #endif
102         return(1);
103         }
104
105 int X509v3_get_key_usage(x)
106 X509 *x;
107         {
108         X509_EXTENSION *ext;
109         ASN1_STRING *st;
110         char *p;
111         int i;
112
113         i=X509_get_ext_by_NID(x,NID_key_usage,-1);
114         if (i < 0) return(X509v3_KU_UNDEF);
115         ext=X509_get_ext(x,i);
116         st=X509v3_unpack_string(NULL,V_ASN1_BIT_STRING,
117                 X509_EXTENSION_get_data(X509_get_ext(x,i)));
118
119         p=(char *)ASN1_STRING_data(st);
120         if (ASN1_STRING_length(st) == 1)
121                 i=p[0];
122         else if (ASN1_STRING_length(st) == 2)
123                 i=p[0]|(p[1]<<8);
124         else
125                 i=0;
126         return(i);
127         }
128
129 static struct
130         {
131         char *name;
132         unsigned int value;
133         } key_usage_data[] ={
134         {"digitalSignature",    X509v3_KU_DIGITAL_SIGNATURE},
135         {"nonRepudiation",      X509v3_KU_NON_REPUDIATION},
136         {"keyEncipherment",     X509v3_KU_KEY_ENCIPHERMENT},
137         {"dataEncipherment",    X509v3_KU_DATA_ENCIPHERMENT},
138         {"keyAgreement",        X509v3_KU_KEY_AGREEMENT},
139         {"keyCertSign",         X509v3_KU_KEY_CERT_SIGN},
140         {"cRLSign",             X509v3_KU_CRL_SIGN},
141         {"encipherOnly",        X509v3_KU_ENCIPHER_ONLY},
142         {"decipherOnly",        X509v3_KU_DECIPHER_ONLY},
143         {NULL,0},
144         };
145
146 #if 0
147 static int a2i_key_usage(x,str,len)
148 X509 *x;
149 char *str;
150 int len;
151         {
152         return(X509v3_set_key_usage(x,a2i_X509v3_key_usage(str)));
153         }
154
155 static int i2a_key_usage(bp,x)
156 BIO *bp;
157 X509 *x;
158         {
159         return(i2a_X509v3_key_usage(bp,X509v3_get_key_usage(x)));
160         }
161 #endif
162
163 int i2a_X509v3_key_usage(bp,use)
164 BIO *bp;
165 unsigned int use;
166         {
167         int i=0,first=1;
168
169         for (;;)
170                 {
171                 if (use | key_usage_data[i].value)
172                         {
173                         BIO_printf(bp,"%s%s",((first)?"":" "),
174                                 key_usage_data[i].name);
175                         first=0;
176                         }
177                 break;
178                 }
179         return(1);
180         }
181
182 unsigned int a2i_X509v3_key_usage(p)
183 char *p;
184         {
185         unsigned int ret=0;
186         char *q,*s;
187         int i,n;
188
189         q=p;
190         for (;;)
191                 {
192                 while ((*q != '\0') && isalnum(*q))
193                         q++;
194                 if (*q == '\0') break;
195                 s=q++;
196                 while (isalnum(*q))
197                         q++;
198                 n=q-s;
199                 i=0;
200                 for (;;)
201                         {
202                         if (strncmp(key_usage_data[i].name,s,n) == 0)
203                                 {
204                                 ret|=key_usage_data[i].value;
205                                 break;
206                                 }
207                         i++;
208                         if (key_usage_data[i].name == NULL)
209                                 return(X509v3_KU_UNDEF);
210                         }
211                 }
212         return(ret);
213         }
214
215 int X509v3_set_key_usage(x,use)
216 X509 *x;
217 unsigned int use;
218         {
219         ASN1_OCTET_STRING *os;
220         X509_EXTENSION *ext;
221         int i;
222         unsigned char data[4];
223
224         i=X509_get_ext_by_NID(x,NID_key_usage,-1);
225         if (i < 0)
226                 {
227                 i=X509_get_ext_count(x)+1;
228                 if ((ext=X509_EXTENSION_new()) == NULL) return(0);
229                 if (!X509_add_ext(x,ext,i))
230                         {
231                         X509_EXTENSION_free(ext);
232                         return(0);
233                         }
234                 }
235         else
236                 ext=X509_get_ext(x,i);
237
238         /* fill in 'ext' */
239         os=X509_EXTENSION_get_data(ext);
240
241         i=0;
242         if (use > 0)
243                 {
244                 i=1;
245                 data[0]=use&0xff;
246                 }
247         if (use > 0xff)
248                 {
249                 i=2;
250                 data[1]=(use>>8)&0xff;
251                 }
252         return((X509v3_pack_string(&os,V_ASN1_BIT_STRING,data,i) == NULL)?0:1);
253         }
254