@@ -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;
0 commit comments