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 **********************************************************************/
10 #include "lax_der_parsing.h"
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;
16 unsigned char tmpsig[64] = {0};
19 /* Hack to initialize sig with a correctly-parsed but invalid signature. */
20 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
22 /* Sequence tag byte */
23 if (pos == inputlen || input[pos] != 0x30) {
28 /* Sequence length bytes */
29 if (pos == inputlen) {
32 lenbyte = input[pos++];
35 if (lenbyte > inputlen - pos) {
41 /* Integer tag byte for R */
42 if (pos == inputlen || input[pos] != 0x02) {
47 /* Integer length for R */
48 if (pos == inputlen) {
51 lenbyte = input[pos++];
54 if (lenbyte > inputlen - pos) {
57 while (lenbyte > 0 && input[pos] == 0) {
61 if (lenbyte >= sizeof(size_t)) {
66 rlen = (rlen << 8) + input[pos];
73 if (rlen > inputlen - pos) {
79 /* Integer tag byte for S */
80 if (pos == inputlen || input[pos] != 0x02) {
85 /* Integer length for S */
86 if (pos == inputlen) {
89 lenbyte = input[pos++];
92 if (lenbyte > inputlen - pos) {
95 while (lenbyte > 0 && input[pos] == 0) {
99 if (lenbyte >= sizeof(size_t)) {
103 while (lenbyte > 0) {
104 slen = (slen << 8) + input[pos];
111 if (slen > inputlen - pos) {
117 /* Ignore leading zeroes in R */
118 while (rlen > 0 && input[rpos] == 0) {
126 memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
129 /* Ignore leading zeroes in S */
130 while (slen > 0 && input[spos] == 0) {
138 memcpy(tmpsig + 64 - slen, input + spos, slen);
142 overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
145 memset(tmpsig, 0, 64);
146 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);