github.com/snowblossomcoin/go-ethereum@v1.9.25/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c (about) 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. */ 20 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 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