Fabcoin Core  0.16.2
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 http://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 (pos + lenbyte > inputlen) {
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 (pos + lenbyte > inputlen) {
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 (pos + lenbyte > inputlen) {
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  pos += slen;
116 
117  /* Ignore leading zeroes in R */
118  while (rlen > 0 && input[rpos] == 0) {
119  rlen--;
120  rpos++;
121  }
122  /* Copy R value */
123  if (rlen > 32) {
124  overflow = 1;
125  } else {
126  memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
127  }
128 
129  /* Ignore leading zeroes in S */
130  while (slen > 0 && input[spos] == 0) {
131  slen--;
132  spos++;
133  }
134  /* Copy S value */
135  if (slen > 32) {
136  overflow = 1;
137  } else {
138  memcpy(tmpsig + 64 - slen, input + spos, slen);
139  }
140 
141  if (!overflow) {
142  overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
143  }
144  if (overflow) {
145  memset(tmpsig, 0, 64);
146  secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
147  }
148  return 1;
149 }
150 
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.
Opaque data structured that holds a parsed ECDSA signature.
Definition: secp256k1.h:66
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:228
void * memcpy(void *a, const void *b, size_t c)