xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/crypto/x509/x509name.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young ([email protected]).
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 ([email protected]).
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 ([email protected])"
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 ([email protected])"
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 <string.h>
58 
59 #include <openssl/asn1.h>
60 #include <openssl/bytestring.h>
61 #include <openssl/err.h>
62 #include <openssl/evp.h>
63 #include <openssl/obj.h>
64 #include <openssl/stack.h>
65 #include <openssl/x509.h>
66 
67 #include "../internal.h"
68 #include "internal.h"
69 
70 
X509_NAME_get_text_by_NID(const X509_NAME * name,int nid,char * buf,int len)71 int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, char *buf,
72                               int len) {
73   const ASN1_OBJECT *obj;
74 
75   obj = OBJ_nid2obj(nid);
76   if (obj == NULL) {
77     return -1;
78   }
79   return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
80 }
81 
X509_NAME_get_text_by_OBJ(const X509_NAME * name,const ASN1_OBJECT * obj,char * buf,int len)82 int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
83                               char *buf, int len) {
84   int i = X509_NAME_get_index_by_OBJ(name, obj, -1);
85   if (i < 0) {
86     return -1;
87   }
88   const ASN1_STRING *data =
89       X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
90   unsigned char *text = NULL;
91   int ret = -1;
92   int text_len = ASN1_STRING_to_UTF8(&text, data);
93   // Fail if we could not encode as UTF-8.
94   if (text_len < 0) {
95     goto out;
96   }
97   CBS cbs;
98   CBS_init(&cbs, text, text_len);
99   // Fail if the UTF-8 encoding constains a 0 byte because this is
100   // returned as a C string and callers very often do not check.
101   if (CBS_contains_zero_byte(&cbs)) {
102     goto out;
103   }
104   // We still support the "pass NULL to find out how much" API
105   if (buf != NULL) {
106     if (text_len >= len || len <= 0 ||
107         !CBS_copy_bytes(&cbs, (uint8_t *)buf, text_len)) {
108       goto out;
109     }
110     // It must be a C string
111     buf[text_len] = '\0';
112   }
113   ret = text_len;
114 
115 out:
116   OPENSSL_free(text);
117   return ret;
118 }
119 
X509_NAME_entry_count(const X509_NAME * name)120 int X509_NAME_entry_count(const X509_NAME *name) {
121   if (name == NULL) {
122     return 0;
123   }
124   return (int)sk_X509_NAME_ENTRY_num(name->entries);
125 }
126 
X509_NAME_get_index_by_NID(const X509_NAME * name,int nid,int lastpos)127 int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) {
128   const ASN1_OBJECT *obj;
129 
130   obj = OBJ_nid2obj(nid);
131   if (obj == NULL) {
132     return -2;
133   }
134   return X509_NAME_get_index_by_OBJ(name, obj, lastpos);
135 }
136 
137 // NOTE: you should be passsing -1, not 0 as lastpos
X509_NAME_get_index_by_OBJ(const X509_NAME * name,const ASN1_OBJECT * obj,int lastpos)138 int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
139                                int lastpos) {
140   if (name == NULL) {
141     return -1;
142   }
143   if (lastpos < 0) {
144     lastpos = -1;
145   }
146   const STACK_OF(X509_NAME_ENTRY) *sk = name->entries;
147   int n = (int)sk_X509_NAME_ENTRY_num(sk);
148   for (lastpos++; lastpos < n; lastpos++) {
149     const X509_NAME_ENTRY *ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
150     if (OBJ_cmp(ne->object, obj) == 0) {
151       return lastpos;
152     }
153   }
154   return -1;
155 }
156 
X509_NAME_get_entry(const X509_NAME * name,int loc)157 X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) {
158   if (name == NULL || loc < 0 ||
159       sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) {
160     return NULL;
161   } else {
162     return (sk_X509_NAME_ENTRY_value(name->entries, loc));
163   }
164 }
165 
X509_NAME_delete_entry(X509_NAME * name,int loc)166 X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) {
167   if (name == NULL || loc < 0 ||
168       sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) {
169     return NULL;
170   }
171 
172   STACK_OF(X509_NAME_ENTRY) *sk = name->entries;
173   X509_NAME_ENTRY *ret = sk_X509_NAME_ENTRY_delete(sk, loc);
174   size_t n = sk_X509_NAME_ENTRY_num(sk);
175   name->modified = 1;
176   if ((size_t)loc == n) {
177     return ret;
178   }
179 
180   int set_prev;
181   if (loc != 0) {
182     set_prev = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
183   } else {
184     set_prev = ret->set - 1;
185   }
186   int set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
187 
188   // If we removed a singleton RDN, update the RDN indices so they are
189   // consecutive again.
190   if (set_prev + 1 < set_next) {
191     for (size_t i = loc; i < n; i++) {
192       sk_X509_NAME_ENTRY_value(sk, i)->set--;
193     }
194   }
195   return ret;
196 }
197 
X509_NAME_add_entry_by_OBJ(X509_NAME * name,const ASN1_OBJECT * obj,int type,const unsigned char * bytes,ossl_ssize_t len,int loc,int set)198 int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
199                                int type, const unsigned char *bytes,
200                                ossl_ssize_t len, int loc, int set) {
201   X509_NAME_ENTRY *ne =
202       X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
203   if (!ne) {
204     return 0;
205   }
206   int ret = X509_NAME_add_entry(name, ne, loc, set);
207   X509_NAME_ENTRY_free(ne);
208   return ret;
209 }
210 
X509_NAME_add_entry_by_NID(X509_NAME * name,int nid,int type,const unsigned char * bytes,ossl_ssize_t len,int loc,int set)211 int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
212                                const unsigned char *bytes, ossl_ssize_t len,
213                                int loc, int set) {
214   X509_NAME_ENTRY *ne =
215       X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
216   if (!ne) {
217     return 0;
218   }
219   int ret = X509_NAME_add_entry(name, ne, loc, set);
220   X509_NAME_ENTRY_free(ne);
221   return ret;
222 }
223 
X509_NAME_add_entry_by_txt(X509_NAME * name,const char * field,int type,const unsigned char * bytes,ossl_ssize_t len,int loc,int set)224 int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
225                                const unsigned char *bytes, ossl_ssize_t len,
226                                int loc, int set) {
227   X509_NAME_ENTRY *ne =
228       X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
229   if (!ne) {
230     return 0;
231   }
232   int ret = X509_NAME_add_entry(name, ne, loc, set);
233   X509_NAME_ENTRY_free(ne);
234   return ret;
235 }
236 
237 // if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
238 // guy we are about to stomp on.
X509_NAME_add_entry(X509_NAME * name,const X509_NAME_ENTRY * entry,int loc,int set)239 int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *entry, int loc,
240                         int set) {
241   X509_NAME_ENTRY *new_name = NULL;
242   int i, inc;
243   STACK_OF(X509_NAME_ENTRY) *sk;
244 
245   if (name == NULL) {
246     return 0;
247   }
248   sk = name->entries;
249   int n = (int)sk_X509_NAME_ENTRY_num(sk);
250   if (loc > n) {
251     loc = n;
252   } else if (loc < 0) {
253     loc = n;
254   }
255 
256   inc = (set == 0);
257   name->modified = 1;
258 
259   if (set == -1) {
260     if (loc == 0) {
261       set = 0;
262       inc = 1;
263     } else {
264       set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
265     }
266   } else {  // if (set >= 0)
267 
268     if (loc >= n) {
269       if (loc != 0) {
270         set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
271       } else {
272         set = 0;
273       }
274     } else {
275       set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
276     }
277   }
278 
279   if ((new_name = X509_NAME_ENTRY_dup(entry)) == NULL) {
280     goto err;
281   }
282   new_name->set = set;
283   if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
284     goto err;
285   }
286   if (inc) {
287     n = (int)sk_X509_NAME_ENTRY_num(sk);
288     for (i = loc + 1; i < n; i++) {
289       sk_X509_NAME_ENTRY_value(sk, i)->set += 1;
290     }
291   }
292   return 1;
293 err:
294   if (new_name != NULL) {
295     X509_NAME_ENTRY_free(new_name);
296   }
297   return 0;
298 }
299 
X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY ** ne,const char * field,int type,const unsigned char * bytes,ossl_ssize_t len)300 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
301                                                const char *field, int type,
302                                                const unsigned char *bytes,
303                                                ossl_ssize_t len) {
304   ASN1_OBJECT *obj;
305   X509_NAME_ENTRY *nentry;
306 
307   obj = OBJ_txt2obj(field, 0);
308   if (obj == NULL) {
309     OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
310     ERR_add_error_data(2, "name=", field);
311     return NULL;
312   }
313   nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
314   ASN1_OBJECT_free(obj);
315   return nentry;
316 }
317 
X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY ** ne,int nid,int type,const unsigned char * bytes,ossl_ssize_t len)318 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
319                                                int type,
320                                                const unsigned char *bytes,
321                                                ossl_ssize_t len) {
322   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
323   if (obj == NULL) {
324     OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
325     return NULL;
326   }
327   return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
328 }
329 
X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY ** ne,const ASN1_OBJECT * obj,int type,const unsigned char * bytes,ossl_ssize_t len)330 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
331                                                const ASN1_OBJECT *obj, int type,
332                                                const unsigned char *bytes,
333                                                ossl_ssize_t len) {
334   X509_NAME_ENTRY *ret;
335 
336   if ((ne == NULL) || (*ne == NULL)) {
337     if ((ret = X509_NAME_ENTRY_new()) == NULL) {
338       return NULL;
339     }
340   } else {
341     ret = *ne;
342   }
343 
344   if (!X509_NAME_ENTRY_set_object(ret, obj)) {
345     goto err;
346   }
347   if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) {
348     goto err;
349   }
350 
351   if ((ne != NULL) && (*ne == NULL)) {
352     *ne = ret;
353   }
354   return ret;
355 err:
356   if ((ne == NULL) || (ret != *ne)) {
357     X509_NAME_ENTRY_free(ret);
358   }
359   return NULL;
360 }
361 
X509_NAME_ENTRY_set_object(X509_NAME_ENTRY * ne,const ASN1_OBJECT * obj)362 int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) {
363   if ((ne == NULL) || (obj == NULL)) {
364     OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
365     return 0;
366   }
367   ASN1_OBJECT_free(ne->object);
368   ne->object = OBJ_dup(obj);
369   return ((ne->object == NULL) ? 0 : 1);
370 }
371 
X509_NAME_ENTRY_set_data(X509_NAME_ENTRY * ne,int type,const unsigned char * bytes,ossl_ssize_t len)372 int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
373                              const unsigned char *bytes, ossl_ssize_t len) {
374   if ((ne == NULL) || ((bytes == NULL) && (len != 0))) {
375     return 0;
376   }
377   if ((type > 0) && (type & MBSTRING_FLAG)) {
378     return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type,
379                                   OBJ_obj2nid(ne->object))
380                ? 1
381                : 0;
382   }
383   if (len < 0) {
384     len = strlen((const char *)bytes);
385   }
386   if (!ASN1_STRING_set(ne->value, bytes, len)) {
387     return 0;
388   }
389   if (type != V_ASN1_UNDEF) {
390     ne->value->type = type;
391   }
392   return 1;
393 }
394 
X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY * ne)395 ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) {
396   if (ne == NULL) {
397     return NULL;
398   }
399   return ne->object;
400 }
401 
X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY * ne)402 ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) {
403   if (ne == NULL) {
404     return NULL;
405   }
406   return ne->value;
407 }
408