Skip to content

Commit d86174c

Browse files
committed
src/ssl.c: in wolfSSL_check_domain_name(), use XSTRCMP(), not strcmp();
wolfcrypt/src/asn.c, wolfssl/wolfcrypt/asn.h, src/ssl.c, wolfssl/ssl.h: move wolfssl_local_IsValidFQDN() from ASN.1 layer (where it has no users and is gated out in lean PSK builds) to TLS layer (where its users are); scripts/crl-revoked.test: use `cp --symbolic-link` opportunistically but fall back to `cp -p`.
1 parent b6de2d3 commit d86174c

5 files changed

Lines changed: 78 additions & 82 deletions

File tree

scripts/crl-revoked.test

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ trap restore_file_system EXIT
8585
TMP_DIR=$(mktemp -d) || exit $?
8686
SRC_DIR="$PWD"
8787
pushd "$TMP_DIR" || exit $?
88-
cp -r --symbolic-link "${SRC_DIR}/certs" . || exit $?
88+
if ! cp -R --symbolic-link "${SRC_DIR}/certs" . 2>/dev/null; then
89+
cp -pR "${SRC_DIR}/certs" . || exit $?
90+
fi
8991
popd || exit $?
9092
CERT_DIR="${TMP_DIR}/certs"
9193

src/ssl.c

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7712,6 +7712,78 @@ int wolfSSL_Cleanup(void)
77127712
return ret;
77137713
}
77147714

7715+
/* Returns 1 if name is a syntactically valid DNS FQDN per RFC 952/1123.
7716+
*
7717+
* Rules enforced:
7718+
* - Total effective length (excluding optional trailing dot) in [1, 253]
7719+
* - Each label is 1-63 octets of [a-zA-Z0-9-], with _ allowed in all but
7720+
* the last label.
7721+
* - No label starts or ends with '-'
7722+
* - At least two labels (single-label names are not "fully qualified")
7723+
* - Final label (TLD) contains at least one letter (rejects all-numeric
7724+
* strings that could be confused with IPv4 literals, and matches the
7725+
* ICANN constraint that TLDs are alphabetic)
7726+
* - Optional trailing dot is accepted (absolute FQDN form)
7727+
* - Internationalized names are valid in their ACE/punycode (xn--) form
7728+
*/
7729+
int wolfssl_local_IsValidFQDN(const char* name, word32 nameSz)
7730+
{
7731+
word32 i;
7732+
int labelLen = 0;
7733+
int labelCount = 0;
7734+
int curLabelHasAlpha = 0;
7735+
int curLabelHasUnderscore = 0;
7736+
7737+
if (name == NULL || nameSz == 0)
7738+
return 0;
7739+
7740+
/* Strip a single optional trailing dot before measuring. "example.com."
7741+
* is the absolute form of the same FQDN.
7742+
*/
7743+
if (name[nameSz - 1] == '.')
7744+
--nameSz;
7745+
7746+
if (nameSz < 1 || nameSz > 253)
7747+
return 0;
7748+
7749+
for (i = 0; i < nameSz; i++) {
7750+
byte c = (byte)name[i];
7751+
7752+
if (c == '.') {
7753+
if (labelLen == 0 || name[i - 1] == '-')
7754+
return 0;
7755+
++labelCount;
7756+
labelLen = 0;
7757+
curLabelHasAlpha = 0;
7758+
curLabelHasUnderscore = 0;
7759+
continue;
7760+
}
7761+
7762+
if (++labelLen > 63)
7763+
return 0;
7764+
7765+
if (c == '-') {
7766+
if (labelLen == 1)
7767+
return 0;
7768+
}
7769+
else if (((c | 0x20) >= 'a') && ((c | 0x20) <= 'z')) {
7770+
curLabelHasAlpha = 1;
7771+
}
7772+
else if (c == '_') {
7773+
curLabelHasUnderscore = 1;
7774+
}
7775+
else if ((c < '0') || (c > '9')) {
7776+
return 0;
7777+
}
7778+
}
7779+
7780+
/* Final label (no trailing dot in the effective range to close it) */
7781+
if ((labelLen == 0) || (name[nameSz - 1] == '-') || curLabelHasUnderscore)
7782+
return 0;
7783+
++labelCount;
7784+
7785+
return ((labelCount > 1) && curLabelHasAlpha);
7786+
}
77157787

77167788
/* call before SSL_connect, if verifying will add name check to
77177789
date check and signature check */
@@ -7730,7 +7802,7 @@ int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
77307802
dn_len = XSTRLEN(dn);
77317803

