Returns: 1 when the signature could be parsed, 0 otherwise. Args: ctx: a secp256k1 context object Out: sig: a pointer to a signature object In: input: a pointer to the signature to be parsed inputlen: the length of the array pointed to be input
This function will accept any valid DER encoded signature, even if the encoded numbers are out of range. In addition, it will accept signatures which violate the DER spec in various ways. Its purpose is to allow validation of the Bitcoin blockchain, which includes non-DER signatures from before the network rules were updated to enforce DER. Note that the set of supported violations is a strict subset of what OpenSSL will accept.
After the call, sig will always be initialized. If parsing failed or the encoded numbers are out of range, signature validation with it is guaranteed to fail for every message and public key.
11 {
12 size_t rpos, rlen, spos, slen;
13 size_t pos = 0;
14 size_t lenbyte;
15 unsigned char tmpsig[64] = {0};
17
18
20
21
22 if (pos == inputlen || input[pos] != 0x30) {
23 return 0;
24 }
25 pos++;
26
27
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
41 if (pos == inputlen || input[pos] != 0x02) {
42 return 0;
43 }
44 pos++;
45
46
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
79 if (pos == inputlen || input[pos] != 0x02) {
80 return 0;
81 }
82 pos++;
83
84
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
116 while (rlen > 0 && input[rpos] == 0) {
117 rlen--;
118 rpos++;
119 }
120
121 if (rlen > 32) {
123 } else if (rlen) {
124 memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
125 }
126
127
128 while (slen > 0 && input[spos] == 0) {
129 slen--;
130 spos++;
131 }
132
133 if (slen > 32) {
135 } else if (slen) {
136 memcpy(tmpsig + 64 - slen, input + spos, slen);
137 }
138
141 }
145 }
146 return 1;
147}
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)
memset(pInfo->slotDescription, ' ', 64)
memcpy((char *) pInfo->slotDescription, s, l)