diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2022-06-25 16:15:19 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2022-06-25 16:15:19 +0000 |
commit | c9951670996345043c9dff02e55052d7e7a6957d (patch) | |
tree | f15e6a1ba0d4899e9f7b5fa6294c6a1eec467fcb /lib/libcrypto/asn1 | |
parent | bb921259269a25f2917c71748d5f84a5448cf62f (diff) |
Reuse ASN1_INTEGER functions for ASN1_ENUMERATED_{get,set}()
Instead of having a separate get/set implementation, reuse the ASN1_INTEGER
code. Also prepare to provide ASN1_ENUMERATED_{get,set}_int64().
ok beck@ tb@
Diffstat (limited to 'lib/libcrypto/asn1')
-rw-r--r-- | lib/libcrypto/asn1/a_enum.c | 109 | ||||
-rw-r--r-- | lib/libcrypto/asn1/asn1.h | 6 |
2 files changed, 59 insertions, 56 deletions
diff --git a/lib/libcrypto/asn1/a_enum.c b/lib/libcrypto/asn1/a_enum.c index 007a4218495..11868cef377 100644 --- a/lib/libcrypto/asn1/a_enum.c +++ b/lib/libcrypto/asn1/a_enum.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_enum.c,v 1.23 2021/12/25 13:17:48 jsing Exp $ */ +/* $OpenBSD: a_enum.c,v 1.24 2022/06/25 16:15:18 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -57,7 +57,7 @@ */ #include <limits.h> -#include <stdio.h> +#include <string.h> #include <openssl/asn1.h> #include <openssl/asn1t.h> @@ -65,6 +65,9 @@ #include <openssl/buffer.h> #include <openssl/err.h> +#include "asn1_locl.h" +#include "bytestring.h" + /* * Code for ENUMERATED type: identical to INTEGER apart from a different tag. * for comments on encoding see a_int.c @@ -82,6 +85,16 @@ ASN1_ENUMERATED_new(void) return (ASN1_ENUMERATED *)ASN1_item_new(&ASN1_ENUMERATED_it); } +static void +asn1_aenum_clear(ASN1_ENUMERATED *aenum) +{ + freezero(aenum->data, aenum->length); + + memset(aenum, 0, sizeof(*aenum)); + + aenum->type = V_ASN1_ENUMERATED; +} + void ASN1_ENUMERATED_free(ASN1_ENUMERATED *a) { @@ -89,73 +102,59 @@ ASN1_ENUMERATED_free(ASN1_ENUMERATED *a) } int -ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) +ASN1_ENUMERATED_get_int64(int64_t *out_val, const ASN1_ENUMERATED *aenum) { - int j, k; - unsigned int i; - unsigned char buf[sizeof(long) + 1]; - long d; - - a->type = V_ASN1_ENUMERATED; - if (a->length < (int)(sizeof(long) + 1)) { - free(a->data); - a->data = calloc(1, sizeof(long) + 1); - } - if (a->data == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - return (0); - } - d = v; - if (d < 0) { - d = -d; - a->type = V_ASN1_NEG_ENUMERATED; + CBS cbs; + + *out_val = 0; + + if (aenum == NULL || aenum->length < 0) + return 0; + + if (aenum->type != V_ASN1_ENUMERATED && + aenum->type != V_ASN1_NEG_ENUMERATED) { + ASN1error(ASN1_R_WRONG_INTEGER_TYPE); + return 0; } - for (i = 0; i < sizeof(long); i++) { - if (d == 0) - break; - buf[i] = (int)d & 0xff; - d >>= 8; + CBS_init(&cbs, aenum->data, aenum->length); + + return asn1_aint_get_int64(&cbs, (aenum->type == V_ASN1_NEG_ENUMERATED), + out_val); +} + +int +ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *aenum, int64_t val) +{ + asn1_aenum_clear(aenum); + + if (val < 0) { + aenum->type = V_ASN1_NEG_ENUMERATED; + val = -val; } - j = 0; - for (k = i - 1; k >= 0; k--) - a->data[j++] = buf[k]; - a->length = j; - return (1); + + return asn1_aint_set_uint64((uint64_t)val, &aenum->data, &aenum->length); } long -ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) +ASN1_ENUMERATED_get(const ASN1_ENUMERATED *aenum) { - int neg = 0, i; - unsigned long r = 0; + int64_t val; - if (a == NULL) - return (0L); - i = a->type; - if (i == V_ASN1_NEG_ENUMERATED) - neg = 1; - else if (i != V_ASN1_ENUMERATED) + if (!ASN1_ENUMERATED_get_int64(&val, aenum)) return -1; - - if (a->length > (int)sizeof(long)) { - /* hmm... a bit ugly */ + if (val < LONG_MIN || val > LONG_MAX) { + /* hmm... a bit ugly, return all ones */ return -1; } - if (a->data == NULL) - return 0; - - for (i = 0; i < a->length; i++) { - r <<= 8; - r |= (unsigned char)a->data[i]; - } - if (r > LONG_MAX) - return -1; + return (long)val; +} - if (neg) - return -(long)r; - return (long)r; +int +ASN1_ENUMERATED_set(ASN1_ENUMERATED *aenum, long val) +{ + return ASN1_ENUMERATED_set_int64(aenum, val); } ASN1_ENUMERATED * diff --git a/lib/libcrypto/asn1/asn1.h b/lib/libcrypto/asn1/asn1.h index d6adb0d22e4..0db0b1d8fee 100644 --- a/lib/libcrypto/asn1/asn1.h +++ b/lib/libcrypto/asn1/asn1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1.h,v 1.63 2022/06/25 15:39:12 jsing Exp $ */ +/* $OpenBSD: asn1.h,v 1.64 2022/06/25 16:15:18 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -759,6 +759,10 @@ long ASN1_INTEGER_get(const ASN1_INTEGER *a); ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); +#ifdef LIBRESSL_INTERNAL +int ASN1_ENUMERATED_get_int64(int64_t *out_val, const ASN1_ENUMERATED *aenum); +int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *aenum, int64_t val); +#endif int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai); |