Skip to content

Commit 615b869

Browse files
authored
Merge branch 'main' into avx2_keccak_x4_hollight
2 parents 73342fe + 4738958 commit 615b869

File tree

18 files changed

+1057
-197
lines changed

18 files changed

+1057
-197
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cmake_policy(SET CMP0091 NEW)
55
endif()
66

77
set(SOFTWARE_NAME "awslc")
8-
set(SOFTWARE_VERSION "1.70.0")
8+
set(SOFTWARE_VERSION "1.71.0")
99
set(ABI_VERSION 0)
1010
set(CRYPTO_LIB_NAME "crypto")
1111
set(SSL_LIB_NAME "ssl")

crypto/evp_extra/p_rsa_asn1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ static int rsa_priv_decode(EVP_PKEY *out, CBS *oid, CBS *params, CBS *key, CBS *
107107
return 0;
108108
}
109109

110-
// Per RFC 3447, A.1, the parameters have type NULL.
110+
// Per RFC 8017, A.1, the parameters have type NULL.
111111
CBS null;
112112
if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) ||
113113
CBS_len(&null) != 0 ||

crypto/evp_extra/print.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ typedef struct {
311311
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent);
312312
} EVP_PKEY_PRINT_METHOD;
313313

314-
static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
314+
static const EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
315315
{
316316
EVP_PKEY_RSA,
317317
rsa_pub_print,
@@ -340,7 +340,7 @@ static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
340340

341341
static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods);
342342

343-
static EVP_PKEY_PRINT_METHOD *find_method(int type) {
343+
static const EVP_PKEY_PRINT_METHOD *find_method(int type) {
344344
for (size_t i = 0; i < kPrintMethodsLen; i++) {
345345
if (kPrintMethods[i].type == type) {
346346
return &kPrintMethods[i];
@@ -358,7 +358,7 @@ static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
358358

359359
int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
360360
ASN1_PCTX *pctx) {
361-
EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
361+
const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
362362
if (method != NULL && method->pub_print != NULL) {
363363
return method->pub_print(out, pkey, indent);
364364
}
@@ -367,7 +367,7 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
367367

368368
int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
369369
ASN1_PCTX *pctx) {
370-
EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
370+
const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
371371
if (method != NULL && method->priv_print != NULL) {
372372
return method->priv_print(out, pkey, indent);
373373
}
@@ -376,7 +376,7 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
376376

377377
int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
378378
ASN1_PCTX *pctx) {
379-
EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
379+
const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey));
380380
if (method != NULL && method->param_print != NULL) {
381381
return method->param_print(out, pkey, indent);
382382
}

crypto/ocsp/ocsp_verify.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) {
3535
for (size_t i = 0; i < sk_X509_num(certs); i++) {
3636
cert = sk_X509_value(certs, i);
3737
if (X509_pubkey_digest(cert, EVP_sha1(), tmphash, NULL)) {
38-
if (memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH) == 0) {
38+
if (OPENSSL_memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH) == 0) {
3939
return cert;
4040
}
4141
}
@@ -201,6 +201,8 @@ static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) {
201201
return 1;
202202
}
203203

204+
// Returns -1 on fatal error, 0 if there is no match and 1 if there is a
205+
// match.
204206
static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
205207
STACK_OF(OCSP_SINGLERESP) *sresp) {
206208
if (cert == NULL) {
@@ -232,13 +234,14 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
232234
return 0;
233235
}
234236
}
235-
if (memcmp(md, cid->issuerNameHash->data, mdlen) != 0) {
237+
if (0 != OPENSSL_memcmp(md, cid->issuerNameHash->data, mdlen)) {
236238
return 0;
237239
}
238-
if (0 <= X509_pubkey_digest(cert, dgst, md, NULL)) {
239-
if (memcmp(md, cid->issuerKeyHash->data, mdlen) != 0) {
240-
return 0;
241-
}
240+
if (1 != X509_pubkey_digest(cert, dgst, md, NULL)) {
241+
return -1;
242+
}
243+
if (0 != OPENSSL_memcmp(md, cid->issuerKeyHash->data, mdlen)) {
244+
return 0;
242245
}
243246
return 1;
244247

@@ -473,8 +476,8 @@ int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
473476
int ret = 0;
474477
if (!IS_OCSP_FLAG_SET(flags, OCSP_NOVERIFY)) {
475478
// Initialize and set purpose of |ctx| for verification.
476-
if (!X509_STORE_CTX_init(ctx, store, signer, NULL) &&
477-
!X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER)) {
479+
if (1 != X509_STORE_CTX_init(ctx, store, signer, NULL) ||
480+
1 != X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER)) {
478481
OPENSSL_PUT_ERROR(OCSP, ERR_R_X509_LIB);
479482
goto end;
480483
}

crypto/rsa_extra/rsa_asn1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
9999
}
100100

101101
// kVersionTwoPrime is the value of the version field for a two-prime
102-
// RSAPrivateKey structure (RFC 3447).
102+
// RSAPrivateKey structure (RFC 8017).
103103
static const uint64_t kVersionTwoPrime = 0;
104104

105105
// Distinguisher for stripped JCA RSA private keys, sets zeroed values to NULL

crypto/x509/v3_ncons.c

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
2828
static int print_nc_ipadd(BIO *bp, const ASN1_OCTET_STRING *ip);
2929

3030
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
31-
static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
31+
static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen,
32+
int excluding);
3233
static int nc_dn(X509_NAME *sub, X509_NAME *nm);
33-
static int nc_dns(const ASN1_IA5STRING *sub, const ASN1_IA5STRING *dns);
34+
static int nc_dns(const ASN1_IA5STRING *sub, const ASN1_IA5STRING *dns,
35+
int excluding);
3436
static int nc_email(const ASN1_IA5STRING *sub, const ASN1_IA5STRING *eml);
3537
static int nc_uri(const ASN1_IA5STRING *uri, const ASN1_IA5STRING *base);
3638
static int nc_ip(const ASN1_OCTET_STRING *ip, const ASN1_OCTET_STRING *base);
@@ -295,24 +297,46 @@ int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen) {
295297
}
296298

