|
4 | 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* |
5 | 5 | **********************************************************************/ |
6 | 6 |
|
7 | | -/* This file contains a code snippet that parses DER with various errors and |
| 7 | +/**** |
| 8 | + * Please do not link this file directly. It is not part of the libsecp256k1 |
| 9 | + * project and does not promise any stability in its API, functionality or |
| 10 | + * presence. Projects which use this code should instead copy this header |
| 11 | + * and its accompanying .c file directly into their codebase. |
| 12 | + ****/ |
| 13 | + |
| 14 | +/* This file defines a function that parses DER with various errors and |
8 | 15 | * violations. This is not a part of the library itself, because the allowed |
9 | 16 | * violations are chosen arbitrarily and do not follow or establish any |
10 | 17 | * standard. |
|
44 | 51 | #ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ |
45 | 52 | #define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ |
46 | 53 |
|
47 | | -#include <string.h> |
48 | 54 | #include <secp256k1.h> |
49 | 55 |
|
50 | | -static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen); |
| 56 | +# ifdef __cplusplus |
| 57 | +extern "C" { |
| 58 | +# endif |
51 | 59 |
|
52 | | -static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { |
53 | | - size_t rpos, rlen, spos, slen; |
54 | | - size_t pos = 0; |
55 | | - size_t lenbyte; |
56 | | - unsigned char tmpsig[64] = {0}; |
57 | | - int overflow = 0; |
58 | | - |
59 | | - /* Hack to initialize sig with a correctly-parsed but invalid signature. */ |
60 | | - secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); |
61 | | - |
62 | | - /* Sequence tag byte */ |
63 | | - if (pos == inputlen || input[pos] != 0x30) { |
64 | | - return 0; |
65 | | - } |
66 | | - pos++; |
67 | | - |
68 | | - /* Sequence length bytes */ |
69 | | - if (pos == inputlen) { |
70 | | - return 0; |
71 | | - } |
72 | | - lenbyte = input[pos++]; |
73 | | - if (lenbyte & 0x80) { |
74 | | - lenbyte -= 0x80; |
75 | | - if (pos + lenbyte > inputlen) { |
76 | | - return 0; |
77 | | - } |
78 | | - pos += lenbyte; |
79 | | - } |
80 | | - |
81 | | - /* Integer tag byte for R */ |
82 | | - if (pos == inputlen || input[pos] != 0x02) { |
83 | | - return 0; |
84 | | - } |
85 | | - pos++; |
86 | | - |
87 | | - /* Integer length for R */ |
88 | | - if (pos == inputlen) { |
89 | | - return 0; |
90 | | - } |
91 | | - lenbyte = input[pos++]; |
92 | | - if (lenbyte & 0x80) { |
93 | | - lenbyte -= 0x80; |
94 | | - if (pos + lenbyte > inputlen) { |
95 | | - return 0; |
96 | | - } |
97 | | - while (lenbyte > 0 && input[pos] == 0) { |
98 | | - pos++; |
99 | | - lenbyte--; |
100 | | - } |
101 | | - if (lenbyte >= sizeof(size_t)) { |
102 | | - return 0; |
103 | | - } |
104 | | - rlen = 0; |
105 | | - while (lenbyte > 0) { |
106 | | - rlen = (rlen << 8) + input[pos]; |
107 | | - pos++; |
108 | | - lenbyte--; |
109 | | - } |
110 | | - } else { |
111 | | - rlen = lenbyte; |
112 | | - } |
113 | | - if (rlen > inputlen - pos) { |
114 | | - return 0; |
115 | | - } |
116 | | - rpos = pos; |
117 | | - pos += rlen; |
118 | | - |
119 | | - /* Integer tag byte for S */ |
120 | | - if (pos == inputlen || input[pos] != 0x02) { |
121 | | - return 0; |
122 | | - } |
123 | | - pos++; |
124 | | - |
125 | | - /* Integer length for S */ |
126 | | - if (pos == inputlen) { |
127 | | - return 0; |
128 | | - } |
129 | | - lenbyte = input[pos++]; |
130 | | - if (lenbyte & 0x80) { |
131 | | - lenbyte -= 0x80; |
132 | | - if (pos + lenbyte > inputlen) { |
133 | | - return 0; |
134 | | - } |
135 | | - while (lenbyte > 0 && input[pos] == 0) { |
136 | | - pos++; |
137 | | - lenbyte--; |
138 | | - } |
139 | | - if (lenbyte >= sizeof(size_t)) { |
140 | | - return 0; |
141 | | - } |
142 | | - slen = 0; |
143 | | - while (lenbyte > 0) { |
144 | | - slen = (slen << 8) + input[pos]; |
145 | | - pos++; |
146 | | - lenbyte--; |
147 | | - } |
148 | | - } else { |
149 | | - slen = lenbyte; |
150 | | - } |
151 | | - if (slen > inputlen - pos) { |
152 | | - return 0; |
153 | | - } |
154 | | - spos = pos; |
155 | | - pos += slen; |
156 | | - |
157 | | - /* Ignore leading zeroes in R */ |
158 | | - while (rlen > 0 && input[rpos] == 0) { |
159 | | - rlen--; |
160 | | - rpos++; |
161 | | - } |
162 | | - /* Copy R value */ |
163 | | - if (rlen > 32) { |
164 | | - overflow = 1; |
165 | | - } else { |
166 | | - memcpy(tmpsig + 32 - rlen, input + rpos, rlen); |
167 | | - } |
168 | | - |
169 | | - /* Ignore leading zeroes in S */ |
170 | | - while (slen > 0 && input[spos] == 0) { |
171 | | - slen--; |
172 | | - spos++; |
173 | | - } |
174 | | - /* Copy S value */ |
175 | | - if (slen > 32) { |
176 | | - overflow = 1; |
177 | | - } else { |
178 | | - memcpy(tmpsig + 64 - slen, input + spos, slen); |
179 | | - } |
180 | | - |
181 | | - if (!overflow) { |
182 | | - overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); |
183 | | - } |
184 | | - if (overflow) { |
185 | | - memset(tmpsig, 0, 64); |
186 | | - secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); |
187 | | - } |
188 | | - return 1; |
| 60 | +/** Parse a signature in "lax DER" format |
| 61 | + * |
| 62 | + * Returns: 1 when the signature could be parsed, 0 otherwise. |
| 63 | + * Args: ctx: a secp256k1 context object |
| 64 | + * Out: sig: a pointer to a signature object |
| 65 | + * In: input: a pointer to the signature to be parsed |
| 66 | + * inputlen: the length of the array pointed to be input |
| 67 | + * |
| 68 | + * This function will accept any valid DER encoded signature, even if the |
| 69 | + * encoded numbers are out of range. In addition, it will accept signatures |
| 70 | + * which violate the DER spec in various ways. Its purpose is to allow |
| 71 | + * validation of the Bitcoin blockchain, which includes non-DER signatures |
| 72 | + * from before the network rules were updated to enforce DER. Note that |
| 73 | + * the set of supported violations is a strict subset of what OpenSSL will |
| 74 | + * accept. |
| 75 | + * |
| 76 | + * After the call, sig will always be initialized. If parsing failed or the |
| 77 | + * encoded numbers are out of range, signature validation with it is |
| 78 | + * guaranteed to fail for every message and public key. |
| 79 | + */ |
| 80 | +int ecdsa_signature_parse_der_lax( |
| 81 | + const secp256k1_context* ctx, |
| 82 | + secp256k1_ecdsa_signature* sig, |
| 83 | + const unsigned char *input, |
| 84 | + size_t inputlen |
| 85 | +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); |
| 86 | + |
| 87 | +#ifdef __cplusplus |
189 | 88 | } |
| 89 | +#endif |
190 | 90 |
|
191 | 91 | #endif |
0 commit comments