1 /* 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (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 "internal/x509_int.h" 18 19 int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) 20 { 21 ASN1_OBJECT *obj; 22 23 obj = OBJ_nid2obj(nid); 24 if (obj == NULL) 25 return -1; 26 return X509_NAME_get_text_by_OBJ(name, obj, buf, len); 27 } 28 29 int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, 30 char *buf, int len) 31 { 32 int i; 33 const ASN1_STRING *data; 34 35 i = X509_NAME_get_index_by_OBJ(name, obj, -1); 36 if (i < 0) 37 return -1; 38 data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); 39 if (buf == NULL) 40 return data->length; 41 if (len <= 0) 42 return 0; 43 i = (data->length > (len - 1)) ? (len - 1) : data->length; 44 memcpy(buf, data->data, i); 45 buf[i] = '\0'; 46 return i; 47 } 48 49 int X509_NAME_entry_count(const X509_NAME *name) 50 { 51 if (name == NULL) 52 return 0; 53 return sk_X509_NAME_ENTRY_num(name->entries); 54 } 55 56 int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) 57 { 58 ASN1_OBJECT *obj; 59 60 obj = OBJ_nid2obj(nid); 61 if (obj == NULL) 62 return -2; 63 return X509_NAME_get_index_by_OBJ(name, obj, lastpos); 64 } 65 66 /* NOTE: you should be passing -1, not 0 as lastpos */ 67 int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int lastpos) 68 { 69 int n; 70 X509_NAME_ENTRY *ne; 71 STACK_OF(X509_NAME_ENTRY) *sk; 72 73 if (name == NULL) 74 return -1; 75 if (lastpos < 0) 76 lastpos = -1; 77 sk = name->entries; 78 n = sk_X509_NAME_ENTRY_num(sk); 79 for (lastpos++; lastpos < n; lastpos++) { 80 ne = sk_X509_NAME_ENTRY_value(sk, lastpos); 81 if (OBJ_cmp(ne->object, obj) == 0) 82 return lastpos; 83 } 84 return -1; 85 } 86 87 X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) 88 { 89 if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc 90 || loc < 0) 91 return NULL; 92 93 return sk_X509_NAME_ENTRY_value(name->entries, loc); 94 } 95 96 X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) 97 { 98 X509_NAME_ENTRY *ret; 99 int i, n, set_prev, set_next; 100 STACK_OF(X509_NAME_ENTRY) *sk; 101 102 if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc 103 || loc < 0) 104 return NULL; 105 106 sk = name->entries; 107 ret = sk_X509_NAME_ENTRY_delete(sk, loc); 108 n = sk_X509_NAME_ENTRY_num(sk); 109 name->modified = 1; 110 if (loc == n) 111 return ret; 112 113 /* else we need to fixup the set field */ 114 if (loc != 0) 115 set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; 116 else 117 set_prev = ret->set - 1; 118 set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; 119 120 /*- 121 * set_prev is the previous set 122 * set is the current set 123 * set_next is the following 124 * prev 1 1 1 1 1 1 1 1 125 * set 1 1 2 2 126 * next 1 1 2 2 2 2 3 2 127 * so basically only if prev and next differ by 2, then 128 * re-number down by 1 129 */ 130 if (set_prev + 1 < set_next) 131 for (i = loc; i < n; i++) 132 sk_X509_NAME_ENTRY_value(sk, i)->set--; 133 return ret; 134 } 135 136 int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, 137 const unsigned char *bytes, int len, int loc, 138 int set) 139 { 140 X509_NAME_ENTRY *ne; 141 int ret; 142 143 ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); 144 if (!ne) 145 return 0; 146 ret = X509_NAME_add_entry(name, ne, loc, set); 147 X509_NAME_ENTRY_free(ne); 148 return ret; 149 } 150 151 int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, 152 const unsigned char *bytes, int len, int loc, 153 int set) 154 { 155 X509_NAME_ENTRY *ne; 156 int ret; 157 ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); 158 if (!ne) 159 return 0; 160 ret = X509_NAME_add_entry(name, ne, loc, set); 161 X509_NAME_ENTRY_free(ne); 162 return ret; 163 } 164 165 int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, 166 const unsigned char *bytes, int len, int loc, 167 int set) 168 { 169 X509_NAME_ENTRY *ne; 170 int ret; 171 ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); 172 if (!ne) 173 return 0; 174 ret = X509_NAME_add_entry(name, ne, loc, set); 175 X509_NAME_ENTRY_free(ne); 176 return ret; 177 } 178 179 /* 180 * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the 181 * guy we are about to stomp on. 182 */ 183 int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, 184 int set) 185 { 186 X509_NAME_ENTRY *new_name = NULL; 187 int n, i, inc; 188 STACK_OF(X509_NAME_ENTRY) *sk; 189 190 if (name == NULL) 191 return 0; 192 sk = name->entries; 193 n = sk_X509_NAME_ENTRY_num(sk); 194 if (loc > n) 195 loc = n; 196 else if (loc < 0) 197 loc = n; 198 inc = (set == 0); 199 name->modified = 1; 200 201 if (set == -1) { 202 if (loc == 0) { 203 set = 0; 204 inc = 1; 205 } else { 206 set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; 207 } 208 } else { /* if (set >= 0) */ 209 210 if (loc >= n) { 211 if (loc != 0) 212 set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; 213 else 214 set = 0; 215 } else 216 set = sk_X509_NAME_ENTRY_value(sk, loc)->set; 217 } 218 219 /* 220 * X509_NAME_ENTRY_dup is ASN1 generated code, that can't be easily 221 * const'ified; harmless cast since dup() don't modify its input. 222 */ 223 if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL) 224 goto err; 225 new_name->set = set; 226 if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { 227 X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE); 228 goto err; 229 } 230 if (inc) { 231 n = sk_X509_NAME_ENTRY_num(sk); 232 for (i = loc + 1; i < n; i++) 233 sk_X509_NAME_ENTRY_value(sk, i)->set += 1; 234 } 235 return 1; 236 err: 237 X509_NAME_ENTRY_free(new_name); 238 return 0; 239 } 240 241 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, 242 const char *field, int type, 243 const unsigned char *bytes, 244 int len) 245 { 246 ASN1_OBJECT *obj; 247 X509_NAME_ENTRY *nentry; 248 249 obj = OBJ_txt2obj(field, 0); 250 if (obj == NULL) { 251 X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, 252 X509_R_INVALID_FIELD_NAME); 253 ERR_add_error_data(2, "name=", 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 X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, 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 X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT, 310 ERR_R_PASSED_NULL_PARAMETER); 311 return 0; 312 } 313 ASN1_OBJECT_free(ne->object); 314 ne->object = OBJ_dup(obj); 315 return ((ne->object == NULL) ? 0 : 1); 316 } 317 318 int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, 319 const unsigned char *bytes, int len) 320 { 321 int i; 322 323 if ((ne == NULL) || ((bytes == NULL) && (len != 0))) 324 return 0; 325 if ((type > 0) && (type & MBSTRING_FLAG)) 326 return ASN1_STRING_set_by_NID(&ne->value, bytes, 327 len, type, 328 OBJ_obj2nid(ne->object)) ? 1 : 0; 329 if (len < 0) 330 len = strlen((const char *)bytes); 331 i = ASN1_STRING_set(ne->value, bytes, len); 332 if (!i) 333 return 0; 334 if (type != V_ASN1_UNDEF) { 335 if (type == V_ASN1_APP_CHOOSE) 336 ne->value->type = ASN1_PRINTABLE_type(bytes, len); 337 else 338 ne->value->type = type; 339 } 340 return 1; 341 } 342 343 ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) 344 { 345 if (ne == NULL) 346 return NULL; 347 return ne->object; 348 } 349 350 ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) 351 { 352 if (ne == NULL) 353 return NULL; 354 return ne->value; 355 } 356 357 int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) 358 { 359 return ne->set; 360 } 361