LCOV - code coverage report
Current view: top level - plugins/quic - certs.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 71 79 89.9 %
Date: 2023-07-05 22:20:52 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2019 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <openssl/pem.h>
      17             : 
      18             : #include <vppinfra/error.h>
      19             : 
      20             : #include <quic/certs.h>
      21             : 
      22             : 
      23             : int
      24         276 : ptls_compare_separator_line (const char *line, const char *begin_or_end,
      25             :                              const char *label)
      26             : {
      27         276 :   int ret = strncmp (line, "-----", 5);
      28         276 :   size_t text_index = 5;
      29             : 
      30         276 :   if (ret == 0)
      31             :     {
      32          24 :       size_t begin_or_end_length = strlen (begin_or_end);
      33          24 :       ret = strncmp (line + text_index, begin_or_end, begin_or_end_length);
      34          24 :       text_index += begin_or_end_length;
      35             :     }
      36             : 
      37         276 :   if (ret == 0)
      38             :     {
      39          24 :       ret = line[text_index] - ' ';
      40          24 :       text_index++;
      41             :     }
      42             : 
      43         276 :   if (ret == 0)
      44             :     {
      45          24 :       size_t label_length = strlen (label);
      46          24 :       ret = strncmp (line + text_index, label, label_length);
      47          24 :       text_index += label_length;
      48             :     }
      49             : 
      50         276 :   if (ret == 0)
      51             :     {
      52          24 :       ret = strncmp (line + text_index, "-----", 5);
      53             :     }
      54             : 
      55         276 :   return ret;
      56             : }
      57             : 
      58             : int
      59          24 : ptls_get_bio_pem_object (BIO * bio, const char *label, ptls_buffer_t * buf)
      60             : {
      61          24 :   int ret = PTLS_ERROR_PEM_LABEL_NOT_FOUND;
      62             :   char line[256];
      63             :   ptls_base64_decode_state_t state;
      64             : 
      65             :   /* Get the label on a line by itself */
      66          24 :   while (BIO_gets (bio, line, 256))
      67             :     {
      68          12 :       if (ptls_compare_separator_line (line, "BEGIN", label) == 0)
      69             :         {
      70          12 :           ret = 0;
      71          12 :           ptls_base64_decode_init (&state);
      72          12 :           break;
      73             :         }
      74             :     }
      75             :   /* Get the data in the buffer */
      76         276 :   while (ret == 0 && BIO_gets (bio, line, 256))
      77             :     {
      78         264 :       if (ptls_compare_separator_line (line, "END", label) == 0)
      79             :         {
      80          12 :           if (state.status == PTLS_BASE64_DECODE_DONE
      81           0 :               || (state.status == PTLS_BASE64_DECODE_IN_PROGRESS
      82           0 :                   && state.nbc == 0))
      83             :             {
      84          12 :               ret = 0;
      85             :             }
      86             :           else
      87             :             {
      88           0 :               ret = PTLS_ERROR_INCORRECT_BASE64;
      89             :             }
      90          12 :           break;
      91             :         }
      92             :       else
      93             :         {
      94         252 :           ret = ptls_base64_decode (line, &state, buf);
      95             :         }
      96             :     }
      97             : 
      98          24 :   return ret;
      99             : }
     100             : 
     101             : int
     102          12 : ptls_load_bio_pem_objects (BIO * bio, const char *label, ptls_iovec_t * list,
     103             :                            size_t list_max, size_t * nb_objects)
     104             : {
     105          12 :   int ret = 0;
     106          12 :   size_t count = 0;
     107             : 
     108          12 :   *nb_objects = 0;
     109             : 
     110          12 :   if (ret == 0)
     111             :     {
     112          24 :       while (count < list_max)
     113             :         {
     114             :           ptls_buffer_t buf;
     115             : 
     116          24 :           ptls_buffer_init (&buf, "", 0);
     117             : 
     118          24 :           ret = ptls_get_bio_pem_object (bio, label, &buf);
     119             : 
     120          24 :           if (ret == 0)
     121             :             {
     122          12 :               if (buf.off > 0 && buf.is_allocated)
     123             :                 {
     124          12 :                   list[count].base = buf.base;
     125          12 :                   list[count].len = buf.off;
     126          12 :                   count++;
     127             :                 }
     128             :               else
     129             :                 {
     130           0 :                   ptls_buffer_dispose (&buf);
     131             :                 }
     132             :             }
     133             :           else
     134             :             {
     135          12 :               ptls_buffer_dispose (&buf);
     136          12 :               break;
     137             :             }
     138             :         }
     139             :     }
     140             : 
     141          12 :   if (ret == PTLS_ERROR_PEM_LABEL_NOT_FOUND && count > 0)
     142             :     {
     143          12 :       ret = 0;
     144             :     }
     145             : 
     146          12 :   *nb_objects = count;
     147             : 
     148          12 :   return ret;
     149             : }
     150             : 
     151             : #define PTLS_MAX_CERTS_IN_CONTEXT 16
     152             : 
     153             : int
     154          12 : ptls_load_bio_certificates (ptls_context_t * ctx, BIO * bio)
     155             : {
     156          12 :   int ret = 0;
     157             : 
     158          12 :   ctx->certificates.list =
     159          12 :     (ptls_iovec_t *) malloc (PTLS_MAX_CERTS_IN_CONTEXT *
     160             :                              sizeof (ptls_iovec_t));
     161             : 
     162          12 :   if (ctx->certificates.list == NULL)
     163             :     {
     164           0 :       ret = PTLS_ERROR_NO_MEMORY;
     165             :     }
     166             :   else
     167             :     {
     168             :       ret =
     169          12 :         ptls_load_bio_pem_objects (bio, "CERTIFICATE", ctx->certificates.list,
     170             :                                    PTLS_MAX_CERTS_IN_CONTEXT,
     171             :                                    &ctx->certificates.count);
     172             :     }
     173             : 
     174          12 :   return ret;
     175             : }
     176             : 
     177             : int
     178          12 : load_bio_certificate_chain (ptls_context_t * ctx, const char *cert_data)
     179             : {
     180             :   BIO *cert_bio;
     181          12 :   cert_bio = BIO_new_mem_buf (cert_data, -1);
     182          12 :   if (ptls_load_bio_certificates (ctx, cert_bio) != 0)
     183             :     {
     184           0 :       BIO_free (cert_bio);
     185           0 :       return -1;
     186             :     }
     187          12 :   BIO_free (cert_bio);
     188          12 :   return 0;
     189             : }
     190             : 
     191             : int
     192          12 : load_bio_private_key (ptls_context_t * ctx, const char *pk_data)
     193             : {
     194             :   static ptls_openssl_sign_certificate_t sc;
     195             :   EVP_PKEY *pkey;
     196             :   BIO *key_bio;
     197             : 
     198          12 :   key_bio = BIO_new_mem_buf (pk_data, -1);
     199          12 :   pkey = PEM_read_bio_PrivateKey (key_bio, NULL, NULL, NULL);
     200          12 :   BIO_free (key_bio);
     201             : 
     202          12 :   if (pkey == NULL)
     203           0 :     return -1;
     204             : 
     205          12 :   ptls_openssl_init_sign_certificate (&sc, pkey);
     206          12 :   EVP_PKEY_free (pkey);
     207             : 
     208          12 :   ctx->sign_certificate = &sc.super;
     209          12 :   return 0;
     210             : }

Generated by: LCOV version 1.14