* https://www.openssl.org/source/license.html
*/
-#include "e_os.h" /* for strncasecmp */
#include "internal/cryptlib.h"
-#include <limits.h>
+#include "internal/numbers.h"
#include <stdio.h>
#include "internal/asn1_int.h"
#include <openssl/asn1t.h>
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+/*
+ * We cannot use strncasecmp here because that applies locale specific rules.
+ * For example in Turkish 'I' is not the uppercase character for 'i'. We need to
+ * do a simple ASCII case comparison ignoring the locale (that is why we use
+ * numeric constants below).
+ */
+static int ia5ncasecmp(const char *s1, const char *s2, size_t n)
+{
+ for (; n > 0; n--, s1++, s2++) {
+ if (*s1 != *s2) {
+ unsigned char c1 = (unsigned char)*s1, c2 = (unsigned char)*s2;
+
+ /* Convert to lower case */
+ if (c1 >= 0x41 /* A */ && c1 <= 0x5A /* Z */)
+ c1 += 0x20;
+ if (c2 >= 0x41 /* A */ && c2 <= 0x5A /* Z */)
+ c2 += 0x20;
+
+ if (c1 == c2)
+ continue;
+
+ if (c1 < c2)
+ return -1;
+
+ /* c1 > c2 */
+ return 1;
+ } else if (*s1 == 0) {
+ /* If we get here we know that *s2 == 0 too */
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+static int ia5casecmp(const char *s1, const char *s2)
+{
+ return ia5ncasecmp(s1, s2, SIZE_MAX);
+}
+
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
{
return X509_V_ERR_PERMITTED_VIOLATION;
}
- if (strcasecmp(baseptr, dnsptr))
+ if (ia5casecmp(baseptr, dnsptr))
return X509_V_ERR_PERMITTED_VIOLATION;
return X509_V_OK;
if (!baseat && (*baseptr == '.')) {
if (eml->length > base->length) {
emlptr += eml->length - base->length;
- if (strcasecmp(baseptr, emlptr) == 0)
+ if (ia5casecmp(baseptr, emlptr) == 0)
return X509_V_OK;
}
return X509_V_ERR_PERMITTED_VIOLATION;
}
emlptr = emlat + 1;
/* Just have hostname left to match: case insensitive */
- if (strcasecmp(baseptr, emlptr))
+ if (ia5casecmp(baseptr, emlptr))
return X509_V_ERR_PERMITTED_VIOLATION;
return X509_V_OK;
if (*baseptr == '.') {
if (hostlen > base->length) {
p = hostptr + hostlen - base->length;
- if (strncasecmp(p, baseptr, base->length) == 0)
+ if (ia5ncasecmp(p, baseptr, base->length) == 0)
return X509_V_OK;
}
return X509_V_ERR_PERMITTED_VIOLATION;
}
if ((base->length != (int)hostlen)
- || strncasecmp(hostptr, baseptr, hostlen))
+ || ia5ncasecmp(hostptr, baseptr, hostlen))
return X509_V_ERR_PERMITTED_VIOLATION;
return X509_V_OK;