1 /* 2 * X.509 base functions for creating certificates / CSRs 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 */ 7 8 #include "common.h" 9 10 #if defined(MBEDTLS_X509_CREATE_C) 11 12 #include "x509_internal.h" 13 #include "mbedtls/asn1write.h" 14 #include "mbedtls/error.h" 15 #include "mbedtls/oid.h" 16 17 #include <string.h> 18 19 #include "mbedtls/platform.h" 20 21 #include "mbedtls/asn1.h" 22 23 /* Structure linking OIDs for X.509 DN AttributeTypes to their 24 * string representations and default string encodings used by Mbed TLS. */ 25 typedef struct { 26 const char *name; /* String representation of AttributeType, e.g. 27 * "CN" or "emailAddress". */ 28 size_t name_len; /* Length of 'name', without trailing 0 byte. */ 29 const char *oid; /* String representation of OID of AttributeType, 30 * as per RFC 5280, Appendix A.1. encoded as per 31 * X.690 */ 32 int default_tag; /* The default character encoding used for the 33 * given attribute type, e.g. 34 * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */ 35 } x509_attr_descriptor_t; 36 37 #define ADD_STRLEN(s) s, sizeof(s) - 1 38 39 /* X.509 DN attributes from RFC 5280, Appendix A.1. */ 40 static const x509_attr_descriptor_t x509_attrs[] = 41 { 42 { ADD_STRLEN("CN"), 43 MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, 44 { ADD_STRLEN("commonName"), 45 MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, 46 { ADD_STRLEN("C"), 47 MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, 48 { ADD_STRLEN("countryName"), 49 MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, 50 { ADD_STRLEN("O"), 51 MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, 52 { ADD_STRLEN("organizationName"), 53 MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, 54 { ADD_STRLEN("L"), 55 MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, 56 { ADD_STRLEN("locality"), 57 MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, 58 { ADD_STRLEN("R"), 59 MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, 60 { ADD_STRLEN("OU"), 61 MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, 62 { ADD_STRLEN("organizationalUnitName"), 63 MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, 64 { ADD_STRLEN("ST"), 65 MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, 66 { ADD_STRLEN("stateOrProvinceName"), 67 MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, 68 { ADD_STRLEN("emailAddress"), 69 MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, 70 { ADD_STRLEN("serialNumber"), 71 MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING }, 72 { ADD_STRLEN("postalAddress"), 73 MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING }, 74 { ADD_STRLEN("postalCode"), 75 MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING }, 76 { ADD_STRLEN("dnQualifier"), 77 MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING }, 78 { ADD_STRLEN("title"), 79 MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING }, 80 { ADD_STRLEN("surName"), 81 MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, 82 { ADD_STRLEN("SN"), 83 MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, 84 { ADD_STRLEN("givenName"), 85 MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, 86 { ADD_STRLEN("GN"), 87 MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, 88 { ADD_STRLEN("initials"), 89 MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING }, 90 { ADD_STRLEN("pseudonym"), 91 MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING }, 92 { ADD_STRLEN("generationQualifier"), 93 MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING }, 94 { ADD_STRLEN("domainComponent"), 95 MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, 96 { ADD_STRLEN("DC"), 97 MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, 98 { NULL, 0, NULL, MBEDTLS_ASN1_NULL } 99 }; 100 101 static const x509_attr_descriptor_t *x509_attr_descr_from_name(const char *name, size_t name_len) 102 { 103 const x509_attr_descriptor_t *cur; 104 105 for (cur = x509_attrs; cur->name != NULL; cur++) { 106 if (cur->name_len == name_len && 107 strncmp(cur->name, name, name_len) == 0) { 108 break; 109 } 110 } 111 112 if (cur->name == NULL) { 113 return NULL; 114 } 115 116 return cur; 117 } 118 119 static int hex_to_int(char c) 120 { 121 return ('0' <= c && c <= '9') ? (c - '0') : 122 ('a' <= c && c <= 'f') ? (c - 'a' + 10) : 123 ('A' <= c && c <= 'F') ? (c - 'A' + 10) : -1; 124 } 125 126 static int hexpair_to_int(const char *hexpair) 127 { 128 int n1 = hex_to_int(*hexpair); 129 int n2 = hex_to_int(*(hexpair + 1)); 130 131 if (n1 != -1 && n2 != -1) { 132 return (n1 << 4) | n2; 133 } else { 134 return -1; 135 } 136 } 137 138 static int parse_attribute_value_string(const char *s, 139 int len, 140 unsigned char *data, 141 size_t *data_len) 142 { 143 const char *c; 144 const char *end = s + len; 145 unsigned char *d = data; 146 int n; 147 148 for (c = s; c < end; c++) { 149 if (*c == '\\') { 150 c++; 151 152 /* Check for valid escaped characters as per RFC 4514 Section 3 */ 153 if (c + 1 < end && (n = hexpair_to_int(c)) != -1) { 154 if (n == 0) { 155 return MBEDTLS_ERR_X509_INVALID_NAME; 156 } 157 *(d++) = n; 158 c++; 159 } else if (c < end && strchr(" ,=+<>#;\"\\", *c)) { 160 *(d++) = *c; 161 } else { 162 return MBEDTLS_ERR_X509_INVALID_NAME; 163 } 164 } else { 165 *(d++) = *c; 166 } 167 168 if (d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE) { 169 return MBEDTLS_ERR_X509_INVALID_NAME; 170 } 171 } 172 *data_len = (size_t) (d - data); 173 return 0; 174 } 175 176 /** Parse a hexstring containing a DER-encoded string. 177 * 178 * \param s A string of \p len bytes hexadecimal digits. 179 * \param len Number of bytes to read from \p s. 180 * \param data Output buffer of size \p data_size. 181 * On success, it contains the payload that's DER-encoded 182 * in the input (content without the tag and length). 183 * If the DER tag is a string tag, the payload is guaranteed 184 * not to contain null bytes. 185 * \param data_size Length of the \p data buffer. 186 * \param data_len On success, the length of the parsed string. 187 * It is guaranteed to be less than 188 * #MBEDTLS_X509_MAX_DN_NAME_SIZE. 189 * \param tag The ASN.1 tag that the payload in \p data is encoded in. 190 * 191 * \retval 0 on success. 192 * \retval #MBEDTLS_ERR_X509_INVALID_NAME if \p s does not contain 193 * a valid hexstring, 194 * or if the decoded hexstring is not valid DER, 195 * or if the payload does not fit in \p data, 196 * or if the payload is more than 197 * #MBEDTLS_X509_MAX_DN_NAME_SIZE bytes, 198 * of if \p *tag is an ASN.1 string tag and the payload 199 * contains a null byte. 200 * \retval #MBEDTLS_ERR_X509_ALLOC_FAILED on low memory. 201 */ 202 static int parse_attribute_value_hex_der_encoded(const char *s, 203 size_t len, 204 unsigned char *data, 205 size_t data_size, 206 size_t *data_len, 207 int *tag) 208 { 209 /* Step 1: preliminary length checks. */ 210 /* Each byte is encoded by exactly two hexadecimal digits. */ 211 if (len % 2 != 0) { 212 /* Odd number of hex digits */ 213 return MBEDTLS_ERR_X509_INVALID_NAME; 214 } 215 size_t const der_length = len / 2; 216 if (der_length > MBEDTLS_X509_MAX_DN_NAME_SIZE + 4) { 217 /* The payload would be more than MBEDTLS_X509_MAX_DN_NAME_SIZE 218 * (after subtracting the ASN.1 tag and length). Reject this early 219 * to avoid allocating a large intermediate buffer. */ 220 return MBEDTLS_ERR_X509_INVALID_NAME; 221 } 222 if (der_length < 1) { 223 /* Avoid empty-buffer shenanigans. A valid DER encoding is never 224 * empty. */ 225 return MBEDTLS_ERR_X509_INVALID_NAME; 226 } 227 228 /* Step 2: Decode the hex string into an intermediate buffer. */ 229 unsigned char *der = mbedtls_calloc(1, der_length); 230 if (der == NULL) { 231 return MBEDTLS_ERR_X509_ALLOC_FAILED; 232 } 233 /* Beyond this point, der needs to be freed on exit. */ 234 for (size_t i = 0; i < der_length; i++) { 235 int c = hexpair_to_int(s + 2 * i); 236 if (c < 0) { 237 goto error; 238 } 239 der[i] = c; 240 } 241 242 /* Step 3: decode the DER. */ 243 /* We've checked that der_length >= 1 above. */ 244 *tag = der[0]; 245 { 246 unsigned char *p = der + 1; 247 if (mbedtls_asn1_get_len(&p, der + der_length, data_len) != 0) { 248 goto error; 249 } 250 /* Now p points to the first byte of the payload inside der, 251 * and *data_len is the length of the payload. */ 252 253 /* Step 4: payload validation */ 254 if (*data_len > MBEDTLS_X509_MAX_DN_NAME_SIZE) { 255 goto error; 256 } 257 /* Strings must not contain null bytes. */ 258 if (MBEDTLS_ASN1_IS_STRING_TAG(*tag)) { 259 for (size_t i = 0; i < *data_len; i++) { 260 if (p[i] == 0) { 261 goto error; 262 } 263 } 264 } 265 266 /* Step 5: output the payload. */ 267 if (*data_len > data_size) { 268 goto error; 269 } 270 memcpy(data, p, *data_len); 271 } 272 mbedtls_free(der); 273 274 return 0; 275 276 error: 277 mbedtls_free(der); 278 return MBEDTLS_ERR_X509_INVALID_NAME; 279 } 280 281 int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name) 282 { 283 int ret = MBEDTLS_ERR_X509_INVALID_NAME; 284 int parse_ret = 0; 285 const char *s = name, *c = s; 286 const char *end = s + strlen(s); 287 mbedtls_asn1_buf oid = { .p = NULL, .len = 0, .tag = MBEDTLS_ASN1_NULL }; 288 const x509_attr_descriptor_t *attr_descr = NULL; 289 int in_attr_type = 1; 290 int tag; 291 int numericoid = 0; 292 unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; 293 size_t data_len = 0; 294 295 /* Ensure the output parameter is not already populated. 296 * (If it were, overwriting it would likely cause a memory leak.) 297 */ 298 if (*head != NULL) { 299 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 300 } 301 302 while (c <= end) { 303 if (in_attr_type && *c == '=') { 304 if ((attr_descr = x509_attr_descr_from_name(s, (size_t) (c - s))) == NULL) { 305 if ((mbedtls_oid_from_numeric_string(&oid, s, (size_t) (c - s))) != 0) { 306 return MBEDTLS_ERR_X509_INVALID_NAME; 307 } else { 308 numericoid = 1; 309 } 310 } else { 311 oid.len = strlen(attr_descr->oid); 312 oid.p = mbedtls_calloc(1, oid.len); 313 memcpy(oid.p, attr_descr->oid, oid.len); 314 numericoid = 0; 315 } 316 317 s = c + 1; 318 in_attr_type = 0; 319 } 320 321 if (!in_attr_type && ((*c == ',' && *(c-1) != '\\') || c == end)) { 322 if (s == c) { 323 mbedtls_free(oid.p); 324 return MBEDTLS_ERR_X509_INVALID_NAME; 325 } else if (*s == '#') { 326 /* We know that c >= s (loop invariant) and c != s (in this 327 * else branch), hence c - s - 1 >= 0. */ 328 parse_ret = parse_attribute_value_hex_der_encoded( 329 s + 1, (size_t) (c - s) - 1, 330 data, sizeof(data), &data_len, &tag); 331 if (parse_ret != 0) { 332 mbedtls_free(oid.p); 333 return parse_ret; 334 } 335 } else { 336 if (numericoid) { 337 mbedtls_free(oid.p); 338 return MBEDTLS_ERR_X509_INVALID_NAME; 339 } else { 340 if ((parse_ret = 341 parse_attribute_value_string(s, (int) (c - s), data, 342 &data_len)) != 0) { 343 mbedtls_free(oid.p); 344 return parse_ret; 345 } 346 tag = attr_descr->default_tag; 347 } 348 } 349 350 mbedtls_asn1_named_data *cur = 351 mbedtls_asn1_store_named_data(head, (char *) oid.p, oid.len, 352 (unsigned char *) data, 353 data_len); 354 mbedtls_free(oid.p); 355 oid.p = NULL; 356 if (cur == NULL) { 357 return MBEDTLS_ERR_X509_ALLOC_FAILED; 358 } 359 360 // set tagType 361 cur->val.tag = tag; 362 363 while (c < end && *(c + 1) == ' ') { 364 c++; 365 } 366 367 s = c + 1; 368 in_attr_type = 1; 369 370 /* Successfully parsed one name, update ret to success */ 371 ret = 0; 372 } 373 c++; 374 } 375 if (oid.p != NULL) { 376 mbedtls_free(oid.p); 377 } 378 return ret; 379 } 380 381 /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved 382 * to store the critical boolean for us 383 */ 384 int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, 385 int critical, const unsigned char *val, size_t val_len) 386 { 387 mbedtls_asn1_named_data *cur; 388 389 if (val_len > (SIZE_MAX - 1)) { 390 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 391 } 392 393 if ((cur = mbedtls_asn1_store_named_data(head, oid, oid_len, 394 NULL, val_len + 1)) == NULL) { 395 return MBEDTLS_ERR_X509_ALLOC_FAILED; 396 } 397 398 cur->val.p[0] = critical; 399 memcpy(cur->val.p + 1, val, val_len); 400 401 return 0; 402 } 403 404 /* 405 * RelativeDistinguishedName ::= 406 * SET OF AttributeTypeAndValue 407 * 408 * AttributeTypeAndValue ::= SEQUENCE { 409 * type AttributeType, 410 * value AttributeValue } 411 * 412 * AttributeType ::= OBJECT IDENTIFIER 413 * 414 * AttributeValue ::= ANY DEFINED BY AttributeType 415 */ 416 static int x509_write_name(unsigned char **p, 417 unsigned char *start, 418 mbedtls_asn1_named_data *cur_name) 419 { 420 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 421 size_t len = 0; 422 const char *oid = (const char *) cur_name->oid.p; 423 size_t oid_len = cur_name->oid.len; 424 const unsigned char *name = cur_name->val.p; 425 size_t name_len = cur_name->val.len; 426 427 // Write correct string tag and value 428 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tagged_string(p, start, 429 cur_name->val.tag, 430 (const char *) name, 431 name_len)); 432 // Write OID 433 // 434 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, 435 oid_len)); 436 437 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 438 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, 439 MBEDTLS_ASN1_CONSTRUCTED | 440 MBEDTLS_ASN1_SEQUENCE)); 441 442 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 443 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, 444 MBEDTLS_ASN1_CONSTRUCTED | 445 MBEDTLS_ASN1_SET)); 446 447 return (int) len; 448 } 449 450 int mbedtls_x509_write_names(unsigned char **p, unsigned char *start, 451 mbedtls_asn1_named_data *first) 452 { 453 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 454 size_t len = 0; 455 mbedtls_asn1_named_data *cur = first; 456 457 while (cur != NULL) { 458 MBEDTLS_ASN1_CHK_ADD(len, x509_write_name(p, start, cur)); 459 cur = cur->next; 460 } 461 462 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 463 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED | 464 MBEDTLS_ASN1_SEQUENCE)); 465 466 return (int) len; 467 } 468 469 int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start, 470 const char *oid, size_t oid_len, 471 unsigned char *sig, size_t size, 472 mbedtls_pk_type_t pk_alg) 473 { 474 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 475 int write_null_par; 476 size_t len = 0; 477 478 if (*p < start || (size_t) (*p - start) < size) { 479 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 480 } 481 482 len = size; 483 (*p) -= len; 484 memcpy(*p, sig, len); 485 486 if (*p - start < 1) { 487 return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 488 } 489 490 *--(*p) = 0; 491 len += 1; 492 493 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 494 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_BIT_STRING)); 495 496 // Write OID 497 // 498 if (pk_alg == MBEDTLS_PK_ECDSA) { 499 /* 500 * The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature 501 * algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and 502 * https://www.rfc-editor.org/rfc/rfc5758#section-3. 503 */ 504 write_null_par = 0; 505 } else { 506 write_null_par = 1; 507 } 508 MBEDTLS_ASN1_CHK_ADD(len, 509 mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, 510 0, write_null_par)); 511 512 return (int) len; 513 } 514 515 static int x509_write_extension(unsigned char **p, unsigned char *start, 516 mbedtls_asn1_named_data *ext) 517 { 518 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 519 size_t len = 0; 520 521 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, ext->val.p + 1, 522 ext->val.len - 1)); 523 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, ext->val.len - 1)); 524 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_OCTET_STRING)); 525 526 if (ext->val.p[0] != 0) { 527 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_bool(p, start, 1)); 528 } 529 530 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, ext->oid.p, 531 ext->oid.len)); 532 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, ext->oid.len)); 533 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_OID)); 534 535 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 536 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED | 537 MBEDTLS_ASN1_SEQUENCE)); 538 539 return (int) len; 540 } 541 542 /* 543 * Extension ::= SEQUENCE { 544 * extnID OBJECT IDENTIFIER, 545 * critical BOOLEAN DEFAULT FALSE, 546 * extnValue OCTET STRING 547 * -- contains the DER encoding of an ASN.1 value 548 * -- corresponding to the extension type identified 549 * -- by extnID 550 * } 551 */ 552 int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start, 553 mbedtls_asn1_named_data *first) 554 { 555 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 556 size_t len = 0; 557 mbedtls_asn1_named_data *cur_ext = first; 558 559 while (cur_ext != NULL) { 560 MBEDTLS_ASN1_CHK_ADD(len, x509_write_extension(p, start, cur_ext)); 561 cur_ext = cur_ext->next; 562 } 563 564 return (int) len; 565 } 566 567 #endif /* MBEDTLS_X509_CREATE_C */ 568