/*
* X.509v3 certificate parsing and processing (RFC 3280 profile)
- * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2011, 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
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
return -1;
}
- val = os_malloc(hdr.length + 1);
+ val = dup_binstr(hdr.payload, hdr.length);
if (val == NULL) {
x509_free_name(name);
return -1;
}
- os_memcpy(val, hdr.payload, hdr.length);
- val[hdr.length] = '\0';
if (os_strlen(val) != hdr.length) {
wpa_printf(MSG_INFO, "X509: Reject certificate with "
"embedded NUL byte in a string (%s[NUL])",
val);
+ os_free(val);
x509_free_name(name);
return -1;
}
ret = os_snprintf(pos, end - pos, "%s=%s, ",
x509_name_attr_str(name->attr[i].type),
name->attr[i].value);
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
goto done;
pos += ret;
}
if (name->email) {
ret = os_snprintf(pos, end - pos, "/emailAddress=%s",
name->email);
- if (ret < 0 || ret >= end - pos)
+ if (os_snprintf_error(end - pos, ret))
goto done;
pos += ret;
}
wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
/* TODO: parse UniqueIdentifier ::= BIT STRING */
- if (hdr.payload + hdr.length == end)
+ pos = hdr.payload + hdr.length;
+ if (pos == end)
return 0;
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
/* TODO: parse UniqueIdentifier ::= BIT STRING */
- if (hdr.payload + hdr.length == end)
+ pos = hdr.payload + hdr.length;
+ if (pos == end)
return 0;
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
if (pos + hdr.length < end) {
wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
"encoded certificate",
- pos + hdr.length, end - pos + hdr.length);
+ pos + hdr.length, end - (pos + hdr.length));
end = pos + hdr.length;
}
}
if (hdr.length != hash_len ||
- os_memcmp(hdr.payload, hash, hdr.length) != 0) {
+ os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
"with calculated tbsCertificate hash");
os_free(data);
return -1;
}
+ if (hdr.payload + hdr.length < data + data_len) {
+ wpa_hexdump(MSG_INFO,
+ "X509: Extra data after certificate signature hash",
+ hdr.payload + hdr.length,
+ data + data_len - hdr.payload - hdr.length);
+ os_free(data);
+ return -1;
+ }
+
os_free(data);
wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
*/
int x509_certificate_chain_validate(struct x509_certificate *trusted,
struct x509_certificate *chain,
- int *reason)
+ int *reason, int disable_time_checks)
{
long unsigned idx;
int chain_trusted = 0;
if (chain_trusted)
continue;
- if ((unsigned long) now.sec <
- (unsigned long) cert->not_before ||
- (unsigned long) now.sec >
- (unsigned long) cert->not_after) {
+ if (!disable_time_checks &&
+ ((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);