lax_der_parsing.c (3689B)
1 /*********************************************************************** 2 * Copyright (c) 2015 Pieter Wuille * 3 * Distributed under the MIT software license, see the accompanying * 4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 ***********************************************************************/ 6 7 #include <string.h> 8 9 #include "lax_der_parsing.h" 10 11 int haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der_lax(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { 12 size_t rpos, rlen, spos, slen; 13 size_t pos = 0; 14 size_t lenbyte; 15 unsigned char tmpsig[64] = {0}; 16 int overflow = 0; 17 18 /* Hack to initialize sig with a correctly-parsed but invalid signature. */ 19 haskellsecp256k1_v0_1_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 20 21 /* Sequence tag byte */ 22 if (pos == inputlen || input[pos] != 0x30) { 23 return 0; 24 } 25 pos++; 26 27 /* Sequence length bytes */ 28 if (pos == inputlen) { 29 return 0; 30 } 31 lenbyte = input[pos++]; 32 if (lenbyte & 0x80) { 33 lenbyte -= 0x80; 34 if (lenbyte > inputlen - pos) { 35 return 0; 36 } 37 pos += lenbyte; 38 } 39 40 /* Integer tag byte for R */ 41 if (pos == inputlen || input[pos] != 0x02) { 42 return 0; 43 } 44 pos++; 45 46 /* Integer length for R */ 47 if (pos == inputlen) { 48 return 0; 49 } 50 lenbyte = input[pos++]; 51 if (lenbyte & 0x80) { 52 lenbyte -= 0x80; 53 if (lenbyte > inputlen - pos) { 54 return 0; 55 } 56 while (lenbyte > 0 && input[pos] == 0) { 57 pos++; 58 lenbyte--; 59 } 60 if (lenbyte >= sizeof(size_t)) { 61 return 0; 62 } 63 rlen = 0; 64 while (lenbyte > 0) { 65 rlen = (rlen << 8) + input[pos]; 66 pos++; 67 lenbyte--; 68 } 69 } else { 70 rlen = lenbyte; 71 } 72 if (rlen > inputlen - pos) { 73 return 0; 74 } 75 rpos = pos; 76 pos += rlen; 77 78 /* Integer tag byte for S */ 79 if (pos == inputlen || input[pos] != 0x02) { 80 return 0; 81 } 82 pos++; 83 84 /* Integer length for S */ 85 if (pos == inputlen) { 86 return 0; 87 } 88 lenbyte = input[pos++]; 89 if (lenbyte & 0x80) { 90 lenbyte -= 0x80; 91 if (lenbyte > inputlen - pos) { 92 return 0; 93 } 94 while (lenbyte > 0 && input[pos] == 0) { 95 pos++; 96 lenbyte--; 97 } 98 if (lenbyte >= sizeof(size_t)) { 99 return 0; 100 } 101 slen = 0; 102 while (lenbyte > 0) { 103 slen = (slen << 8) + input[pos]; 104 pos++; 105 lenbyte--; 106 } 107 } else { 108 slen = lenbyte; 109 } 110 if (slen > inputlen - pos) { 111 return 0; 112 } 113 spos = pos; 114 115 /* Ignore leading zeroes in R */ 116 while (rlen > 0 && input[rpos] == 0) { 117 rlen--; 118 rpos++; 119 } 120 /* Copy R value */ 121 if (rlen > 32) { 122 overflow = 1; 123 } else if (rlen) { 124 memcpy(tmpsig + 32 - rlen, input + rpos, rlen); 125 } 126 127 /* Ignore leading zeroes in S */ 128 while (slen > 0 && input[spos] == 0) { 129 slen--; 130 spos++; 131 } 132 /* Copy S value */ 133 if (slen > 32) { 134 overflow = 1; 135 } else if (slen) { 136 memcpy(tmpsig + 64 - slen, input + spos, slen); 137 } 138 139 if (!overflow) { 140 overflow = !haskellsecp256k1_v0_1_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 141 } 142 if (overflow) { 143 memset(tmpsig, 0, 64); 144 haskellsecp256k1_v0_1_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 145 } 146 return 1; 147 } 148