Bitcoin Core 28.99.0
P2P Digital Currency
lax_der_parsing.c
Go to the documentation of this file.
1/***********************************************************************
2 * Copyright (c) 2015 Pieter Wuille *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5 ***********************************************************************/
6
7#include <string.h>
8
9#include "lax_der_parsing.h"
10
11int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
12 size_t rpos, rlen, spos, slen;
13 size_t pos = 0;
14 size_t lenbyte;
15 unsigned char tmpsig[64] = {0};
16 int overflow = 0;
17
18 /* Hack to initialize sig with a correctly-parsed but invalid signature. */
20
21 /* Sequence tag byte */
22 if (pos == inputlen || input[pos] != 0x30) {
23 return 0;
24 }
25 pos++;
26
27 /* Sequence length bytes */
28 if (pos == inputlen) {
29 return 0;
30 }
31 lenbyte = input[pos++];
32 if (lenbyte & 0x80) {
33 lenbyte -= 0x80;
34 if (lenbyte > inputlen - pos) {
35 return 0;
36 }
37 pos += lenbyte;
38 }
39
40 /* Integer tag byte for R */
41 if (pos == inputlen || input[pos] != 0x02) {
42 return 0;
43 }
44 pos++;
45
46 /* Integer length for R */
47 if (pos == inputlen) {
48 return 0;
49 }
50 lenbyte = input[pos++];
51 if (lenbyte & 0x80) {
52 lenbyte -= 0x80;
53 if (lenbyte > inputlen - pos) {
54 return 0;
55 }
56 while (lenbyte > 0 && input[pos] == 0) {
57 pos++;
58 lenbyte--;
59 }
60 if (lenbyte >= sizeof(size_t)) {
61 return 0;
62 }
63 rlen = 0;
64 while (lenbyte > 0) {
65 rlen = (rlen << 8) + input[pos];
66 pos++;
67 lenbyte--;
68 }
69 } else {
70 rlen = lenbyte;
71 }
72 if (rlen > inputlen - pos) {
73 return 0;
74 }
75 rpos = pos;
76 pos += rlen;
77
78 /* Integer tag byte for S */
79 if (pos == inputlen || input[pos] != 0x02) {
80 return 0;
81 }
82 pos++;
83
84 /* Integer length for S */
85 if (pos == inputlen) {
86 return 0;
87 }
88 lenbyte = input[pos++];
89 if (lenbyte & 0x80) {
90 lenbyte -= 0x80;
91 if (lenbyte > inputlen - pos) {
92 return 0;
93 }
94 while (lenbyte > 0 && input[pos] == 0) {
95 pos++;
96 lenbyte--;
97 }
98 if (lenbyte >= sizeof(size_t)) {
99 return 0;
100 }
101 slen = 0;
102 while (lenbyte > 0) {
103 slen = (slen << 8) + input[pos];
104 pos++;
105 lenbyte--;
106 }
107 } else {
108 slen = lenbyte;
109 }
110 if (slen > inputlen - pos) {
111 return 0;
112 }
113 spos = pos;
114
115 /* Ignore leading zeroes in R */
116 while (rlen > 0 && input[rpos] == 0) {
117 rlen--;
118 rpos++;
119 }
120 /* Copy R value */
121 if (rlen > 32) {
122 overflow = 1;
123 } else if (rlen) {
124 memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
125 }
126
127 /* Ignore leading zeroes in S */
128 while (slen > 0 && input[spos] == 0) {
129 slen--;
130 spos++;
131 }
132 /* Copy S value */
133 if (slen > 32) {
134 overflow = 1;
135 } else if (slen) {
136 memcpy(tmpsig + 64 - slen, input + spos, slen);
137 }
138
139 if (!overflow) {
140 overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
141 }
142 if (overflow) {
143 memset(tmpsig, 0, 64);
145 }
146 return 1;
147}
148
int ecdsa_signature_parse_der_lax(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input, size_t inputlen)
Parse a signature in "lax DER" format.
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input64) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse an ECDSA signature in compact (64 bytes) format.
Definition: secp256k1.c:385
Opaque data structure that holds a parsed ECDSA signature.
Definition: secp256k1.h:74