LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - pkcs7-output.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 124 144 86.1 %
Date: 2020-10-30 04:50:48 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2015 Red Hat, Inc.
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : #include "gnutls_int.h"
      24             : #include <common.h>
      25             : #include <x509.h>
      26             : #include <x509_int.h>
      27             : #include <num.h>
      28             : #include "errors.h"
      29             : #include <extras/randomart.h>
      30             : #include <pkcs7_int.h>
      31             : 
      32             : #define addf _gnutls_buffer_append_printf
      33             : #define adds _gnutls_buffer_append_str
      34             : 
      35          53 : static void print_dn(gnutls_buffer_st * str, const char *prefix,
      36             :                      const gnutls_datum_t * raw)
      37             : {
      38          53 :         gnutls_x509_dn_t dn = NULL;
      39          53 :         gnutls_datum_t output = { NULL, 0 };
      40          53 :         int ret;
      41             : 
      42          53 :         ret = gnutls_x509_dn_init(&dn);
      43          53 :         if (ret < 0) {
      44           0 :                 addf(str, "%s: [error]\n", prefix);
      45           0 :                 return;
      46             :         }
      47             : 
      48          53 :         ret = gnutls_x509_dn_import(dn, raw);
      49          53 :         if (ret < 0) {
      50           0 :                 addf(str, "%s: [error]\n", prefix);
      51           0 :                 goto cleanup;
      52             :         }
      53             : 
      54          53 :         ret = gnutls_x509_dn_get_str2(dn, &output, 0);
      55          53 :         if (ret < 0) {
      56           0 :                 addf(str, "%s: [error]\n", prefix);
      57           0 :                 goto cleanup;
      58             :         }
      59             : 
      60          53 :         addf(str, "%s: %s\n", prefix, output.data);
      61             : 
      62          53 :  cleanup:
      63          53 :         gnutls_x509_dn_deinit(dn);
      64          53 :         gnutls_free(output.data);
      65             : }
      66             : 
      67             : /* Do not encode ASN1 and type for now */
      68             : #define ENTRY(oid, name, type) {oid, sizeof(oid)-1, name, sizeof(name)-1, NULL, type}
      69             : #define ENTRY2(oid, name) {oid, sizeof(oid)-1, name, sizeof(name)-1, NULL, ASN1_ETYPE_INVALID}
      70             : 
      71             : static const struct oid_to_string pkcs7_attrs[] = {
      72             :         ENTRY ("1.2.840.113549.1.9.3", "contentType", ASN1_ETYPE_OBJECT_ID),
      73             :         ENTRY ("1.2.840.113549.1.9.4", "messageDigest", ASN1_ETYPE_OCTET_STRING),
      74             :         ENTRY ("1.2.840.113549.1.9.5", "signingTime", ASN1_ETYPE_INVALID),
      75             :         ENTRY2("1.2.840.113549.1.9.6", "countersignature"),
      76             :         ENTRY2("1.2.840.113549.1.9.15", "smimeCapabilities"),
      77             : 
      78             :         ENTRY2("1.2.840.113549.1.9.16.2.1", "aa-receiptRequest"),
      79             :         ENTRY2("1.2.840.113549.1.9.16.2.2", "aa-securityLabel"),
      80             :         ENTRY2("1.2.840.113549.1.9.16.2.3", "aa-mlExpandHistory"),
      81             :         ENTRY2("1.2.840.113549.1.9.16.2.4", "aa-contentHint"),
      82             :         ENTRY2("1.2.840.113549.1.9.16.2.9", "aa-equivalentLabels"),
      83             :         ENTRY2("1.2.840.113549.1.9.16.2.10", "aa-contentReference"),
      84             :         ENTRY2("1.2.840.113549.1.9.16.2.11", "aa-encrypKeyPref"),
      85             :         ENTRY2("1.2.840.113549.1.9.16.2.12", "aa-signingCertificate"),
      86             :         ENTRY2("1.2.840.113549.1.9.16.2.19", "aa-ets-otherSigCert"),
      87             :         ENTRY2("1.2.840.113549.1.9.16.2.47", "aa-signingCertificateV2"),
      88             : 
      89             :         {NULL, 0, NULL, 0, NULL, 0}
      90             : };
      91             : 
      92        3053 : static void print_raw(gnutls_buffer_st * str, const char *prefix,
      93             :                       const gnutls_datum_t * raw)
      94             : {
      95        3053 :         gnutls_datum_t result;
      96        3053 :         int ret;
      97             : 
      98        3053 :         if (raw->data == NULL || raw->size == 0)
      99        1508 :                 return;
     100             : 
     101        1545 :         ret = gnutls_hex_encode2(raw, &result);
     102        1545 :         if (ret < 0) {
     103           0 :                 addf(str, "%s: [error]\n", prefix);
     104           0 :                 return;
     105             :         }
     106             : 
     107        1545 :         addf(str, "%s: %s\n", prefix, result.data);
     108        1545 :         gnutls_free(result.data);
     109             : }
     110             : 
     111        1508 : static void print_pkcs7_info(gnutls_pkcs7_signature_info_st * info,
     112             :                              gnutls_buffer_st * str,
     113             :                              gnutls_certificate_print_formats_t format)
     114             : {
     115        1508 :         unsigned i;
     116        1508 :         char *oid;
     117        1508 :         gnutls_datum_t data;
     118        1508 :         char prefix[128];
     119        1508 :         char s[42];
     120        1508 :         size_t max;
     121        1508 :         int ret;
     122        1508 :         const struct oid_to_string * entry;
     123             : 
     124        1508 :         if (info->issuer_dn.size > 0)
     125          53 :                 print_dn(str, "\tSigner's issuer DN", &info->issuer_dn);
     126        1508 :         print_raw(str, "\tSigner's serial", &info->signer_serial);
     127        1508 :         print_raw(str, "\tSigner's issuer key ID", &info->issuer_keyid);
     128        1508 :         if (info->signing_time != -1) {
     129          27 :                 struct tm t;
     130          27 :                 if (gmtime_r(&info->signing_time, &t) == NULL) {
     131           0 :                         addf(str, "error: gmtime_r (%ld)\n",
     132           0 :                              (unsigned long)info->signing_time);
     133             :                 } else {
     134          27 :                         max = sizeof(s);
     135          27 :                         if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t) ==
     136             :                             0) {
     137           0 :                                 addf(str, "error: strftime (%ld)\n",
     138           0 :                                      (unsigned long)info->signing_time);
     139             :                         } else {
     140          27 :                                 addf(str, "\tSigning time: %s\n", s);
     141             :                         }
     142             :                 }
     143             :         }
     144             : 
     145        1508 :         addf(str, "\tSignature Algorithm: %s\n",
     146             :              gnutls_sign_get_name(info->algo));
     147             : 
     148        1508 :         if (format == GNUTLS_CRT_PRINT_FULL) {
     149        1464 :                 if (info->signed_attrs) {
     150          36 :                         for (i = 0;; i++) {
     151          82 :                                 ret =
     152          46 :                                     gnutls_pkcs7_get_attr(info->signed_attrs, i,
     153             :                                                           &oid, &data, 0);
     154          46 :                                 if (ret < 0)
     155             :                                         break;
     156          36 :                                 if (i == 0)
     157          10 :                                         addf(str, "\tSigned Attributes:\n");
     158             : 
     159          36 :                                 entry = _gnutls_oid_get_entry(pkcs7_attrs, oid);
     160          36 :                                 snprintf(prefix, sizeof(prefix), "\t\t%s",
     161          32 :                                                 (entry && entry->name_desc) ? entry->name_desc : oid);
     162          36 :                                 print_raw(str, prefix, &data);
     163          36 :                                 gnutls_free(data.data);
     164             :                         }
     165             :                 }
     166        1464 :                 if (info->unsigned_attrs) {
     167           1 :                         for (i = 0;; i++) {
     168           3 :                                 ret =
     169           2 :                                     gnutls_pkcs7_get_attr(info->unsigned_attrs,
     170             :                                                           i, &oid, &data, 0);
     171           2 :                                 if (ret < 0)
     172             :                                         break;
     173           1 :                                 if (i == 0)
     174           1 :                                         addf(str, "\tUnsigned Attributes:\n");
     175             : 
     176           1 :                                 entry = _gnutls_oid_get_entry(pkcs7_attrs, oid);
     177           1 :                                 snprintf(prefix, sizeof(prefix), "\t\t%s",
     178           1 :                                                 (entry && entry->name_desc) ? entry->name_desc : oid);
     179           1 :                                 print_raw(str, prefix, &data);
     180           1 :                                 gnutls_free(data.data);
     181             :                         }
     182             :                 }
     183             :         }
     184        1508 :         adds(str, "\n");
     185        1508 : }
     186             : 
     187             : /**
     188             :  * gnutls_pkcs7_print_signature_info:
     189             :  * @info: The PKCS7 signature info struct to be printed
     190             :  * @format: Indicate the format to use
     191             :  * @out: Newly allocated datum with null terminated string.
     192             :  *
     193             :  * This function will pretty print a PKCS #7 signature info structure, suitable
     194             :  * for display to a human.
     195             :  *
     196             :  * Currently the supported formats are %GNUTLS_CRT_PRINT_FULL and
     197             :  * %GNUTLS_CRT_PRINT_COMPACT.
     198             :  *
     199             :  * The output @out needs to be deallocated using gnutls_free().
     200             :  *
     201             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     202             :  *   negative error value.
     203             :  *
     204             :  * Since: 3.6.14
     205             :  **/
     206          44 : int gnutls_pkcs7_print_signature_info(gnutls_pkcs7_signature_info_st * info,
     207             :                                       gnutls_certificate_print_formats_t format,
     208             :                                       gnutls_datum_t * out)
     209             : {
     210          44 :         gnutls_buffer_st str;
     211             : 
     212          44 :         _gnutls_buffer_init(&str);
     213          44 :         print_pkcs7_info(info, &str, format);
     214             : 
     215          44 :         return _gnutls_buffer_to_datum(&str, out, 1);
     216             : }
     217             : 
     218             : /**
     219             :  * gnutls_pkcs7_crt_print:
     220             :  * @pkcs7: The PKCS7 struct to be printed
     221             :  * @format: Indicate the format to use
     222             :  * @out: Newly allocated datum with null terminated string.
     223             :  *
     224             :  * This function will pretty print a signed PKCS #7 structure, suitable for
     225             :  * display to a human.
     226             :  *
     227             :  * Currently the supported formats are %GNUTLS_CRT_PRINT_FULL and
     228             :  * %GNUTLS_CRT_PRINT_COMPACT.
     229             :  *
     230             :  * The output @out needs to be deallocated using gnutls_free().
     231             :  *
     232             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     233             :  *   negative error value.
     234             :  **/
     235         137 : int gnutls_pkcs7_print(gnutls_pkcs7_t pkcs7,
     236             :                        gnutls_certificate_print_formats_t format,
     237             :                        gnutls_datum_t * out)
     238             : {
     239         137 :         int count, ret, i;
     240         137 :         gnutls_pkcs7_signature_info_st info;
     241         137 :         gnutls_buffer_st str;
     242         137 :         const char *oid;
     243             : 
     244         137 :         _gnutls_buffer_init(&str);
     245             : 
     246             :         /* For backwards compatibility with structures using the default OID,
     247             :          * we don't print the eContent Type explicitly */
     248         137 :         oid = gnutls_pkcs7_get_embedded_data_oid(pkcs7);
     249         137 :         if (oid) {
     250         137 :                 if (strcmp(oid, DATA_OID) != 0
     251         123 :                     && strcmp(oid, DIGESTED_DATA_OID) != 0) {
     252         122 :                         addf(&str, "eContent Type: %s\n", oid);
     253             :                 }
     254             :         }
     255             : 
     256        1464 :         for (i = 0;; i++) {
     257        1601 :                 if (i == 0)
     258         137 :                         addf(&str, "Signers:\n");
     259             : 
     260        1601 :                 ret = gnutls_pkcs7_get_signature_info(pkcs7, i, &info);
     261        1601 :                 if (ret < 0)
     262             :                         break;
     263             : 
     264        1464 :                 print_pkcs7_info(&info, &str, format);
     265        1464 :                 gnutls_pkcs7_signature_info_deinit(&info);
     266             :         }
     267             : 
     268         137 :         if (format == GNUTLS_CRT_PRINT_FULL) {
     269         137 :                 gnutls_datum_t data, b64;
     270             : 
     271         137 :                 count = gnutls_pkcs7_get_crt_count(pkcs7);
     272             : 
     273         137 :                 if (count > 0) {
     274          46 :                         addf(&str, "Number of certificates: %u\n\n",
     275             :                              count);
     276             : 
     277       11396 :                         for (i = 0; i < count; i++) {
     278       11304 :                                 ret =
     279       11304 :                                     gnutls_pkcs7_get_crt_raw2(pkcs7, i, &data);
     280       11304 :                                 if (ret < 0) {
     281           0 :                                         addf(&str,
     282             :                                              "Error: cannot print certificate %d\n",
     283             :                                              i);
     284           0 :                                         continue;
     285             :                                 }
     286             : 
     287       11304 :                                 ret =
     288       11304 :                                     gnutls_pem_base64_encode_alloc
     289             :                                     ("CERTIFICATE", &data, &b64);
     290       11304 :                                 if (ret < 0) {
     291           0 :                                         gnutls_free(data.data);
     292           0 :                                         continue;
     293             :                                 }
     294             : 
     295       11304 :                                 adds(&str, (char*)b64.data);
     296       11304 :                                 adds(&str, "\n");
     297       11304 :                                 gnutls_free(b64.data);
     298       11304 :                                 gnutls_free(data.data);
     299             :                         }
     300             :                 }
     301             : 
     302         137 :                 count = gnutls_pkcs7_get_crl_count(pkcs7);
     303         137 :                 if (count > 0) {
     304          16 :                         addf(&str, "Number of CRLs: %u\n\n", count);
     305             : 
     306         613 :                         for (i = 0; i < count; i++) {
     307         581 :                                 ret =
     308         581 :                                     gnutls_pkcs7_get_crl_raw2(pkcs7, i, &data);
     309         581 :                                 if (ret < 0) {
     310           0 :                                         addf(&str,
     311             :                                              "Error: cannot print certificate %d\n",
     312             :                                              i);
     313           0 :                                         continue;
     314             :                                 }
     315             : 
     316         581 :                                 ret =
     317         581 :                                     gnutls_pem_base64_encode_alloc("X509 CRL",
     318             :                                                                    &data, &b64);
     319         581 :                                 if (ret < 0) {
     320           0 :                                         gnutls_free(data.data);
     321           0 :                                         continue;
     322             :                                 }
     323             : 
     324         581 :                                 adds(&str, (char*)b64.data);
     325         581 :                                 adds(&str, "\n");
     326         581 :                                 gnutls_free(b64.data);
     327         581 :                                 gnutls_free(data.data);
     328             :                         }
     329             :                 }
     330             :         }
     331             : 
     332         137 :         return _gnutls_buffer_to_datum(&str, out, 1);
     333             : }

Generated by: LCOV version 1.14