xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/a_object.c (revision 2139:6243c3338933)
1 /* crypto/asn1/a_object.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 "cryptlib.h"
61 #include <openssl/buffer.h>
62 #include <openssl/asn1.h>
63 #include <openssl/objects.h>
64 
i2d_ASN1_OBJECT(ASN1_OBJECT * a,unsigned char ** pp)65 int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
66 	{
67 	unsigned char *p;
68 	int objsize;
69 
70 	if ((a == NULL) || (a->data == NULL)) return(0);
71 
72 	objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
73 	if (pp == NULL) return objsize;
74 
75 	p= *pp;
76 	ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
77 	memcpy(p,a->data,a->length);
78 	p+=a->length;
79 
80 	*pp=p;
81 	return(objsize);
82 	}
83 
a2d_ASN1_OBJECT(unsigned char * out,int olen,const char * buf,int num)84 int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
85 	{
86 	int i,first,len=0,c;
87 	char tmp[24];
88 	const char *p;
89 	unsigned long l;
90 
91 	if (num == 0)
92 		return(0);
93 	else if (num == -1)
94 		num=strlen(buf);
95 
96 	p=buf;
97 	c= *(p++);
98 	num--;
99 	if ((c >= '0') && (c <= '2'))
100 		{
101 		first=(c-'0')*40;
102 		}
103 	else
104 		{
105 		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
106 		goto err;
107 		}
108 
109 	if (num <= 0)
110 		{
111 		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
112 		goto err;
113 		}
114 	c= *(p++);
115 	num--;
116 	for (;;)
117 		{
118 		if (num <= 0) break;
119 		if ((c != '.') && (c != ' '))
120 			{
121 			ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
122 			goto err;
123 			}
124 		l=0;
125 		for (;;)
126 			{
127 			if (num <= 0) break;
128 			num--;
129 			c= *(p++);
130 			if ((c == ' ') || (c == '.'))
131 				break;
132 			if ((c < '0') || (c > '9'))
133 				{
134 				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
135 				goto err;
136 				}
137 			l=l*10L+(long)(c-'0');
138 			}
139 		if (len == 0)
140 			{
141 			if ((first < 2) && (l >= 40))
142 				{
143 				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
144 				goto err;
145 				}
146 			l+=(long)first;
147 			}
148 		i=0;
149 		for (;;)
150 			{
151 			tmp[i++]=(unsigned char)l&0x7f;
152 			l>>=7L;
153 			if (l == 0L) break;
154 			}
155 		if (out != NULL)
156 			{
157 			if (len+i > olen)
158 				{
159 				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
160 				goto err;
161 				}
162 			while (--i > 0)
163 				out[len++]=tmp[i]|0x80;
164 			out[len++]=tmp[0];
165 			}
166 		else
167 			len+=i;
168 		}
169 	return(len);
170 err:
171 	return(0);
172 	}
173 
i2t_ASN1_OBJECT(char * buf,int buf_len,ASN1_OBJECT * a)174 int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
175 {
176 	return OBJ_obj2txt(buf, buf_len, a, 0);
177 }
178 
i2a_ASN1_OBJECT(BIO * bp,ASN1_OBJECT * a)179 int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
180 	{
181 	char buf[80];
182 	int i;
183 
184 	if ((a == NULL) || (a->data == NULL))
185 		return(BIO_write(bp,"NULL",4));
186 	i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
187 	if (i > (int)sizeof(buf)) i=sizeof buf;
188 	BIO_write(bp,buf,i);
189 	return(i);
190 	}
191 
d2i_ASN1_OBJECT(ASN1_OBJECT ** a,const unsigned char ** pp,long length)192 ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
193 	     long length)
194 {
195 	const unsigned char *p;
196 	long len;
197 	int tag,xclass;
198 	int inf,i;
199 	ASN1_OBJECT *ret = NULL;
200 	p= *pp;
201 	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
202 	if (inf & 0x80)
203 		{
204 		i=ASN1_R_BAD_OBJECT_HEADER;
205 		goto err;
206 		}
207 
208 	if (tag != V_ASN1_OBJECT)
209 		{
210 		i=ASN1_R_EXPECTING_AN_OBJECT;
211 		goto err;
212 		}
213 	ret = c2i_ASN1_OBJECT(a, &p, len);
214 	if(ret) *pp = p;
215 	return ret;
216 err:
217 	ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
218 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
219 		ASN1_OBJECT_free(ret);
220 	return(NULL);
221 }
c2i_ASN1_OBJECT(ASN1_OBJECT ** a,const unsigned char ** pp,long len)222 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
223 	     long len)
224 	{
225 	ASN1_OBJECT *ret=NULL;
226 	const unsigned char *p;
227 	int i;
228 
229 	/* only the ASN1_OBJECTs from the 'table' will have values
230 	 * for ->sn or ->ln */
231 	if ((a == NULL) || ((*a) == NULL) ||
232 		!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
233 		{
234 		if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
235 		}
236 	else	ret=(*a);
237 
238 	p= *pp;
239 	if ((ret->data == NULL) || (ret->length < len))
240 		{
241 		if (ret->data != NULL) OPENSSL_free(ret->data);
242 		ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
243 		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
244 		if (ret->data == NULL)
245 			{ i=ERR_R_MALLOC_FAILURE; goto err; }
246 		}
247 	memcpy(ret->data,p,(int)len);
248 	ret->length=(int)len;
249 	ret->sn=NULL;
250 	ret->ln=NULL;
251 	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
252 	p+=len;
253 
254 	if (a != NULL) (*a)=ret;
255 	*pp=p;
256 	return(ret);
257 err:
258 	ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
259 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
260 		ASN1_OBJECT_free(ret);
261 	return(NULL);
262 	}
263 
ASN1_OBJECT_new(void)264 ASN1_OBJECT *ASN1_OBJECT_new(void)
265 	{
266 	ASN1_OBJECT *ret;
267 
268 	ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
269 	if (ret == NULL)
270 		{
271 		ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
272 		return(NULL);
273 		}
274 	ret->length=0;
275 	ret->data=NULL;
276 	ret->nid=0;
277 	ret->sn=NULL;
278 	ret->ln=NULL;
279 	ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
280 	return(ret);
281 	}
282 
ASN1_OBJECT_free(ASN1_OBJECT * a)283 void ASN1_OBJECT_free(ASN1_OBJECT *a)
284 	{
285 	if (a == NULL) return;
286 	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
287 		{
288 #ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
289 		if (a->sn != NULL) OPENSSL_free((void *)a->sn);
290 		if (a->ln != NULL) OPENSSL_free((void *)a->ln);
291 #endif
292 		a->sn=a->ln=NULL;
293 		}
294 	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
295 		{
296 		if (a->data != NULL) OPENSSL_free(a->data);
297 		a->data=NULL;
298 		a->length=0;
299 		}
300 	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
301 		OPENSSL_free(a);
302 	}
303 
ASN1_OBJECT_create(int nid,unsigned char * data,int len,const char * sn,const char * ln)304 ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
305 	     const char *sn, const char *ln)
306 	{
307 	ASN1_OBJECT o;
308 
309 	o.sn=sn;
310 	o.ln=ln;
311 	o.data=data;
312 	o.nid=nid;
313 	o.length=len;
314 	o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
315 		ASN1_OBJECT_FLAG_DYNAMIC_DATA;
316 	return(OBJ_dup(&o));
317 	}
318 
319 IMPLEMENT_STACK_OF(ASN1_OBJECT)
320 IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
321