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 **********************************************************************/
7 /* This file contains a code snippet that parses DER with various errors and
8 * violations. This is not a part of the library itself, because the allowed
9 * violations are chosen arbitrarily and do not follow or establish any
12 * In many places it matters that different implementations do not only accept
13 * the same set of valid signatures, but also reject the same set of signatures.
14 * The only means to accomplish that is by strictly obeying a standard, and not
15 * accepting anything else.
17 * Nonetheless, sometimes there is a need for compatibility with systems that
18 * use signatures which do not strictly obey DER. The snippet below shows how
19 * certain violations are easily supported. You may need to adapt it.
21 * Do not use this for new systems. Use well-defined DER or compact signatures
22 * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and
23 * secp256k1_ecdsa_signature_parse_compact).
25 * The supported violations are:
26 * - All numbers are parsed as nonnegative integers, even though X.609-0207
27 * section 8.3.3 specifies that integers are always encoded as two's
29 * - Integers can have length 0, even though section 8.3.1 says they can't.
30 * - Integers with overly long padding are accepted, violation section
32 * - 127-byte long length descriptors are accepted, even though section
33 * 8.1.3.5.c says that they are not.
34 * - Trailing garbage data inside or after the signature is ignored.
35 * - The length descriptor of the sequence is ignored.
37 * Compared to for example OpenSSL, many violations are NOT supported:
38 * - Using overly long tag descriptors for the sequence or integers inside,
39 * violating section 8.1.2.2.
40 * - Encoding primitive integers as constructed values, violating section
44 #ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_
45 #define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_
48 #include <secp256k1.h>
50 static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen);
52 static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
53 size_t rpos, rlen, spos, slen;
56 unsigned char tmpsig[64] = {0};
59 /* Hack to initialize sig with a correctly-parsed but invalid signature. */
60 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
62 /* Sequence tag byte */
63 if (pos == inputlen || input[pos] != 0x30) {
68 /* Sequence length bytes */
69 if (pos == inputlen) {
72 lenbyte = input[pos++];
75 if (pos + lenbyte > inputlen) {
81 /* Integer tag byte for R */
82 if (pos == inputlen || input[pos] != 0x02) {
87 /* Integer length for R */
88 if (pos == inputlen) {
91 lenbyte = input[pos++];
94 if (pos + lenbyte > inputlen) {
97 while (lenbyte > 0 && input[pos] == 0) {
101 if (lenbyte >= sizeof(size_t)) {
105 while (lenbyte > 0) {
106 rlen = (rlen << 8) + input[pos];
113 if (rlen > inputlen - pos) {
119 /* Integer tag byte for S */
120 if (pos == inputlen || input[pos] != 0x02) {
125 /* Integer length for S */
126 if (pos == inputlen) {
129 lenbyte = input[pos++];
130 if (lenbyte & 0x80) {
132 if (pos + lenbyte > inputlen) {
135 while (lenbyte > 0 && input[pos] == 0) {
139 if (lenbyte >= sizeof(size_t)) {
143 while (lenbyte > 0) {
144 slen = (slen << 8) + input[pos];
151 if (slen > inputlen - pos) {
157 /* Ignore leading zeroes in R */
158 while (rlen > 0 && input[rpos] == 0) {
166 memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
169 /* Ignore leading zeroes in S */
170 while (slen > 0 && input[spos] == 0) {
178 memcpy(tmpsig + 64 - slen, input + spos, slen);
182 overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
185 memset(tmpsig, 0, 64);
186 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);