diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/a_int.c')
-rw-r--r-- | src/lib/libcrypto/asn1/a_int.c | 286 |
1 files changed, 143 insertions, 143 deletions
diff --git a/src/lib/libcrypto/asn1/a_int.c b/src/lib/libcrypto/asn1/a_int.c index 314bd2b369..9218a17c11 100644 --- a/src/lib/libcrypto/asn1/a_int.c +++ b/src/lib/libcrypto/asn1/a_int.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_int.c,v 1.35 2021/12/15 18:00:31 jsing Exp $ */ | 1 | /* $OpenBSD: a_int.c,v 1.36 2021/12/25 07:48:09 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -103,6 +103,148 @@ ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | int | 105 | int |
106 | ASN1_INTEGER_set(ASN1_INTEGER *a, long v) | ||
107 | { | ||
108 | int j, k; | ||
109 | unsigned int i; | ||
110 | unsigned char buf[sizeof(long) + 1]; | ||
111 | long d; | ||
112 | |||
113 | a->type = V_ASN1_INTEGER; | ||
114 | /* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */ | ||
115 | if (a->length < (int)(sizeof(long) + 1)) { | ||
116 | free(a->data); | ||
117 | a->data = calloc(1, sizeof(long) + 1); | ||
118 | } | ||
119 | if (a->data == NULL) { | ||
120 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
121 | return (0); | ||
122 | } | ||
123 | d = v; | ||
124 | if (d < 0) { | ||
125 | d = -d; | ||
126 | a->type = V_ASN1_NEG_INTEGER; | ||
127 | } | ||
128 | |||
129 | for (i = 0; i < sizeof(long); i++) { | ||
130 | if (d == 0) | ||
131 | break; | ||
132 | buf[i] = (int)d & 0xff; | ||
133 | d >>= 8; | ||
134 | } | ||
135 | j = 0; | ||
136 | for (k = i - 1; k >= 0; k--) | ||
137 | a->data[j++] = buf[k]; | ||
138 | a->length = j; | ||
139 | return (1); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * XXX this particular API is a gibbering eidrich horror that makes it | ||
144 | * impossible to determine valid return cases from errors.. "a bit | ||
145 | * ugly" is preserved for posterity, unfortunately this is probably | ||
146 | * unfixable without changing public API | ||
147 | */ | ||
148 | long | ||
149 | ASN1_INTEGER_get(const ASN1_INTEGER *a) | ||
150 | { | ||
151 | int neg = 0, i; | ||
152 | unsigned long r = 0; | ||
153 | |||
154 | if (a == NULL) | ||
155 | return (0L); | ||
156 | i = a->type; | ||
157 | if (i == V_ASN1_NEG_INTEGER) | ||
158 | neg = 1; | ||
159 | else if (i != V_ASN1_INTEGER) | ||
160 | return -1; | ||
161 | |||
162 | if (!ASN1_INTEGER_valid(a)) | ||
163 | return -1; /* XXX best effort */ | ||
164 | |||
165 | if (a->length > (int)sizeof(long)) { | ||
166 | /* hmm... a bit ugly, return all ones */ | ||
167 | return -1; | ||
168 | } | ||
169 | if (a->data == NULL) | ||
170 | return 0; | ||
171 | |||
172 | for (i = 0; i < a->length; i++) { | ||
173 | r <<= 8; | ||
174 | r |= (unsigned char)a->data[i]; | ||
175 | } | ||
176 | |||
177 | if (r > LONG_MAX) | ||
178 | return -1; | ||
179 | |||
180 | if (neg) | ||
181 | return -(long)r; | ||
182 | return (long)r; | ||
183 | } | ||
184 | |||
185 | ASN1_INTEGER * | ||
186 | BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) | ||
187 | { | ||
188 | ASN1_INTEGER *ret; | ||
189 | int len, j; | ||
190 | |||
191 | if (ai == NULL) | ||
192 | ret = ASN1_INTEGER_new(); | ||
193 | else | ||
194 | ret = ai; | ||
195 | if (ret == NULL) { | ||
196 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
197 | goto err; | ||
198 | } | ||
199 | |||
200 | if (!ASN1_INTEGER_valid(ret)) | ||
201 | goto err; | ||
202 | |||
203 | if (BN_is_negative(bn)) | ||
204 | ret->type = V_ASN1_NEG_INTEGER; | ||
205 | else | ||
206 | ret->type = V_ASN1_INTEGER; | ||
207 | j = BN_num_bits(bn); | ||
208 | len = ((j == 0) ? 0 : ((j / 8) + 1)); | ||
209 | if (ret->length < len + 4) { | ||
210 | unsigned char *new_data = realloc(ret->data, len + 4); | ||
211 | if (!new_data) { | ||
212 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
213 | goto err; | ||
214 | } | ||
215 | ret->data = new_data; | ||
216 | } | ||
217 | ret->length = BN_bn2bin(bn, ret->data); | ||
218 | |||
219 | /* Correct zero case */ | ||
220 | if (!ret->length) { | ||
221 | ret->data[0] = 0; | ||
222 | ret->length = 1; | ||
223 | } | ||
224 | return (ret); | ||
225 | |||
226 | err: | ||
227 | if (ret != ai) | ||
228 | ASN1_INTEGER_free(ret); | ||
229 | return (NULL); | ||
230 | } | ||
231 | |||
232 | BIGNUM * | ||
233 | ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) | ||
234 | { | ||
235 | BIGNUM *ret; | ||
236 | |||
237 | if (!ASN1_INTEGER_valid(ai)) | ||
238 | return (NULL); | ||
239 | |||
240 | if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) | ||
241 | ASN1error(ASN1_R_BN_LIB); | ||
242 | else if (ai->type == V_ASN1_NEG_INTEGER) | ||
243 | BN_set_negative(ret, 1); | ||
244 | return (ret); | ||
245 | } | ||
246 | |||
247 | int | ||
106 | i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a) | 248 | i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a) |
107 | { | 249 | { |
108 | int i, n = 0; | 250 | int i, n = 0; |
@@ -499,145 +641,3 @@ err: | |||
499 | ASN1_INTEGER_free(ret); | 641 | ASN1_INTEGER_free(ret); |
500 | return (NULL); | 642 | return (NULL); |
501 | } | 643 | } |
502 | |||
503 | int | ||
504 | ASN1_INTEGER_set(ASN1_INTEGER *a, long v) | ||
505 | { | ||
506 | int j, k; | ||
507 | unsigned int i; | ||
508 | unsigned char buf[sizeof(long) + 1]; | ||
509 | long d; | ||
510 | |||
511 | a->type = V_ASN1_INTEGER; | ||
512 | /* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */ | ||
513 | if (a->length < (int)(sizeof(long) + 1)) { | ||
514 | free(a->data); | ||
515 | a->data = calloc(1, sizeof(long) + 1); | ||
516 | } | ||
517 | if (a->data == NULL) { | ||
518 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
519 | return (0); | ||
520 | } | ||
521 | d = v; | ||
522 | if (d < 0) { | ||
523 | d = -d; | ||
524 | a->type = V_ASN1_NEG_INTEGER; | ||
525 | } | ||
526 | |||
527 | for (i = 0; i < sizeof(long); i++) { | ||
528 | if (d == 0) | ||
529 | break; | ||
530 | buf[i] = (int)d & 0xff; | ||
531 | d >>= 8; | ||
532 | } | ||
533 | j = 0; | ||
534 | for (k = i - 1; k >= 0; k--) | ||
535 | a->data[j++] = buf[k]; | ||
536 | a->length = j; | ||
537 | return (1); | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * XXX this particular API is a gibbering eidrich horror that makes it | ||
542 | * impossible to determine valid return cases from errors.. "a bit | ||
543 | * ugly" is preserved for posterity, unfortunately this is probably | ||
544 | * unfixable without changing public API | ||
545 | */ | ||
546 | long | ||
547 | ASN1_INTEGER_get(const ASN1_INTEGER *a) | ||
548 | { | ||
549 | int neg = 0, i; | ||
550 | unsigned long r = 0; | ||
551 | |||
552 | if (a == NULL) | ||
553 | return (0L); | ||
554 | i = a->type; | ||
555 | if (i == V_ASN1_NEG_INTEGER) | ||
556 | neg = 1; | ||
557 | else if (i != V_ASN1_INTEGER) | ||
558 | return -1; | ||
559 | |||
560 | if (!ASN1_INTEGER_valid(a)) | ||
561 | return -1; /* XXX best effort */ | ||
562 | |||
563 | if (a->length > (int)sizeof(long)) { | ||
564 | /* hmm... a bit ugly, return all ones */ | ||
565 | return -1; | ||
566 | } | ||
567 | if (a->data == NULL) | ||
568 | return 0; | ||
569 | |||
570 | for (i = 0; i < a->length; i++) { | ||
571 | r <<= 8; | ||
572 | r |= (unsigned char)a->data[i]; | ||
573 | } | ||
574 | |||
575 | if (r > LONG_MAX) | ||
576 | return -1; | ||
577 | |||
578 | if (neg) | ||
579 | return -(long)r; | ||
580 | return (long)r; | ||
581 | } | ||
582 | |||
583 | ASN1_INTEGER * | ||
584 | BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) | ||
585 | { | ||
586 | ASN1_INTEGER *ret; | ||
587 | int len, j; | ||
588 | |||
589 | if (ai == NULL) | ||
590 | ret = ASN1_INTEGER_new(); | ||
591 | else | ||
592 | ret = ai; | ||
593 | if (ret == NULL) { | ||
594 | ASN1error(ERR_R_NESTED_ASN1_ERROR); | ||
595 | goto err; | ||
596 | } | ||
597 | |||
598 | if (!ASN1_INTEGER_valid(ret)) | ||
599 | goto err; | ||
600 | |||
601 | if (BN_is_negative(bn)) | ||
602 | ret->type = V_ASN1_NEG_INTEGER; | ||
603 | else | ||
604 | ret->type = V_ASN1_INTEGER; | ||
605 | j = BN_num_bits(bn); | ||
606 | len = ((j == 0) ? 0 : ((j / 8) + 1)); | ||
607 | if (ret->length < len + 4) { | ||
608 | unsigned char *new_data = realloc(ret->data, len + 4); | ||
609 | if (!new_data) { | ||
610 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
611 | goto err; | ||
612 | } | ||
613 | ret->data = new_data; | ||
614 | } | ||
615 | ret->length = BN_bn2bin(bn, ret->data); | ||
616 | |||
617 | /* Correct zero case */ | ||
618 | if (!ret->length) { | ||
619 | ret->data[0] = 0; | ||
620 | ret->length = 1; | ||
621 | } | ||
622 | return (ret); | ||
623 | |||
624 | err: | ||
625 | if (ret != ai) | ||
626 | ASN1_INTEGER_free(ret); | ||
627 | return (NULL); | ||
628 | } | ||
629 | |||
630 | BIGNUM * | ||
631 | ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) | ||
632 | { | ||
633 | BIGNUM *ret; | ||
634 | |||
635 | if (!ASN1_INTEGER_valid(ai)) | ||
636 | return (NULL); | ||
637 | |||
638 | if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) | ||
639 | ASN1error(ASN1_R_BN_LIB); | ||
640 | else if (ai->type == V_ASN1_NEG_INTEGER) | ||
641 | BN_set_negative(ret, 1); | ||
642 | return (ret); | ||
643 | } | ||