lax_der_parsing.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. #include <string.h>
  7. #include <secp256k1.h>
  8. #include "lax_der_parsing.h"
  9. int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
  10. size_t rpos, rlen, spos, slen;
  11. size_t pos = 0;
  12. size_t lenbyte;
  13. unsigned char tmpsig[64] = {0};
  14. int overflow = 0;
  15. /* Hack to initialize sig with a correctly-parsed but invalid signature. */
  16. secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
  17. /* Sequence tag byte */
  18. if (pos == inputlen || input[pos] != 0x30) {
  19. return 0;
  20. }
  21. pos++;
  22. /* Sequence length bytes */
  23. if (pos == inputlen) {
  24. return 0;
  25. }
  26. lenbyte = input[pos++];
  27. if (lenbyte & 0x80) {
  28. lenbyte -= 0x80;
  29. if (pos + lenbyte > inputlen) {
  30. return 0;
  31. }
  32. pos += lenbyte;
  33. }
  34. /* Integer tag byte for R */
  35. if (pos == inputlen || input[pos] != 0x02) {
  36. return 0;
  37. }
  38. pos++;
  39. /* Integer length for R */
  40. if (pos == inputlen) {
  41. return 0;
  42. }
  43. lenbyte = input[pos++];
  44. if (lenbyte & 0x80) {
  45. lenbyte -= 0x80;
  46. if (pos + lenbyte > inputlen) {
  47. return 0;
  48. }
  49. while (lenbyte > 0 && input[pos] == 0) {
  50. pos++;
  51. lenbyte--;
  52. }
  53. if (lenbyte >= sizeof(size_t)) {
  54. return 0;
  55. }
  56. rlen = 0;
  57. while (lenbyte > 0) {
  58. rlen = (rlen << 8) + input[pos];
  59. pos++;
  60. lenbyte--;
  61. }
  62. } else {
  63. rlen = lenbyte;
  64. }
  65. if (rlen > inputlen - pos) {
  66. return 0;
  67. }
  68. rpos = pos;
  69. pos += rlen;
  70. /* Integer tag byte for S */
  71. if (pos == inputlen || input[pos] != 0x02) {
  72. return 0;
  73. }
  74. pos++;
  75. /* Integer length for S */
  76. if (pos == inputlen) {
  77. return 0;
  78. }
  79. lenbyte = input[pos++];
  80. if (lenbyte & 0x80) {
  81. lenbyte -= 0x80;
  82. if (pos + lenbyte > inputlen) {
  83. return 0;
  84. }
  85. while (lenbyte > 0 && input[pos] == 0) {
  86. pos++;
  87. lenbyte--;
  88. }
  89. if (lenbyte >= sizeof(size_t)) {
  90. return 0;
  91. }
  92. slen = 0;
  93. while (lenbyte > 0) {
  94. slen = (slen << 8) + input[pos];
  95. pos++;
  96. lenbyte--;
  97. }
  98. } else {
  99. slen = lenbyte;
  100. }
  101. if (slen > inputlen - pos) {
  102. return 0;
  103. }
  104. spos = pos;
  105. pos += slen;
  106. /* Ignore leading zeroes in R */
  107. while (rlen > 0 && input[rpos] == 0) {
  108. rlen--;
  109. rpos++;
  110. }
  111. /* Copy R value */
  112. if (rlen > 32) {
  113. overflow = 1;
  114. } else {
  115. memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
  116. }
  117. /* Ignore leading zeroes in S */
  118. while (slen > 0 && input[spos] == 0) {
  119. slen--;
  120. spos++;
  121. }
  122. /* Copy S value */
  123. if (slen > 32) {
  124. overflow = 1;
  125. } else {
  126. memcpy(tmpsig + 64 - slen, input + spos, slen);
  127. }
  128. if (!overflow) {
  129. overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
  130. }
  131. if (overflow) {
  132. memset(tmpsig, 0, 64);
  133. secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
  134. }
  135. return 1;
  136. }