297299
int isdnsname = 0;
300+
int has_non_dns_char = 0;
301+
302+
// Per RFC 6125 Section 6.4.3, a wildcard DNS-ID uses a leading "*." covering
303+
// the first label. Skip past it for validation, but return the full value so
304+
// |nc_dns| can match it against name constraints.
305+
int check_start = 0;
306+
if (utf8_length > 2 && utf8_value[0] == '*' && utf8_value[1] == '.') {
307+
check_start = 2;
308+
}
298309

299-
// XXX: Deviation from strict DNS name syntax, also check names with '_'
300-
// Check DNS name syntax, any '-' or '.' must be internal,
301-
// and on either side of each '.' we can't have a '-' or '.'.
310+
// Check DNS name syntax. Any '-' or '.' must be internal, and on either side
311+
// of each '.' we can't have a '-' or '.'. Names with '_' are also accepted
312+
// as a deviation from strict DNS syntax.
302313
//
303-
// If the name has just one label, we don't consider it a DNS name. This
314+
// If the name has just one label, we don't consider it a DNS name. This
304315
// means that "CN=sometld" cannot be precluded by DNS name constraints, but
305-
// that is not a problem.
306-
for (int i = 0; i < utf8_length; ++i) {
316+
// that is not a problem. Single-label CNs may contain non-ASCII characters
317+
// (e.g. "CN=Ünternehmen") and are silently skipped.
318+
//
319+
// Multi-label CNs that resemble DNS names must be ASCII-only. Per RFC 6125
320+
// Section 6.4.2, internationalized domain names should appear in A-label
321+
// (punycode) form. A multi-label CN containing non-ASCII bytes or control
322+
// characters is rejected with |X509_V_ERR_UNSUPPORTED_NAME_SYNTAX| to
323+
// prevent it from bypassing name constraints while still being accepted by
324+
// hostname verification.
325+
for (int i = check_start; i < utf8_length; ++i) {
307326
const unsigned char c = utf8_value[i];
308327

309328
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
310329
(c >= '0' && c <= '9') || c == '_') {
311330
continue;
312331
}
313332

333+
if (c >= 0x80 || c <= 0x20 || c == 0x7F) {
334+
has_non_dns_char = 1;
335+
continue;
336+
}
337+
314338
// Dot and hyphen cannot be first or last.
315-
if (i > 0 && i < utf8_length - 1) {
339+
if (i > check_start && i < utf8_length - 1) {
316340
if (c == '-') {
317341
continue;
318342
}
@@ -330,6 +354,13 @@ int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen) {
330354
break;
331355
}
332356

357+
if (isdnsname && has_non_dns_char) {
358+
// Multi-label CN with non-ASCII bytes or control characters. This
359+
// resembles a DNS name but contains characters not permitted in DNS.
360+
OPENSSL_free(utf8_value);
361+
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
362+
}
363+
333364
if (isdnsname) {
334365
*dnsid = utf8_value;
335366
*idlen = (size_t)utf8_length;
@@ -402,7 +433,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) {
402433
if (match == 0) {
403434
match = 1;
404435
}
405-
r = nc_match_single(gen, sub->base);
436+
r = nc_match_single(gen, sub->base, /*excluding=*/0);
406437
if (r == X509_V_OK) {
407438
match = 2;
408439
} else if (r != X509_V_ERR_PERMITTED_VIOLATION) {
@@ -425,7 +456,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) {
425456
return X509_V_ERR_SUBTREE_MINMAX;
426457
}
427458

428-
r = nc_match_single(gen, sub->base);
459+
r = nc_match_single(gen, sub->base, /*excluding=*/1);
429460
if (r == X509_V_OK) {
430461
return X509_V_ERR_EXCLUDED_VIOLATION;
431462
} else if (r != X509_V_ERR_PERMITTED_VIOLATION) {
@@ -436,13 +467,14 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) {
436467
return X509_V_OK;
437468
}
438469

439-
static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) {
470+
static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base,
471+
int excluding) {
440472
switch (base->type) {
441473
case GEN_DIRNAME:
442474
return nc_dn(gen->d.directoryName, base->d.directoryName);
443475

444476
case GEN_DNS:
445-
return nc_dns(gen->d.dNSName, base->d.dNSName);
477+
return nc_dns(gen->d.dNSName, base->d.dNSName, excluding);
446478

447479
case GEN_EMAIL:
448480
return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
@@ -484,6 +516,15 @@ static int starts_with(const CBS *cbs, uint8_t c) {
484516
return CBS_len(cbs) > 0 && CBS_data(cbs)[0] == c;
485517
}
486518

519+
static int starts_with_str(const CBS *cbs, const char *str, size_t str_len) {
520+
return CBS_len(cbs) >= str_len &&
521+
!OPENSSL_memcmp(CBS_data(cbs), str, str_len);
522+
}
523+
524+
static int ends_with_byte(const CBS *cbs, uint8_t c) {
525+
return CBS_len(cbs) > 0 && CBS_data(cbs)[CBS_len(cbs) - 1] == c;
526+
}
527+
487528
static int equal_case(const CBS *a, const CBS *b) {
488529
if (CBS_len(a) != CBS_len(b)) {
489530
return 0;
@@ -508,7 +549,8 @@ static int has_suffix_case(const CBS *a, const CBS *b) {
508549
return equal_case(&copy, b);
509550
}
510551

511-
static int nc_dns(const ASN1_IA5STRING *dns, const ASN1_IA5STRING *base) {
552+
static int nc_dns(const ASN1_IA5STRING *dns, const ASN1_IA5STRING *base,
553+
int excluding) {
512554
CBS dns_cbs, base_cbs;
513555
CBS_init(&dns_cbs, dns->data, dns->length);
514556
CBS_init(&base_cbs, base->data, base->length);
@@ -518,6 +560,34 @@ static int nc_dns(const ASN1_IA5STRING *dns, const ASN1_IA5STRING *base) {
518560
return X509_V_OK;
519561
}
520562

563+
// Normalize absolute DNS names by removing the trailing dot, if any.
564+
if (ends_with_byte(&dns_cbs, '.')) {
565+
uint8_t unused;
566+
CBS_get_last_u8(&dns_cbs, &unused);
567+
}
568+
if (ends_with_byte(&base_cbs, '.')) {
569+
uint8_t unused;
570+
CBS_get_last_u8(&base_cbs, &unused);
571+
}
572+
573+
// Wildcard partial-match handling ("*.bar.com" matching name constraint
574+
// "foo.bar.com"). This only handles the case where the dnsname and the
575+
// constraint match after removing the leftmost label, otherwise it is handled
576+
// by falling through to the check of whether the dnsname is fully within or
577+
// fully outside of the constraint.
578+
if (excluding && starts_with_str(&dns_cbs, "*.", 2)) {
579+
CBS unused;
580+
CBS base_parent_cbs = base_cbs;
581+
CBS dns_parent_cbs = dns_cbs;
582+
CBS_skip(&dns_parent_cbs, 2);
583+
if (CBS_get_until_first(&base_parent_cbs, &unused, '.') &&
584+
CBS_skip(&base_parent_cbs, 1)) {
585+
if (equal_case(&dns_parent_cbs, &base_parent_cbs)) {
586+
return X509_V_OK;
587+
}
588+
}
589+
}
590+
521591
// If |base_cbs| begins with a '.', do a simple suffix comparison. This is
522592
// not part of RFC5280, but is part of OpenSSL's original behavior.
523593
if (starts_with(&base_cbs, '.')) {

crypto/x509/x509_compat_test.cc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,6 +2496,39 @@ TEST(X509CompatTest, CommonNameToDNS) {
24962496
{"eXaMpLe", false, ""},
24972497
{"cn with spaces", false, ""},
24982498
{"1 and 2 and 3", false, ""},
2499+
// Wildcard CN test cases: wildcard CNs must be recognized as DNS-IDs
2500+
// so that name constraints are enforced on them.
2501+
{"*.example.com", true, "*.example.com"},
2502+
{"*.sub.example.com", true, "*.sub.example.com"},
2503+
{"*.exa_mple.com", true, "*.exa_mple.com"},
2504+
{"*.foo-bar.example.com", true, "*.foo-bar.example.com"},
2505+
// Wildcard with single remaining label is not a DNS name.
2506+
{"*.com", false, ""},
2507+
// Bare wildcard or incomplete wildcard prefix.
2508+
{"*", false, ""},
2509+
{"*.", false, ""},
2510+
{"*..", false, ""},
2511+
// Star without dot is not a valid wildcard prefix.
2512+
{"*example.com", false, ""},
2513+
// Double star is not valid.
2514+
{"**.example.com", false, ""},
2515+
// Invalid DNS syntax after wildcard prefix.
2516+
{"*.-example.com", false, ""},
2517+
{"*.example-.com", false, ""},
2518+
{"*.example..com", false, ""},
2519+
{"*.example.com.", false, ""},
2520+
{".*.example.com", false, ""},
2521+
// Single-label CNs with non-ASCII are accepted (not DNS names).
2522+
{"r\xc3\xa4ger", false, ""},
2523+
{"\xc3\x9cnternehmen", false, ""},
2524+
// Single-label CNs with control characters are accepted (not DNS names).
2525+
{"foo\x01" "bar", false, ""},
2526+
{std::string("\x7f") + "tld", false, ""},
2527+
// Single-label CN with space is accepted (not a DNS name).
2528+
{"foo bar", false, ""},
2529+
// Punycode equivalents are valid ASCII DNS names.
2530+
{"xn--rger-koa.evil.com", true, "xn--rger-koa.evil.com"},
2531+
{"xn--caf-dma.example.com", true, "xn--caf-dma.example.com"},
24992532
};
25002533

25012534
for (CommonNameToDNSTestParam &param : params) {
@@ -2520,6 +2553,38 @@ TEST(X509CompatTest, CommonNameToDNS) {
25202553
ASSERT_EQ((size_t)0, idlen);
25212554
}
25222555
}
2556+
2557+
// Multi-label CNs with non-ASCII bytes should return
2558+
// X509_V_ERR_UNSUPPORTED_NAME_SYNTAX. Per RFC 6125 Section 6.4.2,
2559+
// internationalized domain names should use A-label (punycode) form.
2560+
const std::string non_ascii_dns[] = {
2561+
"r\xc3\xa4ger.evil.com",
2562+
"caf\xc3\xa9.example.com",
2563+
"*.r\xc3\xa4ger.evil.com",
2564+
// Control characters in multi-label CNs.
2565+
"foo\x01.evil.com",
2566+
std::string("bar\x7f") + ".evil.com",
2567+
"baz\x1f.example.com",
2568+
// Space in multi-label CN.
2569+
"foo .evil.com",
2570+
};
2571+
for (const std::string &name : non_ascii_dns) {
2572+
SCOPED_TRACE(name);
2573+
ASN1_STRING *asn1_str_ptr = NULL;
2574+
std::vector<uint8_t> cn(name.begin(), name.end());
2575+
ASSERT_GE(ASN1_mbstring_copy(&asn1_str_ptr, cn.data(), cn.size(),
2576+
MBSTRING_UTF8, V_ASN1_IA5STRING),
2577+
0);
2578+
bssl::UniquePtr<ASN1_STRING> asn1_cn(asn1_str_ptr);
2579+
ASSERT_TRUE(asn1_cn);
2580+
unsigned char *dnsid_ptr = NULL;
2581+
size_t idlen = 0;
2582+
ASSERT_EQ(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX,
2583+
cn2dnsid(asn1_cn.get(), &dnsid_ptr, &idlen));
2584+
ASSERT_FALSE(dnsid_ptr);
2585+
ASSERT_EQ((size_t)0, idlen);
2586+
}
2587+
25232588
}
25242589

25252590

0 commit comments

Comments
 (0)