77327804
if ((! wolfssl_local_IsValidFQDN(dn, (word32)dn_len)) &&
7733-
(strcmp(dn, "localhost") != 0))
7805+
(XSTRCMP(dn, "localhost") != 0))
77347806
{
77357807
WOLFSSL_MSG("Bad function argument: fails wolfssl_local_IsValidFQDN");
77367808
return WOLFSSL_FAILURE;

wolfcrypt/src/asn.c

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -18075,81 +18075,6 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
1807518075

1807618076
#endif /* IGNORE_NAME_CONSTRAINTS */
1807718077

18078-
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS)
18079-
/* Returns 1 if name is a syntactically valid DNS FQDN per RFC 952/1123.
18080-
*
18081-
* Rules enforced:
18082-
* - Total effective length (excluding optional trailing dot) in [1, 253]
18083-
* - Each label is 1-63 octets of [a-zA-Z0-9-], with _ allowed in all but
18084-
* the last label.
18085-
* - No label starts or ends with '-'
18086-
* - At least two labels (single-label names are not "fully qualified")
18087-
* - Final label (TLD) contains at least one letter (rejects all-numeric
18088-
* strings that could be confused with IPv4 literals, and matches the
18089-
* ICANN constraint that TLDs are alphabetic)
18090-
* - Optional trailing dot is accepted (absolute FQDN form)
18091-
* - Internationalized names are valid in their ACE/punycode (xn--) form
18092-
*/
18093-
int wolfssl_local_IsValidFQDN(const char* name, word32 nameSz)
18094-
{
18095-
word32 i;
18096-
int labelLen = 0;
18097-
int labelCount = 0;
18098-
int curLabelHasAlpha = 0;
18099-
int curLabelHasUnderscore = 0;
18100-
18101-
if (name == NULL || nameSz == 0)
18102-
return 0;
18103-
18104-
/* Strip a single optional trailing dot before measuring. "example.com."
18105-
* is the absolute form of the same FQDN.
18106-
*/
18107-
if (name[nameSz - 1] == '.')
18108-
--nameSz;
18109-
18110-
if (nameSz < 1 || nameSz > 253)
18111-
return 0;
18112-
18113-
for (i = 0; i < nameSz; i++) {
18114-
byte c = (byte)name[i];
18115-
18116-
if (c == '.') {
18117-
if (labelLen == 0 || name[i - 1] == '-')
18118-
return 0;
18119-
++labelCount;
18120-
labelLen = 0;
18121-
curLabelHasAlpha = 0;
18122-
curLabelHasUnderscore = 0;
18123-
continue;
18124-
}
18125-
18126-
if (++labelLen > 63)
18127-
return 0;
18128-
18129-
if (c == '-') {
18130-
if (labelLen == 1)
18131-
return 0;
18132-
}
18133-
else if (((c | 0x20) >= 'a') && ((c | 0x20) <= 'z')) {
18134-
curLabelHasAlpha = 1;
18135-
}
18136-
else if (c == '_') {
18137-
curLabelHasUnderscore = 1;
18138-
}
18139-
else if ((c < '0') || (c > '9')) {
18140-
return 0;
18141-
}
18142-
}
18143-
18144-
/* Final label (no trailing dot in the effective range to close it) */
18145-
if ((labelLen == 0) || (name[nameSz - 1] == '-') || curLabelHasUnderscore)
18146-
return 0;
18147-
++labelCount;
18148-
18149-
return ((labelCount > 1) && curLabelHasAlpha);
18150-
}
18151-
#endif /* !WOLFCRYPT_ONLY && !NO_CERTS */
18152-
1815318078
#ifdef WOLFSSL_ASN_TEMPLATE
1815418079
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
1815518080
/* ASN.1 template for OtherName of an X.509 certificate.

wolfssl/ssl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3395,6 +3395,8 @@ WOLFSSL_API int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
33953395
/* call before SSL_connect, if verifying will add name check to
33963396
date check and signature check */
33973397
WOLFSSL_ABI WOLFSSL_API int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn);
3398+
WOLFSSL_TEST_VIS int wolfssl_local_IsValidFQDN(const char* name,
3399+
word32 nameSz);
33983400
/* call before SSL_connect, if verifying will add IP address check to
33993401
date check and signature check */
34003402
WOLFSSL_ABI WOLFSSL_API int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr);

wolfssl/wolfcrypt/asn.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3179,11 +3179,6 @@ WOLFSSL_TEST_VIS int wolfssl_local_MatchIpSubnet(const byte* ip, int ipSz,
31793179
int constraintSz);
31803180
#endif
31813181

3182-
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS)
3183-
WOLFSSL_TEST_VIS int wolfssl_local_IsValidFQDN(const char* name,
3184-
word32 nameSz);
3185-
#endif
3186-
31873182
#if ((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) \
31883183
|| (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) \
31893184
|| (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \

0 commit comments

Comments
 (0)