1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/asn1.h>
58 #include <openssl/err.h>
59 #include <openssl/evp.h>
60 #include <openssl/obj.h>
61 #include <openssl/stack.h>
62 #include <openssl/x509.h>
63 #include <openssl/x509v3.h>
64 
65 
X509v3_get_ext_count(const STACK_OF (X509_EXTENSION)* x)66 int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
67 	{
68 	if (x == NULL) return(0);
69 	return(sk_X509_EXTENSION_num(x));
70 	}
71 
X509v3_get_ext_by_NID(const STACK_OF (X509_EXTENSION)* x,int nid,int lastpos)72 int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
73 			  int lastpos)
74 	{
75 	const ASN1_OBJECT *obj;
76 
77 	obj=OBJ_nid2obj(nid);
78 	if (obj == NULL) return(-2);
79 	return(X509v3_get_ext_by_OBJ(x,obj,lastpos));
80 	}
81 
X509v3_get_ext_by_OBJ(const STACK_OF (X509_EXTENSION)* sk,const ASN1_OBJECT * obj,int lastpos)82 int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, const ASN1_OBJECT *obj,
83 			  int lastpos)
84 	{
85 	int n;
86 	X509_EXTENSION *ex;
87 
88 	if (sk == NULL) return(-1);
89 	lastpos++;
90 	if (lastpos < 0)
91 		lastpos=0;
92 	n=sk_X509_EXTENSION_num(sk);
93 	for ( ; lastpos < n; lastpos++)
94 		{
95 		ex=sk_X509_EXTENSION_value(sk,lastpos);
96 		if (OBJ_cmp(ex->object,obj) == 0)
97 			return(lastpos);
98 		}
99 	return(-1);
100 	}
101 
X509v3_get_ext_by_critical(const STACK_OF (X509_EXTENSION)* sk,int crit,int lastpos)102 int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
103 			       int lastpos)
104 	{
105 	int n;
106 	X509_EXTENSION *ex;
107 
108 	if (sk == NULL) return(-1);
109 	lastpos++;
110 	if (lastpos < 0)
111 		lastpos=0;
112 	n=sk_X509_EXTENSION_num(sk);
113 	for ( ; lastpos < n; lastpos++)
114 		{
115 		ex=sk_X509_EXTENSION_value(sk,lastpos);
116 		if (	((ex->critical > 0) && crit) ||
117 			((ex->critical <= 0) && !crit))
118 			return(lastpos);
119 		}
120 	return(-1);
121 	}
122 
X509v3_get_ext(const STACK_OF (X509_EXTENSION)* x,int loc)123 X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
124 	{
125 	if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t) loc)
126 		return NULL;
127 	else
128 		return sk_X509_EXTENSION_value(x,loc);
129 	}
130 
X509v3_delete_ext(STACK_OF (X509_EXTENSION)* x,int loc)131 X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
132 	{
133 	X509_EXTENSION *ret;
134 
135 	if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t) loc)
136 		return(NULL);
137 	ret=sk_X509_EXTENSION_delete(x,loc);
138 	return(ret);
139 	}
140 
STACK_OF(X509_EXTENSION)141 STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
142 					 X509_EXTENSION *ex, int loc)
143 	{
144 	X509_EXTENSION *new_ex=NULL;
145 	int n;
146 	STACK_OF(X509_EXTENSION) *sk=NULL;
147 
148 	if (x == NULL)
149 		{
150 		OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
151 		goto err2;
152 		}
153 
154 	if (*x == NULL)
155 		{
156 		if ((sk=sk_X509_EXTENSION_new_null()) == NULL)
157 			goto err;
158 		}
159 	else
160 		sk= *x;
161 
162 	n=sk_X509_EXTENSION_num(sk);
163 	if (loc > n) loc=n;
164 	else if (loc < 0) loc=n;
165 
166 	if ((new_ex=X509_EXTENSION_dup(ex)) == NULL)
167 		goto err2;
168 	if (!sk_X509_EXTENSION_insert(sk,new_ex,loc))
169 		goto err;
170 	if (*x == NULL)
171 		*x=sk;
172 	return(sk);
173 err:
174 	OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
175 err2:
176 	if (new_ex != NULL) X509_EXTENSION_free(new_ex);
177 	if (sk != NULL) sk_X509_EXTENSION_free(sk);
178 	return(NULL);
179 	}
180 
X509_EXTENSION_create_by_NID(X509_EXTENSION ** ex,int nid,int crit,ASN1_OCTET_STRING * data)181 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
182 	     int crit, ASN1_OCTET_STRING *data)
183 	{
184 	const ASN1_OBJECT *obj;
185 	X509_EXTENSION *ret;
186 
187 	obj=OBJ_nid2obj(nid);
188 	if (obj == NULL)
189 		{
190 		OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
191 		return(NULL);
192 		}
193 	ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data);
194 	return(ret);
195 	}
196 
X509_EXTENSION_create_by_OBJ(X509_EXTENSION ** ex,const ASN1_OBJECT * obj,int crit,ASN1_OCTET_STRING * data)197 X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
198 	     const ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data)
199 	{
200 	X509_EXTENSION *ret;
201 
202 	if ((ex == NULL) || (*ex == NULL))
203 		{
204 		if ((ret=X509_EXTENSION_new()) == NULL)
205 			{
206 			OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
207 			return(NULL);
208 			}
209 		}
210 	else
211 		ret= *ex;
212 
213 	if (!X509_EXTENSION_set_object(ret,obj))
214 		goto err;
215 	if (!X509_EXTENSION_set_critical(ret,crit))
216 		goto err;
217 	if (!X509_EXTENSION_set_data(ret,data))
218 		goto err;
219 
220 	if ((ex != NULL) && (*ex == NULL)) *ex=ret;
221 	return(ret);
222 err:
223 	if ((ex == NULL) || (ret != *ex))
224 		X509_EXTENSION_free(ret);
225 	return(NULL);
226 	}
227 
X509_EXTENSION_set_object(X509_EXTENSION * ex,const ASN1_OBJECT * obj)228 int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj)
229 	{
230 	if ((ex == NULL) || (obj == NULL))
231 		return(0);
232 	ASN1_OBJECT_free(ex->object);
233 	ex->object=OBJ_dup(obj);
234 	return ex->object != NULL;
235 	}
236 
X509_EXTENSION_set_critical(X509_EXTENSION * ex,int crit)237 int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
238 	{
239 	if (ex == NULL) return(0);
240 	ex->critical=(crit)?0xFF:-1;
241 	return(1);
242 	}
243 
X509_EXTENSION_set_data(X509_EXTENSION * ex,ASN1_OCTET_STRING * data)244 int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
245 	{
246 	int i;
247 
248 	if (ex == NULL) return(0);
249 	i=M_ASN1_OCTET_STRING_set(ex->value,data->data,data->length);
250 	if (!i) return(0);
251 	return(1);
252 	}
253 
X509_EXTENSION_get_object(X509_EXTENSION * ex)254 ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
255 	{
256 	if (ex == NULL) return(NULL);
257 	return(ex->object);
258 	}
259 
X509_EXTENSION_get_data(X509_EXTENSION * ex)260 ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
261 	{
262 	if (ex == NULL) return(NULL);
263 	return(ex->value);
264 	}
265 
X509_EXTENSION_get_critical(X509_EXTENSION * ex)266 int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
267 	{
268 	if (ex == NULL) return(0);
269 	if(ex->critical > 0) return 1;
270 	return 0;
271 	}
272