1 /* 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/safestack.h> 13 #include <openssl/asn1.h> 14 #include <openssl/objects.h> 15 #include <openssl/evp.h> 16 #include <openssl/x509.h> 17 #include "crypto/x509.h" 18 19 int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, 20 char *buf, int len) 21 { 22 ASN1_OBJECT *obj; 23 24 obj = OBJ_nid2obj(nid); 25 if (obj == NULL) 26 return -1; 27 return X509_NAME_get_text_by_OBJ(name, obj, buf, len); 28 } 29 30 int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, 31 char *buf, int len) 32 { 33 int i; 34 const ASN1_STRING *data; 35 36 i = X509_NAME_get_index_by_OBJ(name, obj, -1); 37 if (i < 0) 38 return -1; 39 data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); 40 if (buf == NULL) 41 return data->length; 42 if (len <= 0) 43 return 0; 44 i = (data->length > (len - 1)) ? (len - 1) : data->length; 45 memcpy(buf, data->data, i); 46 buf[i] = '\0'; 47 return i; 48 } 49 50 int X509_NAME_entry_count(const X509_NAME *name) 51 { 52 int ret; 53 54 if (name == NULL) 55 return 0; 56 ret = sk_X509_NAME_ENTRY_num(name->entries); 57 return ret > 0 ? ret : 0; 58 } 59 60 int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos) 61 { 62 ASN1_OBJECT *obj; 63 64 obj = OBJ_nid2obj(nid); 65 if (obj == NULL) 66 return -2; 67 return X509_NAME_get_index_by_OBJ(name, obj, lastpos); 68 } 69 70 /* NOTE: you should be passing -1, not 0 as lastpos */ 71 int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, 72 int lastpos) 73 { 74 int n; 75 X509_NAME_ENTRY *ne; 76 STACK_OF(X509_NAME_ENTRY) *sk; 77 78 if (name == NULL) 79 return -1; 80 if (lastpos < 0) 81 lastpos = -1; 82 sk = name->entries; 83 n = sk_X509_NAME_ENTRY_num(sk); 84 for (lastpos++; lastpos < n; lastpos++) { 85 ne = sk_X509_NAME_ENTRY_value(sk, lastpos); 86 if (OBJ_cmp(ne->object, obj) == 0) 87 return lastpos; 88 } 89 return -1; 90 } 91 92 X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) 93 { 94 if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc 95 || loc < 0) 96 return NULL; 97 98 return sk_X509_NAME_ENTRY_value(name->entries, loc); 99 } 100 101 X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) 102 { 103 X509_NAME_ENTRY *ret; 104 int i, n, set_prev, set_next; 105 STACK_OF(X509_NAME_ENTRY) *sk; 106 107 if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc 108 || loc < 0) 109 return NULL; 110 111 sk = name->entries; 112 ret = sk_X509_NAME_ENTRY_delete(sk, loc); 113 n = sk_X509_NAME_ENTRY_num(sk); 114 name->modified = 1; 115 if (loc == n) 116 return ret; 117 118 /* else we need to fixup the set field */ 119 if (loc != 0) 120 set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; 121 else 122 set_prev = ret->set - 1; 123 set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; 124 125 /*- 126 * set_prev is the previous set 127 * set is the current set 128 * set_next is the following 129 * prev 1 1 1 1 1 1 1 1 130 * set 1 1 2 2 131 * next 1 1 2 2 2 2 3 2 132 * so basically only if prev and next differ by 2, then 133 * re-number down by 1 134 */ 135 if (set_prev + 1 < set_next) 136 for (i = loc; i < n; i++) 137 sk_X509_NAME_ENTRY_value(sk, i)->set--; 138 return ret; 139 } 140 141 int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, 142 const unsigned char *bytes, int len, int loc, 143 int set) 144 { 145 X509_NAME_ENTRY *ne; 146 int ret; 147 148 ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); 149 if (!ne) 150 return 0; 151 ret = X509_NAME_add_entry(name, ne, loc, set); 152 X509_NAME_ENTRY_free(ne); 153 return ret; 154 } 155 156 int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, 157 const unsigned char *bytes, int len, int loc, 158 int set) 159 { 160 X509_NAME_ENTRY *ne; 161 int ret; 162 ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); 163 if (!ne) 164 return 0; 165 ret = X509_NAME_add_entry(name, ne, loc, set); 166 X509_NAME_ENTRY_free(ne); 167 return ret; 168 } 169 170 int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, 171 const unsigned char *bytes, int len, int loc, 172 int set) 173 { 174 X509_NAME_ENTRY *ne; 175 int ret; 176 ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); 177 if (!ne) 178 return 0; 179 ret = X509_NAME_add_entry(name, ne, loc, set); 180 X509_NAME_ENTRY_free(ne); 181 return ret; 182 } 183 184 /* 185 * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the 186 * guy we are about to stomp on. 187 */ 188 int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, 189 int set) 190 { 191 X509_NAME_ENTRY *new_name = NULL; 192 int n, i, inc; 193 STACK_OF(X509_NAME_ENTRY) *sk; 194 195 if (name == NULL) 196 return 0; 197 sk = name->entries; 198 n = sk_X509_NAME_ENTRY_num(sk); 199 if (loc > n) 200 loc = n; 201 else if (loc < 0) 202 loc = n; 203 inc = (set == 0); 204 name->modified = 1; 205 206 if (set == -1) { 207 if (loc == 0) { 208 set = 0; 209 inc = 1; 210 } else { 211 set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; 212 } 213 } else { /* if (set >= 0) */ 214 215 if (loc >= n) { 216 if (loc != 0) 217 set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; 218 else 219 set = 0; 220 } else 221 set = sk_X509_NAME_ENTRY_value(sk, loc)->set; 222 } 223 224 if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) 225 goto err; 226 new_name->set = set; 227 if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { 228 ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 229 goto err; 230 } 231 if (inc) { 232 n = sk_X509_NAME_ENTRY_num(sk); 233 for (i = loc + 1; i < n; i++) 234 sk_X509_NAME_ENTRY_value(sk, i)->set += 1; 235 } 236 return 1; 237 err: 238 X509_NAME_ENTRY_free(new_name); 239 return 0; 240 } 241 242 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, 243 const char *field, int type, 244 const unsigned char *bytes, 245 int len) 246 { 247 ASN1_OBJECT *obj; 248 X509_NAME_ENTRY *nentry; 249 250 obj = OBJ_txt2obj(field, 0); 251 if (obj == NULL) { 252 ERR_raise_data(ERR_LIB_X509, X509_R_INVALID_FIELD_NAME, 253 "name=%s", field); 254 return NULL; 255 } 256 nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); 257 ASN1_OBJECT_free(obj); 258 return nentry; 259 } 260 261 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, 262 int type, 263 const unsigned char *bytes, 264 int len) 265 { 266 ASN1_OBJECT *obj; 267 X509_NAME_ENTRY *nentry; 268 269 obj = OBJ_nid2obj(nid); 270 if (obj == NULL) { 271 ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID); 272 return NULL; 273 } 274 nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); 275 ASN1_OBJECT_free(obj); 276 return nentry; 277 } 278 279 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, 280 const ASN1_OBJECT *obj, int type, 281 const unsigned char *bytes, 282 int len) 283 { 284 X509_NAME_ENTRY *ret; 285 286 if ((ne == NULL) || (*ne == NULL)) { 287 if ((ret = X509_NAME_ENTRY_new()) == NULL) 288 return NULL; 289 } else 290 ret = *ne; 291 292 if (!X509_NAME_ENTRY_set_object(ret, obj)) 293 goto err; 294 if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) 295 goto err; 296 297 if ((ne != NULL) && (*ne == NULL)) 298 *ne = ret; 299 return ret; 300 err: 301 if ((ne == NULL) || (ret != *ne)) 302 X509_NAME_ENTRY_free(ret); 303 return NULL; 304 } 305 306 int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) 307 { 308 if ((ne == NULL) || (obj == NULL)) { 309 ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); 310 return 0; 311 } 312 ASN1_OBJECT_free(ne->object); 313 ne->object = OBJ_dup(obj); 314 return ((ne->object == NULL) ? 0 : 1); 315 } 316 317 int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, 318 const unsigned char *bytes, int len) 319 { 320 int i; 321 322 if ((ne == NULL) || ((bytes == NULL) && (len != 0))) 323 return 0; 324 if ((type > 0) && (type & MBSTRING_FLAG)) 325 return ASN1_STRING_set_by_NID(&ne->value, bytes, 326 len, type, 327 OBJ_obj2nid(ne->object)) ? 1 : 0; 328 if (len < 0) 329 len = strlen((const char *)bytes); 330 i = ASN1_STRING_set(ne->value, bytes, len); 331 if (!i) 332 return 0; 333 if (type != V_ASN1_UNDEF) { 334 if (type == V_ASN1_APP_CHOOSE) 335 ne->value->type = ASN1_PRINTABLE_type(bytes, len); 336 else 337 ne->value->type = type; 338 } 339 return 1; 340 } 341 342 ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) 343 { 344 if (ne == NULL) 345 return NULL; 346 return ne->object; 347 } 348 349 ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) 350 { 351 if (ne == NULL) 352 return NULL; 353 return ne->value; 354 } 355 356 int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) 357 { 358 return ne->set; 359 } 360