quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

lib3102.c (4367B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "first.h"
     25 
     26 #include "memdebug.h"
     27 
     28 /*
     29  * Verify correct order of certificates in the chain by comparing the
     30  * subject and issuer attributes of each certificate.
     31  */
     32 static bool is_chain_in_order(struct curl_certinfo *cert_info)
     33 {
     34   char *last_issuer = NULL;
     35   int cert;
     36 
     37   /* Chains with only a single certificate are always in order */
     38   if(cert_info->num_of_certs <= 1)
     39     return 1;
     40 
     41   /* Enumerate each certificate in the chain */
     42   for(cert = 0; cert < cert_info->num_of_certs; cert++) {
     43     struct curl_slist *slist = cert_info->certinfo[cert];
     44     char *issuer = NULL;
     45     char *subject = NULL;
     46 
     47     /* Find the certificate issuer and subject by enumerating each field */
     48     for(; slist && (!issuer || !subject); slist = slist->next) {
     49       static const char issuer_prefix[] = "Issuer:";
     50       static const char subject_prefix[] = "Subject:";
     51 
     52       if(!strncmp(slist->data, issuer_prefix, sizeof(issuer_prefix)-1)) {
     53         issuer = slist->data + sizeof(issuer_prefix)-1;
     54       }
     55       if(!strncmp(slist->data, subject_prefix, sizeof(subject_prefix)-1)) {
     56         subject = slist->data + sizeof(subject_prefix)-1;
     57       }
     58     }
     59 
     60     if(subject && issuer) {
     61       curl_mprintf("cert %d\n", cert);
     62       curl_mprintf("  subject: %s\n", subject);
     63       curl_mprintf("  issuer: %s\n", issuer);
     64 
     65       if(last_issuer) {
     66         /* If the last certificate's issuer matches the current certificate's
     67          * subject, then the chain is in order */
     68         if(strcmp(last_issuer, subject) != 0) {
     69           curl_mfprintf(stderr,
     70                         "cert %d issuer does not match cert %d subject\n",
     71                         cert - 1, cert);
     72           curl_mfprintf(stderr, "certificate chain is not in order\n");
     73           return false;
     74         }
     75       }
     76     }
     77 
     78     last_issuer = issuer;
     79   }
     80 
     81   curl_mprintf("certificate chain is in order\n");
     82   return true;
     83 }
     84 
     85 static size_t wrfu(void *ptr,  size_t  size,  size_t  nmemb,  void *stream)
     86 {
     87   (void)stream;
     88   (void)ptr;
     89   return size * nmemb;
     90 }
     91 
     92 static CURLcode test_lib3102(char *URL)
     93 {
     94   CURL *curl;
     95   CURLcode res = CURLE_OK;
     96 
     97   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
     98     curl_mfprintf(stderr, "curl_global_init() failed\n");
     99     return TEST_ERR_MAJOR_BAD;
    100   }
    101 
    102   curl = curl_easy_init();
    103   if(!curl) {
    104     curl_mfprintf(stderr, "curl_easy_init() failed\n");
    105     curl_global_cleanup();
    106     return TEST_ERR_MAJOR_BAD;
    107   }
    108 
    109   /* Set the HTTPS url to retrieve. */
    110   test_setopt(curl, CURLOPT_URL, URL);
    111 
    112   /* Capture certificate information */
    113   test_setopt(curl, CURLOPT_CERTINFO, 1L);
    114 
    115   /* Ignore output */
    116   test_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu);
    117 
    118   /* No peer verify */
    119   test_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    120   test_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
    121 
    122   /* Perform the request, res will get the return code */
    123   res = curl_easy_perform(curl);
    124   if(!res || res == CURLE_GOT_NOTHING) {
    125     struct curl_certinfo *cert_info = NULL;
    126     /* Get the certificate information */
    127     res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &cert_info);
    128     if(!res) {
    129       /* Check to see if the certificate chain is ordered correctly */
    130       if(!is_chain_in_order(cert_info))
    131         res = TEST_ERR_FAILURE;
    132     }
    133   }
    134 
    135 test_cleanup:
    136 
    137   /* always cleanup */
    138   curl_easy_cleanup(curl);
    139   curl_global_cleanup();
    140 
    141   return res;
    142 }