summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libcrypto/asn1/x_long.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/lib/libcrypto/asn1/x_long.c b/lib/libcrypto/asn1/x_long.c
index ff72338cc07..b51ea6f2144 100644
--- a/lib/libcrypto/asn1/x_long.c
+++ b/lib/libcrypto/asn1/x_long.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: x_long.c,v 1.16 2019/04/20 11:13:15 jsing Exp $ */
+/* $OpenBSD: x_long.c,v 1.17 2022/06/26 13:10:15 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -70,6 +70,7 @@
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void long_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
@@ -83,7 +84,7 @@ static ASN1_PRIMITIVE_FUNCS long_pf = {
.flags = 0,
.prim_new = long_new,
.prim_free = long_free,
- .prim_clear = long_free, /* Clear should set to initial value */
+ .prim_clear = long_clear,
.prim_c2i = long_c2i,
.prim_i2c = long_i2c,
.prim_print = long_print,
@@ -109,17 +110,37 @@ const ASN1_ITEM ZLONG_it = {
.sname = "ZLONG",
};
+static void
+long_get(ASN1_VALUE **pval, long *out_val)
+{
+ memcpy(out_val, pval, sizeof(long));
+}
+
+static void
+long_set(ASN1_VALUE **pval, long val)
+{
+ memcpy(pval, &val, sizeof(long));
+}
+
static int
long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
- *(long *)pval = it->size;
+ long_clear(pval, it);
+
return 1;
}
static void
long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
- *(long *)pval = it->size;
+ long_clear(pval, it);
+}
+
+static void
+long_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ /* Zero value. */
+ long_set(pval, it->size);
}
static int
@@ -129,11 +150,8 @@ long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
long ltmp;
unsigned long utmp;
int clen, pad, i;
- /* this exists to bypass broken gcc optimization */
- char *cp = (char *)pval;
- /* use memcpy, because we may not be long aligned */
- memcpy(&ltmp, cp, sizeof(long));
+ long_get(pval, &ltmp);
if (ltmp == it->size)
return -1;
@@ -175,7 +193,7 @@ long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
int neg, i;
long ltmp;
unsigned long utmp = 0;
- char *cp = (char *)pval;
+
if (len > (int)sizeof(long)) {
ASN1error(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
@@ -202,7 +220,9 @@ long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
ASN1error(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
- memcpy(cp, &ltmp, sizeof(long));
+
+ long_set(pval, ltmp);
+
return 1;
}
@@ -210,7 +230,11 @@ static int
long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent,
const ASN1_PCTX *pctx)
{
- if (BIO_printf(out, "%ld\n", *(long *)pval) <= 0)
+ long val;
+
+ long_get(pval, &val);
+
+ if (BIO_printf(out, "%ld\n", val) <= 0)
return 0;
return 1;