Bitcoin ABC  0.26.3
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 #include <secp256k1.h>
9 
10 #include "lax_der_parsing.h"
11 
12 int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
13  size_t rpos, rlen, spos, slen;
14  size_t pos = 0;
15  size_t lenbyte;
16  unsigned char tmpsig[64] = {0};
17  int overflow = 0;
18 
19  /* Hack to initialize sig with a correctly-parsed but invalid signature. */
21 
22  /* Sequence tag byte */
23  if (pos == inputlen || input[pos] != 0x30) {
24  return 0;
25  }
26  pos++;
27 
28  /* Sequence length bytes */
29  if (pos == inputlen) {
30  return 0;
31  }
32  lenbyte = input[pos++];
33  if (lenbyte & 0x80) {
34  lenbyte -= 0x80;
35  if (lenbyte > inputlen - pos) {
36  return 0;
37  }
38  pos += lenbyte;
39  }
40 
41  /* Integer tag byte for R */
42  if (pos == inputlen || input[pos] != 0x02) {
43  return 0;
44  }
45  pos++;
46 
47  /* Integer length for R */
48  if (pos == inputlen) {
49  return 0;
50  }
51  lenbyte = input[pos++];
52  if (lenbyte & 0x80) {
53  lenbyte -= 0x80;
54  if (lenbyte > inputlen - pos) {
55  return 0;
56  }
57  while (lenbyte > 0 && input[pos] == 0) {
58  pos++;
59  lenbyte--;
60  }
61  if (lenbyte >= sizeof(size_t)) {
62  return 0;
63  }
64  rlen = 0;
65  while (lenbyte > 0) {
66  rlen = (rlen << 8) + input[pos];
67  pos++;
68  lenbyte--;
69  }
70  } else {
71  rlen = lenbyte;
72  }
73  if (rlen > inputlen - pos) {
74  return 0;
75  }
76  rpos = pos;
77  pos += rlen;
78 
79  /* Integer tag byte for S */
80  if (pos == inputlen || input[pos] != 0x02) {
81  return 0;
82  }
83  pos++;
84 
85  /* Integer length for S */
86  if (pos == inputlen) {
87  return 0;
88  }
89  lenbyte = input[pos++];
90  if (lenbyte & 0x80) {
91  lenbyte -= 0x80;
92  if (lenbyte > inputlen - pos) {
93  return 0;
94  }
95  while (lenbyte > 0 && input[pos] == 0) {
96  pos++;
97  lenbyte--;
98  }
99  if (lenbyte >= sizeof(size_t)) {
100  return 0;
101  }
102  slen = 0;
103  while (lenbyte > 0) {
104  slen = (slen << 8) + input[pos];
105  pos++;
106  lenbyte--;
107  }
108  } else {
109  slen = lenbyte;
110  }
111  if (slen > inputlen - pos) {
112  return 0;
113  }
114  spos = pos;
115 
116  /* Ignore leading zeroes in R */
117  while (rlen > 0 && input[rpos] == 0) {
118  rlen--;
119  rpos++;
120  }
121  /* Copy R value */
122  if (rlen > 32) {
123  overflow = 1;
124  } else {
125  memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
126  }
127 
128  /* Ignore leading zeroes in S */
129  while (slen > 0 && input[spos] == 0) {
130  slen--;
131  spos++;
132  }
133  /* Copy S value */
134  if (slen > 32) {
135  overflow = 1;
136  } else {
137  memcpy(tmpsig + 64 - slen, input + spos, slen);
138  }
139 
140  if (!overflow) {
141  overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
142  }
143  if (overflow) {
144  memset(tmpsig, 0, 64);
146  }
147  return 1;
148 }
149 
secp256k1_context * ctx
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.
SchnorrSig sig
Definition: processor.cpp:491
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:359
Opaque data structured that holds a parsed ECDSA signature.
Definition: secp256k1.h:80