diff options
| author | jsing <> | 2022-07-30 13:42:25 +0000 |
|---|---|---|
| committer | jsing <> | 2022-07-30 13:42:25 +0000 |
| commit | 2fbb23904f84edcbeba01b273bff5c8fb605f564 (patch) | |
| tree | 089cb6d64c531aa03fcb07b3b53bb1e713556c68 /src | |
| parent | 1dc2e65d098d6b432c6aec3f1e0446795467eb24 (diff) | |
| download | openbsd-2fbb23904f84edcbeba01b273bff5c8fb605f564.tar.gz openbsd-2fbb23904f84edcbeba01b273bff5c8fb605f564.tar.bz2 openbsd-2fbb23904f84edcbeba01b273bff5c8fb605f564.zip | |
Use ASN1_INTEGER to encode/decode BIGNUM_it.
The current code simply shoves the unvalidated ASN.1 bytes into a BIGNUM on
the hope that other things will detect issues (such as negative values
being flipped to positive). Instead of doing this, decode and validate the
ASN.1 data using ASN1_INTEGER, then convert it to a BIGNUM. Similarly, for
encoding convert from BIGNUM to ASN1_INTEGER and use ASN1_INTEGER encoding.
ok tb@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/asn1/x_bignum.c | 82 |
1 files changed, 48 insertions, 34 deletions
diff --git a/src/lib/libcrypto/asn1/x_bignum.c b/src/lib/libcrypto/asn1/x_bignum.c index 9ad7810306..d1f735b47d 100644 --- a/src/lib/libcrypto/asn1/x_bignum.c +++ b/src/lib/libcrypto/asn1/x_bignum.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x_bignum.c,v 1.11 2022/07/30 13:37:17 jsing Exp $ */ | 1 | /* $OpenBSD: x_bignum.c,v 1.12 2022/07/30 13:42:25 jsing Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2000. | 3 | * project 2000. |
| 4 | */ | 4 | */ |
| @@ -61,11 +61,11 @@ | |||
| 61 | #include <openssl/asn1t.h> | 61 | #include <openssl/asn1t.h> |
| 62 | #include <openssl/bn.h> | 62 | #include <openssl/bn.h> |
| 63 | 63 | ||
| 64 | #include "asn1_locl.h" | ||
| 65 | #include "bytestring.h" | ||
| 66 | |||
| 64 | /* | 67 | /* |
| 65 | * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a | 68 | * Custom primitive type for that reads an ASN.1 INTEGER into a BIGNUM. |
| 66 | * BIGNUM directly. Currently it ignores the sign which isn't a problem since | ||
| 67 | * all BIGNUMs used are non negative and anything that looks negative is | ||
| 68 | * normally due to an encoding error. | ||
| 69 | */ | 69 | */ |
| 70 | 70 | ||
| 71 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); | 71 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); |
| @@ -136,51 +136,65 @@ bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | |||
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int | 138 | static int |
| 139 | bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it) | 139 | bn_i2c(ASN1_VALUE **pval, unsigned char *content, int *putype, const ASN1_ITEM *it) |
| 140 | { | 140 | { |
| 141 | BIGNUM *bn; | 141 | ASN1_INTEGER *aint = NULL; |
| 142 | int pad, len; | 142 | unsigned char **pp = NULL; |
| 143 | const BIGNUM *bn; | ||
| 144 | int ret; | ||
| 143 | 145 | ||
| 144 | if (*pval == NULL) | 146 | if (*pval == NULL) |
| 145 | return -1; | 147 | return -1; |
| 146 | bn = (BIGNUM *)*pval; | 148 | |
| 147 | /* If MSB set in an octet we need a padding byte */ | 149 | bn = (const BIGNUM *)*pval; |
| 148 | if (BN_num_bits(bn) & 0x7) | 150 | |
| 149 | pad = 0; | 151 | if ((aint = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) |
| 150 | else | 152 | return -1; |
| 151 | pad = 1; | 153 | |
| 152 | if (cont) { | 154 | if (content != NULL) |
| 153 | if (pad) | 155 | pp = &content; |
| 154 | *cont++ = 0; | 156 | |
| 155 | len = BN_bn2bin(bn, cont); | 157 | ret = i2c_ASN1_INTEGER(aint, pp); |
| 156 | } else | 158 | |
| 157 | len = BN_num_bytes(bn); | 159 | ASN1_INTEGER_free(aint); |
| 158 | return pad + len; | 160 | |
| 161 | return ret; | ||
| 159 | } | 162 | } |
| 160 | 163 | ||
| 161 | static int | 164 | static int |
| 162 | bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | 165 | bn_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, int utype, |
| 163 | char *free_cont, const ASN1_ITEM *it) | 166 | char *free_content, const ASN1_ITEM *it) |
| 164 | { | 167 | { |
| 168 | ASN1_INTEGER *aint = NULL; | ||
| 165 | BIGNUM *bn; | 169 | BIGNUM *bn; |
| 170 | CBS cbs; | ||
| 171 | int ret = 0; | ||
| 166 | 172 | ||
| 167 | if (*pval == NULL) { | 173 | bn_clear(pval, it); |
| 168 | if (bn_new(pval, it) == 0) | 174 | |
| 169 | return 0; | 175 | if (len < 0) |
| 170 | } | 176 | goto err; |
| 171 | bn = (BIGNUM *)*pval; | 177 | CBS_init(&cbs, content, len); |
| 172 | if (!BN_bin2bn(cont, len, bn)) { | 178 | if (!c2i_ASN1_INTEGER_cbs(&aint, &cbs)) |
| 173 | bn_free(pval, it); | 179 | goto err; |
| 174 | return 0; | 180 | |
| 175 | } | 181 | if ((bn = ASN1_INTEGER_to_BN(aint, NULL)) == NULL) |
| 176 | return 1; | 182 | goto err; |
| 183 | *pval = (ASN1_VALUE *)bn; | ||
| 184 | |||
| 185 | ret = 1; | ||
| 186 | |||
| 187 | err: | ||
| 188 | ASN1_INTEGER_free(aint); | ||
| 189 | |||
| 190 | return ret; | ||
| 177 | } | 191 | } |
| 178 | 192 | ||
| 179 | static int | 193 | static int |
| 180 | bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, | 194 | bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, |
| 181 | const ASN1_PCTX *pctx) | 195 | const ASN1_PCTX *pctx) |
| 182 | { | 196 | { |
| 183 | BIGNUM *bn = (BIGNUM *)*pval; | 197 | const BIGNUM *bn = (BIGNUM *)*pval; |
| 184 | 198 | ||
| 185 | if (!BN_print(out, bn)) | 199 | if (!BN_print(out, bn)) |
| 186 | return 0; | 200 | return 0; |
