-/* $OpenBSD: asn1_locl.h,v 1.36 2022/09/03 18:45:51 jsing Exp $ */
+/* $OpenBSD: asn1_locl.h,v 1.37 2022/09/03 18:52:18 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
int asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number,
CBS *out_content);
+int asn1_must_be_constructed(int tag);
+int asn1_must_be_primitive(int tag);
int asn1_tag2charwidth(int tag);
int asn1_abs_set_unused_bits(ASN1_BIT_STRING *abs, uint8_t unused_bits);
int c2i_ASN1_ENUMERATED_cbs(ASN1_ENUMERATED **out_aenum, CBS *cbs);
+int c2i_ASN1_ENUMERATED_cbs(ASN1_ENUMERATED **out_aenum, CBS *cbs);
+
int asn1_aint_get_uint64(CBS *cbs, uint64_t *out_val);
int asn1_aint_set_uint64(uint64_t val, uint8_t **out_data, int *out_len);
int asn1_aint_get_int64(CBS *cbs, int negative, int64_t *out_val);
-/* $OpenBSD: asn1_types.c,v 1.1 2021/12/14 17:35:21 jsing Exp $ */
+/* $OpenBSD: asn1_types.c,v 1.2 2022/09/03 18:52:18 jsing Exp $ */
/*
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
#include <openssl/asn1.h>
+#define ASN1_ENCODING_CONSTRUCTED_ONLY 1
+#define ASN1_ENCODING_PRIMITIVE_ONLY 2
+
struct asn1_type {
const char *name;
uint32_t bit_value;
int char_width;
+ int encoding;
};
/*
.name = "BOOLEAN",
.bit_value = 0,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[2] = {
/* Tag 2 (0x02) - Integer */
.name = "INTEGER",
.bit_value = 0,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[3] = {
/* Tag 3 (0x03) - BitString */
.name = "NULL",
.bit_value = 0,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[6] = {
/* Tag 6 (0x06) - Object Identifier */
.name = "OBJECT",
.bit_value = 0,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[7] = {
/* Tag 7 (0x07) - Object Descriptor */
.name = "REAL",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[10] = {
/* Tag 10 (0x0a) - Enumerated */
.name = "ENUMERATED",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[11] = {
/* Tag 11 (0x0b) - Embedded PDV */
.name = "<ASN1 13 RELATIVE OID>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[14] = {
/* Tag 14 (0x0e) - Time */
.name = "<ASN1 14 TIME>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
+ .encoding = ASN1_ENCODING_PRIMITIVE_ONLY,
},
[15] = {
/* Tag 15 (0x0f) - Reserved */
.name = "SEQUENCE",
.bit_value = B_ASN1_SEQUENCE,
.char_width = -1,
+ .encoding = ASN1_ENCODING_CONSTRUCTED_ONLY,
},
[17] = {
/* Tag 17 (0x11) - Set */
.name = "SET",
.bit_value = 0,
.char_width = -1,
+ .encoding = ASN1_ENCODING_CONSTRUCTED_ONLY,
},
[18] = {
/* Tag 18 (0x12) - NumericString */
return &asn1_types[tag];
}
+int
+asn1_must_be_constructed(int tag)
+{
+ const struct asn1_type *at;
+
+ if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
+ tag &= ~V_ASN1_NEG;
+ if ((at = asn1_type_by_tag(tag)) != NULL)
+ return at->encoding == ASN1_ENCODING_CONSTRUCTED_ONLY;
+
+ return 0;
+}
+
+int
+asn1_must_be_primitive(int tag)
+{
+ const struct asn1_type *at;
+
+ if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
+ tag &= ~V_ASN1_NEG;
+ if ((at = asn1_type_by_tag(tag)) != NULL)
+ return at->encoding == ASN1_ENCODING_PRIMITIVE_ONLY;
+
+ return 0;
+}
+
int
asn1_tag2charwidth(int tag)
{
-/* $OpenBSD: tasn_dec.c,v 1.79 2022/09/03 18:45:51 jsing Exp $ */
+/* $OpenBSD: tasn_dec.c,v 1.80 2022/09/03 18:52:18 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
CBS_dup(cbs, &cbs_initial);
CBS_init(&cbs_content, NULL, 0);
- /* XXX - check primitive vs constructed based on utype. */
-
- /* SEQUENCE and SET must be constructed. */
- if ((utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET) && !constructed) {
+ if (asn1_must_be_constructed(utype) && !constructed) {
ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED);
goto err;
}
+ if (asn1_must_be_primitive(utype) && constructed) {
+ ASN1error(ASN1_R_TYPE_NOT_PRIMITIVE);
+ goto err;
+ }
/* SEQUENCE, SET and "OTHER" are left in encoded form. */
if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET ||