Provide and use long_{get,set}()
authorjsing <jsing@openbsd.org>
Sun, 26 Jun 2022 13:10:15 +0000 (13:10 +0000)
committerjsing <jsing@openbsd.org>
Sun, 26 Jun 2022 13:10:15 +0000 (13:10 +0000)
Apparently at some point a LONG_it was misaligned - provide and use
long_{get,set}() so that we always memcpy() rather than doing it some times
but not others. While here provide long_clear() rather than abusing and
reusing long_free().

ok tb@

lib/libcrypto/asn1/x_long.c

index ff72338..b51ea6f 100644 (file)
@@ -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;