Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/x509/x509name.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/x509/x509name.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 <openssl/stack.h>
61
#include "cryptlib.h"
62
#include <openssl/asn1.h>
63
#include <openssl/objects.h>
64
#include <openssl/evp.h>
65
#include <openssl/x509.h>
66
67
int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
68
0
{
69
0
    ASN1_OBJECT *obj;
70
71
0
    obj = OBJ_nid2obj(nid);
72
0
    if (obj == NULL)
73
0
        return (-1);
74
0
    return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
75
0
}
76
77
int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,
78
                              int len)
79
0
{
80
0
    int i;
81
0
    ASN1_STRING *data;
82
83
0
    i = X509_NAME_get_index_by_OBJ(name, obj, -1);
84
0
    if (i < 0)
85
0
        return (-1);
86
0
    data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
87
0
    i = (data->length > (len - 1)) ? (len - 1) : data->length;
88
0
    if (buf == NULL)
89
0
        return (data->length);
90
0
    memcpy(buf, data->data, i);
91
0
    buf[i] = '\0';
92
0
    return (i);
93
0
}
94
95
int X509_NAME_entry_count(X509_NAME *name)
96
0
{
97
0
    if (name == NULL)
98
0
        return (0);
99
0
    return (sk_X509_NAME_ENTRY_num(name->entries));
100
0
}
101
102
int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
103
0
{
104
0
    ASN1_OBJECT *obj;
105
106
0
    obj = OBJ_nid2obj(nid);
107
0
    if (obj == NULL)
108
0
        return (-2);
109
0
    return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
110
0
}
111
112
/* NOTE: you should be passsing -1, not 0 as lastpos */
113
int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos)
114
0
{
115
0
    int n;
116
0
    X509_NAME_ENTRY *ne;
117
0
    STACK_OF(X509_NAME_ENTRY) *sk;
118
119
0
    if (name == NULL)
120
0
        return (-1);
121
0
    if (lastpos < 0)
122
0
        lastpos = -1;
123
0
    sk = name->entries;
124
0
    n = sk_X509_NAME_ENTRY_num(sk);
125
0
    for (lastpos++; lastpos < n; lastpos++) {
126
0
        ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
127
0
        if (OBJ_cmp(ne->object, obj) == 0)
128
0
            return (lastpos);
129
0
    }
130
0
    return (-1);
131
0
}
132
133
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
134
0
{
135
0
    if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
136
0
        || loc < 0)
137
0
        return (NULL);
138
0
    else
139
0
        return (sk_X509_NAME_ENTRY_value(name->entries, loc));
140
0
}
141
142
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
143
0
{
144
0
    X509_NAME_ENTRY *ret;
145
0
    int i, n, set_prev, set_next;
146
0
    STACK_OF(X509_NAME_ENTRY) *sk;
147
148
0
    if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
149
0
        || loc < 0)
150
0
        return (NULL);
151
0
    sk = name->entries;
152
0
    ret = sk_X509_NAME_ENTRY_delete(sk, loc);
153
0
    n = sk_X509_NAME_ENTRY_num(sk);
154
0
    name->modified = 1;
155
0
    if (loc == n)
156
0
        return (ret);
157
158
    /* else we need to fixup the set field */
159
0
    if (loc != 0)
160
0
        set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
161
0
    else
162
0
        set_prev = ret->set - 1;
163
0
    set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
164
165
    /*-
166
     * set_prev is the previous set
167
     * set is the current set
168
     * set_next is the following
169
     * prev  1 1    1 1     1 1     1 1
170
     * set   1      1       2       2
171
     * next  1 1    2 2     2 2     3 2
172
     * so basically only if prev and next differ by 2, then
173
     * re-number down by 1
174
     */
175
0
    if (set_prev + 1 < set_next)
176
0
        for (i = loc; i < n; i++)
177
0
            sk_X509_NAME_ENTRY_value(sk, i)->set--;
178
0
    return (ret);
179
0
}
180
181
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
182
                               unsigned char *bytes, int len, int loc,
183
                               int set)
184
0
{
185
0
    X509_NAME_ENTRY *ne;
186
0
    int ret;
187
0
    ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
188
0
    if (!ne)
189
0
        return 0;
190
0
    ret = X509_NAME_add_entry(name, ne, loc, set);
191
0
    X509_NAME_ENTRY_free(ne);
192
0
    return ret;
193
0
}
194
195
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
196
                               unsigned char *bytes, int len, int loc,
197
                               int set)
198
0
{
199
0
    X509_NAME_ENTRY *ne;
200
0
    int ret;
201
0
    ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
202
0
    if (!ne)
203
0
        return 0;
204
0
    ret = X509_NAME_add_entry(name, ne, loc, set);
205
0
    X509_NAME_ENTRY_free(ne);
206
0
    return ret;
207
0
}
208
209
int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
210
                               const unsigned char *bytes, int len, int loc,
211
                               int set)
212
0
{
213
0
    X509_NAME_ENTRY *ne;
214
0
    int ret;
215
0
    ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
216
0
    if (!ne)
217
0
        return 0;
218
0
    ret = X509_NAME_add_entry(name, ne, loc, set);
219
0
    X509_NAME_ENTRY_free(ne);
220
0
    return ret;
221
0
}
222
223
/*
224
 * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
225
 * guy we are about to stomp on.
226
 */
227
int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
228
                        int set)
