forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
0c6ab2f Introduce explicit lower-S normalization (Pieter Wuille) fea19e7 Add contrib/lax_der_parsing.h (Pieter Wuille) 3bb9c44 Rewrite ECDSA signature parsing code (Pieter Wuille) fa57f1b Use secp256k1_rand_int and secp256k1_rand_bits more (Pieter Wuille) 49b3749 Add new tests for the extra testrand functions (Pieter Wuille) f684d7d Faster secp256k1_rand_int implementation (Pieter Wuille) 251b1a6 Improve testrand: add extra random functions (Pieter Wuille)
- Loading branch information
Showing
12 changed files
with
1,006 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
/********************************************************************** | ||
* Copyright (c) 2015 Pieter Wuille * | ||
* Distributed under the MIT software license, see the accompanying * | ||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.* | ||
**********************************************************************/ | ||
|
||
/* This file contains a code snippet that parses DER with various errors and | ||
* violations. This is not a part of the library itself, because the allowed | ||
* violations are chosen arbitrarily and do not follow or establish any | ||
* standard. | ||
* | ||
* In many places it matters that different implementations do not only accept | ||
* the same set of valid signatures, but also reject the same set of signatures. | ||
* The only means to accomplish that is by strictly obeying a standard, and not | ||
* accepting anything else. | ||
* | ||
* Nonetheless, sometimes there is a need for compatibility with systems that | ||
* use signatures which do not strictly obey DER. The snippet below shows how | ||
* certain violations are easily supported. You may need to adapt it. | ||
* | ||
* Do not use this for new systems. Use well-defined DER or compact signatures | ||
* instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and | ||
* secp256k1_ecdsa_signature_parse_compact). | ||
* | ||
* The supported violations are: | ||
* - All numbers are parsed as nonnegative integers, even though X.609-0207 | ||
* section 8.3.3 specifies that integers are always encoded as two's | ||
* complement. | ||
* - Integers can have length 0, even though section 8.3.1 says they can't. | ||
* - Integers with overly long padding are accepted, violation section | ||
* 8.3.2. | ||
* - 127-byte long length descriptors are accepted, even though section | ||
* 8.1.3.5.c says that they are not. | ||
* - Trailing garbage data inside or after the signature is ignored. | ||
* - The length descriptor of the sequence is ignored. | ||
* | ||
* Compared to for example OpenSSL, many violations are NOT supported: | ||
* - Using overly long tag descriptors for the sequence or integers inside, | ||
* violating section 8.1.2.2. | ||
* - Encoding primitive integers as constructed values, violating section | ||
* 8.3.1. | ||
*/ | ||
|
||
#ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ | ||
#define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ | ||
|
||
#include <string.h> | ||
#include <secp256k1.h> | ||
|
||
static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen); | ||
|
||
static int secp256k1_ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { | ||
size_t rpos, rlen, spos, slen; | ||
size_t pos = 0; | ||
size_t lenbyte; | ||
unsigned char tmpsig[64] = {0}; | ||
int overflow = 0; | ||
|
||
/* Hack to initialize sig with a correctly-parsed but invalid signature. */ | ||
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); | ||
|
||
/* Sequence tag byte */ | ||
if (pos == inputlen || input[pos] != 0x30) { | ||
return 0; | ||
} | ||
pos++; | ||
|
||
/* Sequence length bytes */ | ||
if (pos == inputlen) { | ||
return 0; | ||
} | ||
lenbyte = input[pos++]; | ||
if (lenbyte & 0x80) { | ||
lenbyte -= 0x80; | ||
if (pos + lenbyte > inputlen) { | ||
return 0; | ||
} | ||
pos += lenbyte; | ||
} | ||
|
||
/* Integer tag byte for R */ | ||
if (pos == inputlen || input[pos] != 0x02) { | ||
return 0; | ||
} | ||
pos++; | ||
|
||
/* Integer length for R */ | ||
if (pos == inputlen) { | ||
return 0; | ||
} | ||
lenbyte = input[pos++]; | ||
if (lenbyte & 0x80) { | ||
lenbyte -= 0x80; | ||
if (pos + lenbyte > inputlen) { | ||
return 0; | ||
} | ||
while (lenbyte > 0 && input[pos] == 0) { | ||
pos++; | ||
lenbyte--; | ||
} | ||
if (lenbyte >= sizeof(size_t)) { | ||
return 0; | ||
} | ||
rlen = 0; | ||
while (lenbyte > 0) { | ||
rlen = (rlen << 8) + input[pos]; | ||
pos++; | ||
lenbyte--; | ||
} | ||
} else { | ||
rlen = lenbyte; | ||
} | ||
if (rlen > inputlen - pos) { | ||
return 0; | ||
} | ||
rpos = pos; | ||
pos += rlen; | ||
|
||
/* Integer tag byte for S */ | ||
if (pos == inputlen || input[pos] != 0x02) { | ||
return 0; | ||
} | ||
pos++; | ||
|
||
/* Integer length for S */ | ||
if (pos == inputlen) { | ||
return 0; | ||
} | ||
lenbyte = input[pos++]; | ||
if (lenbyte & 0x80) { | ||
lenbyte -= 0x80; | ||
if (pos + lenbyte > inputlen) { | ||
return 0; | ||
} | ||
while (lenbyte > 0 && input[pos] == 0) { | ||
pos++; | ||
lenbyte--; | ||
} | ||
if (lenbyte >= sizeof(size_t)) { | ||
return 0; | ||
} | ||
slen = 0; | ||
while (lenbyte > 0) { | ||
slen = (slen << 8) + input[pos]; | ||
pos++; | ||
lenbyte--; | ||
} | ||
} else { | ||
slen = lenbyte; | ||
} | ||
if (slen > inputlen - pos) { | ||
return 0; | ||
} | ||
spos = pos; | ||
pos += slen; | ||
|
||
/* Ignore leading zeroes in R */ | ||
while (rlen > 0 && input[rpos] == 0) { | ||
rlen--; | ||
rpos++; | ||
} | ||
/* Copy R value */ | ||
if (rlen > 32) { | ||
overflow = 1; | ||
} else { | ||
memcpy(tmpsig + 32 - rlen, input + rpos, rlen); | ||
} | ||
|
||
/* Ignore leading zeroes in S */ | ||
while (slen > 0 && input[spos] == 0) { | ||
slen--; | ||
spos++; | ||
} | ||
/* Copy S value */ | ||
if (slen > 32) { | ||
overflow = 1; | ||
} else { | ||
memcpy(tmpsig + 64 - slen, input + spos, slen); | ||
} | ||
|
||
if (!overflow) { | ||
overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); | ||
} | ||
if (overflow) { | ||
memset(tmpsig, 0, 64); | ||
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); | ||
} | ||
return 1; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.