Bitcoin Core  27.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 
11 int 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);
144  secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
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:379
Opaque data structured that holds a parsed ECDSA signature.
Definition: secp256k1.h:87