diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2016-07-03 21:41:57 +0100 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2016-07-11 23:30:04 +0100 |
commit | 5bd5dcd49605ca2aa7931599894302a3ac4b0b04 (patch) | |
tree | 6a0b8a29f6688a2e97b098ee29f690f7b10ed041 /crypto/asn1/a_strex.c | |
parent | 1d03b7b893223b1b049cb992e5c57c9a10f5846c (diff) |
Add nameConstraints commonName checking.
New hostname checking function asn1_valid_host()
Check commonName entries against nameConstraints: any CN components in
EE certificate which look like hostnames are checked against
nameConstraints.
Note that RFC5280 et al only require checking subject alt name against
DNS name constraints.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'crypto/asn1/a_strex.c')
-rw-r--r-- | crypto/asn1/a_strex.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c index d419e9d2ce..eb55c6b5d7 100644 --- a/crypto/asn1/a_strex.c +++ b/crypto/asn1/a_strex.c @@ -10,6 +10,7 @@ #include <stdio.h> #include <string.h> #include "internal/cryptlib.h" +#include "internal/asn1_int.h" #include <openssl/crypto.h> #include <openssl/x509.h> #include <openssl/asn1.h> @@ -592,3 +593,53 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) *out = stmp.data; return stmp.length; } + +/* Return 1 if host is a valid hostname and 0 otherwise */ +int asn1_valid_host(const ASN1_STRING *host) +{ + int hostlen = host->length; + const unsigned char *hostptr = host->data; + int type = host->type; + int i; + char width = -1; + unsigned short chflags = 0, prevchflags; + + if (type > 0 && type < 31) + width = tag2nbyte[type]; + if (width == -1 || hostlen == 0) + return 0; + /* Treat UTF8String as width 1 as any MSB set is invalid */ + if (width == 0) + width = 1; + for (i = 0 ; i < hostlen; i+= width) { + prevchflags = chflags; + /* Value must be <= 0x7F: check upper bytes are all zeroes */ + if (width == 4) { + if (*hostptr++ != 0 || *hostptr++ != 0 || *hostptr++ != 0) + return 0; + } else if (width == 2) { + if (*hostptr++ != 0) + return 0; + } + if (*hostptr > 0x7f) + return 0; + chflags = char_type[*hostptr++]; + if (!(chflags & (CHARTYPE_HOST_ANY | CHARTYPE_HOST_WILD))) { + /* Nothing else allowed at start or end of string */ + if (i == 0 || i == hostlen - 1) + return 0; + /* Otherwise invalid if not dot or hyphen */ + if (!(chflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN))) + return 0; + /* + * If previous is dot or hyphen then illegal unless both + * are hyphens: as .- -. .. are all illegal + */ + if (prevchflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN) + && ((prevchflags & CHARTYPE_HOST_DOT) + || (chflags & CHARTYPE_HOST_DOT))) + return 0; + } + } + return 1; +} |