summaryrefslogtreecommitdiffstats
path: root/contrib/wpa_supplicant/x509v3.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2008-03-24 19:46:53 +0000
committersam <sam@FreeBSD.org>2008-03-24 19:46:53 +0000
commit153f9c1cd9a5b749f57e28682fadb39c781e1e5d (patch)
treef77bae77287d18eaa89acc25e38b5acccca132fe /contrib/wpa_supplicant/x509v3.c
parent35aef052ff21baa52c4cec68b512986c21f70a48 (diff)
downloadFreeBSD-src-153f9c1cd9a5b749f57e28682fadb39c781e1e5d.zip
FreeBSD-src-153f9c1cd9a5b749f57e28682fadb39c781e1e5d.tar.gz
Import of WPA supplicant 0.5.10
Diffstat (limited to 'contrib/wpa_supplicant/x509v3.c')
-rw-r--r--contrib/wpa_supplicant/x509v3.c96
1 files changed, 88 insertions, 8 deletions
diff --git a/contrib/wpa_supplicant/x509v3.c b/contrib/wpa_supplicant/x509v3.c
index 1283fff..484c54b 100644
--- a/contrib/wpa_supplicant/x509v3.c
+++ b/contrib/wpa_supplicant/x509v3.c
@@ -1,6 +1,6 @@
/*
* X.509v3 certificate parsing and processing (RFC 3280 profile)
- * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -75,8 +75,39 @@ void x509_certificate_chain_free(struct x509_certificate *cert)
}
+static int x509_whitespace(char c)
+{
+ return c == ' ' || c == '\t';
+}
+
+
+static void x509_str_strip_whitespace(char *a)
+{
+ char *ipos, *opos;
+ int remove_whitespace = 1;
+
+ ipos = opos = a;
+
+ while (*ipos) {
+ if (remove_whitespace && x509_whitespace(*ipos))
+ ipos++;
+ else {
+ remove_whitespace = x509_whitespace(*ipos);
+ *opos++ = *ipos++;
+ }
+ }
+
+ *opos-- = '\0';
+ if (opos > a && x509_whitespace(*opos))
+ *opos = '\0';
+}
+
+
static int x509_str_compare(const char *a, const char *b)
{
+ char *aa, *bb;
+ int ret;
+
if (!a && b)
return -1;
if (a && !b)
@@ -84,14 +115,31 @@ static int x509_str_compare(const char *a, const char *b)
if (!a && !b)
return 0;
- return os_strcmp(a, b);
+ aa = os_strdup(a);
+ bb = os_strdup(b);
+
+ if (aa == NULL || bb == NULL) {
+ os_free(aa);
+ os_free(bb);
+ return os_strcasecmp(a, b);
+ }
+
+ x509_str_strip_whitespace(aa);
+ x509_str_strip_whitespace(bb);
+
+ ret = os_strcasecmp(aa, bb);
+
+ os_free(aa);
+ os_free(bb);
+
+ return ret;
}
/**
* x509_name_compare - Compare X.509 certificate names
* @a: Certificate name
- * @b: Certifiatte name
+ * @b: Certificate name
* Returns: <0, 0, or >0 based on whether a is less than, equal to, or
* greater than b
*/
@@ -553,6 +601,17 @@ static int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag,
if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
buf, len);
+ if (year < 1970) {
+ /*
+ * At least some test certificates have been configured
+ * to use dates prior to 1970. Set the date to
+ * beginning of 1970 to handle these case.
+ */
+ wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
+ "assume epoch as the time", year);
+ *val = 0;
+ return 0;
+ }
return -1;
}
@@ -720,7 +779,8 @@ static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
return 0;
}
- if (asn1_get_next(pos, len, &hdr) < 0 ||
+ if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length,
+ &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL) {
wpa_printf(MSG_DEBUG, "X509: Failed to parse "
"BasicConstraints");
@@ -1443,6 +1503,13 @@ static int x509_valid_issuer(const struct x509_certificate *cert)
return -1;
}
+ if (cert->version == X509_CERT_V3 &&
+ !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
+ wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
+ "include BasicConstraints extension");
+ return -1;
+ }
+
if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
!(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
@@ -1466,7 +1533,8 @@ int x509_certificate_chain_validate(struct x509_certificate *trusted,
struct x509_certificate *chain,
int *reason)
{
- int idx, chain_trusted = 0;
+ long unsigned idx;
+ int chain_trusted = 0;
struct x509_certificate *cert, *trust;
char buf[128];
struct os_time now;
@@ -1478,12 +1546,15 @@ int x509_certificate_chain_validate(struct x509_certificate *trusted,
for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
x509_name_string(&cert->subject, buf, sizeof(buf));
- wpa_printf(MSG_DEBUG, "X509: %d: %s", idx, buf);
+ wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
if (chain_trusted)
continue;
- if (now.sec < cert->not_before || now.sec > cert->not_after) {
+ if ((unsigned long) now.sec <
+ (unsigned long) cert->not_before ||
+ (unsigned long) now.sec >
+ (unsigned long) cert->not_after) {
wpa_printf(MSG_INFO, "X509: Certificate not valid "
"(now=%lu not_before=%lu not_after=%lu)",
now.sec, cert->not_before, cert->not_after);
@@ -1505,7 +1576,16 @@ int x509_certificate_chain_validate(struct x509_certificate *trusted,
return -1;
}
- /* TODO: validate pathLenConstraint */
+ if ((cert->next->extensions_present &
+ X509_EXT_PATH_LEN_CONSTRAINT) &&
+ idx > cert->next->path_len_constraint) {
+ wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
+ " not met (idx=%lu issuer "
+ "pathLenConstraint=%lu)", idx,
+ cert->next->path_len_constraint);
+ *reason = X509_VALIDATE_BAD_CERTIFICATE;
+ return -1;
+ }
if (x509_certificate_check_signature(cert->next, cert)
< 0) {
OpenPOWER on IntegriCloud