From 86a4f29f99c126c5e72c9c0092a9821b2ee5d2f6 Mon Sep 17 00:00:00 2001 From: jsing Date: Sat, 25 Dec 2021 07:48:09 +0000 Subject: [PATCH] Move ASN1__* functions to the top, encoding/decoding to the bottom. No functional change. --- lib/libcrypto/asn1/a_bitstr.c | 244 ++++++++++++++--------------- lib/libcrypto/asn1/a_int.c | 286 +++++++++++++++++----------------- lib/libcrypto/asn1/a_object.c | 100 ++++++------ lib/libcrypto/asn1/a_time.c | 28 ++-- 4 files changed, 329 insertions(+), 329 deletions(-) diff --git a/lib/libcrypto/asn1/a_bitstr.c b/lib/libcrypto/asn1/a_bitstr.c index 68cefee4a2d..207d80ab389 100644 --- a/lib/libcrypto/asn1/a_bitstr.c +++ b/lib/libcrypto/asn1/a_bitstr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_bitstr.c,v 1.31 2021/12/15 18:00:31 jsing Exp $ */ +/* $OpenBSD: a_bitstr.c,v 1.32 2021/12/25 07:48:09 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -70,6 +70,127 @@ ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) return ASN1_STRING_set(x, d, len); } +int +ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) +{ + int w, v, iv; + unsigned char *c; + + w = n/8; + v = 1 << (7 - (n & 0x07)); + iv = ~v; + if (!value) + v = 0; + + if (a == NULL) + return 0; + + a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ + + if ((a->length < (w + 1)) || (a->data == NULL)) { + if (!value) + return(1); /* Don't need to set */ + if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) { + ASN1error(ERR_R_MALLOC_FAILURE); + return 0; + } + a->data = c; + a->length = w + 1; + } + a->data[w] = ((a->data[w]) & iv) | v; + while ((a->length > 0) && (a->data[a->length - 1] == 0)) + a->length--; + + return (1); +} + +int +ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) +{ + int w, v; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) + return (0); + return ((a->data[w] & v) != 0); +} + +/* + * Checks if the given bit string contains only bits specified by + * the flags vector. Returns 0 if there is at least one bit set in 'a' + * which is not specified in 'flags', 1 otherwise. + * 'len' is the length of 'flags'. + */ +int +ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags, + int flags_len) +{ + int i, ok; + + /* Check if there is one bit set at all. */ + if (!a || !a->data) + return 1; + + /* Check each byte of the internal representation of the bit string. */ + ok = 1; + for (i = 0; i < a->length && ok; ++i) { + unsigned char mask = i < flags_len ? ~flags[i] : 0xff; + /* We are done if there is an unneeded bit set. */ + ok = (a->data[i] & mask) == 0; + } + return ok; +} + +int +ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent) +{ + BIT_STRING_BITNAME *bnam; + char first = 1; + + BIO_printf(out, "%*s", indent, ""); + for (bnam = tbl; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) { + if (!first) + BIO_puts(out, ", "); + BIO_puts(out, bnam->lname); + first = 0; + } + } + BIO_puts(out, "\n"); + return 1; +} + +int +ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value, + BIT_STRING_BITNAME *tbl) +{ + int bitnum; + + bitnum = ASN1_BIT_STRING_num_asc(name, tbl); + if (bitnum < 0) + return 0; + if (bs) { + if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value)) + return 0; + } + return 1; +} + +int +ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl) +{ + BIT_STRING_BITNAME *bnam; + + for (bnam = tbl; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, name) || + !strcmp(bnam->lname, name)) + return bnam->bitnum; + } + return -1; +} + int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { @@ -192,124 +313,3 @@ c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **pp, long len) return (NULL); } - -int -ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) -{ - int w, v, iv; - unsigned char *c; - - w = n/8; - v = 1 << (7 - (n & 0x07)); - iv = ~v; - if (!value) - v = 0; - - if (a == NULL) - return 0; - - a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ - - if ((a->length < (w + 1)) || (a->data == NULL)) { - if (!value) - return(1); /* Don't need to set */ - if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - return 0; - } - a->data = c; - a->length = w + 1; - } - a->data[w] = ((a->data[w]) & iv) | v; - while ((a->length > 0) && (a->data[a->length - 1] == 0)) - a->length--; - - return (1); -} - -int -ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) -{ - int w, v; - - w = n / 8; - v = 1 << (7 - (n & 0x07)); - if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) - return (0); - return ((a->data[w] & v) != 0); -} - -/* - * Checks if the given bit string contains only bits specified by - * the flags vector. Returns 0 if there is at least one bit set in 'a' - * which is not specified in 'flags', 1 otherwise. - * 'len' is the length of 'flags'. - */ -int -ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags, - int flags_len) -{ - int i, ok; - - /* Check if there is one bit set at all. */ - if (!a || !a->data) - return 1; - - /* Check each byte of the internal representation of the bit string. */ - ok = 1; - for (i = 0; i < a->length && ok; ++i) { - unsigned char mask = i < flags_len ? ~flags[i] : 0xff; - /* We are done if there is an unneeded bit set. */ - ok = (a->data[i] & mask) == 0; - } - return ok; -} - -int -ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, - BIT_STRING_BITNAME *tbl, int indent) -{ - BIT_STRING_BITNAME *bnam; - char first = 1; - - BIO_printf(out, "%*s", indent, ""); - for (bnam = tbl; bnam->lname; bnam++) { - if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) { - if (!first) - BIO_puts(out, ", "); - BIO_puts(out, bnam->lname); - first = 0; - } - } - BIO_puts(out, "\n"); - return 1; -} - -int -ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value, - BIT_STRING_BITNAME *tbl) -{ - int bitnum; - - bitnum = ASN1_BIT_STRING_num_asc(name, tbl); - if (bitnum < 0) - return 0; - if (bs) { - if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value)) - return 0; - } - return 1; -} - -int -ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl) -{ - BIT_STRING_BITNAME *bnam; - - for (bnam = tbl; bnam->lname; bnam++) { - if (!strcmp(bnam->sname, name) || - !strcmp(bnam->lname, name)) - return bnam->bitnum; - } - return -1; -} diff --git a/lib/libcrypto/asn1/a_int.c b/lib/libcrypto/asn1/a_int.c index 314bd2b369e..9218a17c118 100644 --- a/lib/libcrypto/asn1/a_int.c +++ b/lib/libcrypto/asn1/a_int.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_int.c,v 1.35 2021/12/15 18:00:31 jsing Exp $ */ +/* $OpenBSD: a_int.c,v 1.36 2021/12/25 07:48:09 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -102,6 +102,148 @@ ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) return ret; } +int +ASN1_INTEGER_set(ASN1_INTEGER *a, long v) +{ + int j, k; + unsigned int i; + unsigned char buf[sizeof(long) + 1]; + long d; + + a->type = V_ASN1_INTEGER; + /* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */ + 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_INTEGER; + } + + for (i = 0; i < sizeof(long); i++) { + if (d == 0) + break; + buf[i] = (int)d & 0xff; + d >>= 8; + } + j = 0; + for (k = i - 1; k >= 0; k--) + a->data[j++] = buf[k]; + a->length = j; + return (1); +} + +/* + * XXX this particular API is a gibbering eidrich horror that makes it + * impossible to determine valid return cases from errors.. "a bit + * ugly" is preserved for posterity, unfortunately this is probably + * unfixable without changing public API + */ +long +ASN1_INTEGER_get(const ASN1_INTEGER *a) +{ + int neg = 0, i; + unsigned long r = 0; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_INTEGER) + neg = 1; + else if (i != V_ASN1_INTEGER) + return -1; + + if (!ASN1_INTEGER_valid(a)) + return -1; /* XXX best effort */ + + if (a->length > (int)sizeof(long)) { + /* 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; + + if (neg) + return -(long)r; + return (long)r; +} + +ASN1_INTEGER * +BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) +{ + ASN1_INTEGER *ret; + int len, j; + + if (ai == NULL) + ret = ASN1_INTEGER_new(); + else + ret = ai; + if (ret == NULL) { + ASN1error(ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + if (!ASN1_INTEGER_valid(ret)) + goto err; + + if (BN_is_negative(bn)) + ret->type = V_ASN1_NEG_INTEGER; + else + ret->type = V_ASN1_INTEGER; + j = BN_num_bits(bn); + len = ((j == 0) ? 0 : ((j / 8) + 1)); + if (ret->length < len + 4) { + unsigned char *new_data = realloc(ret->data, len + 4); + if (!new_data) { + ASN1error(ERR_R_MALLOC_FAILURE); + goto err; + } + ret->data = new_data; + } + ret->length = BN_bn2bin(bn, ret->data); + + /* Correct zero case */ + if (!ret->length) { + ret->data[0] = 0; + ret->length = 1; + } + return (ret); + +err: + if (ret != ai) + ASN1_INTEGER_free(ret); + return (NULL); +} + +BIGNUM * +ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) +{ + BIGNUM *ret; + + if (!ASN1_INTEGER_valid(ai)) + return (NULL); + + if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) + ASN1error(ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_INTEGER) + BN_set_negative(ret, 1); + return (ret); +} + int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a) { @@ -499,145 +641,3 @@ err: ASN1_INTEGER_free(ret); return (NULL); } - -int -ASN1_INTEGER_set(ASN1_INTEGER *a, long v) -{ - int j, k; - unsigned int i; - unsigned char buf[sizeof(long) + 1]; - long d; - - a->type = V_ASN1_INTEGER; - /* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */ - 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_INTEGER; - } - - for (i = 0; i < sizeof(long); i++) { - if (d == 0) - break; - buf[i] = (int)d & 0xff; - d >>= 8; - } - j = 0; - for (k = i - 1; k >= 0; k--) - a->data[j++] = buf[k]; - a->length = j; - return (1); -} - -/* - * XXX this particular API is a gibbering eidrich horror that makes it - * impossible to determine valid return cases from errors.. "a bit - * ugly" is preserved for posterity, unfortunately this is probably - * unfixable without changing public API - */ -long -ASN1_INTEGER_get(const ASN1_INTEGER *a) -{ - int neg = 0, i; - unsigned long r = 0; - - if (a == NULL) - return (0L); - i = a->type; - if (i == V_ASN1_NEG_INTEGER) - neg = 1; - else if (i != V_ASN1_INTEGER) - return -1; - - if (!ASN1_INTEGER_valid(a)) - return -1; /* XXX best effort */ - - if (a->length > (int)sizeof(long)) { - /* 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; - - if (neg) - return -(long)r; - return (long)r; -} - -ASN1_INTEGER * -BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) -{ - ASN1_INTEGER *ret; - int len, j; - - if (ai == NULL) - ret = ASN1_INTEGER_new(); - else - ret = ai; - if (ret == NULL) { - ASN1error(ERR_R_NESTED_ASN1_ERROR); - goto err; - } - - if (!ASN1_INTEGER_valid(ret)) - goto err; - - if (BN_is_negative(bn)) - ret->type = V_ASN1_NEG_INTEGER; - else - ret->type = V_ASN1_INTEGER; - j = BN_num_bits(bn); - len = ((j == 0) ? 0 : ((j / 8) + 1)); - if (ret->length < len + 4) { - unsigned char *new_data = realloc(ret->data, len + 4); - if (!new_data) { - ASN1error(ERR_R_MALLOC_FAILURE); - goto err; - } - ret->data = new_data; - } - ret->length = BN_bn2bin(bn, ret->data); - - /* Correct zero case */ - if (!ret->length) { - ret->data[0] = 0; - ret->length = 1; - } - return (ret); - -err: - if (ret != ai) - ASN1_INTEGER_free(ret); - return (NULL); -} - -BIGNUM * -ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) -{ - BIGNUM *ret; - - if (!ASN1_INTEGER_valid(ai)) - return (NULL); - - if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) - ASN1error(ASN1_R_BN_LIB); - else if (ai->type == V_ASN1_NEG_INTEGER) - BN_set_negative(ret, 1); - return (ret); -} diff --git a/lib/libcrypto/asn1/a_object.c b/lib/libcrypto/asn1/a_object.c index 9b3bae0442e..cc4f5dd4243 100644 --- a/lib/libcrypto/asn1/a_object.c +++ b/lib/libcrypto/asn1/a_object.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_object.c,v 1.33 2021/12/03 16:58:11 jsing Exp $ */ +/* $OpenBSD: a_object.c,v 1.34 2021/12/25 07:48:09 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -66,6 +66,55 @@ #include #include +ASN1_OBJECT * +ASN1_OBJECT_new(void) +{ + ASN1_OBJECT *a; + + if ((a = calloc(1, sizeof(ASN1_OBJECT))) == NULL) { + ASN1error(ERR_R_MALLOC_FAILURE); + return (NULL); + } + a->flags = ASN1_OBJECT_FLAG_DYNAMIC; + + return a; +} + +void +ASN1_OBJECT_free(ASN1_OBJECT *a) +{ + if (a == NULL) + return; + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { + free((void *)a->sn); + free((void *)a->ln); + a->sn = a->ln = NULL; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { + freezero((void *)a->data, a->length); + a->data = NULL; + a->length = 0; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) + free(a); +} + +ASN1_OBJECT * +ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln) +{ + ASN1_OBJECT o; + + o.sn = sn; + o.ln = ln; + o.data = data; + o.nid = nid; + o.length = len; + o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA; + return (OBJ_dup(&o)); +} + int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp) { @@ -350,52 +399,3 @@ err: ASN1_OBJECT_free(ret); return (NULL); } - -ASN1_OBJECT * -ASN1_OBJECT_new(void) -{ - ASN1_OBJECT *a; - - if ((a = calloc(1, sizeof(ASN1_OBJECT))) == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - return (NULL); - } - a->flags = ASN1_OBJECT_FLAG_DYNAMIC; - - return a; -} - -void -ASN1_OBJECT_free(ASN1_OBJECT *a) -{ - if (a == NULL) - return; - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { - free((void *)a->sn); - free((void *)a->ln); - a->sn = a->ln = NULL; - } - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { - freezero((void *)a->data, a->length); - a->data = NULL; - a->length = 0; - } - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) - free(a); -} - -ASN1_OBJECT * -ASN1_OBJECT_create(int nid, unsigned char *data, int len, - const char *sn, const char *ln) -{ - ASN1_OBJECT o; - - o.sn = sn; - o.ln = ln; - o.data = data; - o.nid = nid; - o.length = len; - o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | - ASN1_OBJECT_FLAG_DYNAMIC_DATA; - return (OBJ_dup(&o)); -} diff --git a/lib/libcrypto/asn1/a_time.c b/lib/libcrypto/asn1/a_time.c index 79bcbffa26e..cd6a790cacd 100644 --- a/lib/libcrypto/asn1/a_time.c +++ b/lib/libcrypto/asn1/a_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_time.c,v 1.32 2021/11/06 07:52:22 jsing Exp $ */ +/* $OpenBSD: a_time.c,v 1.33 2021/12/25 07:48:09 jsing Exp $ */ /* ==================================================================== * Copyright (c) 1999 The OpenSSL Project. All rights reserved. * @@ -80,19 +80,6 @@ const ASN1_ITEM ASN1_TIME_it = { .sname = "ASN1_TIME", }; -ASN1_TIME * -d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len) -{ - return (ASN1_TIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - &ASN1_TIME_it); -} - -int -i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out) -{ - return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_TIME_it); -} - ASN1_TIME * ASN1_TIME_new(void) { @@ -132,3 +119,16 @@ ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to) return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to); } + +ASN1_TIME * +d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len) +{ + return (ASN1_TIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ASN1_TIME_it); +} + +int +i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_TIME_it); +} -- 2.20.1