der_decode_integer.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtomcrypt.org
  10. */
  11. #include "mycrypt.h"
  12. /* decodes a DER INTEGER in [in]. You have to tell this function
  13. * how many bytes are available [inlen]. It will then attempt to
  14. * read the INTEGER. If all goes well it stores the number of bytes
  15. * read in [inlen] and the number in [num].
  16. */
  17. int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num)
  18. {
  19. unsigned long tmplen, y, z;
  20. _ARGCHK(num != NULL);
  21. _ARGCHK(in != NULL);
  22. _ARGCHK(inlen != NULL);
  23. /* save copy of max output size */
  24. tmplen = *inlen;
  25. *inlen = 0;
  26. /* min DER INTEGER is 0x02 01 00 == 0 */
  27. if (tmplen < (1 + 1 + 1)) {
  28. return CRYPT_INVALID_PACKET;
  29. }
  30. /* ok expect 0x02 when we AND with 0011 1111 [3F] */
  31. if ((*in++ & 0x3F) != 0x02) {
  32. return CRYPT_INVALID_PACKET;
  33. }
  34. ++(*inlen);
  35. /* now decode the len stuff */
  36. z = *in++;
  37. ++(*inlen);
  38. if ((z & 0x80) == 0x00) {
  39. /* short form */
  40. /* will it overflow? */
  41. if (*inlen + z > tmplen) {
  42. return CRYPT_INVALID_PACKET;
  43. }
  44. /* no so read it */
  45. (*inlen) += z;
  46. return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z));
  47. } else {
  48. /* long form */
  49. z &= 0x7F;
  50. /* will number of length bytes overflow? (or > 4) */
  51. if (((*inlen + z) > tmplen) || (z > 4)) {
  52. return CRYPT_INVALID_PACKET;
  53. }
  54. /* now read it in */
  55. y = 0;
  56. while (z--) {
  57. y = ((unsigned long)(*in++)) | (y << 8);
  58. ++(*inlen);
  59. }
  60. /* now will reading y bytes overrun? */
  61. if ((*inlen + y) > tmplen) {
  62. return CRYPT_INVALID_PACKET;
  63. }
  64. /* no so read it */
  65. (*inlen) += y;
  66. return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y));
  67. }
  68. }