diff options
-rw-r--r-- | lib/libcrypto/asn1/x_long.c | 46 |
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(<mp, cp, sizeof(long)); + long_get(pval, <mp); 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, <mp, 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; |