xref: /aosp_15_r20/external/boringssl/src/crypto/x509/x509name.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (C) 1995-1998 Eric Young ([email protected])
2*8fb009dcSAndroid Build Coastguard Worker  * All rights reserved.
3*8fb009dcSAndroid Build Coastguard Worker  *
4*8fb009dcSAndroid Build Coastguard Worker  * This package is an SSL implementation written
5*8fb009dcSAndroid Build Coastguard Worker  * by Eric Young ([email protected]).
6*8fb009dcSAndroid Build Coastguard Worker  * The implementation was written so as to conform with Netscapes SSL.
7*8fb009dcSAndroid Build Coastguard Worker  *
8*8fb009dcSAndroid Build Coastguard Worker  * This library is free for commercial and non-commercial use as long as
9*8fb009dcSAndroid Build Coastguard Worker  * the following conditions are aheared to.  The following conditions
10*8fb009dcSAndroid Build Coastguard Worker  * apply to all code found in this distribution, be it the RC4, RSA,
11*8fb009dcSAndroid Build Coastguard Worker  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12*8fb009dcSAndroid Build Coastguard Worker  * included with this distribution is covered by the same copyright terms
13*8fb009dcSAndroid Build Coastguard Worker  * except that the holder is Tim Hudson ([email protected]).
14*8fb009dcSAndroid Build Coastguard Worker  *
15*8fb009dcSAndroid Build Coastguard Worker  * Copyright remains Eric Young's, and as such any Copyright notices in
16*8fb009dcSAndroid Build Coastguard Worker  * the code are not to be removed.
17*8fb009dcSAndroid Build Coastguard Worker  * If this package is used in a product, Eric Young should be given attribution
18*8fb009dcSAndroid Build Coastguard Worker  * as the author of the parts of the library used.
19*8fb009dcSAndroid Build Coastguard Worker  * This can be in the form of a textual message at program startup or
20*8fb009dcSAndroid Build Coastguard Worker  * in documentation (online or textual) provided with the package.
21*8fb009dcSAndroid Build Coastguard Worker  *
22*8fb009dcSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
23*8fb009dcSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
24*8fb009dcSAndroid Build Coastguard Worker  * are met:
25*8fb009dcSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the copyright
26*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
27*8fb009dcSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
28*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
29*8fb009dcSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
30*8fb009dcSAndroid Build Coastguard Worker  * 3. All advertising materials mentioning features or use of this software
31*8fb009dcSAndroid Build Coastguard Worker  *    must display the following acknowledgement:
32*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes cryptographic software written by
33*8fb009dcSAndroid Build Coastguard Worker  *     Eric Young ([email protected])"
34*8fb009dcSAndroid Build Coastguard Worker  *    The word 'cryptographic' can be left out if the rouines from the library
35*8fb009dcSAndroid Build Coastguard Worker  *    being used are not cryptographic related :-).
36*8fb009dcSAndroid Build Coastguard Worker  * 4. If you include any Windows specific code (or a derivative thereof) from
37*8fb009dcSAndroid Build Coastguard Worker  *    the apps directory (application code) you must include an acknowledgement:
38*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes software written by Tim Hudson ([email protected])"
39*8fb009dcSAndroid Build Coastguard Worker  *
40*8fb009dcSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41*8fb009dcSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*8fb009dcSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43*8fb009dcSAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44*8fb009dcSAndroid Build Coastguard Worker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45*8fb009dcSAndroid Build Coastguard Worker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46*8fb009dcSAndroid Build Coastguard Worker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*8fb009dcSAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48*8fb009dcSAndroid Build Coastguard Worker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49*8fb009dcSAndroid Build Coastguard Worker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50*8fb009dcSAndroid Build Coastguard Worker  * SUCH DAMAGE.
51*8fb009dcSAndroid Build Coastguard Worker  *
52*8fb009dcSAndroid Build Coastguard Worker  * The licence and distribution terms for any publically available version or
53*8fb009dcSAndroid Build Coastguard Worker  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54*8fb009dcSAndroid Build Coastguard Worker  * copied and put under another distribution licence
55*8fb009dcSAndroid Build Coastguard Worker  * [including the GNU Public Licence.] */
56*8fb009dcSAndroid Build Coastguard Worker 
57*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
58*8fb009dcSAndroid Build Coastguard Worker 
59*8fb009dcSAndroid Build Coastguard Worker #include <openssl/asn1.h>
60*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bytestring.h>
61*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
62*8fb009dcSAndroid Build Coastguard Worker #include <openssl/evp.h>
63*8fb009dcSAndroid Build Coastguard Worker #include <openssl/obj.h>
64*8fb009dcSAndroid Build Coastguard Worker #include <openssl/stack.h>
65*8fb009dcSAndroid Build Coastguard Worker #include <openssl/x509.h>
66*8fb009dcSAndroid Build Coastguard Worker 
67*8fb009dcSAndroid Build Coastguard Worker #include "../internal.h"
68*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
69*8fb009dcSAndroid Build Coastguard Worker 
70*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_get_text_by_NID(const X509_NAME * name,int nid,char * buf,int len)71*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, char *buf,
72*8fb009dcSAndroid Build Coastguard Worker                               int len) {
73*8fb009dcSAndroid Build Coastguard Worker   const ASN1_OBJECT *obj;
74*8fb009dcSAndroid Build Coastguard Worker 
75*8fb009dcSAndroid Build Coastguard Worker   obj = OBJ_nid2obj(nid);
76*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
77*8fb009dcSAndroid Build Coastguard Worker     return -1;
78*8fb009dcSAndroid Build Coastguard Worker   }
79*8fb009dcSAndroid Build Coastguard Worker   return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
80*8fb009dcSAndroid Build Coastguard Worker }
81*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_get_text_by_OBJ(const X509_NAME * name,const ASN1_OBJECT * obj,char * buf,int len)82*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
83*8fb009dcSAndroid Build Coastguard Worker                               char *buf, int len) {
84*8fb009dcSAndroid Build Coastguard Worker   int i = X509_NAME_get_index_by_OBJ(name, obj, -1);
85*8fb009dcSAndroid Build Coastguard Worker   if (i < 0) {
86*8fb009dcSAndroid Build Coastguard Worker     return -1;
87*8fb009dcSAndroid Build Coastguard Worker   }
88*8fb009dcSAndroid Build Coastguard Worker   const ASN1_STRING *data =
89*8fb009dcSAndroid Build Coastguard Worker       X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
90*8fb009dcSAndroid Build Coastguard Worker   unsigned char *text = NULL;
91*8fb009dcSAndroid Build Coastguard Worker   int ret = -1;
92*8fb009dcSAndroid Build Coastguard Worker   int text_len = ASN1_STRING_to_UTF8(&text, data);
93*8fb009dcSAndroid Build Coastguard Worker   // Fail if we could not encode as UTF-8.
94*8fb009dcSAndroid Build Coastguard Worker   if (text_len < 0) {
95*8fb009dcSAndroid Build Coastguard Worker     goto out;
96*8fb009dcSAndroid Build Coastguard Worker   }
97*8fb009dcSAndroid Build Coastguard Worker   CBS cbs;
98*8fb009dcSAndroid Build Coastguard Worker   CBS_init(&cbs, text, text_len);
99*8fb009dcSAndroid Build Coastguard Worker   // Fail if the UTF-8 encoding constains a 0 byte because this is
100*8fb009dcSAndroid Build Coastguard Worker   // returned as a C string and callers very often do not check.
101*8fb009dcSAndroid Build Coastguard Worker   if (CBS_contains_zero_byte(&cbs)) {
102*8fb009dcSAndroid Build Coastguard Worker     goto out;
103*8fb009dcSAndroid Build Coastguard Worker   }
104*8fb009dcSAndroid Build Coastguard Worker   // We still support the "pass NULL to find out how much" API
105*8fb009dcSAndroid Build Coastguard Worker   if (buf != NULL) {
106*8fb009dcSAndroid Build Coastguard Worker     if (text_len >= len || len <= 0 ||
107*8fb009dcSAndroid Build Coastguard Worker         !CBS_copy_bytes(&cbs, (uint8_t *)buf, text_len)) {
108*8fb009dcSAndroid Build Coastguard Worker       goto out;
109*8fb009dcSAndroid Build Coastguard Worker     }
110*8fb009dcSAndroid Build Coastguard Worker     // It must be a C string
111*8fb009dcSAndroid Build Coastguard Worker     buf[text_len] = '\0';
112*8fb009dcSAndroid Build Coastguard Worker   }
113*8fb009dcSAndroid Build Coastguard Worker   ret = text_len;
114*8fb009dcSAndroid Build Coastguard Worker 
115*8fb009dcSAndroid Build Coastguard Worker out:
116*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(text);
117*8fb009dcSAndroid Build Coastguard Worker   return ret;
118*8fb009dcSAndroid Build Coastguard Worker }
119*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_entry_count(const X509_NAME * name)120*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_entry_count(const X509_NAME *name) {
121*8fb009dcSAndroid Build Coastguard Worker   if (name == NULL) {
122*8fb009dcSAndroid Build Coastguard Worker     return 0;
123*8fb009dcSAndroid Build Coastguard Worker   }
124*8fb009dcSAndroid Build Coastguard Worker   return (int)sk_X509_NAME_ENTRY_num(name->entries);
125*8fb009dcSAndroid Build Coastguard Worker }
126*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_get_index_by_NID(const X509_NAME * name,int nid,int lastpos)127*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) {
128*8fb009dcSAndroid Build Coastguard Worker   const ASN1_OBJECT *obj;
129*8fb009dcSAndroid Build Coastguard Worker 
130*8fb009dcSAndroid Build Coastguard Worker   obj = OBJ_nid2obj(nid);
131*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
132*8fb009dcSAndroid Build Coastguard Worker     return -2;
133*8fb009dcSAndroid Build Coastguard Worker   }
134*8fb009dcSAndroid Build Coastguard Worker   return X509_NAME_get_index_by_OBJ(name, obj, lastpos);
135*8fb009dcSAndroid Build Coastguard Worker }
136*8fb009dcSAndroid Build Coastguard Worker 
137*8fb009dcSAndroid Build Coastguard Worker // 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*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
139*8fb009dcSAndroid Build Coastguard Worker                                int lastpos) {
140*8fb009dcSAndroid Build Coastguard Worker   if (name == NULL) {
141*8fb009dcSAndroid Build Coastguard Worker     return -1;
142*8fb009dcSAndroid Build Coastguard Worker   }
143*8fb009dcSAndroid Build Coastguard Worker   if (lastpos < 0) {
144*8fb009dcSAndroid Build Coastguard Worker     lastpos = -1;
145*8fb009dcSAndroid Build Coastguard Worker   }
146*8fb009dcSAndroid Build Coastguard Worker   const STACK_OF(X509_NAME_ENTRY) *sk = name->entries;
147*8fb009dcSAndroid Build Coastguard Worker   int n = (int)sk_X509_NAME_ENTRY_num(sk);
148*8fb009dcSAndroid Build Coastguard Worker   for (lastpos++; lastpos < n; lastpos++) {
149*8fb009dcSAndroid Build Coastguard Worker     const X509_NAME_ENTRY *ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
150*8fb009dcSAndroid Build Coastguard Worker     if (OBJ_cmp(ne->object, obj) == 0) {
151*8fb009dcSAndroid Build Coastguard Worker       return lastpos;
152*8fb009dcSAndroid Build Coastguard Worker     }
153*8fb009dcSAndroid Build Coastguard Worker   }
154*8fb009dcSAndroid Build Coastguard Worker   return -1;
155*8fb009dcSAndroid Build Coastguard Worker }
156*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_get_entry(const X509_NAME * name,int loc)157*8fb009dcSAndroid Build Coastguard Worker X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) {
158*8fb009dcSAndroid Build Coastguard Worker   if (name == NULL || loc < 0 ||
159*8fb009dcSAndroid Build Coastguard Worker       sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) {
160*8fb009dcSAndroid Build Coastguard Worker     return NULL;
161*8fb009dcSAndroid Build Coastguard Worker   } else {
162*8fb009dcSAndroid Build Coastguard Worker     return (sk_X509_NAME_ENTRY_value(name->entries, loc));
163*8fb009dcSAndroid Build Coastguard Worker   }
164*8fb009dcSAndroid Build Coastguard Worker }
165*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_delete_entry(X509_NAME * name,int loc)166*8fb009dcSAndroid Build Coastguard Worker X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) {
167*8fb009dcSAndroid Build Coastguard Worker   if (name == NULL || loc < 0 ||
168*8fb009dcSAndroid Build Coastguard Worker       sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) {
169*8fb009dcSAndroid Build Coastguard Worker     return NULL;
170*8fb009dcSAndroid Build Coastguard Worker   }
171*8fb009dcSAndroid Build Coastguard Worker 
172*8fb009dcSAndroid Build Coastguard Worker   STACK_OF(X509_NAME_ENTRY) *sk = name->entries;
173*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY *ret = sk_X509_NAME_ENTRY_delete(sk, loc);
174*8fb009dcSAndroid Build Coastguard Worker   size_t n = sk_X509_NAME_ENTRY_num(sk);
175*8fb009dcSAndroid Build Coastguard Worker   name->modified = 1;
176*8fb009dcSAndroid Build Coastguard Worker   if ((size_t)loc == n) {
177*8fb009dcSAndroid Build Coastguard Worker     return ret;
178*8fb009dcSAndroid Build Coastguard Worker   }
179*8fb009dcSAndroid Build Coastguard Worker 
180*8fb009dcSAndroid Build Coastguard Worker   int set_prev;
181*8fb009dcSAndroid Build Coastguard Worker   if (loc != 0) {
182*8fb009dcSAndroid Build Coastguard Worker     set_prev = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
183*8fb009dcSAndroid Build Coastguard Worker   } else {
184*8fb009dcSAndroid Build Coastguard Worker     set_prev = ret->set - 1;
185*8fb009dcSAndroid Build Coastguard Worker   }
186*8fb009dcSAndroid Build Coastguard Worker   int set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
187*8fb009dcSAndroid Build Coastguard Worker 
188*8fb009dcSAndroid Build Coastguard Worker   // If we removed a singleton RDN, update the RDN indices so they are
189*8fb009dcSAndroid Build Coastguard Worker   // consecutive again.
190*8fb009dcSAndroid Build Coastguard Worker   if (set_prev + 1 < set_next) {
191*8fb009dcSAndroid Build Coastguard Worker     for (size_t i = loc; i < n; i++) {
192*8fb009dcSAndroid Build Coastguard Worker       sk_X509_NAME_ENTRY_value(sk, i)->set--;
193*8fb009dcSAndroid Build Coastguard Worker     }
194*8fb009dcSAndroid Build Coastguard Worker   }
195*8fb009dcSAndroid Build Coastguard Worker   return ret;
196*8fb009dcSAndroid Build Coastguard Worker }
197*8fb009dcSAndroid Build Coastguard Worker 
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*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
199*8fb009dcSAndroid Build Coastguard Worker                                int type, const unsigned char *bytes,
200*8fb009dcSAndroid Build Coastguard Worker                                ossl_ssize_t len, int loc, int set) {
201*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY *ne =
202*8fb009dcSAndroid Build Coastguard Worker       X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
203*8fb009dcSAndroid Build Coastguard Worker   if (!ne) {
204*8fb009dcSAndroid Build Coastguard Worker     return 0;
205*8fb009dcSAndroid Build Coastguard Worker   }
206*8fb009dcSAndroid Build Coastguard Worker   int ret = X509_NAME_add_entry(name, ne, loc, set);
207*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY_free(ne);
208*8fb009dcSAndroid Build Coastguard Worker   return ret;
209*8fb009dcSAndroid Build Coastguard Worker }
210*8fb009dcSAndroid Build Coastguard Worker 
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*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
212*8fb009dcSAndroid Build Coastguard Worker                                const unsigned char *bytes, ossl_ssize_t len,
213*8fb009dcSAndroid Build Coastguard Worker                                int loc, int set) {
214*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY *ne =
215*8fb009dcSAndroid Build Coastguard Worker       X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
216*8fb009dcSAndroid Build Coastguard Worker   if (!ne) {
217*8fb009dcSAndroid Build Coastguard Worker     return 0;
218*8fb009dcSAndroid Build Coastguard Worker   }
219*8fb009dcSAndroid Build Coastguard Worker   int ret = X509_NAME_add_entry(name, ne, loc, set);
220*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY_free(ne);
221*8fb009dcSAndroid Build Coastguard Worker   return ret;
222*8fb009dcSAndroid Build Coastguard Worker }
223*8fb009dcSAndroid Build Coastguard Worker 
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*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
225*8fb009dcSAndroid Build Coastguard Worker                                const unsigned char *bytes, ossl_ssize_t len,
226*8fb009dcSAndroid Build Coastguard Worker                                int loc, int set) {
227*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY *ne =
228*8fb009dcSAndroid Build Coastguard Worker       X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
229*8fb009dcSAndroid Build Coastguard Worker   if (!ne) {
230*8fb009dcSAndroid Build Coastguard Worker     return 0;
231*8fb009dcSAndroid Build Coastguard Worker   }
232*8fb009dcSAndroid Build Coastguard Worker   int ret = X509_NAME_add_entry(name, ne, loc, set);
233*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY_free(ne);
234*8fb009dcSAndroid Build Coastguard Worker   return ret;
235*8fb009dcSAndroid Build Coastguard Worker }
236*8fb009dcSAndroid Build Coastguard Worker 
237*8fb009dcSAndroid Build Coastguard Worker // if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
238*8fb009dcSAndroid Build Coastguard Worker // guy we are about to stomp on.
X509_NAME_add_entry(X509_NAME * name,const X509_NAME_ENTRY * entry,int loc,int set)239*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *entry, int loc,
240*8fb009dcSAndroid Build Coastguard Worker                         int set) {
241*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY *new_name = NULL;
242*8fb009dcSAndroid Build Coastguard Worker   int i, inc;
243*8fb009dcSAndroid Build Coastguard Worker   STACK_OF(X509_NAME_ENTRY) *sk;
244*8fb009dcSAndroid Build Coastguard Worker 
245*8fb009dcSAndroid Build Coastguard Worker   if (name == NULL) {
246*8fb009dcSAndroid Build Coastguard Worker     return 0;
247*8fb009dcSAndroid Build Coastguard Worker   }
248*8fb009dcSAndroid Build Coastguard Worker   sk = name->entries;
249*8fb009dcSAndroid Build Coastguard Worker   int n = (int)sk_X509_NAME_ENTRY_num(sk);
250*8fb009dcSAndroid Build Coastguard Worker   if (loc > n) {
251*8fb009dcSAndroid Build Coastguard Worker     loc = n;
252*8fb009dcSAndroid Build Coastguard Worker   } else if (loc < 0) {
253*8fb009dcSAndroid Build Coastguard Worker     loc = n;
254*8fb009dcSAndroid Build Coastguard Worker   }
255*8fb009dcSAndroid Build Coastguard Worker 
256*8fb009dcSAndroid Build Coastguard Worker   inc = (set == 0);
257*8fb009dcSAndroid Build Coastguard Worker   name->modified = 1;
258*8fb009dcSAndroid Build Coastguard Worker 
259*8fb009dcSAndroid Build Coastguard Worker   if (set == -1) {
260*8fb009dcSAndroid Build Coastguard Worker     if (loc == 0) {
261*8fb009dcSAndroid Build Coastguard Worker       set = 0;
262*8fb009dcSAndroid Build Coastguard Worker       inc = 1;
263*8fb009dcSAndroid Build Coastguard Worker     } else {
264*8fb009dcSAndroid Build Coastguard Worker       set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
265*8fb009dcSAndroid Build Coastguard Worker     }
266*8fb009dcSAndroid Build Coastguard Worker   } else {  // if (set >= 0)
267*8fb009dcSAndroid Build Coastguard Worker 
268*8fb009dcSAndroid Build Coastguard Worker     if (loc >= n) {
269*8fb009dcSAndroid Build Coastguard Worker       if (loc != 0) {
270*8fb009dcSAndroid Build Coastguard Worker         set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
271*8fb009dcSAndroid Build Coastguard Worker       } else {
272*8fb009dcSAndroid Build Coastguard Worker         set = 0;
273*8fb009dcSAndroid Build Coastguard Worker       }
274*8fb009dcSAndroid Build Coastguard Worker     } else {
275*8fb009dcSAndroid Build Coastguard Worker       set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
276*8fb009dcSAndroid Build Coastguard Worker     }
277*8fb009dcSAndroid Build Coastguard Worker   }
278*8fb009dcSAndroid Build Coastguard Worker 
279*8fb009dcSAndroid Build Coastguard Worker   if ((new_name = X509_NAME_ENTRY_dup(entry)) == NULL) {
280*8fb009dcSAndroid Build Coastguard Worker     goto err;
281*8fb009dcSAndroid Build Coastguard Worker   }
282*8fb009dcSAndroid Build Coastguard Worker   new_name->set = set;
283*8fb009dcSAndroid Build Coastguard Worker   if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
284*8fb009dcSAndroid Build Coastguard Worker     goto err;
285*8fb009dcSAndroid Build Coastguard Worker   }
286*8fb009dcSAndroid Build Coastguard Worker   if (inc) {
287*8fb009dcSAndroid Build Coastguard Worker     n = (int)sk_X509_NAME_ENTRY_num(sk);
288*8fb009dcSAndroid Build Coastguard Worker     for (i = loc + 1; i < n; i++) {
289*8fb009dcSAndroid Build Coastguard Worker       sk_X509_NAME_ENTRY_value(sk, i)->set += 1;
290*8fb009dcSAndroid Build Coastguard Worker     }
291*8fb009dcSAndroid Build Coastguard Worker   }
292*8fb009dcSAndroid Build Coastguard Worker   return 1;
293*8fb009dcSAndroid Build Coastguard Worker err:
294*8fb009dcSAndroid Build Coastguard Worker   if (new_name != NULL) {
295*8fb009dcSAndroid Build Coastguard Worker     X509_NAME_ENTRY_free(new_name);
296*8fb009dcSAndroid Build Coastguard Worker   }
297*8fb009dcSAndroid Build Coastguard Worker   return 0;
298*8fb009dcSAndroid Build Coastguard Worker }
299*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY ** ne,const char * field,int type,const unsigned char * bytes,ossl_ssize_t len)300*8fb009dcSAndroid Build Coastguard Worker X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
301*8fb009dcSAndroid Build Coastguard Worker                                                const char *field, int type,
302*8fb009dcSAndroid Build Coastguard Worker                                                const unsigned char *bytes,
303*8fb009dcSAndroid Build Coastguard Worker                                                ossl_ssize_t len) {
304*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT *obj;
305*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY *nentry;
306*8fb009dcSAndroid Build Coastguard Worker 
307*8fb009dcSAndroid Build Coastguard Worker   obj = OBJ_txt2obj(field, 0);
308*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
309*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
310*8fb009dcSAndroid Build Coastguard Worker     ERR_add_error_data(2, "name=", field);
311*8fb009dcSAndroid Build Coastguard Worker     return NULL;
312*8fb009dcSAndroid Build Coastguard Worker   }
313*8fb009dcSAndroid Build Coastguard Worker   nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
314*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT_free(obj);
315*8fb009dcSAndroid Build Coastguard Worker   return nentry;
316*8fb009dcSAndroid Build Coastguard Worker }
317*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY ** ne,int nid,int type,const unsigned char * bytes,ossl_ssize_t len)318*8fb009dcSAndroid Build Coastguard Worker X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
319*8fb009dcSAndroid Build Coastguard Worker                                                int type,
320*8fb009dcSAndroid Build Coastguard Worker                                                const unsigned char *bytes,
321*8fb009dcSAndroid Build Coastguard Worker                                                ossl_ssize_t len) {
322*8fb009dcSAndroid Build Coastguard Worker   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
323*8fb009dcSAndroid Build Coastguard Worker   if (obj == NULL) {
324*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
325*8fb009dcSAndroid Build Coastguard Worker     return NULL;
326*8fb009dcSAndroid Build Coastguard Worker   }
327*8fb009dcSAndroid Build Coastguard Worker   return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
328*8fb009dcSAndroid Build Coastguard Worker }
329*8fb009dcSAndroid Build Coastguard Worker 
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*8fb009dcSAndroid Build Coastguard Worker X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
331*8fb009dcSAndroid Build Coastguard Worker                                                const ASN1_OBJECT *obj, int type,
332*8fb009dcSAndroid Build Coastguard Worker                                                const unsigned char *bytes,
333*8fb009dcSAndroid Build Coastguard Worker                                                ossl_ssize_t len) {
334*8fb009dcSAndroid Build Coastguard Worker   X509_NAME_ENTRY *ret;
335*8fb009dcSAndroid Build Coastguard Worker 
336*8fb009dcSAndroid Build Coastguard Worker   if ((ne == NULL) || (*ne == NULL)) {
337*8fb009dcSAndroid Build Coastguard Worker     if ((ret = X509_NAME_ENTRY_new()) == NULL) {
338*8fb009dcSAndroid Build Coastguard Worker       return NULL;
339*8fb009dcSAndroid Build Coastguard Worker     }
340*8fb009dcSAndroid Build Coastguard Worker   } else {
341*8fb009dcSAndroid Build Coastguard Worker     ret = *ne;
342*8fb009dcSAndroid Build Coastguard Worker   }
343*8fb009dcSAndroid Build Coastguard Worker 
344*8fb009dcSAndroid Build Coastguard Worker   if (!X509_NAME_ENTRY_set_object(ret, obj)) {
345*8fb009dcSAndroid Build Coastguard Worker     goto err;
346*8fb009dcSAndroid Build Coastguard Worker   }
347*8fb009dcSAndroid Build Coastguard Worker   if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) {
348*8fb009dcSAndroid Build Coastguard Worker     goto err;
349*8fb009dcSAndroid Build Coastguard Worker   }
350*8fb009dcSAndroid Build Coastguard Worker 
351*8fb009dcSAndroid Build Coastguard Worker   if ((ne != NULL) && (*ne == NULL)) {
352*8fb009dcSAndroid Build Coastguard Worker     *ne = ret;
353*8fb009dcSAndroid Build Coastguard Worker   }
354*8fb009dcSAndroid Build Coastguard Worker   return ret;
355*8fb009dcSAndroid Build Coastguard Worker err:
356*8fb009dcSAndroid Build Coastguard Worker   if ((ne == NULL) || (ret != *ne)) {
357*8fb009dcSAndroid Build Coastguard Worker     X509_NAME_ENTRY_free(ret);
358*8fb009dcSAndroid Build Coastguard Worker   }
359*8fb009dcSAndroid Build Coastguard Worker   return NULL;
360*8fb009dcSAndroid Build Coastguard Worker }
361*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_ENTRY_set_object(X509_NAME_ENTRY * ne,const ASN1_OBJECT * obj)362*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) {
363*8fb009dcSAndroid Build Coastguard Worker   if ((ne == NULL) || (obj == NULL)) {
364*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
365*8fb009dcSAndroid Build Coastguard Worker     return 0;
366*8fb009dcSAndroid Build Coastguard Worker   }
367*8fb009dcSAndroid Build Coastguard Worker   ASN1_OBJECT_free(ne->object);
368*8fb009dcSAndroid Build Coastguard Worker   ne->object = OBJ_dup(obj);
369*8fb009dcSAndroid Build Coastguard Worker   return ((ne->object == NULL) ? 0 : 1);
370*8fb009dcSAndroid Build Coastguard Worker }
371*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_ENTRY_set_data(X509_NAME_ENTRY * ne,int type,const unsigned char * bytes,ossl_ssize_t len)372*8fb009dcSAndroid Build Coastguard Worker int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
373*8fb009dcSAndroid Build Coastguard Worker                              const unsigned char *bytes, ossl_ssize_t len) {
374*8fb009dcSAndroid Build Coastguard Worker   if ((ne == NULL) || ((bytes == NULL) && (len != 0))) {
375*8fb009dcSAndroid Build Coastguard Worker     return 0;
376*8fb009dcSAndroid Build Coastguard Worker   }
377*8fb009dcSAndroid Build Coastguard Worker   if ((type > 0) && (type & MBSTRING_FLAG)) {
378*8fb009dcSAndroid Build Coastguard Worker     return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type,
379*8fb009dcSAndroid Build Coastguard Worker                                   OBJ_obj2nid(ne->object))
380*8fb009dcSAndroid Build Coastguard Worker                ? 1
381*8fb009dcSAndroid Build Coastguard Worker                : 0;
382*8fb009dcSAndroid Build Coastguard Worker   }
383*8fb009dcSAndroid Build Coastguard Worker   if (len < 0) {
384*8fb009dcSAndroid Build Coastguard Worker     len = strlen((const char *)bytes);
385*8fb009dcSAndroid Build Coastguard Worker   }
386*8fb009dcSAndroid Build Coastguard Worker   if (!ASN1_STRING_set(ne->value, bytes, len)) {
387*8fb009dcSAndroid Build Coastguard Worker     return 0;
388*8fb009dcSAndroid Build Coastguard Worker   }
389*8fb009dcSAndroid Build Coastguard Worker   if (type != V_ASN1_UNDEF) {
390*8fb009dcSAndroid Build Coastguard Worker     ne->value->type = type;
391*8fb009dcSAndroid Build Coastguard Worker   }
392*8fb009dcSAndroid Build Coastguard Worker   return 1;
393*8fb009dcSAndroid Build Coastguard Worker }
394*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY * ne)395*8fb009dcSAndroid Build Coastguard Worker ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) {
396*8fb009dcSAndroid Build Coastguard Worker   if (ne == NULL) {
397*8fb009dcSAndroid Build Coastguard Worker     return NULL;
398*8fb009dcSAndroid Build Coastguard Worker   }
399*8fb009dcSAndroid Build Coastguard Worker   return ne->object;
400*8fb009dcSAndroid Build Coastguard Worker }
401*8fb009dcSAndroid Build Coastguard Worker 
X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY * ne)402*8fb009dcSAndroid Build Coastguard Worker ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) {
403*8fb009dcSAndroid Build Coastguard Worker   if (ne == NULL) {
404*8fb009dcSAndroid Build Coastguard Worker     return NULL;
405*8fb009dcSAndroid Build Coastguard Worker   }
406*8fb009dcSAndroid Build Coastguard Worker   return ne->value;
407*8fb009dcSAndroid Build Coastguard Worker }
408