summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/asn1/x_bignum.c82
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
71static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); 71static 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
138static int 138static int
139bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it) 139bn_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
161static int 164static int
162bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, 165bn_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
179static int 193static int
180bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, 194bn_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;