src/internal_format.c
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Thu, 04 Jun 2020 11:18:45 +0200
changeset 4729 3df9a2a67597
parent 4639 09116d12e937
child 4792 7056435ab9e7
permissions -rw-r--r--
forgot test files
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include "platform.h"
     5 
     6 #include "pEp_internal.h"
     7 #include "internal_format.h"
     8 
     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 
    17     // OpenPGP
    18     { 'K',  2, "application/pgp-keys" },
    19 
    20     // x.509
    21     { 'K',  3, "application/pkcs10" },
    22     { 'K',  4, "application/pkix-cert" },
    23     { 'K',  5, "application/pkix-crl" },
    24     { 'K',  6, "application/pkcs7-mime" },
    25     { 'K',  7, "application/x-x509-ca-cert" },
    26     { 'K',  8, "application/x-x509-user-cert" },
    27     { 'K',  9, "application/x-pkcs7-crl" },
    28     { 'K', 10, "application/x-pem-file" },
    29     { 'K', 11, "application/x-pkcs12" },
    30     { 'K', 12, "application/x-pkcs7-certificates" },
    31     { 'K', 13, "application/x-pkcs7-certreqresp" },
    32 
    33     // Sync
    34     { 'S', 0, "application/pEp.sync" },
    35 
    36     // Distribution
    37     { 'D', 0, "application/pEp.distribution" },
    38     { 'D', 0, "application/pEp.keyreset" },
    39 
    40     // Authentication
    41     { 'A', 0, "application/auth" },
    42     { 'A', 1, "application/signature" },
    43 
    44     // OpenPGP
    45     { 'A', 2, "application/pgp-signature" },
    46 
    47     // x.509
    48     { 'A', 3, "application/pkcs7-signature" },
    49     { 'A', 3, "application/x-pkcs7-signature" },
    50     
    51     // end marker
    52     { 0, 0, NULL }
    53 };
    54 
    55 DYNAMIC_API PEP_STATUS encode_internal(
    56         const char *value,
    57         size_t size,
    58         const char *mime_type,
    59         char **code,
    60         size_t *code_size
    61     )
    62 {
    63     assert(value && size && mime_type && code && code_size);
    64     if (!(value && size && mime_type && code && code_size))
    65         return PEP_ILLEGAL_VALUE;
    66 
    67     *code = NULL;
    68     *code_size = 0;
    69 
    70     char type = 0;
    71     char subtype;
    72 
    73     struct _internal_message_type *mt;
    74     for (mt = message_type; mt->type; ++mt) {
    75         if (strcasecmp(mime_type, mt->mime_type) == 0) {
    76             type = mt->type;
    77             subtype = mt->subtype;
    78             break;
    79         }
    80     }
    81 
    82     // unsupported MIME type
    83     if (!type)
    84         return PEP_STATUS_OK;
    85 
    86     // those are more BSOBs than BLOBS, so we copy
    87     char *result = malloc(size + 4);
    88     assert(result);
    89     if (!result)
    90         return PEP_OUT_OF_MEMORY;
    91 
    92     result[0] = 0;
    93     result[1] = type;
    94     result[2] = subtype;
    95     result[3] = 0;
    96 
    97     memcpy(result + 4, value, size);
    98     
    99     *code = result;
   100     *code_size = size + 4;
   101 
   102     return PEP_STATUS_OK;
   103 }
   104 
   105 DYNAMIC_API PEP_STATUS decode_internal(
   106         const char *code,
   107         size_t code_size,
   108         char **value,
   109         size_t *size,
   110         char **mime_type
   111     )
   112 {
   113     assert(value && size && mime_type && code && !code[0] && code_size);
   114     if (!(value && size && mime_type && code && !code[0] && code_size))
   115         return PEP_ILLEGAL_VALUE;
   116 
   117     *value = NULL;
   118     *size = 0;
   119     *mime_type = NULL;
   120 
   121     // elevated attachments have at least 5 bytes
   122     assert(code_size > 4);
   123     if (code_size < 5)
   124         return PEP_ILLEGAL_VALUE;
   125 
   126     assert(!code[0]);
   127     char type = code[1];
   128     char subtype = code[2];
   129     // char reserved = code[3];
   130 
   131     char *_mime_type = NULL;
   132 
   133     struct _internal_message_type *mt;
   134     for (mt = message_type; mt->type; ++mt) {
   135         if (type == mt->type && subtype == mt->subtype) {
   136             assert(mt->mime_type);
   137             _mime_type = strdup(mt->mime_type);
   138             assert(_mime_type);
   139             if (!_mime_type)
   140                 return PEP_OUT_OF_MEMORY;
   141 
   142             break;
   143         }
   144     }
   145 
   146     if (!_mime_type)
   147         return PEP_ILLEGAL_VALUE;
   148 
   149     char *result = malloc(code_size - 4);
   150     assert(result);
   151     if (!result) {
   152         free(_mime_type);
   153         return PEP_OUT_OF_MEMORY;
   154     }
   155 
   156     memcpy(result, code + 4, code_size - 4);
   157 
   158     *value = result;
   159     *size = code_size - 4;
   160     *mime_type = _mime_type;
   161 
   162     return PEP_STATUS_OK;
   163 }
   164