From 0090c6809e04e08e1476b0c6a97c055d50f51ba5 Mon Sep 17 00:00:00 2001 From: jsing Date: Sat, 26 Mar 2022 14:47:58 +0000 Subject: [PATCH] Provide asn1_get_primitive() This takes a CBS, gets the ASN.1 identifier and length, ensures the resulting identifier is a valid primitive, then returns the tag number and the content as a CBS. ok inoguchi@ tb@ --- lib/libcrypto/asn1/asn1_lib.c | 33 ++++++++++++++++++++++++++++++++- lib/libcrypto/asn1/asn1_locl.h | 4 +++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/libcrypto/asn1/asn1_lib.c b/lib/libcrypto/asn1/asn1_lib.c index 542a72f6f15..6a29c327fe2 100644 --- a/lib/libcrypto/asn1/asn1_lib.c +++ b/lib/libcrypto/asn1/asn1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_lib.c,v 1.51 2021/12/25 07:04:03 jsing Exp $ */ +/* $OpenBSD: asn1_lib.c,v 1.52 2022/03/26 14:47:58 jsing Exp $ */ /* * Copyright (c) 2021 Joel Sing * @@ -16,6 +16,7 @@ */ #include +#include #include "bytestring.h" @@ -169,3 +170,33 @@ asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_tag_class, return 1; } + +int +asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number, + CBS *out_content) +{ + int constructed, indefinite; + uint32_t tag_number, length; + uint8_t tag_class; + + *out_tag_number = 0; + + CBS_init(out_content, NULL, 0); + + if (!asn1_get_identifier_cbs(cbs, der_mode, &tag_class, &constructed, + &tag_number)) + return 0; + if (!asn1_get_length_cbs(cbs, der_mode, &indefinite, &length)) + return 0; + + /* A primitive is not constructed and has a definite length. */ + if (constructed || indefinite) + return 0; + + if (!CBS_get_bytes(cbs, out_content, length)) + return 0; + + *out_tag_number = tag_number; + + return 1; +} diff --git a/lib/libcrypto/asn1/asn1_locl.h b/lib/libcrypto/asn1/asn1_locl.h index 12f7eadfb3f..756e4070ba4 100644 --- a/lib/libcrypto/asn1/asn1_locl.h +++ b/lib/libcrypto/asn1/asn1_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_locl.h,v 1.23 2022/03/19 17:49:32 jsing Exp $ */ +/* $OpenBSD: asn1_locl.h,v 1.24 2022/03/26 14:47:58 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -196,6 +196,8 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_class, int *out_constructed, uint32_t *out_tag_number, int *out_indefinite, uint32_t *out_length); +int asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number, + CBS *out_content); int asn1_tag2charwidth(int tag); -- 2.20.1