der_encode_sequence_multi.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
  2. /* SPDX-License-Identifier: Unlicense */
  3. #include "tomcrypt_private.h"
  4. #include <stdarg.h>
  5. /**
  6. @file der_encode_sequence_multi.c
  7. ASN.1 DER, encode a SEQUENCE, Tom St Denis
  8. */
  9. #ifdef LTC_DER
  10. /**
  11. Encode a SEQUENCE type using a VA list
  12. @param out [out] Destination for data
  13. @param outlen [in/out] Length of buffer and resulting length of output
  14. @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
  15. @return CRYPT_OK on success
  16. */
  17. int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
  18. {
  19. int err;
  20. ltc_asn1_type type;
  21. unsigned long size, x;
  22. void *data;
  23. va_list args;
  24. ltc_asn1_list *list;
  25. LTC_ARGCHK(out != NULL);
  26. LTC_ARGCHK(outlen != NULL);
  27. /* get size of output that will be required */
  28. va_start(args, outlen);
  29. x = 0;
  30. for (;;) {
  31. type = (ltc_asn1_type)va_arg(args, int);
  32. if (type == LTC_ASN1_EOL) {
  33. break;
  34. }
  35. size = va_arg(args, unsigned long);
  36. data = va_arg(args, void*);
  37. LTC_UNUSED_PARAM(size);
  38. LTC_UNUSED_PARAM(data);
  39. switch (type) {
  40. case LTC_ASN1_BOOLEAN:
  41. case LTC_ASN1_INTEGER:
  42. case LTC_ASN1_SHORT_INTEGER:
  43. case LTC_ASN1_BIT_STRING:
  44. case LTC_ASN1_OCTET_STRING:
  45. case LTC_ASN1_NULL:
  46. case LTC_ASN1_OBJECT_IDENTIFIER:
  47. case LTC_ASN1_IA5_STRING:
  48. case LTC_ASN1_PRINTABLE_STRING:
  49. case LTC_ASN1_UTF8_STRING:
  50. case LTC_ASN1_UTCTIME:
  51. case LTC_ASN1_SEQUENCE:
  52. case LTC_ASN1_SET:
  53. case LTC_ASN1_SETOF:
  54. case LTC_ASN1_RAW_BIT_STRING:
  55. case LTC_ASN1_GENERALIZEDTIME:
  56. ++x;
  57. break;
  58. case LTC_ASN1_CHOICE:
  59. case LTC_ASN1_CUSTOM_TYPE:
  60. case LTC_ASN1_EOL:
  61. case LTC_ASN1_TELETEX_STRING:
  62. va_end(args);
  63. return CRYPT_INVALID_ARG;
  64. }
  65. }
  66. va_end(args);
  67. /* allocate structure for x elements */
  68. if (x == 0) {
  69. return CRYPT_NOP;
  70. }
  71. list = XCALLOC(x, sizeof(*list));
  72. if (list == NULL) {
  73. return CRYPT_MEM;
  74. }
  75. /* fill in the structure */
  76. va_start(args, outlen);
  77. x = 0;
  78. for (;;) {
  79. type = (ltc_asn1_type)va_arg(args, int);
  80. if (type == LTC_ASN1_EOL) {
  81. break;
  82. }
  83. size = va_arg(args, unsigned long);
  84. data = va_arg(args, void*);
  85. switch (type) {
  86. case LTC_ASN1_BOOLEAN:
  87. case LTC_ASN1_INTEGER:
  88. case LTC_ASN1_SHORT_INTEGER:
  89. case LTC_ASN1_BIT_STRING:
  90. case LTC_ASN1_OCTET_STRING:
  91. case LTC_ASN1_NULL:
  92. case LTC_ASN1_OBJECT_IDENTIFIER:
  93. case LTC_ASN1_IA5_STRING:
  94. case LTC_ASN1_PRINTABLE_STRING:
  95. case LTC_ASN1_UTF8_STRING:
  96. case LTC_ASN1_UTCTIME:
  97. case LTC_ASN1_SEQUENCE:
  98. case LTC_ASN1_SET:
  99. case LTC_ASN1_SETOF:
  100. case LTC_ASN1_RAW_BIT_STRING:
  101. case LTC_ASN1_GENERALIZEDTIME:
  102. LTC_SET_ASN1(list, x++, type, data, size);
  103. break;
  104. case LTC_ASN1_CHOICE:
  105. case LTC_ASN1_CUSTOM_TYPE:
  106. case LTC_ASN1_EOL:
  107. case LTC_ASN1_TELETEX_STRING:
  108. va_end(args);
  109. err = CRYPT_INVALID_ARG;
  110. goto LBL_ERR;
  111. }
  112. }
  113. va_end(args);
  114. err = der_encode_sequence(list, x, out, outlen);
  115. LBL_ERR:
  116. XFREE(list);
  117. return err;
  118. }
  119. #endif