summaryrefslogtreecommitdiff
path: root/lib/libcrypto/asn1
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2022-06-25 16:15:19 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2022-06-25 16:15:19 +0000
commitc9951670996345043c9dff02e55052d7e7a6957d (patch)
treef15e6a1ba0d4899e9f7b5fa6294c6a1eec467fcb /lib/libcrypto/asn1
parentbb921259269a25f2917c71748d5f84a5448cf62f (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.c109
-rw-r--r--lib/libcrypto/asn1/asn1.h6
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);