untrusted comment: verify with openbsd-68-base.pub
RWQZj25CSG5R2mIQDep891t6cUijyOifN1i+jDC8wduAq4vkfarrIfbCk42fmsPtgfBvycnKCFi/rch/F/d2QXyhhm36zcce7g0=

OpenBSD 6.8 errata 008, December 8, 2020:

Malformed ASN.1 in a certificate revocation list or a timestamp
response token can lead to a NULL pointer dereference.

Apply by doing:
    signify -Vep /etc/signify/openbsd-68-base.pub -x 008_asn1.patch.sig \
        -m - | (cd /usr/src && patch -p0)

And then rebuild and install libcrypto, isakmpd and unwind:
    cd /usr/src/lib/libcrypto
    make obj
    make includes
    make
    make install
    cd /usr/src/sbin/isakmpd
    make obj
    make
    make install
    cd /usr/src/sbin/unwind
    make obj
    make
    make install

Index: lib/libcrypto/asn1/asn1.h
===================================================================
RCS file: /cvs/src/lib/libcrypto/asn1/asn1.h,v
retrieving revision 1.53
diff -u -p -r1.53 asn1.h
--- lib/libcrypto/asn1/asn1.h	30 Nov 2018 04:51:19 -0000	1.53
+++ lib/libcrypto/asn1/asn1.h	3 Dec 2020 18:56:53 -0000
@@ -1137,6 +1137,7 @@ void ERR_load_ASN1_strings(void);
 #define ASN1_R_BAD_OBJECT_HEADER			 102
 #define ASN1_R_BAD_PASSWORD_READ			 103
 #define ASN1_R_BAD_TAG					 104
+#define ASN1_R_BAD_TEMPLATE				 230
 #define ASN1_R_BMPSTRING_IS_WRONG_LENGTH		 214
 #define ASN1_R_BN_LIB					 105
 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
Index: lib/libcrypto/asn1/asn1_err.c
===================================================================
RCS file: /cvs/src/lib/libcrypto/asn1/asn1_err.c,v
retrieving revision 1.21
diff -u -p -r1.21 asn1_err.c
--- lib/libcrypto/asn1/asn1_err.c	29 Mar 2018 02:29:24 -0000	1.21
+++ lib/libcrypto/asn1/asn1_err.c	3 Dec 2020 18:56:53 -0000
@@ -85,6 +85,7 @@ static ERR_STRING_DATA ASN1_str_reasons[
 	{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER)    , "bad object header"},
 	{ERR_REASON(ASN1_R_BAD_PASSWORD_READ)    , "bad password read"},
 	{ERR_REASON(ASN1_R_BAD_TAG)              , "bad tag"},
+	{ERR_REASON(ASN1_R_BAD_TEMPLATE)         , "bad template"},
 	{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), "bmpstring is wrong length"},
 	{ERR_REASON(ASN1_R_BN_LIB)               , "bn lib"},
 	{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},
