summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJob Snijders <job@cvs.openbsd.org>2023-04-23 21:31:17 +0000
committerJob Snijders <job@cvs.openbsd.org>2023-04-23 21:31:17 +0000
commit51a2efc4d0c7da6cafddb26f81bf783fc89823c5 (patch)
tree210f7610c3ef46f2420a549d6bf72a39de695836
parent0d4c5be083434537a6fba3bcbad80673fb85ec57 (diff)
Add compliance checks for the X.509 version field
Check whether the X.509 version is in the range of valid version values, and also checks whether the version is consistent with fields new to those versions (such as X.509 v3 extensions). X.690 section 11.5 states: "The encoding of a set value or a sequence value shall not include an encoding for any component value which is equal to its default value." However, enforcing version 1 (value 0) to be absent reportedly caused some issues as recent as July 2020, so accept version 1 even if it is explicitly encoded. OK tb@ beck@
-rw-r--r--lib/libcrypto/asn1/x_x509.c29
-rw-r--r--lib/libcrypto/x509/x509.h3
-rw-r--r--lib/libcrypto/x509/x509_err.c3
3 files changed, 31 insertions, 4 deletions
diff --git a/lib/libcrypto/asn1/x_x509.c b/lib/libcrypto/asn1/x_x509.c
index 227af88e824..87b714877f9 100644
--- a/lib/libcrypto/asn1/x_x509.c
+++ b/lib/libcrypto/asn1/x_x509.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x_x509.c,v 1.31 2022/11/26 16:08:50 tb Exp $ */
+/* $OpenBSD: x_x509.c,v 1.32 2023/04/23 21:31:16 job Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -61,6 +61,7 @@
#include <openssl/opensslconf.h>
#include <openssl/asn1t.h>
+#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -194,10 +195,34 @@ x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
break;
- case ASN1_OP_D2I_POST:
+ case ASN1_OP_D2I_POST: {
+ const ASN1_BIT_STRING *issuerUID = NULL, *subjectUID = NULL;
+ long version;
+
+ version = X509_get_version(ret);
+ /* accept 0 despite DER requiring omission of default values */
+ if (version < 0 || version > 2) {
+ X509error(X509_R_INVALID_VERSION);
+ return 0;
+ }
+
+ /* RFC 5280 section 4.1.2.8, these fields require v2 or v3 */
+ X509_get0_uids(ret, &issuerUID, &subjectUID);
+ if ((issuerUID != NULL || subjectUID != NULL) && version == 0) {
+ X509error(X509_R_INVALID_VERSION);
+ return 0;
+ }
+
+ /* RFC 5280 section 4.1.2.9, extensions require v3. */
+ if (X509_get_ext_count(ret) != 0 && version != 2) {
+ X509error(X509_R_INVALID_VERSION);
+ return 0;
+ }
+
free(ret->name);
ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
break;
+ }
case ASN1_OP_FREE_POST:
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
diff --git a/lib/libcrypto/x509/x509.h b/lib/libcrypto/x509/x509.h
index 9f87700c60f..e8cedaae13e 100644
--- a/lib/libcrypto/x509/x509.h
+++ b/lib/libcrypto/x509/x509.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509.h,v 1.96 2023/04/18 08:47:28 tb Exp $ */
+/* $OpenBSD: x509.h,v 1.97 2023/04/23 21:31:16 job Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1200,6 +1200,7 @@ void ERR_load_X509_strings(void);
#define X509_R_UNSUPPORTED_ALGORITHM 111
#define X509_R_WRONG_LOOKUP_TYPE 112
#define X509_R_WRONG_TYPE 122
+#define X509_R_INVALID_VERSION 123
#ifdef __cplusplus
}
diff --git a/lib/libcrypto/x509/x509_err.c b/lib/libcrypto/x509/x509_err.c
index 272d2894d86..84328df62a2 100644
--- a/lib/libcrypto/x509/x509_err.c
+++ b/lib/libcrypto/x509/x509_err.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509_err.c,v 1.19 2023/02/16 08:38:17 tb Exp $ */
+/* $OpenBSD: x509_err.c,v 1.20 2023/04/23 21:31:16 job Exp $ */
/* ====================================================================
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
*
@@ -104,6 +104,7 @@ static ERR_STRING_DATA X509_str_reasons[] = {
{ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
{ERR_REASON(X509_R_WRONG_LOOKUP_TYPE) , "wrong lookup type"},
{ERR_REASON(X509_R_WRONG_TYPE) , "wrong type"},
+ {ERR_REASON(X509_R_INVALID_VERSION) , "wrong x509 version"},
{0, NULL}
};