]>
Commit | Line | Data |
---|---|---|
d3819813 | 1 | /* |
7bf7a6d0 | 2 | * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. |
3e575651 | 3 | * |
7bf7a6d0 MTL |
4 | * Licensed under the OpenSSL license (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
3e575651 SL |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
7bf7a6d0 | 11 | #include "internal/cryptlib.h" |
3e575651 SL |
12 | #include <openssl/asn1t.h> |
13 | #include <openssl/bn.h> | |
14 | ||
d3819813 MTL |
15 | /* |
16 | * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER | |
17 | * as a BIGNUM directly. Currently it ignores the sign which isn't a problem | |
18 | * since all BIGNUMs used are non negative and anything that looks negative | |
19 | * is normally due to an encoding error. | |
3e575651 SL |
20 | */ |
21 | ||
d3819813 | 22 | #define BN_SENSITIVE 1 |
3e575651 SL |
23 | |
24 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); | |
7bf7a6d0 | 25 | static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it); |
3e575651 SL |
26 | static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); |
27 | ||
d3819813 MTL |
28 | static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, |
29 | const ASN1_ITEM *it); | |
30 | static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, | |
31 | int utype, char *free_cont, const ASN1_ITEM *it); | |
7bf7a6d0 MTL |
32 | static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, |
33 | int utype, char *free_cont, const ASN1_ITEM *it); | |
f4173af1 MTL |
34 | static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, |
35 | int indent, const ASN1_PCTX *pctx); | |
3e575651 SL |
36 | |
37 | static ASN1_PRIMITIVE_FUNCS bignum_pf = { | |
d3819813 MTL |
38 | NULL, 0, |
39 | bn_new, | |
40 | bn_free, | |
41 | 0, | |
42 | bn_c2i, | |
f4173af1 MTL |
43 | bn_i2c, |
44 | bn_print | |
45 | }; | |
46 | ||
7bf7a6d0 MTL |
47 | static ASN1_PRIMITIVE_FUNCS cbignum_pf = { |
48 | NULL, 0, | |
49 | bn_secure_new, | |
50 | bn_free, | |
51 | 0, | |
52 | bn_secure_c2i, | |
53 | bn_i2c, | |
54 | bn_print | |
55 | }; | |
56 | ||
3e575651 | 57 | ASN1_ITEM_start(BIGNUM) |
d3819813 | 58 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM" |
3e575651 SL |
59 | ASN1_ITEM_end(BIGNUM) |
60 | ||
61 | ASN1_ITEM_start(CBIGNUM) | |
7bf7a6d0 | 62 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &cbignum_pf, BN_SENSITIVE, "CBIGNUM" |
3e575651 SL |
63 | ASN1_ITEM_end(CBIGNUM) |
64 | ||
65 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it) | |
66 | { | |
d3819813 | 67 | *pval = (ASN1_VALUE *)BN_new(); |
7bf7a6d0 MTL |
68 | if (*pval != NULL) |
69 | return 1; | |
70 | else | |
71 | return 0; | |
72 | } | |
73 | ||
74 | static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it) | |
75 | { | |
76 | *pval = (ASN1_VALUE *)BN_secure_new(); | |
77 | if (*pval != NULL) | |
d3819813 MTL |
78 | return 1; |
79 | else | |
80 | return 0; | |
3e575651 SL |
81 | } |
82 | ||
83 | static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | |
84 | { | |
d3819813 MTL |
85 | if (!*pval) |
86 | return; | |
87 | if (it->size & BN_SENSITIVE) | |
88 | BN_clear_free((BIGNUM *)*pval); | |
89 | else | |
90 | BN_free((BIGNUM *)*pval); | |
91 | *pval = NULL; | |
3e575651 SL |
92 | } |
93 | ||
d3819813 MTL |
94 | static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, |
95 | const ASN1_ITEM *it) | |
3e575651 | 96 | { |
d3819813 MTL |
97 | BIGNUM *bn; |
98 | int pad; | |
99 | if (!*pval) | |
100 | return -1; | |
101 | bn = (BIGNUM *)*pval; | |
102 | /* If MSB set in an octet we need a padding byte */ | |
103 | if (BN_num_bits(bn) & 0x7) | |
104 | pad = 0; | |
105 | else | |
106 | pad = 1; | |
107 | if (cont) { | |
108 | if (pad) | |
109 | *cont++ = 0; | |
110 | BN_bn2bin(bn, cont); | |
111 | } | |
112 | return pad + BN_num_bytes(bn); | |
3e575651 SL |
113 | } |
114 | ||
115 | static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, | |
d3819813 | 116 | int utype, char *free_cont, const ASN1_ITEM *it) |
3e575651 | 117 | { |
d3819813 | 118 | BIGNUM *bn; |
62f0afa2 MTL |
119 | |
120 | if (*pval == NULL && !bn_new(pval, it)) | |
121 | return 0; | |
d3819813 MTL |
122 | bn = (BIGNUM *)*pval; |
123 | if (!BN_bin2bn(cont, len, bn)) { | |
124 | bn_free(pval, it); | |
125 | return 0; | |
126 | } | |
127 | return 1; | |
3e575651 | 128 | } |
f4173af1 | 129 | |
7bf7a6d0 MTL |
130 | static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, |
131 | int utype, char *free_cont, const ASN1_ITEM *it) | |
132 | { | |
133 | if (!*pval) | |
134 | bn_secure_new(pval, it); | |
135 | return bn_c2i(pval, cont, len, utype, free_cont, it); | |
136 | } | |
137 | ||
f4173af1 MTL |
138 | static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, |
139 | int indent, const ASN1_PCTX *pctx) | |
140 | { | |
141 | if (!BN_print(out, *(BIGNUM **)pval)) | |
142 | return 0; | |
143 | if (BIO_puts(out, "\n") <= 0) | |
144 | return 0; | |
145 | return 1; | |
146 | } |