Skip to content

Commit 94e3caa

Browse files
authored
Merge pull request #10419 from douzzer/20260506-check_domain_name-local_IsValidFQDN
20260506-check_domain_name-local_IsValidFQDN
2 parents 980fc51 + d86174c commit 94e3caa

5 files changed

Lines changed: 101 additions & 93 deletions

File tree

scripts/crl-revoked.test

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ elif [ "${AM_BWRAPPED-}" != "yes" ]; then
2929
unset AM_BWRAPPED
3030
fi
3131

32-
# Workaround to not pollute the certs folder with our files that can impact other tests
33-
RUNNING_DIR=$(mktemp -d)
34-
cp -rp . $RUNNING_DIR/.
35-
cd $RUNNING_DIR
36-
3732
revocation_code="-361"
3833
revocation_code_openssl="23"
3934
exit_code=1
@@ -49,13 +44,9 @@ server_pid=$no_pid
4944
# also let's add some randomness by adding pid in case multiple 'make check's
5045
# per source tree
5146
ready_file=`pwd`/wolfssl_crl_ready$$
52-
CERT_DIR=certs
5347

5448
remove_ready_file() {
55-
if test -e "$ready_file"; then
56-
echo -e "removing existing ready file"
57-
rm "$ready_file"
58-
fi
49+
rm -f "$ready_file"
5950
}
6051

6152
# trap this function so if user aborts with ^C or other kill signal we still
@@ -84,10 +75,22 @@ trap abort_trap INT TERM
8475
# instead use "exit <some value>" and this function will run automatically
8576
restore_file_system() {
8677
remove_ready_file
87-
cd / && rm -rf "$RUNNING_DIR"
78+
if [ -n "$TMP_DIR" ]; then
79+
rm -rf "$TMP_DIR"
80+
fi
8881
}
8982
trap restore_file_system EXIT
9083

84+
# Workaround to not pollute the certs folder with our files that can impact other tests
85+
TMP_DIR=$(mktemp -d) || exit $?
86+
SRC_DIR="$PWD"
87+
pushd "$TMP_DIR" || exit $?
88+
if ! cp -R --symbolic-link "${SRC_DIR}/certs" . 2>/dev/null; then
89+
cp -pR "${SRC_DIR}/certs" . || exit $?
90+
fi
91+
popd || exit $?
92+
CERT_DIR="${TMP_DIR}/certs"
93+
9194
run_test() {
9295
echo -e "\nStarting example server for crl test...\n"
9396

@@ -121,7 +124,7 @@ run_test() {
121124
crl_port="$(cat "$ready_file")"
122125

123126
# starts client on crl_port and captures the output from client
124-
capture_out=$(./examples/client/client -p $crl_port 2>&1)
127+
capture_out=$(cd "${CERT_DIR}/.." && "${SRC_DIR}/examples/client/client" -p $crl_port 2>&1)
125128
client_result=$?
126129

127130
wait $server_pid
@@ -187,7 +190,7 @@ run_hashdir_test() {
187190
crl_port="$(cat "$ready_file")"
188191

189192
# starts client on crl_port and captures the output from client
190-
capture_out=$(./examples/client/client -p $crl_port -9 2>&1)
193+
capture_out=$(cd "${CERT_DIR}/.." && "${SRC_DIR}/examples/client/client" -p $crl_port -9 2>&1)
191194
client_result=$?
192195

193196
wait $server_pid

src/ssl.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7712,19 +7712,102 @@ 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 */
77187790
WOLFSSL_ABI
77197791
int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
77207792
{
7793+
size_t dn_len;
7794+
77217795
WOLFSSL_ENTER("wolfSSL_check_domain_name");
77227796

77237797
if (ssl == NULL || dn == NULL) {
77247798
WOLFSSL_MSG("Bad function argument: NULL");
77257799
return WOLFSSL_FAILURE;
77267800
}
77277801

7802+
dn_len = XSTRLEN(dn);
7803+
7804+
if ((! wolfssl_local_IsValidFQDN(dn, (word32)dn_len)) &&
7805+
(XSTRCMP(dn, "localhost") != 0))
7806+
{
7807+
WOLFSSL_MSG("Bad function argument: fails wolfssl_local_IsValidFQDN");
7808+
return WOLFSSL_FAILURE;
7809+
}
7810+
77287811
if (ssl->buffers.domainName.buffer)
77297812
XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
77307813

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)