/* compare hostname against certificate, taking account of wildcards
* return 1 on success or 0 on error
+ *
+ * note: certnamesize is required as X509 certs can contain embedded NULLs in
+ * the strings such as CN or subjectAltName
*/
int
-_gnutls_hostname_compare (const char *certname, const char *hostname)
+_gnutls_hostname_compare (const char *certname, size_t certnamesize, const char *hostname)
{
/* find the first different character */
for (; *certname && *hostname && toupper (*certname) == toupper (*hostname);
- certname++, hostname++)
+ certname++, hostname++, certnamesize--)
;
/* the strings are the same */
- if (strlen (certname) == 0 && strlen (hostname) == 0)
+ if (certnamesize == 0 && strlen (hostname) == 0)
return 1;
if (*certname == '*')
/* a wildcard certificate */
certname++;
+ certnamesize--;
while (1)
{
/* Use a recursive call to allow multiple wildcards */
- if (_gnutls_hostname_compare (certname, hostname))
+ if (_gnutls_hostname_compare (certname, certnamesize, hostname))
{
return 1;
}
int _gnutls_hex2bin (const opaque * hex_data, int hex_size, opaque * bin_data,
size_t * bin_size);
-int _gnutls_hostname_compare (const char *certname, const char *hostname);
+int _gnutls_hostname_compare (const char *certname, size_t certnamesize, const char *hostname);
#define MAX_CN 256
#endif
if (ret == GNUTLS_SAN_DNSNAME)
{
found_dnsname = 1;
- if (_gnutls_hostname_compare (dnsname, hostname))
+ if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
{
return 1;
}
found_dnsname = 1; /* RFC 2818 is unclear whether the CN
should be compared for IP addresses
too, but we won't do it. */
- if (_gnutls_hostname_compare (dnsname, hostname))
+ if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
{
return 1;
}
return 0;
}
- if (_gnutls_hostname_compare (dnsname, hostname))
+ if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
{
return 1;
}