You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
3.9 KiB

1 year ago
  1. /**
  2. * @file internal_format.c
  3. * @brief internal format (FIXME: derived from filename)
  4. * @license GNU General Public License 3.0 - see LICENSE.txt
  5. */
  6. #include "platform.h"
  7. #include "pEp_internal.h"
  8. #include "internal_format.h"
  9. static struct _internal_message_type {
  10. char type;
  11. char subtype;
  12. const char *mime_type;
  13. } message_type[] = {
  14. // Keys
  15. { 'K', 0, "application/keys" },
  16. // OpenPGP
  17. { 'K', 2, "application/pgp-keys" },
  18. // x.509
  19. { 'K', 3, "application/pkcs10" },
  20. { 'K', 4, "application/pkix-cert" },
  21. { 'K', 5, "application/pkix-crl" },
  22. { 'K', 6, "application/pkcs7-mime" },
  23. { 'K', 7, "application/x-x509-ca-cert" },
  24. { 'K', 8, "application/x-x509-user-cert" },
  25. { 'K', 9, "application/x-pkcs7-crl" },
  26. { 'K', 10, "application/x-pem-file" },
  27. { 'K', 11, "application/x-pkcs12" },
  28. { 'K', 12, "application/x-pkcs7-certificates" },
  29. { 'K', 13, "application/x-pkcs7-certreqresp" },
  30. // Sync
  31. { 'S', 0, "application/pEp.sync" },
  32. // Distribution
  33. { 'D', 0, "application/pEp.distribution" },
  34. { 'D', 0, "application/pEp.keyreset" },
  35. // Authentication
  36. { 'A', 0, "application/auth" },
  37. { 'A', 1, "application/signature" },
  38. // OpenPGP
  39. { 'A', 2, "application/pgp-signature" },
  40. // x.509
  41. { 'A', 3, "application/pkcs7-signature" },
  42. { 'A', 3, "application/x-pkcs7-signature" },
  43. // end marker
  44. { 0, 0, NULL }
  45. };
  46. DYNAMIC_API PEP_STATUS encode_internal(
  47. const char *value,
  48. size_t size,
  49. const char *mime_type,
  50. char **code,
  51. size_t *code_size
  52. )
  53. {
  54. assert(value && size && mime_type && code && code_size);
  55. if (!(value && size && mime_type && code && code_size))
  56. return PEP_ILLEGAL_VALUE;
  57. *code = NULL;
  58. *code_size = 0;
  59. char type = 0;
  60. char subtype;
  61. struct _internal_message_type *mt;
  62. for (mt = message_type; mt->type; ++mt) {
  63. if (strcasecmp(mime_type, mt->mime_type) == 0) {
  64. type = mt->type;
  65. subtype = mt->subtype;
  66. break;
  67. }
  68. }
  69. // unsupported MIME type
  70. if (!type)
  71. return PEP_STATUS_OK;
  72. // those are more BSOBs than BLOBS, so we copy
  73. char *result = malloc(size + 4);
  74. assert(result);
  75. if (!result)
  76. return PEP_OUT_OF_MEMORY;
  77. result[0] = 0;
  78. result[1] = type;
  79. result[2] = subtype;
  80. result[3] = 0;
  81. memcpy(result + 4, value, size);
  82. *code = result;
  83. *code_size = size + 4;
  84. return PEP_STATUS_OK;
  85. }
  86. DYNAMIC_API PEP_STATUS decode_internal(
  87. const char *code,
  88. size_t code_size,
  89. char **value,
  90. size_t *size,
  91. char **mime_type
  92. )
  93. {
  94. assert(value && size && mime_type && code && !code[0] && code_size);
  95. if (!(value && size && mime_type && code && !code[0] && code_size))
  96. return PEP_ILLEGAL_VALUE;
  97. *value = NULL;
  98. *size = 0;
  99. *mime_type = NULL;
  100. // elevated attachments have at least 5 bytes
  101. assert(code_size > 4);
  102. if (code_size < 5)
  103. return PEP_ILLEGAL_VALUE;
  104. assert(!code[0]);
  105. char type = code[1];
  106. char subtype = code[2];
  107. // char reserved = code[3];
  108. char *_mime_type = NULL;
  109. struct _internal_message_type *mt;
  110. for (mt = message_type; mt->type; ++mt) {
  111. if (type == mt->type && subtype == mt->subtype) {
  112. assert(mt->mime_type);
  113. _mime_type = strdup(mt->mime_type);
  114. assert(_mime_type);
  115. if (!_mime_type)
  116. return PEP_OUT_OF_MEMORY;
  117. break;
  118. }
  119. }
  120. if (!_mime_type)
  121. return PEP_ILLEGAL_VALUE;
  122. char *result = malloc(code_size - 4);
  123. assert(result);
  124. if (!result) {
  125. free(_mime_type);
  126. return PEP_OUT_OF_MEMORY;
  127. }
  128. memcpy(result, code + 4, code_size - 4);
  129. *value = result;
  130. *size = code_size - 4;
  131. *mime_type = _mime_type;
  132. return PEP_STATUS_OK;
  133. }