229
0
{
230
0
    X509_NAME_ENTRY *new_name = NULL;
231
0
    int n, i, inc;
232
0
    STACK_OF(X509_NAME_ENTRY) *sk;
233
234
0
    if (name == NULL)
235
0
        return (0);
236
0
    sk = name->entries;
237
0
    n = sk_X509_NAME_ENTRY_num(sk);
238
0
    if (loc > n)
239
0
        loc = n;
240
0
    else if (loc < 0)
241
0
        loc = n;
242
243
0
    name->modified = 1;
244
245
0
    if (set == -1) {
246
0
        if (loc == 0) {
247
0
            set = 0;
248
0
            inc = 1;
249
0
        } else {
250
0
            set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
251
0
            inc = 0;
252
0
        }
253
0
    } else {                    /* if (set >= 0) */
254
255
0
        if (loc >= n) {
256
0
            if (loc != 0)
257
0
                set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
258
0
            else
259
0
                set = 0;
260
0
        } else
261
0
            set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
262
0
        inc = (set == 0) ? 1 : 0;
263
0
    }
264
265
0
    if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL)
266
0
        goto err;
267
0
    new_name->set = set;
268
0
    if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
269
0
        X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE);
270
0
        goto err;
271
0
    }
272
0
    if (inc) {
273
0
        n = sk_X509_NAME_ENTRY_num(sk);
274
0
        for (i = loc + 1; i < n; i++)
275
0
            sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1;
276
0
    }
277
0
    return (1);
278
0
 err:
279
0
    if (new_name != NULL)
280
0
        X509_NAME_ENTRY_free(new_name);
281
0
    return (0);
282
0
}
283
284
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
285
                                               const char *field, int type,
286
                                               const unsigned char *bytes,
287
                                               int len)
288
0
{
289
0
    ASN1_OBJECT *obj;
290
0
    X509_NAME_ENTRY *nentry;
291
292
0
    obj = OBJ_txt2obj(field, 0);
293
0
    if (obj == NULL) {
294
0
        X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
295
0
                X509_R_INVALID_FIELD_NAME);
296
0
        ERR_add_error_data(2, "name=", field);
297
0
        return (NULL);
298
0
    }
299
0
    nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
300
0
    ASN1_OBJECT_free(obj);
301
0
    return nentry;
302
0
}
303
304
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
305
                                               int type, unsigned char *bytes,
306
                                               int len)
307
0
{
308
0
    ASN1_OBJECT *obj;
309
0
    X509_NAME_ENTRY *nentry;
310
311
0
    obj = OBJ_nid2obj(nid);
312
0
    if (obj == NULL) {
313
0
        X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID);
314
0
        return (NULL);
315
0
    }
316
0
    nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
317
0
    ASN1_OBJECT_free(obj);
318
0
    return nentry;
319
0
}
320
321
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
322
                                               ASN1_OBJECT *obj, int type,
323
                                               const unsigned char *bytes,
324
                                               int len)
325
0
{
326
0
    X509_NAME_ENTRY *ret;
327
328
0
    if ((ne == NULL) || (*ne == NULL)) {
329
0
        if ((ret = X509_NAME_ENTRY_new()) == NULL)
330
0
            return (NULL);
331
0
    } else
332
0
        ret = *ne;
333
334
0
    if (!X509_NAME_ENTRY_set_object(ret, obj))
335
0
        goto err;
336
0
    if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
337
0
        goto err;
338
339
0
    if ((ne != NULL) && (*ne == NULL))
340
0
        *ne = ret;
341
0
    return (ret);
342
0
 err:
343
0
    if ((ne == NULL) || (ret != *ne))
344
0
        X509_NAME_ENTRY_free(ret);
345
0
    return (NULL);
346
0
}
347
348
int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj)
349
0
{
350
0
    if ((ne == NULL) || (obj == NULL)) {
351
0
        X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,
352
0
                ERR_R_PASSED_NULL_PARAMETER);
353
0
        return (0);
354
0
    }
355
0
    ASN1_OBJECT_free(ne->object);
356
0
    ne->object = OBJ_dup(obj);
357
0
    return ((ne->object == NULL) ? 0 : 1);
358
0
}
359
360
int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
361
                             const unsigned char *bytes, int len)
362
0
{
363
0
    int i;
364
365
0
    if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
366
0
        return (0);
367
0
    if ((type > 0) && (type & MBSTRING_FLAG))
368
0
        return ASN1_STRING_set_by_NID(&ne->value, bytes,
369
0
                                      len, type,
370
0
                                      OBJ_obj2nid(ne->object)) ? 1 : 0;
371
0
    if (len < 0)
372
0
        len = strlen((const char *)bytes);
373
0
    i = ASN1_STRING_set(ne->value, bytes, len);
374
0
    if (!i)
375
0
        return (0);
376
0
    if (type != V_ASN1_UNDEF) {
377
0
        if (type == V_ASN1_APP_CHOOSE)
378
0
            ne->value->type = ASN1_PRINTABLE_type(bytes, len);
379
0
        else
380
0
            ne->value->type = type;
381
0
    }
382
0
    return (1);
383
0
}
384
385
ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
386
0
{
387
0
    if (ne == NULL)
388
0
        return (NULL);
389
0
    return (ne->object);
390
0
}
391
392
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
393
0
{
394
0
    if (ne == NULL)
395
0
        return (NULL);
396
0
    return (ne->value);
397
0
}