der_encode_generalizedtime.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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://libtom.org
  10. */
  11. #include "tomcrypt.h"
  12. /**
  13. @file der_encode_utctime.c
  14. ASN.1 DER, encode a GeneralizedTime, Steffen Jaeckel
  15. Based on der_encode_utctime.c
  16. */
  17. #ifdef LTC_DER
  18. static const char * const baseten = "0123456789";
  19. #define STORE_V(y) do {\
  20. out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
  21. out[x++] = der_ia5_char_encode(baseten[y % 10]); \
  22. } while(0)
  23. #define STORE_V4(y) do {\
  24. out[x++] = der_ia5_char_encode(baseten[(y/1000) % 10]); \
  25. out[x++] = der_ia5_char_encode(baseten[(y/100) % 10]); \
  26. out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
  27. out[x++] = der_ia5_char_encode(baseten[y % 10]); \
  28. } while(0)
  29. /**
  30. Encodes a Generalized time structure in DER format
  31. @param utctime The UTC time structure to encode
  32. @param out The destination of the DER encoding of the UTC time structure
  33. @param outlen [in/out] The length of the DER encoding
  34. @return CRYPT_OK if successful
  35. */
  36. int der_encode_generalizedtime(ltc_generalizedtime *gtime,
  37. unsigned char *out, unsigned long *outlen)
  38. {
  39. unsigned long x, tmplen;
  40. int err;
  41. LTC_ARGCHK(gtime != NULL);
  42. LTC_ARGCHK(out != NULL);
  43. LTC_ARGCHK(outlen != NULL);
  44. if ((err = der_length_generalizedtime(gtime, &tmplen)) != CRYPT_OK) {
  45. return err;
  46. }
  47. if (tmplen > *outlen) {
  48. *outlen = tmplen;
  49. return CRYPT_BUFFER_OVERFLOW;
  50. }
  51. /* store header */
  52. out[0] = 0x18;
  53. /* store values */
  54. x = 2;
  55. STORE_V4(gtime->YYYY);
  56. STORE_V(gtime->MM);
  57. STORE_V(gtime->DD);
  58. STORE_V(gtime->hh);
  59. STORE_V(gtime->mm);
  60. STORE_V(gtime->ss);
  61. if (gtime->fs) {
  62. unsigned long divisor;
  63. unsigned fs = gtime->fs;
  64. unsigned len = 0;
  65. out[x++] = der_ia5_char_encode('.');
  66. divisor = 1;
  67. do {
  68. fs /= 10;
  69. divisor *= 10;
  70. len++;
  71. } while(fs != 0);
  72. while (len-- > 1) {
  73. divisor /= 10;
  74. out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]);
  75. }
  76. out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]);
  77. }
  78. if (gtime->off_mm || gtime->off_hh) {
  79. out[x++] = der_ia5_char_encode(gtime->off_dir ? '-' : '+');
  80. STORE_V(gtime->off_hh);
  81. STORE_V(gtime->off_mm);
  82. } else {
  83. out[x++] = der_ia5_char_encode('Z');
  84. }
  85. /* store length */
  86. out[1] = (unsigned char)(x - 2);
  87. /* all good let's return */
  88. *outlen = x;
  89. return CRYPT_OK;
  90. }
  91. #endif
  92. /* $Source$ */
  93. /* $Revision$ */
  94. /* $Date$ */