Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
lax_der_parsing.c File Reference
#include <string.h>
#include "lax_der_parsing.h"
Include dependency graph for lax_der_parsing.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int ecdsa_signature_parse_der_lax (const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input, size_t inputlen)
 

Function Documentation

◆ ecdsa_signature_parse_der_lax()

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

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.

Definition at line 11 of file lax_der_parsing.c.

11 {
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) {
141 }
142 if (overflow) {
143 memset(tmpsig, 0, 64);
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)
Definition secp256k1.c:335
bool overflow
memset(pInfo->slotDescription, ' ', 64)
memcpy((char *) pInfo->slotDescription, s, l)
Here is the call graph for this function:
Here is the caller graph for this function: