LCOV - code coverage report
Current view: top level - source4/heimdal/lib/hx509 - file.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 64 149 43.0 %
Date: 2021-09-23 10:06:22 Functions: 3 9 33.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2005 - 2006 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "hx_locl.h"
      35             : 
      36             : int
      37           0 : _hx509_map_file_os(const char *fn, heim_octet_string *os)
      38             : {
      39             :     size_t length;
      40             :     void *data;
      41             :     int ret;
      42             : 
      43           0 :     ret = rk_undumpdata(fn, &data, &length);
      44             : 
      45           0 :     os->data = data;
      46           0 :     os->length = length;
      47             : 
      48           0 :     return ret;
      49             : }
      50             : 
      51             : void
      52           0 : _hx509_unmap_file_os(heim_octet_string *os)
      53             : {
      54           0 :     rk_xfree(os->data);
      55           0 : }
      56             : 
      57             : int
      58           0 : _hx509_write_file(const char *fn, const void *data, size_t length)
      59             : {
      60           0 :     rk_dumpdata(fn, data, length);
      61           0 :     return 0;
      62             : }
      63             : 
      64             : /*
      65             :  *
      66             :  */
      67             : 
      68             : static void
      69           0 : print_pem_stamp(FILE *f, const char *type, const char *str)
      70             : {
      71           0 :     fprintf(f, "-----%s %s-----\n", type, str);
      72           0 : }
      73             : 
      74             : int
      75           0 : hx509_pem_write(hx509_context context, const char *type,
      76             :                 hx509_pem_header *headers, FILE *f,
      77             :                 const void *data, size_t size)
      78             : {
      79           0 :     const char *p = data;
      80             :     size_t length;
      81             :     char *line;
      82             : 
      83             : #define ENCODE_LINE_LENGTH      54
      84             : 
      85           0 :     print_pem_stamp(f, "BEGIN", type);
      86             : 
      87           0 :     while (headers) {
      88           0 :         fprintf(f, "%s: %s\n%s",
      89             :                 headers->header, headers->value,
      90           0 :                 headers->next ? "" : "\n");
      91           0 :         headers = headers->next;
      92             :     }
      93             : 
      94           0 :     while (size > 0) {
      95             :         ssize_t l;
      96             : 
      97           0 :         length = size;
      98           0 :         if (length > ENCODE_LINE_LENGTH)
      99           0 :             length = ENCODE_LINE_LENGTH;
     100             : 
     101           0 :         l = base64_encode(p, length, &line);
     102           0 :         if (l < 0) {
     103           0 :             hx509_set_error_string(context, 0, ENOMEM,
     104             :                                    "malloc - out of memory");
     105           0 :             return ENOMEM;
     106             :         }
     107           0 :         size -= length;
     108           0 :         fprintf(f, "%s\n", line);
     109           0 :         p += length;
     110           0 :         free(line);
     111             :     }
     112             : 
     113           0 :     print_pem_stamp(f, "END", type);
     114             : 
     115           0 :     return 0;
     116             : }
     117             : 
     118             : /*
     119             :  *
     120             :  */
     121             : 
     122             : int
     123           0 : hx509_pem_add_header(hx509_pem_header **headers,
     124             :                      const char *header, const char *value)
     125             : {
     126             :     hx509_pem_header *h;
     127             : 
     128           0 :     h = calloc(1, sizeof(*h));
     129           0 :     if (h == NULL)
     130           0 :         return ENOMEM;
     131           0 :     h->header = strdup(header);
     132           0 :     if (h->header == NULL) {
     133           0 :         free(h);
     134           0 :         return ENOMEM;
     135             :     }
     136           0 :     h->value = strdup(value);
     137           0 :     if (h->value == NULL) {
     138           0 :         free(h->header);
     139           0 :         free(h);
     140           0 :         return ENOMEM;
     141             :     }
     142             : 
     143           0 :     h->next = *headers;
     144           0 :     *headers = h;
     145             : 
     146           0 :     return 0;
     147             : }
     148             : 
     149             : void
     150         282 : hx509_pem_free_header(hx509_pem_header *headers)
     151             : {
     152             :     hx509_pem_header *h;
     153         564 :     while (headers) {
     154           0 :         h = headers;
     155           0 :         headers = headers->next;
     156           0 :         free(h->header);
     157           0 :         free(h->value);
     158           0 :         free(h);
     159             :     }
     160         282 : }
     161             : 
     162             : /*
     163             :  *
     164             :  */
     165             : 
     166             : const char *
     167          94 : hx509_pem_find_header(const hx509_pem_header *h, const char *header)
     168             : {
     169         188 :     while(h) {
     170           0 :         if (strcmp(header, h->header) == 0)
     171           0 :             return h->value;
     172           0 :         h = h->next;
     173             :     }
     174          86 :     return NULL;
     175             : }
     176             : 
     177             : 
     178             : /*
     179             :  *
     180             :  */
     181             : 
     182             : int
     183         282 : hx509_pem_read(hx509_context context,
     184             :                FILE *f,
     185             :                hx509_pem_read_func func,
     186             :                void *ctx)
     187             : {
     188         282 :     hx509_pem_header *headers = NULL;
     189         282 :     char *type = NULL;
     190         282 :     void *data = NULL;
     191         282 :     size_t len = 0;
     192             :     char buf[1024];
     193         282 :     int ret = HX509_PARSING_KEY_FAILED;
     194             : 
     195             :     enum { BEFORE, SEARCHHEADER, INHEADER, INDATA, DONE } where;
     196             : 
     197         282 :     where = BEFORE;
     198             : 
     199       27256 :     while (fgets(buf, sizeof(buf), f) != NULL) {
     200             :         char *p;
     201             :         int i;
     202             : 
     203       26692 :         i = strcspn(buf, "\n");
     204       26692 :         if (buf[i] == '\n') {
     205       26692 :             buf[i] = '\0';
     206       26692 :             if (i > 0)
     207       26410 :                 i--;
     208             :         }
     209       26692 :         if (buf[i] == '\r') {
     210           0 :             buf[i] = '\0';
     211           0 :             if (i > 0)
     212           0 :                 i--;
     213             :         }
     214             : 
     215       26692 :         switch (where) {
     216       12292 :         case BEFORE:
     217       12292 :             if (strncmp("-----BEGIN ", buf, 11) == 0) {
     218         282 :                 type = strdup(buf + 11);
     219         282 :                 if (type == NULL)
     220           0 :                     break;
     221         282 :                 p = strchr(type, '-');
     222         282 :                 if (p)
     223         282 :                     *p = '\0';
     224         258 :                 where = SEARCHHEADER;
     225             :             }
     226       11188 :             break;
     227         282 :         case SEARCHHEADER:
     228         282 :             p = strchr(buf, ':');
     229         282 :             if (p == NULL) {
     230         258 :                 where = INDATA;
     231         258 :                 goto indata;
     232             :             }
     233             :             /* FALLTHOUGH */
     234             :         case INHEADER:
     235           0 :             if (buf[0] == '\0') {
     236           0 :                 where = INDATA;
     237           0 :                 break;
     238             :             }
     239           0 :             p = strchr(buf, ':');
     240           0 :             if (p) {
     241           0 :                 *p++ = '\0';
     242           0 :                 while (isspace((int)*p))
     243           0 :                     p++;
     244           0 :                 ret = hx509_pem_add_header(&headers, buf, p);
     245           0 :                 if (ret)
     246           0 :                     abort();
     247             :             }
     248           0 :             break;
     249             :         case INDATA:
     250       14400 :         indata:
     251             : 
     252       14400 :             if (strncmp("-----END ", buf, 9) == 0) {
     253         258 :                 where = DONE;
     254         258 :                 break;
     255             :             }
     256             : 
     257       14118 :             p = emalloc(i);
     258       14118 :             i = base64_decode(buf, p);
     259       14118 :             if (i < 0) {
     260           0 :                 free(p);
     261           0 :                 goto out;
     262             :             }
     263             : 
     264       14118 :             data = erealloc(data, len + i);
     265       15422 :             memcpy(((char *)data) + len, p, i);
     266       14118 :             free(p);
     267       14118 :             len += i;
     268       14118 :             break;
     269           0 :         case DONE:
     270           0 :             abort();
     271             :         }
     272             : 
     273       26692 :         if (where == DONE) {
     274         282 :             ret = (*func)(context, type, headers, data, len, ctx);
     275         282 :         out:
     276         282 :             free(data);
     277         282 :             data = NULL;
     278         282 :             len = 0;
     279         282 :             free(type);
     280         282 :             type = NULL;
     281         282 :             where = BEFORE;
     282         282 :             hx509_pem_free_header(headers);
     283         282 :             headers = NULL;
     284         282 :             if (ret)
     285           0 :                 break;
     286             :         }
     287             :     }
     288             : 
     289         282 :     if (where != BEFORE) {
     290           0 :         hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
     291             :                                "File ends before end of PEM end tag");
     292           0 :         ret = HX509_PARSING_KEY_FAILED;
     293             :     }
     294         282 :     if (data)
     295           0 :         free(data);
     296         282 :     if (type)
     297           0 :         free(type);
     298         282 :     if (headers)
     299           0 :         hx509_pem_free_header(headers);
     300             : 
     301         282 :     return ret;
     302             : }

Generated by: LCOV version 1.13