More extension code. Incomplete support for subject and issuer alt
[openssl.git] / crypto / x509 / f
1 *** x509name.c  Wed Jul  2 09:35:35 1997
2 --- /home/eay/play/x    Sat Jul  5 01:39:56 1997
3 ***************
4 *** 1,202 ****
5 ! /* crypto/x509/x509name.c */
6 ! /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
7 !  * All rights reserved.
8 !  *
9 !  * This package is an SSL implementation written
10 !  * by Eric Young (eay@cryptsoft.com).
11 !  * The implementation was written so as to conform with Netscapes SSL.
12 !  * 
13 !  * This library is free for commercial and non-commercial use as long as
14 !  * the following conditions are aheared to.  The following conditions
15 !  * apply to all code found in this distribution, be it the RC4, RSA,
16 !  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
17 !  * included with this distribution is covered by the same copyright terms
18 !  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
19 !  * 
20 !  * Copyright remains Eric Young's, and as such any Copyright notices in
21 !  * the code are not to be removed.
22 !  * If this package is used in a product, Eric Young should be given attribution
23 !  * as the author of the parts of the library used.
24 !  * This can be in the form of a textual message at program startup or
25 !  * in documentation (online or textual) provided with the package.
26 !  * 
27 !  * Redistribution and use in source and binary forms, with or without
28 !  * modification, are permitted provided that the following conditions
29 !  * are met:
30 !  * 1. Redistributions of source code must retain the copyright
31 !  *    notice, this list of conditions and the following disclaimer.
32 !  * 2. Redistributions in binary form must reproduce the above copyright
33 !  *    notice, this list of conditions and the following disclaimer in the
34 !  *    documentation and/or other materials provided with the distribution.
35 !  * 3. All advertising materials mentioning features or use of this software
36 !  *    must display the following acknowledgement:
37 !  *    "This product includes cryptographic software written by
38 !  *     Eric Young (eay@cryptsoft.com)"
39 !  *    The word 'cryptographic' can be left out if the rouines from the library
40 !  *    being used are not cryptographic related :-).
41 !  * 4. If you include any Windows specific code (or a derivative thereof) from 
42 !  *    the apps directory (application code) you must include an acknowledgement:
43 !  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
44 !  * 
45 !  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
46 !  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 !  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 !  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 !  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 !  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 !  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 !  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 !  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 !  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 !  * SUCH DAMAGE.
56 !  * 
57 !  * The licence and distribution terms for any publically available version or
58 !  * derivative of this code cannot be changed.  i.e. this code cannot simply be
59 !  * copied and put under another distribution licence
60 !  * [including the GNU Public Licence.]
61 !  */
62
63 ! #include <stdio.h>
64 ! #include "stack.h"
65 ! #include "cryptlib.h"
66 ! #include "asn1.h"
67 ! #include "objects.h"
68 ! #include "evp.h"
69 ! #include "x509.h"
70
71 ! int X509_NAME_get_text_by_NID(name,nid,buf,len)
72 ! X509_NAME *name;
73 ! int nid;
74 ! char *buf;
75 ! int len;
76         {
77         ASN1_OBJECT *obj;
78   
79         obj=OBJ_nid2obj(nid);
80 !       if (obj == NULL) return(-1);
81 !       return(X509_NAME_get_text_by_OBJ(name,obj,buf,len));
82         }
83   
84 - int X509_NAME_get_text_by_OBJ(name,obj,buf,len)
85 - X509_NAME *name;
86 - ASN1_OBJECT *obj;
87 - char *buf;
88 - int len;
89 -       {
90 -       int i;
91 -       ASN1_STRING *data;
92   
93 !       i=X509_NAME_get_index_by_OBJ(name,obj,0);
94 !       if (i < 0) return(-1);
95 !       data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
96 !       i=(data->length > (len-1))?(len-1):data->length;
97 !       if (buf == NULL) return(data->length);
98 !       memcpy(buf,data->data,i);
99 !       buf[i]='\0';
100 !       return(i);
101 !       }
102   
103 ! int X509_NAME_entry_count(name)
104 ! X509_NAME *name;
105         {
106 !       if (name == NULL) return(0);
107 !       return(sk_num(name->entries));
108         }
109   
110 ! int X509_NAME_get_index_by_NID(name,nid,oldpos)
111 ! X509_NAME *name;
112 ! int nid;
113 ! int oldpos;
114 !       {
115 !       ASN1_OBJECT *obj;
116   
117 !       obj=OBJ_nid2obj(nid);
118 !       if (obj == NULL) return(-2);
119 !       return(X509_NAME_get_index_by_OBJ(name,obj,oldpos));
120         }
121   
122 - int X509_NAME_get_index_by_OBJ(name,obj,oldpos)
123 - X509_NAME *name;
124 - ASN1_OBJECT *obj;
125 - int oldpos;
126 -       {
127 -       int n;
128 -       X509_NAME_ENTRY *ne;
129 -       STACK *sk;
130   
131 !       if (name == NULL) return(-1);
132 !       if (oldpos < 0)
133 !               oldpos= -1;
134 !       sk=name->entries;
135 !       n=sk_num(sk);
136 !       for (oldpos++; oldpos < n; oldpos++)
137                 {
138 !               ne=(X509_NAME_ENTRY *)sk_value(sk,oldpos);
139 !               if (OBJ_cmp(ne->object,obj) == 0)
140 !                       return(oldpos);
141                 }
142 !       return(-1);
143         }
144   
145 - X509_NAME_ENTRY *X509_NAME_get_entry(name,loc)
146 - X509_NAME *name;
147 - int loc;
148 -       {
149 -       if (    (name == NULL) || (sk_num(name->entries) <= loc) || (loc < 0))
150 -               return(NULL);
151 -       else
152 -               return((X509_NAME_ENTRY *)sk_value(name->entries,loc));
153 -       }
154   
155 ! X509_NAME_ENTRY *X509_NAME_delete_entry(name,loc)
156 ! X509_NAME *name;
157 ! int loc;
158         {
159 !       X509_NAME_ENTRY *ret;
160 !       int i,j,n,set_prev,set_next;
161 !       STACK *sk;
162
163 !       if ((name == NULL) || (sk_num(name->entries) <= loc) || (loc < 0))
164 !               return(NULL);
165 !       sk=name->entries;
166 !       ret=(X509_NAME_ENTRY *)sk_delete(sk,loc);
167 !       n=sk_num(sk);
168 !       name->modified=1;
169 !       if (loc == n) return(ret);
170
171 !       /* else we need to fixup the set field */
172 !       if (loc != 0)
173 !               set_prev=((X509_NAME_ENTRY *)sk_value(sk,loc-1))->set;
174 !       else
175 !               set_prev=ret->set-1;
176 !       set_next=((X509_NAME_ENTRY *)sk_value(sk,loc))->set;
177   
178 !       /* set_prev is the previous set
179 !        * set is the current set
180 !        * set_next is the following
181 !        * prev  1 1    1 1     1 1     1 1
182 !        * set   1      1       2       2
183 !        * next  1 1    2 2     2 2     3 2
184 !        * so basically only if prev and next differ by 2, then
185 !        * re-number down by 1 */
186 !       if (set_prev+1 < set_next)
187 !               {
188 !               j=set_next-set_prev-1;
189 !               for (i=loc; i<n; i++)
190 !                       ((X509_NAME_ENTRY *)sk_value(sk,loc-1))->set-=j;
191 !               }
192 !       return(ret);
193         }
194   
195   /* if set is -1, append to previous set, 0 'a new one', and 1,
196    * prepend to the guy we are about to stomp on. */
197 ! int X509_NAME_add_entry(name,ne,loc,set)
198 ! X509_NAME *name;
199 ! X509_NAME_ENTRY *ne;
200 ! int loc;
201 ! int set;
202         {
203 !       X509_NAME_ENTRY *new_name=NULL;
204         int n,i,inc;
205         STACK *sk;
206   
207 --- 1,77 ----
208 ! X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
209 !                       int type,unsigned char *bytes, int len)
210         {
211         ASN1_OBJECT *obj;
212   
213         obj=OBJ_nid2obj(nid);
214 !       if (obj == NULL)
215 !               {
216 !               X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID,X509_R_UNKNOWN_NID);
217 !               return(NULL);
218 !               }
219 !       return(X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len));
220         }
221   
222   
223 ! X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
224 !                       ASN1_OBJECT *obj, int type,unsigned char *bytes,
225 !                       int len)
226 !       {
227 !       X509_NAME_ENTRY *ret;
228   
229 !       if ((ne == NULL) || (*ne == NULL))
230                 {
231 !               if ((ret=X509_NAME_ENTRY_new()) == NULL)
232 !                       return(NULL);
233                 }
234 +       else
235 +               ret= *ne;
236   
237 !       if (!X509_NAME_ENTRY_set_object(ret,obj))
238 !               goto err;
239 !       if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
240 !               goto err;
241   
242 !       if ((ne != NULL) && (*ne == NULL)) *ne=ret;
243 !       return(ret);
244 ! err:
245 !       if ((ne == NULL) || (ret != *ne))
246 !               X509_NAME_ENTRY_free(ret);
247 !       return(NULL);
248         }
249   
250   
251 ! int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj)
252 !       {
253 !       if ((ne == NULL) || (obj == NULL))
254                 {
255 !               X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,ERR_R_PASSED_NULL_PARAMETER);
256 !               return(0);
257                 }
258 !       ASN1_OBJECT_free(ne->object);
259 !       ne->object=OBJ_dup(obj);
260 !       return((ne->object == NULL)?0:1);
261         }
262   
263   
264 ! int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne,int type,unsigned char *bytes,int len)
265         {
266 !       int i;
267   
268 !       if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
269 !       if (len < 0) len=strlen((char *)bytes);
270 !       i=ASN1_STRING_set(ne->value,bytes,len);
271 !       if (!i) return(0);
272 !     ne->value->type=ASN1_PRINTABLE_type(bytes,len);
273 !       return(1);
274         }
275   
276   /* if set is -1, append to previous set, 0 'a new one', and 1,
277    * prepend to the guy we are about to stomp on. */
278 ! int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,int loc,int set)
279         {
280 !       /* ERIC: renamed new to nenew for C++ users --tjh */
281 !       X509_NAME_ENTRY *nenew;
282         int n,i,inc;
283       STACK *sk;
284   
285 ***************
286 *** 206,213 ****
287         if (loc > n) loc=n;
288         else if (loc < 0) loc=n;
289   
290 -       name->modified=1;
291
292         if (set == -1)
293                 {
294                 if (loc == 0)
295 --- 81,86 ----
296 ***************
297 *** 223,245 ****
298                 }
299         else /* if (set >= 0) */
300                 {
301 -               inc=(set == 0)?1:0;
302                 if (loc >= n)
303                         {
304                         if (loc != 0)
305                                 set=((X509_NAME_ENTRY *)
306 !                                       sk_value(sk,n-1))->set+1;
307                         else
308                                 set=0;
309                         }
310                 else
311                         set=((X509_NAME_ENTRY *)sk_value(sk,loc))->set;
312                 }
313   
314 !       if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL)
315                 goto err;
316 !       new_name->set=set;
317 !       if (!sk_insert(sk,(char *)new_name,loc))
318                 {
319                 X509err(X509_F_X509_NAME_ADD_ENTRY,ERR_R_MALLOC_FAILURE);
320                 goto err;
321 --- 96,122 ----
322                 }
323         else /* if (set >= 0) */
324                 {
325                 if (loc >= n)
326                         {
327                         if (loc != 0)
328                                 set=((X509_NAME_ENTRY *)
329 !                                       sk_value(sk,loc-1))->set+1;
330                         else
331                                 set=0;
332                         }
333                 else
334                         set=((X509_NAME_ENTRY *)sk_value(sk,loc))->set;
335 +               inc=(set == 0)?1:0;
336                 }
337   
338 !       if ((nenew=X509_NAME_ENTRY_dup(ne)) == NULL)
339                 goto err;
340 !         /* eric forgot to put this in when he cut the nice
341 !        * interface so that I don't have to do the icky things
342 !        * that req.c does --tjh :-)
343 !        */
344 !       nenew->set=set;
345 !       if (!sk_insert(sk,(char *)nenew,loc))
346                 {
347                 X509err(X509_F_X509_NAME_ADD_ENTRY,ERR_R_MALLOC_FAILURE);
348                 goto err;
349 ***************
350 *** 252,357 ****
351                 }       
352         return(1);
353   err:
354 !       if (new_name != NULL)
355                 X509_NAME_ENTRY_free(ne);
356         return(0);
357 -       }
358
359 - X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(ne,nid,type,bytes,len)
360 - X509_NAME_ENTRY **ne;
361 - int nid;
362 - int type;
363 - unsigned char *bytes;
364 - int len;
365 -       {
366 -       ASN1_OBJECT *obj;
367
368 -       obj=OBJ_nid2obj(nid);
369 -       if (obj == NULL)
370 -               {
371 -               X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID,X509_R_UNKNOWN_NID);
372 -               return(NULL);
373 -               }
374 -       return(X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len));
375 -       }
376
377 - X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len)
378 - X509_NAME_ENTRY **ne;
379 - ASN1_OBJECT *obj;
380 - int type;
381 - unsigned char *bytes;
382 - int len;
383 -       {
384 -       X509_NAME_ENTRY *ret;
385
386 -       if ((ne == NULL) || (*ne == NULL))
387 -               {
388 -               if ((ret=X509_NAME_ENTRY_new()) == NULL)
389 -                       return(NULL);
390 -               }
391 -       else
392 -               ret= *ne;
393
394 -       if (!X509_NAME_ENTRY_set_object(ret,obj))
395 -               goto err;
396 -       if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len))
397 -               goto err;
398 -       
399 -       if ((ne != NULL) && (*ne == NULL)) *ne=ret;
400 -       return(ret);
401 - err:
402 -       if ((ne == NULL) || (ret != *ne))
403 -               X509_NAME_ENTRY_free(ret);
404 -       return(NULL);
405 -       }
406
407 - int X509_NAME_ENTRY_set_object(ne,obj)
408 - X509_NAME_ENTRY *ne;
409 - ASN1_OBJECT *obj;
410 -       {
411 -       if ((ne == NULL) || (obj == NULL))
412 -               {
413 -               X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,ERR_R_PASSED_NULL_PARAMETER);
414 -               return(0);
415 -               }
416 -       ASN1_OBJECT_free(ne->object);
417 -       ne->object=OBJ_dup(obj);
418 -       return((ne->object == NULL)?0:1);
419 -       }
420
421 - int X509_NAME_ENTRY_set_data(ne,type,bytes,len)
422 - X509_NAME_ENTRY *ne;
423 - int type;
424 - unsigned char *bytes;
425 - int len;
426 -       {
427 -       int i;
428
429 -       if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0);
430 -       if (len < 0) len=strlen((char *)bytes);
431 -       i=ASN1_STRING_set(ne->value,bytes,len);
432 -       if (!i) return(0);
433 -       if (type != V_ASN1_UNDEF)
434 -               {
435 -               if (type == V_ASN1_APP_CHOOSE)
436 -                       ne->value->type=ASN1_PRINTABLE_type(bytes,len);
437 -               else
438 -                       ne->value->type=type;
439 -               }
440 -       return(1);
441 -       }
442
443 - ASN1_OBJECT *X509_NAME_ENTRY_get_object(ne)
444 - X509_NAME_ENTRY *ne;
445 -       {
446 -       if (ne == NULL) return(NULL);
447 -       return(ne->object);
448 -       }
449
450 - ASN1_STRING *X509_NAME_ENTRY_get_data(ne)
451 - X509_NAME_ENTRY *ne;
452 -       {
453 -       if (ne == NULL) return(NULL);
454 -       return(ne->value);
455         }
456   
457 --- 129,136 ----
458                 }
459         return(1);
460   err:
461 !       if (nenew != NULL)
462                 X509_NAME_ENTRY_free(ne);
463         return(0);
464         }
465