diff options
| author | beck <> | 2022-11-11 12:02:34 +0000 |
|---|---|---|
| committer | beck <> | 2022-11-11 12:02:34 +0000 |
| commit | fadbfece8693f0ef4e461242a68e499a8580c324 (patch) | |
| tree | 0a9a1c7b34e523947e5dbb8897374c8c5c2fec2d /src | |
| parent | fd62f2b8865d2908f2ef9a53dcd73faa76f153c3 (diff) | |
| download | openbsd-fadbfece8693f0ef4e461242a68e499a8580c324.tar.gz openbsd-fadbfece8693f0ef4e461242a68e499a8580c324.tar.bz2 openbsd-fadbfece8693f0ef4e461242a68e499a8580c324.zip | |
Start CBS-ifying the name constraints code.
ok jsing@ tb@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_alt.c | 8 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_constraints.c | 230 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_internal.h | 12 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/x509/Makefile | 3 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/x509/constraints.c | 83 |
5 files changed, 198 insertions, 138 deletions
diff --git a/src/lib/libcrypto/x509/x509_alt.c b/src/lib/libcrypto/x509/x509_alt.c index 8656df82b3..cf8cbf0ce2 100644 --- a/src/lib/libcrypto/x509/x509_alt.c +++ b/src/lib/libcrypto/x509/x509_alt.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_alt.c,v 1.12 2022/03/26 16:34:21 tb Exp $ */ | 1 | /* $OpenBSD: x509_alt.c,v 1.13 2022/11/11 12:02:34 beck Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project. | 3 | * project. |
| 4 | */ | 4 | */ |
| @@ -619,6 +619,7 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, | |||
| 619 | GENERAL_NAME *ret; | 619 | GENERAL_NAME *ret; |
| 620 | size_t len = 0; | 620 | size_t len = 0; |
| 621 | int type; | 621 | int type; |
| 622 | CBS cbs; | ||
| 622 | 623 | ||
| 623 | name = cnf->name; | 624 | name = cnf->name; |
| 624 | value = cnf->value; | 625 | value = cnf->value; |
| @@ -669,9 +670,10 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, | |||
| 669 | } | 670 | } |
| 670 | 671 | ||
| 671 | type = x509_constraints_general_to_bytes(ret, &bytes, &len); | 672 | type = x509_constraints_general_to_bytes(ret, &bytes, &len); |
| 673 | CBS_init(&cbs, bytes, len); | ||
| 672 | switch (type) { | 674 | switch (type) { |
| 673 | case GEN_DNS: | 675 | case GEN_DNS: |
| 674 | if (!x509_constraints_valid_sandns(bytes, len)) { | 676 | if (!x509_constraints_valid_sandns(&cbs)) { |
| 675 | X509V3error(X509V3_R_BAD_OBJECT); | 677 | X509V3error(X509V3_R_BAD_OBJECT); |
| 676 | ERR_asprintf_error_data("name=%s value='%.*s'", name, | 678 | ERR_asprintf_error_data("name=%s value='%.*s'", name, |
| 677 | (int)len, bytes); | 679 | (int)len, bytes); |
| @@ -687,7 +689,7 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, | |||
| 687 | } | 689 | } |
| 688 | break; | 690 | break; |
| 689 | case GEN_EMAIL: | 691 | case GEN_EMAIL: |
| 690 | if (!x509_constraints_parse_mailbox(bytes, len, NULL)) { | 692 | if (!x509_constraints_parse_mailbox(&cbs, NULL)) { |
| 691 | X509V3error(X509V3_R_BAD_OBJECT); | 693 | X509V3error(X509V3_R_BAD_OBJECT); |
| 692 | ERR_asprintf_error_data("name=%s value='%.*s'", name, | 694 | ERR_asprintf_error_data("name=%s value='%.*s'", name, |
| 693 | (int)len, bytes); | 695 | (int)len, bytes); |
diff --git a/src/lib/libcrypto/x509/x509_constraints.c b/src/lib/libcrypto/x509/x509_constraints.c index 8cd8413dfa..e0560c1578 100644 --- a/src/lib/libcrypto/x509/x509_constraints.c +++ b/src/lib/libcrypto/x509/x509_constraints.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_constraints.c,v 1.28 2022/06/27 15:03:11 beck Exp $ */ | 1 | /* $OpenBSD: x509_constraints.c,v 1.29 2022/11/11 12:02:34 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -29,11 +29,33 @@ | |||
| 29 | #include <openssl/x509.h> | 29 | #include <openssl/x509.h> |
| 30 | #include <openssl/x509v3.h> | 30 | #include <openssl/x509v3.h> |
| 31 | 31 | ||
| 32 | #include "bytestring.h" | ||
| 32 | #include "x509_internal.h" | 33 | #include "x509_internal.h" |
| 33 | 34 | ||
| 34 | /* RFC 2821 section 4.5.3.1 */ | 35 | /* RFC 2821 section 4.5.3.1 */ |
| 35 | #define LOCAL_PART_MAX_LEN 64 | 36 | #define LOCAL_PART_MAX_LEN (size_t)64 |
| 36 | #define DOMAIN_PART_MAX_LEN 255 | 37 | #define DOMAIN_PART_MAX_LEN (size_t)255 |
| 38 | #define MAX_IP_ADDRESS_LENGTH (size_t)46 | ||
| 39 | |||
| 40 | static int | ||
| 41 | cbs_is_ip_address(CBS *cbs) | ||
| 42 | { | ||
| 43 | struct sockaddr_in6 sin6; | ||
| 44 | struct sockaddr_in sin4; | ||
| 45 | char *name = NULL; | ||
| 46 | int ret = 0; | ||
| 47 | |||
| 48 | if (CBS_len(cbs) > MAX_IP_ADDRESS_LENGTH) | ||
| 49 | return 0; | ||
| 50 | if (!CBS_strdup(cbs, &name)) | ||
| 51 | return 0; | ||
| 52 | if (inet_pton(AF_INET, name, &sin4) == 1 || | ||
| 53 | inet_pton(AF_INET6, name, &sin6) == 1) | ||
| 54 | ret = 1; | ||
| 55 | |||
| 56 | free(name); | ||
| 57 | return ret; | ||
| 58 | } | ||
| 37 | 59 | ||
| 38 | struct x509_constraints_name * | 60 | struct x509_constraints_name * |
| 39 | x509_constraints_name_new(void) | 61 | x509_constraints_name_new(void) |
| @@ -165,7 +187,6 @@ x509_constraints_names_dup(struct x509_constraints_names *names) | |||
| 165 | return NULL; | 187 | return NULL; |
| 166 | } | 188 | } |
| 167 | 189 | ||
| 168 | |||
| 169 | /* | 190 | /* |
| 170 | * Validate that the name contains only a hostname consisting of RFC | 191 | * Validate that the name contains only a hostname consisting of RFC |
| 171 | * 5890 compliant A-labels (see RFC 6066 section 3). This is more | 192 | * 5890 compliant A-labels (see RFC 6066 section 3). This is more |
| @@ -177,19 +198,23 @@ x509_constraints_names_dup(struct x509_constraints_names *names) | |||
| 177 | * component. | 198 | * component. |
| 178 | */ | 199 | */ |
| 179 | static int | 200 | static int |
| 180 | x509_constraints_valid_domain_internal(uint8_t *name, size_t len, int wildcards) | 201 | x509_constraints_valid_domain_internal(CBS *cbs, int wildcards) |
| 181 | { | 202 | { |
| 203 | int first, component = 0; | ||
| 182 | uint8_t prev, c = 0; | 204 | uint8_t prev, c = 0; |
| 183 | int component = 0; | 205 | size_t i, len; |
| 184 | int first; | 206 | CBS copy; |
| 185 | size_t i; | 207 | |
| 208 | CBS_dup(cbs, ©); | ||
| 209 | |||
| 210 | len = CBS_len(cbs); | ||
| 186 | 211 | ||
| 187 | if (len > DOMAIN_PART_MAX_LEN) | 212 | if (len > DOMAIN_PART_MAX_LEN) |
| 188 | return 0; | 213 | return 0; |
| 189 | |||
| 190 | for (i = 0; i < len; i++) { | 214 | for (i = 0; i < len; i++) { |
| 191 | prev = c; | 215 | prev = c; |
| 192 | c = name[i]; | 216 | if (!CBS_get_u8(©, &c)) |
| 217 | return 0; | ||
| 193 | 218 | ||
| 194 | first = (i == 0); | 219 | first = (i == 0); |
| 195 | 220 | ||
| @@ -234,61 +259,42 @@ x509_constraints_valid_domain_internal(uint8_t *name, size_t len, int wildcards) | |||
| 234 | if (++component > 63) | 259 | if (++component > 63) |
| 235 | return 0; | 260 | return 0; |
| 236 | } | 261 | } |
| 262 | |||
| 237 | return 1; | 263 | return 1; |
| 238 | } | 264 | } |
| 239 | 265 | ||
| 240 | int | 266 | int |
| 241 | x509_constraints_valid_domain(uint8_t *name, size_t len) | 267 | x509_constraints_valid_host(CBS *cbs) |
| 242 | { | 268 | { |
| 243 | if (len == 0) | 269 | uint8_t first; |
| 244 | return 0; | ||
| 245 | /* | ||
| 246 | * A domain may not be less than two characters, so you can't | ||
| 247 | * have a require subdomain name with less than that. | ||
| 248 | */ | ||
| 249 | if (len < 3 && name[0] == '.') | ||
| 250 | return 0; | ||
| 251 | return x509_constraints_valid_domain_internal(name, len, 0); | ||
| 252 | } | ||
| 253 | 270 | ||
| 254 | int | 271 | if (!CBS_peek_u8(cbs, &first)) |
| 255 | x509_constraints_valid_host(uint8_t *name, size_t len) | ||
| 256 | { | ||
| 257 | struct sockaddr_in sin4; | ||
| 258 | struct sockaddr_in6 sin6; | ||
| 259 | |||
| 260 | if (len == 0) | ||
| 261 | return 0; | ||
| 262 | if (name[0] == '.') /* leading . not allowed in a host name*/ | ||
| 263 | return 0; | 272 | return 0; |
| 264 | if (inet_pton(AF_INET, name, &sin4) == 1) | 273 | if (first == '.') |
| 274 | return 0; /* leading . not allowed in a host name */ | ||
| 275 | if (cbs_is_ip_address(cbs)) | ||
| 265 | return 0; | 276 | return 0; |
| 266 | if (inet_pton(AF_INET6, name, &sin6) == 1) | 277 | |
| 267 | return 0; | 278 | return x509_constraints_valid_domain_internal(cbs, 0); |
| 268 | return x509_constraints_valid_domain_internal(name, len, 0); | ||
| 269 | } | 279 | } |
| 270 | 280 | ||
| 271 | int | 281 | int |
| 272 | x509_constraints_valid_sandns(uint8_t *name, size_t len) | 282 | x509_constraints_valid_sandns(CBS *cbs) |
| 273 | { | 283 | { |
| 274 | if (len == 0) | 284 | uint8_t first; |
| 275 | return 0; | ||
| 276 | 285 | ||
| 277 | if (name[0] == '.') /* leading . not allowed in a SAN DNS name */ | 286 | if (!CBS_peek_u8(cbs, &first)) |
| 278 | return 0; | 287 | return 0; |
| 288 | if (first == '.') | ||
| 289 | return 0; /* leading . not allowed in a SAN DNS name */ | ||
| 279 | /* | 290 | /* |
| 280 | * A domain may not be less than two characters, so you | 291 | * A domain may not be less than two characters, so you |
| 281 | * can't wildcard a single domain of less than that | 292 | * can't wildcard a single domain of less than that |
| 282 | */ | 293 | */ |
| 283 | if (len < 4 && name[0] == '*') | 294 | if (CBS_len(cbs) < 4 && first == '*') |
| 284 | return 0; | ||
| 285 | /* | ||
| 286 | * A wildcard may only be followed by a '.' | ||
| 287 | */ | ||
| 288 | if (len >= 4 && name[0] == '*' && name[1] != '.') | ||
| 289 | return 0; | 295 | return 0; |
| 290 | 296 | ||
| 291 | return x509_constraints_valid_domain_internal(name, len, 1); | 297 | return x509_constraints_valid_domain_internal(cbs, 1); |
| 292 | } | 298 | } |
| 293 | 299 | ||
| 294 | static inline int | 300 | static inline int |
| @@ -297,7 +303,7 @@ local_part_ok(char c) | |||
| 297 | return (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || | 303 | return (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || |
| 298 | ('A' <= c && c <= 'Z') || c == '!' || c == '#' || c == '$' || | 304 | ('A' <= c && c <= 'Z') || c == '!' || c == '#' || c == '$' || |
| 299 | c == '%' || c == '&' || c == '\'' || c == '*' || c == '+' || | 305 | c == '%' || c == '&' || c == '\'' || c == '*' || c == '+' || |
| 300 | c == '-' || c == '/' || c == '=' || c == '?' || c == '^' || | 306 | c == '-' || c == '/' || c == '=' || c == '?' || c == '^' || |
| 301 | c == '_' || c == '`' || c == '{' || c == '|' || c == '}' || | 307 | c == '_' || c == '`' || c == '{' || c == '|' || c == '}' || |
| 302 | c == '~' || c == '.'); | 308 | c == '~' || c == '.'); |
| 303 | } | 309 | } |
| @@ -309,25 +315,35 @@ local_part_ok(char c) | |||
| 309 | * local and domain parts of the mailbox to "name->local" and name->name" | 315 | * local and domain parts of the mailbox to "name->local" and name->name" |
| 310 | */ | 316 | */ |
| 311 | int | 317 | int |
| 312 | x509_constraints_parse_mailbox(uint8_t *candidate, size_t len, | 318 | x509_constraints_parse_mailbox(CBS *candidate, |
| 313 | struct x509_constraints_name *name) | 319 | struct x509_constraints_name *name) |
| 314 | { | 320 | { |
| 315 | char working[DOMAIN_PART_MAX_LEN + 1] = { 0 }; | 321 | char working[DOMAIN_PART_MAX_LEN + 1] = { 0 }; |
| 316 | char *candidate_local = NULL; | 322 | char *candidate_local = NULL; |
| 317 | char *candidate_domain = NULL; | 323 | char *candidate_domain = NULL; |
| 318 | size_t i, wi = 0; | 324 | CBS domain_cbs; |
| 325 | size_t i, len, wi = 0; | ||
| 319 | int accept = 0; | 326 | int accept = 0; |
| 320 | int quoted = 0; | 327 | int quoted = 0; |
| 328 | CBS copy; | ||
| 321 | 329 | ||
| 330 | /* XXX This should not be necessary - revisit and remove */ | ||
| 322 | if (candidate == NULL) | 331 | if (candidate == NULL) |
| 323 | return 0; | 332 | return 0; |
| 324 | 333 | ||
| 334 | CBS_dup(candidate, ©); | ||
| 335 | |||
| 336 | if ((len = CBS_len(©)) == 0) | ||
| 337 | return 0; | ||
| 338 | |||
| 325 | /* It can't be bigger than the local part, domain part and the '@' */ | 339 | /* It can't be bigger than the local part, domain part and the '@' */ |
| 326 | if (len > LOCAL_PART_MAX_LEN + DOMAIN_PART_MAX_LEN + 1) | 340 | if (len > LOCAL_PART_MAX_LEN + DOMAIN_PART_MAX_LEN + 1) |
| 327 | return 0; | 341 | return 0; |
| 328 | 342 | ||
| 329 | for (i = 0; i < len; i++) { | 343 | for (i = 0; i < len; i++) { |
| 330 | char c = candidate[i]; | 344 | char c; |
| 345 | if (!CBS_get_u8(©, &c)) | ||
| 346 | goto bad; | ||
| 331 | /* non ascii, cr, lf, or nul is never allowed */ | 347 | /* non ascii, cr, lf, or nul is never allowed */ |
| 332 | if (!isascii(c) || c == '\r' || c == '\n' || c == '\0') | 348 | if (!isascii(c) || c == '\r' || c == '\n' || c == '\0') |
| 333 | goto bad; | 349 | goto bad; |
| @@ -372,8 +388,11 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len, | |||
| 372 | continue; | 388 | continue; |
| 373 | } | 389 | } |
| 374 | if (c == '"' && i != 0) { | 390 | if (c == '"' && i != 0) { |
| 391 | uint8_t next; | ||
| 375 | /* end the quoted part. @ must be next */ | 392 | /* end the quoted part. @ must be next */ |
| 376 | if (i + 1 == len || candidate[i + 1] != '@') | 393 | if (!CBS_peek_u8(©, &next)) |
| 394 | goto bad; | ||
| 395 | if (next != '@') | ||
| 377 | goto bad; | 396 | goto bad; |
| 378 | quoted = 0; | 397 | quoted = 0; |
| 379 | } | 398 | } |
| @@ -401,14 +420,15 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len, | |||
| 401 | continue; | 420 | continue; |
| 402 | } | 421 | } |
| 403 | if (c == '\\') { | 422 | if (c == '\\') { |
| 423 | uint8_t next; | ||
| 404 | /* | 424 | /* |
| 405 | * RFC 3936 hints these can happen outside of | 425 | * RFC 2821 hints these can happen outside of |
| 406 | * quotend string. don't include the \ but | 426 | * quoted string. Don't include the \ but |
| 407 | * next character must be ok. | 427 | * next character must be ok. |
| 408 | */ | 428 | */ |
| 409 | if (i + 1 == len) | 429 | if (!CBS_peek_u8(©, &next)) |
| 410 | goto bad; | 430 | goto bad; |
| 411 | if (!local_part_ok(candidate[i + 1])) | 431 | if (!local_part_ok(next)) |
| 412 | goto bad; | 432 | goto bad; |
| 413 | accept = 1; | 433 | accept = 1; |
| 414 | } | 434 | } |
| @@ -420,8 +440,8 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len, | |||
| 420 | } | 440 | } |
| 421 | if (candidate_local == NULL || candidate_domain == NULL) | 441 | if (candidate_local == NULL || candidate_domain == NULL) |
| 422 | goto bad; | 442 | goto bad; |
| 423 | if (!x509_constraints_valid_host(candidate_domain, | 443 | CBS_init(&domain_cbs, candidate_domain, strlen(candidate_domain)); |
| 424 | strlen(candidate_domain))) | 444 | if (!x509_constraints_valid_host(&domain_cbs)) |
| 425 | goto bad; | 445 | goto bad; |
| 426 | 446 | ||
| 427 | if (name != NULL) { | 447 | if (name != NULL) { |
| @@ -440,18 +460,24 @@ x509_constraints_parse_mailbox(uint8_t *candidate, size_t len, | |||
| 440 | } | 460 | } |
| 441 | 461 | ||
| 442 | int | 462 | int |
| 443 | x509_constraints_valid_domain_constraint(uint8_t *constraint, size_t len) | 463 | x509_constraints_valid_domain_constraint(CBS *cbs) |
| 444 | { | 464 | { |
| 445 | if (len == 0) | 465 | uint8_t first; |
| 466 | |||
| 467 | if (CBS_len(cbs) == 0) | ||
| 446 | return 1; /* empty constraints match */ | 468 | return 1; /* empty constraints match */ |
| 447 | 469 | ||
| 448 | /* | 470 | /* |
| 449 | * A domain may not be less than two characters, so you | 471 | * A domain may not be less than two characters, so you |
| 450 | * can't match a single domain of less than that | 472 | * can't match a single domain of less than that |
| 451 | */ | 473 | */ |
| 452 | if (len < 3 && constraint[0] == '.') | 474 | if (CBS_len(cbs) < 3) { |
| 453 | return 0; | 475 | if (!CBS_peek_u8(cbs, &first)) |
| 454 | return x509_constraints_valid_domain_internal(constraint, len, 0); | 476 | return 0; |
| 477 | if (first == '.') | ||
| 478 | return 0; | ||
| 479 | } | ||
| 480 | return x509_constraints_valid_domain_internal(cbs, 0); | ||
| 455 | } | 481 | } |
| 456 | 482 | ||
| 457 | /* | 483 | /* |
| @@ -480,6 +506,7 @@ x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostpart) | |||
| 480 | size_t i, hostlen = 0; | 506 | size_t i, hostlen = 0; |
| 481 | uint8_t *authority = NULL; | 507 | uint8_t *authority = NULL; |
| 482 | char *host = NULL; | 508 | char *host = NULL; |
| 509 | CBS host_cbs; | ||
| 483 | 510 | ||
| 484 | /* | 511 | /* |
| 485 | * Find first '//'. there must be at least a '//' and | 512 | * Find first '//'. there must be at least a '//' and |
| @@ -529,10 +556,11 @@ x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostpart) | |||
| 529 | return 0; | 556 | return 0; |
| 530 | if (host == NULL) | 557 | if (host == NULL) |
| 531 | host = authority; | 558 | host = authority; |
| 532 | if (!x509_constraints_valid_host(host, hostlen)) | 559 | CBS_init(&host_cbs, host, hostlen); |
| 560 | if (!x509_constraints_valid_host(&host_cbs)) | ||
| 561 | return 0; | ||
| 562 | if (hostpart != NULL && !CBS_strdup(&host_cbs, hostpart)) | ||
| 533 | return 0; | 563 | return 0; |
| 534 | if (hostpart != NULL) | ||
| 535 | *hostpart = strndup(host, hostlen); | ||
| 536 | return 1; | 564 | return 1; |
| 537 | } | 565 | } |
| 538 | 566 | ||
| @@ -593,12 +621,15 @@ x509_constraints_domain(char *domain, size_t dlen, char *constraint, size_t len) | |||
| 593 | } | 621 | } |
| 594 | 622 | ||
| 595 | int | 623 | int |
| 596 | x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, size_t len, | 624 | x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, |
| 625 | size_t len, | ||
| 597 | int *error) | 626 | int *error) |
| 598 | { | 627 | { |
| 599 | int ret = 0; | 628 | int ret = 0; |
| 600 | char *hostpart = NULL; | 629 | char *hostpart = NULL; |
| 630 | CBS cbs; | ||
| 601 | 631 | ||
| 632 | CBS_init(&cbs, constraint, len); | ||
| 602 | if (!x509_constraints_uri_host(uri, ulen, &hostpart)) { | 633 | if (!x509_constraints_uri_host(uri, ulen, &hostpart)) { |
| 603 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | 634 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; |
| 604 | goto err; | 635 | goto err; |
| @@ -607,7 +638,7 @@ x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, size_t len, | |||
| 607 | *error = X509_V_ERR_OUT_OF_MEM; | 638 | *error = X509_V_ERR_OUT_OF_MEM; |
| 608 | goto err; | 639 | goto err; |
| 609 | } | 640 | } |
| 610 | if (!x509_constraints_valid_domain_constraint(constraint, len)) { | 641 | if (!x509_constraints_valid_domain_constraint(&cbs)) { |
| 611 | *error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; | 642 | *error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; |
| 612 | goto err; | 643 | goto err; |
| 613 | } | 644 | } |
| @@ -714,7 +745,6 @@ x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes, | |||
| 714 | return 0; | 745 | return 0; |
| 715 | } | 746 | } |
| 716 | 747 | ||
| 717 | |||
| 718 | /* | 748 | /* |
| 719 | * Extract the relevant names for constraint checking from "cert", | 749 | * Extract the relevant names for constraint checking from "cert", |
| 720 | * validate them, and add them to the list of cert names for "chain". | 750 | * validate them, and add them to the list of cert names for "chain". |
| @@ -734,6 +764,7 @@ x509_constraints_extract_names(struct x509_constraints_names *names, | |||
| 734 | while ((name = sk_GENERAL_NAME_value(cert->altname, i++)) != NULL) { | 764 | while ((name = sk_GENERAL_NAME_value(cert->altname, i++)) != NULL) { |
| 735 | uint8_t *bytes = NULL; | 765 | uint8_t *bytes = NULL; |
| 736 | size_t len = 0; | 766 | size_t len = 0; |
| 767 | CBS cbs; | ||
| 737 | 768 | ||
| 738 | if ((vname = x509_constraints_name_new()) == NULL) { | 769 | if ((vname = x509_constraints_name_new()) == NULL) { |
| 739 | *error = X509_V_ERR_OUT_OF_MEM; | 770 | *error = X509_V_ERR_OUT_OF_MEM; |
| @@ -742,30 +773,31 @@ x509_constraints_extract_names(struct x509_constraints_names *names, | |||
| 742 | 773 | ||
| 743 | name_type = x509_constraints_general_to_bytes(name, &bytes, | 774 | name_type = x509_constraints_general_to_bytes(name, &bytes, |
| 744 | &len); | 775 | &len); |
| 745 | switch(name_type) { | 776 | CBS_init(&cbs, bytes, len); |
| 777 | switch (name_type) { | ||
| 746 | case GEN_DNS: | 778 | case GEN_DNS: |
| 747 | if (!x509_constraints_valid_sandns(bytes, len)) { | 779 | if (!x509_constraints_valid_sandns(&cbs)) { |
| 748 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | 780 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; |
| 749 | goto err; | 781 | goto err; |
| 750 | } | 782 | } |
| 751 | if ((vname->name = strndup(bytes, len)) == NULL) { | 783 | if (!CBS_strdup(&cbs, &vname->name)) { |
| 752 | *error = X509_V_ERR_OUT_OF_MEM; | 784 | *error = X509_V_ERR_OUT_OF_MEM; |
| 753 | goto err; | 785 | goto err; |
| 754 | } | 786 | } |
| 755 | vname->type = GEN_DNS; | 787 | vname->type = GEN_DNS; |
| 756 | include_cn = 0; /* don't use cn from subject */ | 788 | include_cn = 0; /* Don't use cn from subject */ |
| 757 | break; | 789 | break; |
| 758 | case GEN_EMAIL: | 790 | case GEN_EMAIL: |
| 759 | if (!x509_constraints_parse_mailbox(bytes, len, | 791 | if (!x509_constraints_parse_mailbox(&cbs, vname)) { |
| 760 | vname)) { | ||
| 761 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | 792 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; |
| 762 | goto err; | 793 | goto err; |
| 763 | } | 794 | } |
| 764 | vname->type = GEN_EMAIL; | 795 | vname->type = GEN_EMAIL; |
| 765 | include_email = 0; /* don't use email from subject */ | 796 | include_email = 0; /* Don't use email from subject */ |
| 766 | break; | 797 | break; |
| 767 | case GEN_URI: | 798 | case GEN_URI: |
| 768 | if (!x509_constraints_uri_host(bytes, len, &vname->name)) { | 799 | if (!x509_constraints_uri_host(bytes, len, |
| 800 | &vname->name)) { | ||
| 769 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | 801 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; |
| 770 | goto err; | 802 | goto err; |
| 771 | } | 803 | } |
| @@ -850,19 +882,21 @@ x509_constraints_extract_names(struct x509_constraints_names *names, | |||
| 850 | */ | 882 | */ |
| 851 | while (include_email && | 883 | while (include_email && |
| 852 | (i = X509_NAME_get_index_by_NID(subject_name, | 884 | (i = X509_NAME_get_index_by_NID(subject_name, |
| 853 | NID_pkcs9_emailAddress, i)) >= 0) { | 885 | NID_pkcs9_emailAddress, i)) >= 0) { |
| 854 | ASN1_STRING *aname; | 886 | ASN1_STRING *aname; |
| 855 | if ((email = X509_NAME_get_entry(subject_name, i)) == NULL || | 887 | CBS cbs; |
| 888 | if ((email = X509_NAME_get_entry(subject_name, i)) == | ||
| 889 | NULL || | ||
| 856 | (aname = X509_NAME_ENTRY_get_data(email)) == NULL) { | 890 | (aname = X509_NAME_ENTRY_get_data(email)) == NULL) { |
| 857 | *error = X509_V_ERR_OUT_OF_MEM; | 891 | *error = X509_V_ERR_OUT_OF_MEM; |
| 858 | goto err; | 892 | goto err; |
| 859 | } | 893 | } |
| 894 | CBS_init(&cbs, aname->data, aname->length); | ||
| 860 | if ((vname = x509_constraints_name_new()) == NULL) { | 895 | if ((vname = x509_constraints_name_new()) == NULL) { |
| 861 | *error = X509_V_ERR_OUT_OF_MEM; | 896 | *error = X509_V_ERR_OUT_OF_MEM; |
| 862 | goto err; | 897 | goto err; |
| 863 | } | 898 | } |
| 864 | if (!x509_constraints_parse_mailbox(aname->data, | 899 | if (!x509_constraints_parse_mailbox(&cbs, vname)) { |
| 865 | aname->length, vname)) { | ||
| 866 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; | 900 | *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; |
| 867 | goto err; | 901 | goto err; |
| 868 | } | 902 | } |
| @@ -879,22 +913,23 @@ x509_constraints_extract_names(struct x509_constraints_names *names, | |||
| 879 | */ | 913 | */ |
| 880 | while (include_cn && | 914 | while (include_cn && |
| 881 | (i = X509_NAME_get_index_by_NID(subject_name, | 915 | (i = X509_NAME_get_index_by_NID(subject_name, |
| 882 | NID_commonName, i)) >= 0) { | 916 | NID_commonName, i)) >= 0) { |
| 917 | CBS cbs; | ||
| 883 | ASN1_STRING *aname; | 918 | ASN1_STRING *aname; |
| 884 | if ((cn = X509_NAME_get_entry(subject_name, i)) == NULL || | 919 | if ((cn = X509_NAME_get_entry(subject_name, i)) == |
| 920 | NULL || | ||
| 885 | (aname = X509_NAME_ENTRY_get_data(cn)) == NULL) { | 921 | (aname = X509_NAME_ENTRY_get_data(cn)) == NULL) { |
| 886 | *error = X509_V_ERR_OUT_OF_MEM; | 922 | *error = X509_V_ERR_OUT_OF_MEM; |
| 887 | goto err; | 923 | goto err; |
| 888 | } | 924 | } |
| 889 | if (!x509_constraints_valid_host(aname->data, | 925 | CBS_init(&cbs, aname->data, aname->length); |
| 890 | aname->length)) | 926 | if (!x509_constraints_valid_host(&cbs)) |
| 891 | continue; /* ignore it if not a hostname */ | 927 | continue; /* ignore it if not a hostname */ |
| 892 | if ((vname = x509_constraints_name_new()) == NULL) { | 928 | if ((vname = x509_constraints_name_new()) == NULL) { |
| 893 | *error = X509_V_ERR_OUT_OF_MEM; | 929 | *error = X509_V_ERR_OUT_OF_MEM; |
| 894 | goto err; | 930 | goto err; |
| 895 | } | 931 | } |
| 896 | if ((vname->name = strndup(aname->data, | 932 | if (!CBS_strdup(&cbs, &vname->name)) { |
| 897 | aname->length)) == NULL) { | ||
| 898 | *error = X509_V_ERR_OUT_OF_MEM; | 933 | *error = X509_V_ERR_OUT_OF_MEM; |
| 899 | goto err; | 934 | goto err; |
| 900 | } | 935 | } |
| @@ -923,11 +958,12 @@ int | |||
| 923 | x509_constraints_validate(GENERAL_NAME *constraint, | 958 | x509_constraints_validate(GENERAL_NAME *constraint, |
| 924 | struct x509_constraints_name **out_name, int *out_error) | 959 | struct x509_constraints_name **out_name, int *out_error) |
| 925 | { | 960 | { |
| 926 | uint8_t *bytes = NULL; | 961 | uint8_t next, *bytes = NULL; |
| 927 | size_t len = 0; | 962 | size_t len = 0; |
| 928 | struct x509_constraints_name *name; | 963 | struct x509_constraints_name *name; |
| 929 | int error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; | 964 | int error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; |
| 930 | int name_type; | 965 | int name_type; |
| 966 | CBS cbs; | ||
| 931 | 967 | ||
| 932 | if (out_name == NULL || *out_name != NULL) | 968 | if (out_name == NULL || *out_name != NULL) |
| 933 | return 0; | 969 | return 0; |
| @@ -941,6 +977,7 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
| 941 | } | 977 | } |
| 942 | 978 | ||
| 943 | name_type = x509_constraints_general_to_bytes(constraint, &bytes, &len); | 979 | name_type = x509_constraints_general_to_bytes(constraint, &bytes, &len); |
| 980 | CBS_init(&cbs, bytes, len); | ||
| 944 | switch (name_type) { | 981 | switch (name_type) { |
| 945 | case GEN_DIRNAME: | 982 | case GEN_DIRNAME: |
| 946 | if (len == 0) | 983 | if (len == 0) |
| @@ -954,7 +991,7 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
| 954 | name->type = GEN_DIRNAME; | 991 | name->type = GEN_DIRNAME; |
| 955 | break; | 992 | break; |
| 956 | case GEN_DNS: | 993 | case GEN_DNS: |
| 957 | if (!x509_constraints_valid_domain_constraint(bytes, len)) | 994 | if (!x509_constraints_valid_domain_constraint(&cbs)) |
| 958 | goto err; | 995 | goto err; |
| 959 | if ((name->name = strndup(bytes, len)) == NULL) { | 996 | if ((name->name = strndup(bytes, len)) == NULL) { |
| 960 | error = X509_V_ERR_OUT_OF_MEM; | 997 | error = X509_V_ERR_OUT_OF_MEM; |
| @@ -964,7 +1001,7 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
| 964 | break; | 1001 | break; |
| 965 | case GEN_EMAIL: | 1002 | case GEN_EMAIL: |
| 966 | if (len > 0 && memchr(bytes + 1, '@', len - 1) != NULL) { | 1003 | if (len > 0 && memchr(bytes + 1, '@', len - 1) != NULL) { |
| 967 | if (!x509_constraints_parse_mailbox(bytes, len, name)) | 1004 | if (!x509_constraints_parse_mailbox(&cbs, name)) |
| 968 | goto err; | 1005 | goto err; |
| 969 | break; | 1006 | break; |
| 970 | } | 1007 | } |
| @@ -972,13 +1009,17 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
| 972 | * Mail constraints of the form @domain.com are accepted by | 1009 | * Mail constraints of the form @domain.com are accepted by |
| 973 | * OpenSSL and Microsoft. | 1010 | * OpenSSL and Microsoft. |
| 974 | */ | 1011 | */ |
| 975 | if (len > 0 && bytes[0] == '@') { | 1012 | if (CBS_len(&cbs) > 0) { |
| 976 | bytes++; | 1013 | if (!CBS_peek_u8(&cbs, &next)) |
| 977 | len--; | 1014 | goto err; |
| 1015 | if (next == '@') { | ||
| 1016 | if (!CBS_skip(&cbs, 1)) | ||
| 1017 | goto err; | ||
| 1018 | } | ||
| 978 | } | 1019 | } |
| 979 | if (!x509_constraints_valid_domain_constraint(bytes, len)) | 1020 | if (!x509_constraints_valid_domain_constraint(&cbs)) |
| 980 | goto err; | 1021 | goto err; |
| 981 | if ((name->name = strndup(bytes, len)) == NULL) { | 1022 | if (!CBS_strdup(&cbs, &name->name)) { |
| 982 | error = X509_V_ERR_OUT_OF_MEM; | 1023 | error = X509_V_ERR_OUT_OF_MEM; |
| 983 | goto err; | 1024 | goto err; |
| 984 | } | 1025 | } |
| @@ -996,7 +1037,7 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
| 996 | name->type = GEN_IPADD; | 1037 | name->type = GEN_IPADD; |
| 997 | break; | 1038 | break; |
| 998 | case GEN_URI: | 1039 | case GEN_URI: |
| 999 | if (!x509_constraints_valid_domain_constraint(bytes, len)) | 1040 | if (!x509_constraints_valid_domain_constraint(&cbs)) |
| 1000 | goto err; | 1041 | goto err; |
| 1001 | if ((name->name = strndup(bytes, len)) == NULL) { | 1042 | if ((name->name = strndup(bytes, len)) == NULL) { |
| 1002 | error = X509_V_ERR_OUT_OF_MEM; | 1043 | error = X509_V_ERR_OUT_OF_MEM; |
| @@ -1035,7 +1076,6 @@ x509_constraints_extract_constraints(X509 *cert, | |||
| 1035 | return 1; | 1076 | return 1; |
| 1036 | 1077 | ||
| 1037 | for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { | 1078 | for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { |
| 1038 | |||
| 1039 | subtree = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); | 1079 | subtree = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); |
| 1040 | if (subtree->minimum || subtree->maximum) { | 1080 | if (subtree->minimum || subtree->maximum) { |
| 1041 | *error = X509_V_ERR_SUBTREE_MINMAX; | 1081 | *error = X509_V_ERR_SUBTREE_MINMAX; |
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h index 030f24c470..beafd365ed 100644 --- a/src/lib/libcrypto/x509/x509_internal.h +++ b/src/lib/libcrypto/x509/x509_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_internal.h,v 1.19 2022/06/27 14:10:22 tb Exp $ */ | 1 | /* $OpenBSD: x509_internal.h,v 1.20 2022/11/11 12:02:34 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <openssl/x509_verify.h> | 23 | #include <openssl/x509_verify.h> |
| 24 | 24 | ||
| 25 | #include "bytestring.h" | ||
| 25 | #include "x509_lcl.h" | 26 | #include "x509_lcl.h" |
| 26 | 27 | ||
| 27 | /* Hard limits on structure size and number of signature checks. */ | 28 | /* Hard limits on structure size and number of signature checks. */ |
| @@ -111,14 +112,13 @@ struct x509_constraints_names *x509_constraints_names_new(size_t names_max); | |||
| 111 | int x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes, | 112 | int x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes, |
| 112 | size_t *len); | 113 | size_t *len); |
| 113 | void x509_constraints_names_free(struct x509_constraints_names *names); | 114 | void x509_constraints_names_free(struct x509_constraints_names *names); |
| 114 | int x509_constraints_valid_host(uint8_t *name, size_t len); | 115 | int x509_constraints_valid_host(CBS *cbs); |
| 115 | int x509_constraints_valid_sandns(uint8_t *name, size_t len); | 116 | int x509_constraints_valid_sandns(CBS *cbs); |
| 116 | int x509_constraints_domain(char *domain, size_t dlen, char *constraint, | 117 | int x509_constraints_domain(char *domain, size_t dlen, char *constraint, |
| 117 | size_t len); | 118 | size_t len); |
| 118 | int x509_constraints_parse_mailbox(uint8_t *candidate, size_t len, | 119 | int x509_constraints_parse_mailbox(CBS *candidate, |
| 119 | struct x509_constraints_name *name); | 120 | struct x509_constraints_name *name); |
| 120 | int x509_constraints_valid_domain_constraint(uint8_t *constraint, | 121 | int x509_constraints_valid_domain_constraint(CBS *cbs); |
| 121 | size_t len); | ||
| 122 | int x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostp); | 122 | int x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostp); |
| 123 | int x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, | 123 | int x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint, |
| 124 | size_t len, int *error); | 124 | size_t len, int *error); |
diff --git a/src/regress/lib/libcrypto/x509/Makefile b/src/regress/lib/libcrypto/x509/Makefile index 4635d63ed0..a465b37874 100644 --- a/src/regress/lib/libcrypto/x509/Makefile +++ b/src/regress/lib/libcrypto/x509/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.14 2022/06/28 07:56:34 beck Exp $ | 1 | # $OpenBSD: Makefile,v 1.15 2022/11/11 12:02:34 beck Exp $ |
| 2 | 2 | ||
| 3 | PROGS = constraints verify x509attribute x509name x509req_ext callback | 3 | PROGS = constraints verify x509attribute x509name x509req_ext callback |
| 4 | PROGS += expirecallback callbackfailures | 4 | PROGS += expirecallback callbackfailures |
| @@ -10,6 +10,7 @@ LDADD_verify = ${CRYPTO_INT} | |||
| 10 | 10 | ||
| 11 | WARNINGS = Yes | 11 | WARNINGS = Yes |
| 12 | CFLAGS += -DLIBRESSL_INTERNAL -Wall -Werror -I$(BSDSRCDIR)/lib/libcrypto/x509 | 12 | CFLAGS += -DLIBRESSL_INTERNAL -Wall -Werror -I$(BSDSRCDIR)/lib/libcrypto/x509 |
| 13 | CFLAGS += -I$(BSDSRCDIR)/lib/libcrypto/bytestring | ||
| 13 | 14 | ||
| 14 | SUBDIR += bettertls rfc3779 | 15 | SUBDIR += bettertls rfc3779 |
| 15 | 16 | ||
diff --git a/src/regress/lib/libcrypto/x509/constraints.c b/src/regress/lib/libcrypto/x509/constraints.c index 8f7017dd7e..933c4f47c8 100644 --- a/src/regress/lib/libcrypto/x509/constraints.c +++ b/src/regress/lib/libcrypto/x509/constraints.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: constraints.c,v 1.12 2022/10/30 13:27:15 kn Exp $ */ | 1 | /* $OpenBSD: constraints.c,v 1.13 2022/11/11 12:02:34 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -23,11 +23,10 @@ | |||
| 23 | #include <openssl/x509v3.h> | 23 | #include <openssl/x509v3.h> |
| 24 | #include "x509_internal.h" | 24 | #include "x509_internal.h" |
| 25 | 25 | ||
| 26 | 26 | #define FAIL(msg, ...) \ | |
| 27 | #define FAIL(msg, ...) \ | 27 | do { \ |
| 28 | do { \ | 28 | fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ |
| 29 | fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ | 29 | fprintf(stderr, msg, ##__VA_ARGS__); \ |
| 30 | fprintf(stderr, msg, ##__VA_ARGS__); \ | ||
| 31 | } while(0) | 30 | } while(0) |
| 32 | 31 | ||
| 33 | unsigned char *valid_hostnames[] = { | 32 | unsigned char *valid_hostnames[] = { |
| @@ -168,15 +167,16 @@ test_valid_hostnames(void) | |||
| 168 | int i, failure = 0; | 167 | int i, failure = 0; |
| 169 | 168 | ||
| 170 | for (i = 0; valid_hostnames[i] != NULL; i++) { | 169 | for (i = 0; valid_hostnames[i] != NULL; i++) { |
| 171 | if (!x509_constraints_valid_host(valid_hostnames[i], | 170 | CBS cbs; |
| 172 | strlen(valid_hostnames[i]))) { | 171 | CBS_init(&cbs, valid_hostnames[i], strlen(valid_hostnames[i])); |
| 172 | if (!x509_constraints_valid_host(&cbs)) { | ||
| 173 | FAIL("Valid hostname '%s' rejected\n", | 173 | FAIL("Valid hostname '%s' rejected\n", |
| 174 | valid_hostnames[i]); | 174 | valid_hostnames[i]); |
| 175 | failure = 1; | 175 | failure = 1; |
| 176 | goto done; | 176 | goto done; |
| 177 | } | 177 | } |
| 178 | if (!x509_constraints_valid_sandns(valid_hostnames[i], | 178 | CBS_init(&cbs, valid_hostnames[i], strlen(valid_hostnames[i])); |
| 179 | strlen(valid_hostnames[i]))) { | 179 | if (!x509_constraints_valid_sandns(&cbs)) { |
| 180 | FAIL("Valid sandns '%s' rejected\n", | 180 | FAIL("Valid sandns '%s' rejected\n", |
| 181 | valid_hostnames[i]); | 181 | valid_hostnames[i]); |
| 182 | failure = 1; | 182 | failure = 1; |
| @@ -192,8 +192,10 @@ test_valid_sandns_names(void) | |||
| 192 | { | 192 | { |
| 193 | int i, failure = 0; | 193 | int i, failure = 0; |
| 194 | for (i = 0; valid_sandns_names[i] != NULL; i++) { | 194 | for (i = 0; valid_sandns_names[i] != NULL; i++) { |
| 195 | if (!x509_constraints_valid_sandns(valid_sandns_names[i], | 195 | CBS cbs; |
| 196 | strlen(valid_sandns_names[i]))) { | 196 | CBS_init(&cbs, valid_sandns_names[i], |
| 197 | strlen(valid_sandns_names[i])); | ||
| 198 | if (!x509_constraints_valid_sandns(&cbs)) { | ||
| 197 | FAIL("Valid dnsname '%s' rejected\n", | 199 | FAIL("Valid dnsname '%s' rejected\n", |
| 198 | valid_sandns_names[i]); | 200 | valid_sandns_names[i]); |
| 199 | failure = 1; | 201 | failure = 1; |
| @@ -209,8 +211,10 @@ test_valid_domain_constraints(void) | |||
| 209 | { | 211 | { |
| 210 | int i, failure = 0; | 212 | int i, failure = 0; |
| 211 | for (i = 0; valid_domain_constraints[i] != NULL; i++) { | 213 | for (i = 0; valid_domain_constraints[i] != NULL; i++) { |
| 212 | if (!x509_constraints_valid_domain_constraint(valid_domain_constraints[i], | 214 | CBS cbs; |
| 213 | strlen(valid_domain_constraints[i]))) { | 215 | CBS_init(&cbs, valid_domain_constraints[i], |
| 216 | strlen(valid_domain_constraints[i])); | ||
| 217 | if (!x509_constraints_valid_domain_constraint(&cbs)) { | ||
| 214 | FAIL("Valid dnsname '%s' rejected\n", | 218 | FAIL("Valid dnsname '%s' rejected\n", |
| 215 | valid_domain_constraints[i]); | 219 | valid_domain_constraints[i]); |
| 216 | failure = 1; | 220 | failure = 1; |
| @@ -227,8 +231,10 @@ test_valid_mbox_names(void) | |||
| 227 | struct x509_constraints_name name = {0}; | 231 | struct x509_constraints_name name = {0}; |
| 228 | int i, failure = 0; | 232 | int i, failure = 0; |
| 229 | for (i = 0; valid_mbox_names[i] != NULL; i++) { | 233 | for (i = 0; valid_mbox_names[i] != NULL; i++) { |
| 230 | if (!x509_constraints_parse_mailbox(valid_mbox_names[i], | 234 | CBS cbs; |
| 231 | strlen(valid_mbox_names[i]), &name)) { | 235 | CBS_init(&cbs, valid_mbox_names[i], |
| 236 | strlen(valid_mbox_names[i])); | ||
| 237 | if (!x509_constraints_parse_mailbox(&cbs, &name)) { | ||
| 232 | FAIL("Valid mailbox name '%s' rejected\n", | 238 | FAIL("Valid mailbox name '%s' rejected\n", |
| 233 | valid_mbox_names[i]); | 239 | valid_mbox_names[i]); |
| 234 | failure = 1; | 240 | failure = 1; |
| @@ -250,22 +256,25 @@ test_invalid_hostnames(void) | |||
| 250 | char *nulhost = "www.openbsd.org\0"; | 256 | char *nulhost = "www.openbsd.org\0"; |
| 251 | 257 | ||
| 252 | for (i = 0; invalid_hostnames[i] != NULL; i++) { | 258 | for (i = 0; invalid_hostnames[i] != NULL; i++) { |
| 253 | if (x509_constraints_valid_host(invalid_hostnames[i], | 259 | CBS cbs; |
| 254 | strlen(invalid_hostnames[i]))) { | 260 | CBS_init(&cbs, invalid_hostnames[i], |
| 261 | strlen(invalid_hostnames[i])); | ||
| 262 | if (x509_constraints_valid_host(&cbs)) { | ||
| 255 | FAIL("Invalid hostname '%s' accepted\n", | 263 | FAIL("Invalid hostname '%s' accepted\n", |
| 256 | invalid_hostnames[i]); | 264 | invalid_hostnames[i]); |
| 257 | failure = 1; | 265 | failure = 1; |
| 258 | goto done; | 266 | goto done; |
| 259 | } | 267 | } |
| 260 | } | 268 | } |
| 261 | if (x509_constraints_valid_host(nulhost, | 269 | CBS cbs; |
| 262 | strlen(nulhost) + 1)) { | 270 | CBS_init(&cbs, nulhost, strlen(nulhost) + 1); |
| 271 | if (x509_constraints_valid_host(&cbs)) { | ||
| 263 | FAIL("hostname with NUL byte accepted\n"); | 272 | FAIL("hostname with NUL byte accepted\n"); |
| 264 | failure = 1; | 273 | failure = 1; |
| 265 | goto done; | 274 | goto done; |
| 266 | } | 275 | } |
| 267 | if (x509_constraints_valid_sandns(nulhost, | 276 | CBS_init(&cbs, nulhost, strlen(nulhost) + 1); |
| 268 | strlen(nulhost) + 1)) { | 277 | if (x509_constraints_valid_sandns(&cbs)) { |
| 269 | FAIL("sandns with NUL byte accepted\n"); | 278 | FAIL("sandns with NUL byte accepted\n"); |
| 270 | failure = 1; | 279 | failure = 1; |
| 271 | goto done; | 280 | goto done; |
| @@ -279,8 +288,10 @@ test_invalid_sandns_names(void) | |||
| 279 | { | 288 | { |
| 280 | int i, failure = 0; | 289 | int i, failure = 0; |
| 281 | for (i = 0; invalid_sandns_names[i] != NULL; i++) { | 290 | for (i = 0; invalid_sandns_names[i] != NULL; i++) { |
| 282 | if (x509_constraints_valid_sandns(invalid_sandns_names[i], | 291 | CBS cbs; |
| 283 | strlen(invalid_sandns_names[i]))) { | 292 | CBS_init(&cbs, invalid_sandns_names[i], |
| 293 | strlen(invalid_sandns_names[i])); | ||
| 294 | if (x509_constraints_valid_sandns(&cbs)) { | ||
| 284 | FAIL("Valid dnsname '%s' rejected\n", | 295 | FAIL("Valid dnsname '%s' rejected\n", |
| 285 | invalid_sandns_names[i]); | 296 | invalid_sandns_names[i]); |
| 286 | failure = 1; | 297 | failure = 1; |
| @@ -297,8 +308,10 @@ test_invalid_mbox_names(void) | |||
| 297 | int i, failure = 0; | 308 | int i, failure = 0; |
| 298 | struct x509_constraints_name name = {0}; | 309 | struct x509_constraints_name name = {0}; |
| 299 | for (i = 0; invalid_mbox_names[i] != NULL; i++) { | 310 | for (i = 0; invalid_mbox_names[i] != NULL; i++) { |
| 300 | if (x509_constraints_parse_mailbox(invalid_mbox_names[i], | 311 | CBS cbs; |
| 301 | strlen(invalid_mbox_names[i]), &name)) { | 312 | CBS_init(&cbs, invalid_mbox_names[i], |
| 313 | strlen(invalid_mbox_names[i])); | ||
| 314 | if (x509_constraints_parse_mailbox(&cbs, &name)) { | ||
| 302 | FAIL("invalid mailbox name '%s' accepted\n", | 315 | FAIL("invalid mailbox name '%s' accepted\n", |
| 303 | invalid_mbox_names[i]); | 316 | invalid_mbox_names[i]); |
| 304 | failure = 1; | 317 | failure = 1; |
| @@ -318,8 +331,10 @@ test_invalid_domain_constraints(void) | |||
| 318 | { | 331 | { |
| 319 | int i, failure = 0; | 332 | int i, failure = 0; |
| 320 | for (i = 0; invalid_domain_constraints[i] != NULL; i++) { | 333 | for (i = 0; invalid_domain_constraints[i] != NULL; i++) { |
| 321 | if (x509_constraints_valid_domain_constraint(invalid_domain_constraints[i], | 334 | CBS cbs; |
| 322 | strlen(invalid_domain_constraints[i]))) { | 335 | CBS_init(&cbs, invalid_domain_constraints[i], |
| 336 | strlen(invalid_domain_constraints[i])); | ||
| 337 | if (x509_constraints_valid_domain_constraint(&cbs)) { | ||
| 323 | FAIL("invalid dnsname '%s' accepted\n", | 338 | FAIL("invalid dnsname '%s' accepted\n", |
| 324 | invalid_domain_constraints[i]); | 339 | invalid_domain_constraints[i]); |
| 325 | failure = 1; | 340 | failure = 1; |
| @@ -333,12 +348,12 @@ test_invalid_domain_constraints(void) | |||
| 333 | static int | 348 | static int |
| 334 | test_invalid_uri(void) | 349 | test_invalid_uri(void) |
| 335 | { | 350 | { |
| 336 | int j, failure=0; | 351 | int j, failure = 0; |
| 337 | char *hostpart = NULL; | 352 | char *hostpart = NULL; |
| 338 | 353 | ||
| 339 | for (j = 0; invaliduri[j] != NULL; j++) { | 354 | for (j = 0; invaliduri[j] != NULL; j++) { |
| 340 | if (x509_constraints_uri_host(invaliduri[j], | 355 | if (x509_constraints_uri_host(invaliduri[j], |
| 341 | strlen(invaliduri[j]), &hostpart) != 0) { | 356 | strlen(invaliduri[j]), &hostpart) != 0) { |
| 342 | FAIL("invalid URI '%s' accepted\n", | 357 | FAIL("invalid URI '%s' accepted\n", |
| 343 | invaliduri[j]); | 358 | invaliduri[j]); |
| 344 | failure = 1; | 359 | failure = 1; |
| @@ -355,8 +370,10 @@ test_invalid_uri(void) | |||
| 355 | static int | 370 | static int |
| 356 | test_constraints1(void) | 371 | test_constraints1(void) |
| 357 | { | 372 | { |
| 358 | char *c; size_t cl; | 373 | char *c; |
| 359 | char *d; size_t dl; | 374 | size_t cl; |
| 375 | char *d; | ||
| 376 | size_t dl; | ||
| 360 | int failure = 0; | 377 | int failure = 0; |
| 361 | int error = 0; | 378 | int error = 0; |
| 362 | int i, j; | 379 | int i, j; |
| @@ -450,7 +467,7 @@ test_constraints1(void) | |||
| 450 | char *hostpart = NULL; | 467 | char *hostpart = NULL; |
| 451 | error = 0; | 468 | error = 0; |
| 452 | if (!x509_constraints_uri_host(noauthority[j], | 469 | if (!x509_constraints_uri_host(noauthority[j], |
| 453 | strlen(noauthority[j]), &hostpart)) { | 470 | strlen(noauthority[j]), &hostpart)) { |
| 454 | FAIL("name '%s' should parse as a URI", | 471 | FAIL("name '%s' should parse as a URI", |
| 455 | noauthority[j]); | 472 | noauthority[j]); |
| 456 | failure = 1; | 473 | failure = 1; |