Index: lib/libcrypto/asn1/asn1_lib.c
===================================================================
RCS file: /cvs/src/lib/libcrypto/asn1/asn1_lib.c,v
retrieving revision 1.44
diff -u -p -r1.44 asn1_lib.c
--- lib/libcrypto/asn1/asn1_lib.c	17 Nov 2018 09:34:11 -0000	1.44
+++ lib/libcrypto/asn1/asn1_lib.c	3 Dec 2020 18:56:53 -0000
@@ -388,6 +388,8 @@ ASN1_STRING_cmp(const ASN1_STRING *a, co
 {
 	int i;
 
+	if (a == NULL || b == NULL)
+		return -1;
 	i = (a->length - b->length);
 	if (i == 0) {
 		i = memcmp(a->data, b->data, a->length);
Index: lib/libcrypto/asn1/tasn_dec.c
===================================================================
RCS file: /cvs/src/lib/libcrypto/asn1/tasn_dec.c,v
retrieving revision 1.37
diff -u -p -r1.37 tasn_dec.c
--- lib/libcrypto/asn1/tasn_dec.c	1 Apr 2019 15:48:04 -0000	1.37
+++ lib/libcrypto/asn1/tasn_dec.c	3 Dec 2020 18:56:53 -0000
@@ -210,6 +210,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, cons
 		break;
 
 	case ASN1_ITYPE_MSTRING:
+		/*
+		 * It never makes sense for multi-strings to have implicit
+		 * tagging, so if tag != -1, then this looks like an error in
+		 * the template.
+		 */
+		if (tag != -1) {
+			ASN1error(ASN1_R_BAD_TEMPLATE);
+			goto err;
+		}
+
 		p = *in;
 		/* Just read in tag and class */
 		ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
@@ -245,6 +255,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, cons
 		    it, tag, aclass, opt, ctx);
 
 	case ASN1_ITYPE_CHOICE:
+		/*
+		 * It never makes sense for CHOICE types to have implicit
+		 * tagging, so if tag != -1, then this looks like an error in
+		 * the template.
+		 */
+		if (tag != -1) {
+			ASN1error(ASN1_R_BAD_TEMPLATE);
+			goto err;
+		}
+
 		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
 			goto auxerr;
 
Index: lib/libcrypto/asn1/tasn_enc.c
===================================================================
RCS file: /cvs/src/lib/libcrypto/asn1/tasn_enc.c,v
retrieving revision 1.22
diff -u -p -r1.22 tasn_enc.c
--- lib/libcrypto/asn1/tasn_enc.c	1 Apr 2019 15:48:04 -0000	1.22
+++ lib/libcrypto/asn1/tasn_enc.c	3 Dec 2020 18:56:53 -0000
@@ -61,6 +61,7 @@
 
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
+#include <openssl/err.h>
 #include <openssl/objects.h>
 
 static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
@@ -152,9 +153,27 @@ ASN1_item_ex_i2d(ASN1_VALUE **pval, unsi
 		break;
 
 	case ASN1_ITYPE_MSTRING:
+		/*
+		 * It never makes sense for multi-strings to have implicit
+		 * tagging, so if tag != -1, then this looks like an error in
+		 * the template.
+		 */
+		if (tag != -1) {
+			ASN1error(ASN1_R_BAD_TEMPLATE);
+			return 0;
+		}
 		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
 
 	case ASN1_ITYPE_CHOICE:
+		/*
+		 * It never makes sense for CHOICE types to have implicit
+		 * tagging, so if tag != -1, then this looks like an error in
+		 * the template.
+		 */
+		if (tag != -1) {
+			ASN1error(ASN1_R_BAD_TEMPLATE);
+			return 0;
+		}
 		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
 			return 0;
 		i = asn1_get_choice_selector(pval, it);
Index: lib/libcrypto/x509/x509_genn.c
===================================================================
RCS file: /cvs/src/lib/libcrypto/x509/x509_genn.c,v
retrieving revision 1.1
diff -u -p -r1.1 x509_genn.c
--- lib/libcrypto/x509/x509_genn.c	4 Jun 2020 15:19:31 -0000	1.1
+++ lib/libcrypto/x509/x509_genn.c	3 Dec 2020 18:56:53 -0000
@@ -117,16 +117,17 @@ OTHERNAME_free(OTHERNAME *a)
 	ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it);
 }
 
+/* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */
 static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = {
 	{
-		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
 		.tag = 0,
 		.offset = offsetof(EDIPARTYNAME, nameAssigner),
 		.field_name = "nameAssigner",
 		.item = &DIRECTORYSTRING_it,
 	},
 	{
-		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.flags = ASN1_TFLG_EXPLICIT,
 		.tag = 1,
 		.offset = offsetof(EDIPARTYNAME, partyName),
 		.field_name = "partyName",
@@ -324,6 +325,37 @@ GENERAL_NAME_dup(GENERAL_NAME *a)
 	return ASN1_item_dup(&GENERAL_NAME_it, a);
 }
 
+static int
+EDIPARTYNAME_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
+{
+	int res;
+
+	/*
+	 * Shouldn't be possible in a valid GENERAL_NAME, but we handle it
+	 * anyway. OTHERNAME_cmp treats NULL != NULL, so we do the same here.
+	 */
+	if (a == NULL || b == NULL)
+		return -1;
+	if (a->nameAssigner == NULL && b->nameAssigner != NULL)
+		return -1;
+	if (a->nameAssigner != NULL && b->nameAssigner == NULL)
+		return 1;
+	/* If we get here, both have nameAssigner set or both unset. */
+	if (a->nameAssigner != NULL) {
+		res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
+		if (res != 0)
+			return res;
+	}
+	/*
+	 * partyName is required, so these should never be NULL. We treat it in
+	 * the same way as the a == NULL || b == NULL case above.
+	 */
+	if (a->partyName == NULL || b->partyName == NULL)
+		return -1;
+
+	return ASN1_STRING_cmp(a->partyName, b->partyName);
+}
+
 /* Returns 0 if they are equal, != 0 otherwise. */
 int
 GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
@@ -334,8 +366,11 @@ GENERAL_NAME_cmp(GENERAL_NAME *a, GENERA
 		return -1;
 	switch (a->type) {
 	case GEN_X400:
+		result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
+		break;
+
 	case GEN_EDIPARTY:
-		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
+		result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName);
 		break;
 
 	case GEN_OTHERNAME:
@@ -384,8 +419,11 @@ GENERAL_NAME_set0_value(GENERAL_NAME *a,
 {
 	switch (type) {
 	case GEN_X400:
+		a->d.x400Address = value;
+		break;
+
 	case GEN_EDIPARTY:
-		a->d.other = value;
+		a->d.ediPartyName = value;
 		break;
 
 	case GEN_OTHERNAME:
@@ -420,8 +458,10 @@ GENERAL_NAME_get0_value(GENERAL_NAME *a,
 		*ptype = a->type;
 	switch (a->type) {
 	case GEN_X400:
+		return a->d.x400Address;
+
 	case GEN_EDIPARTY:
-		return a->d.other;
+		return a->d.ediPartyName;
 
 	case GEN_OTHERNAME:
 		return a->d.otherName;
