LCOV - code coverage report
Current view: top level - glib/gio - gtlscertificate.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 240 284 84.5 %
Date: 2024-04-23 05:16:05 Functions: 28 30 93.3 %
Branches: 97 143 67.8 %

           Branch data     Line data    Source code
       1                 :            : /* GIO - GLib Input, Output and Certificateing Library
       2                 :            :  *
       3                 :            :  * Copyright (C) 2010 Red Hat, Inc.
       4                 :            :  *
       5                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       6                 :            :  *
       7                 :            :  * This library is free software; you can redistribute it and/or
       8                 :            :  * modify it under the terms of the GNU Lesser General Public
       9                 :            :  * License as published by the Free Software Foundation; either
      10                 :            :  * version 2.1 of the License, or (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This library is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :            :  * Lesser General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU Lesser General
      18                 :            :  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19                 :            :  */
      20                 :            : 
      21                 :            : #include "config.h"
      22                 :            : 
      23                 :            : #include "gtlscertificate.h"
      24                 :            : 
      25                 :            : #include <string.h>
      26                 :            : #include "ginitable.h"
      27                 :            : #include "gtlsbackend.h"
      28                 :            : #include "gtlsconnection.h"
      29                 :            : #include "glibintl.h"
      30                 :            : 
      31                 :            : /**
      32                 :            :  * GTlsCertificate:
      33                 :            :  *
      34                 :            :  * A certificate used for TLS authentication and encryption.
      35                 :            :  * This can represent either a certificate only (eg, the certificate
      36                 :            :  * received by a client from a server), or the combination of
      37                 :            :  * a certificate and a private key (which is needed when acting as a
      38                 :            :  * [iface@Gio.TlsServerConnection]).
      39                 :            :  *
      40                 :            :  * Since: 2.28
      41                 :            :  */
      42                 :            : 
      43                 :            : struct _GTlsCertificatePrivate {
      44                 :            :   gboolean pkcs12_properties_not_overridden;
      45                 :            : };
      46                 :            : 
      47   [ +  +  +  -  :        117 : G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GTlsCertificate, g_tls_certificate, G_TYPE_OBJECT)
                   +  + ]
      48                 :            : 
      49                 :            : enum
      50                 :            : {
      51                 :            :   PROP_0,
      52                 :            : 
      53                 :            :   PROP_CERTIFICATE,
      54                 :            :   PROP_CERTIFICATE_PEM,
      55                 :            :   PROP_PRIVATE_KEY,
      56                 :            :   PROP_PRIVATE_KEY_PEM,
      57                 :            :   PROP_ISSUER,
      58                 :            :   PROP_PKCS11_URI,
      59                 :            :   PROP_PRIVATE_KEY_PKCS11_URI,
      60                 :            :   PROP_NOT_VALID_BEFORE,
      61                 :            :   PROP_NOT_VALID_AFTER,
      62                 :            :   PROP_SUBJECT_NAME,
      63                 :            :   PROP_ISSUER_NAME,
      64                 :            :   PROP_DNS_NAMES,
      65                 :            :   PROP_IP_ADDRESSES,
      66                 :            :   PROP_PKCS12_DATA,
      67                 :            :   PROP_PASSWORD,
      68                 :            : };
      69                 :            : 
      70                 :            : static void
      71                 :         26 : g_tls_certificate_init (GTlsCertificate *cert)
      72                 :            : {
      73                 :         26 : }
      74                 :            : 
      75                 :            : static void
      76                 :          0 : g_tls_certificate_get_property (GObject    *object,
      77                 :            :                                 guint       prop_id,
      78                 :            :                                 GValue     *value,
      79                 :            :                                 GParamSpec *pspec)
      80                 :            : {
      81         [ #  # ]:          0 :   switch (prop_id)
      82                 :            :     {
      83                 :            :     /* Subclasses must override these properties but this allows older backends to not fatally error */
      84                 :          0 :     case PROP_PRIVATE_KEY:
      85                 :            :     case PROP_PRIVATE_KEY_PEM:
      86                 :            :     case PROP_PKCS11_URI:
      87                 :            :     case PROP_PRIVATE_KEY_PKCS11_URI:
      88                 :          0 :       g_value_set_static_string (value, NULL);
      89                 :          0 :       break;
      90                 :          0 :     default:
      91                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      92                 :            :     }
      93                 :          0 : }
      94                 :            : 
      95                 :            : static void
      96                 :         52 : g_tls_certificate_set_property (GObject      *object,
      97                 :            :                                 guint         prop_id,
      98                 :            :                                 const GValue *value,
      99                 :            :                                 GParamSpec   *pspec)
     100                 :            : {
     101                 :         52 :   GTlsCertificate *cert = (GTlsCertificate*)object;
     102                 :         52 :   GTlsCertificatePrivate *priv = g_tls_certificate_get_instance_private (cert);
     103                 :            : 
     104      [ -  +  - ]:         52 :   switch (prop_id)
     105                 :            :     {
     106                 :          0 :     case PROP_PKCS11_URI:
     107                 :            :     case PROP_PRIVATE_KEY_PKCS11_URI:
     108                 :            :       /* Subclasses must override these properties but this allows older backends to not fatally error. */
     109                 :          0 :       break;
     110                 :         52 :     case PROP_PKCS12_DATA:
     111                 :            :     case PROP_PASSWORD:
     112                 :            :       /* We don't error on setting these properties however we track that they were not overridden. */
     113                 :         52 :       priv->pkcs12_properties_not_overridden = TRUE;
     114                 :         52 :       break;
     115                 :          0 :     default:
     116                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     117                 :            :     }
     118                 :         52 : }
     119                 :            : 
     120                 :            : static void
     121                 :          2 : g_tls_certificate_class_init (GTlsCertificateClass *class)
     122                 :            : {
     123                 :          2 :   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
     124                 :            : 
     125                 :          2 :   gobject_class->set_property = g_tls_certificate_set_property;
     126                 :          2 :   gobject_class->get_property = g_tls_certificate_get_property;
     127                 :            : 
     128                 :            :   /**
     129                 :            :    * GTlsCertificate:pkcs12-data: (nullable)
     130                 :            :    *
     131                 :            :    * The PKCS #12 formatted data used to construct the object.
     132                 :            :    *
     133                 :            :    * See also: g_tls_certificate_new_from_pkcs12()
     134                 :            :    *
     135                 :            :    * Since: 2.72
     136                 :            :    */
     137                 :          2 :   g_object_class_install_property (gobject_class, PROP_PKCS12_DATA,
     138                 :            :                                    g_param_spec_boxed ("pkcs12-data", NULL, NULL,
     139                 :            :                                                        G_TYPE_BYTE_ARRAY,
     140                 :            :                                                        G_PARAM_WRITABLE |
     141                 :            :                                                        G_PARAM_CONSTRUCT_ONLY |
     142                 :            :                                                        G_PARAM_STATIC_STRINGS));
     143                 :            : 
     144                 :            :   /**
     145                 :            :    * GTlsCertificate:password: (nullable)
     146                 :            :    *
     147                 :            :    * An optional password used when constructed with GTlsCertificate:pkcs12-data.
     148                 :            :    *
     149                 :            :    * Since: 2.72
     150                 :            :    */
     151                 :          2 :   g_object_class_install_property (gobject_class, PROP_PASSWORD,
     152                 :            :                                    g_param_spec_string ("password", NULL, NULL,
     153                 :            :                                                         NULL,
     154                 :            :                                                         G_PARAM_WRITABLE |
     155                 :            :                                                           G_PARAM_CONSTRUCT_ONLY |
     156                 :            :                                                           G_PARAM_STATIC_STRINGS));
     157                 :            :   /**
     158                 :            :    * GTlsCertificate:certificate:
     159                 :            :    *
     160                 :            :    * The DER (binary) encoded representation of the certificate.
     161                 :            :    * This property and the #GTlsCertificate:certificate-pem property
     162                 :            :    * represent the same data, just in different forms.
     163                 :            :    *
     164                 :            :    * Since: 2.28
     165                 :            :    */
     166                 :          2 :   g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
     167                 :            :                                    g_param_spec_boxed ("certificate", NULL, NULL,
     168                 :            :                                                        G_TYPE_BYTE_ARRAY,
     169                 :            :                                                        G_PARAM_READWRITE |
     170                 :            :                                                        G_PARAM_CONSTRUCT_ONLY |
     171                 :            :                                                        G_PARAM_STATIC_STRINGS));
     172                 :            :   /**
     173                 :            :    * GTlsCertificate:certificate-pem:
     174                 :            :    *
     175                 :            :    * The PEM (ASCII) encoded representation of the certificate.
     176                 :            :    * This property and the #GTlsCertificate:certificate
     177                 :            :    * property represent the same data, just in different forms.
     178                 :            :    *
     179                 :            :    * Since: 2.28
     180                 :            :    */
     181                 :          2 :   g_object_class_install_property (gobject_class, PROP_CERTIFICATE_PEM,
     182                 :            :                                    g_param_spec_string ("certificate-pem", NULL, NULL,
     183                 :            :                                                         NULL,
     184                 :            :                                                         G_PARAM_READWRITE |
     185                 :            :                                                         G_PARAM_CONSTRUCT_ONLY |
     186                 :            :                                                         G_PARAM_STATIC_STRINGS));
     187                 :            :   /**
     188                 :            :    * GTlsCertificate:private-key: (nullable)
     189                 :            :    *
     190                 :            :    * The DER (binary) encoded representation of the certificate's
     191                 :            :    * private key, in either [PKCS \#1 format](https://datatracker.ietf.org/doc/html/rfc8017)
     192                 :            :    * or unencrypted [PKCS \#8 format.](https://datatracker.ietf.org/doc/html/rfc5208)
     193                 :            :    * PKCS \#8 format is supported since 2.32; earlier releases only
     194                 :            :    * support PKCS \#1. You can use the `openssl rsa` tool to convert
     195                 :            :    * PKCS \#8 keys to PKCS \#1.
     196                 :            :    *
     197                 :            :    * This property (or the #GTlsCertificate:private-key-pem property)
     198                 :            :    * can be set when constructing a key (for example, from a file).
     199                 :            :    * Since GLib 2.70, it is now also readable; however, be aware that if
     200                 :            :    * the private key is backed by a PKCS \#11 URI – for example, if it
     201                 :            :    * is stored on a smartcard – then this property will be %NULL. If so,
     202                 :            :    * the private key must be referenced via its PKCS \#11 URI,
     203                 :            :    * #GTlsCertificate:private-key-pkcs11-uri. You must check both
     204                 :            :    * properties to see if the certificate really has a private key.
     205                 :            :    * When this property is read, the output format will be unencrypted
     206                 :            :    * PKCS \#8.
     207                 :            :    *
     208                 :            :    * Since: 2.28
     209                 :            :    */
     210                 :          2 :   g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY,
     211                 :            :                                    g_param_spec_boxed ("private-key", NULL, NULL,
     212                 :            :                                                        G_TYPE_BYTE_ARRAY,
     213                 :            :                                                        G_PARAM_READWRITE |
     214                 :            :                                                        G_PARAM_CONSTRUCT_ONLY |
     215                 :            :                                                        G_PARAM_STATIC_STRINGS));
     216                 :            :   /**
     217                 :            :    * GTlsCertificate:private-key-pem: (nullable)
     218                 :            :    *
     219                 :            :    * The PEM (ASCII) encoded representation of the certificate's
     220                 :            :    * private key in either [PKCS \#1 format](https://datatracker.ietf.org/doc/html/rfc8017)
     221                 :            :    * ("`BEGIN RSA PRIVATE KEY`") or unencrypted
     222                 :            :    * [PKCS \#8 format](https://datatracker.ietf.org/doc/html/rfc5208)
     223                 :            :    * ("`BEGIN PRIVATE KEY`"). PKCS \#8 format is supported since 2.32;
     224                 :            :    * earlier releases only support PKCS \#1. You can use the `openssl rsa`
     225                 :            :    * tool to convert PKCS \#8 keys to PKCS \#1.
     226                 :            :    *
     227                 :            :    * This property (or the #GTlsCertificate:private-key property)
     228                 :            :    * can be set when constructing a key (for example, from a file).
     229                 :            :    * Since GLib 2.70, it is now also readable; however, be aware that if
     230                 :            :    * the private key is backed by a PKCS \#11 URI - for example, if it
     231                 :            :    * is stored on a smartcard - then this property will be %NULL. If so,
     232                 :            :    * the private key must be referenced via its PKCS \#11 URI,
     233                 :            :    * #GTlsCertificate:private-key-pkcs11-uri. You must check both
     234                 :            :    * properties to see if the certificate really has a private key.
     235                 :            :    * When this property is read, the output format will be unencrypted
     236                 :            :    * PKCS \#8.
     237                 :            :    *
     238                 :            :    * Since: 2.28
     239                 :            :    */
     240                 :          2 :   g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PEM,
     241                 :            :                                    g_param_spec_string ("private-key-pem", NULL, NULL,
     242                 :            :                                                         NULL,
     243                 :            :                                                         G_PARAM_READWRITE |
     244                 :            :                                                         G_PARAM_CONSTRUCT_ONLY |
     245                 :            :                                                         G_PARAM_STATIC_STRINGS));
     246                 :            :   /**
     247                 :            :    * GTlsCertificate:issuer:
     248                 :            :    *
     249                 :            :    * A #GTlsCertificate representing the entity that issued this
     250                 :            :    * certificate. If %NULL, this means that the certificate is either
     251                 :            :    * self-signed, or else the certificate of the issuer is not
     252                 :            :    * available.
     253                 :            :    *
     254                 :            :    * Beware the issuer certificate may not be the same as the
     255                 :            :    * certificate that would actually be used to construct a valid
     256                 :            :    * certification path during certificate verification.
     257                 :            :    * [RFC 4158](https://datatracker.ietf.org/doc/html/rfc4158) explains
     258                 :            :    * why an issuer certificate cannot be naively assumed to be part of the
     259                 :            :    * the certification path (though GLib's TLS backends may not follow the
     260                 :            :    * path building strategies outlined in this RFC). Due to the complexity
     261                 :            :    * of certification path building, GLib does not provide any way to know
     262                 :            :    * which certification path will actually be used. Accordingly, this
     263                 :            :    * property cannot be used to make security-related decisions. Only
     264                 :            :    * GLib itself should make security decisions about TLS certificates.
     265                 :            :    *
     266                 :            :    * Since: 2.28
     267                 :            :    */
     268                 :          2 :   g_object_class_install_property (gobject_class, PROP_ISSUER,
     269                 :            :                                    g_param_spec_object ("issuer", NULL, NULL,
     270                 :            :                                                         G_TYPE_TLS_CERTIFICATE,
     271                 :            :                                                         G_PARAM_READWRITE |
     272                 :            :                                                         G_PARAM_CONSTRUCT_ONLY |
     273                 :            :                                                         G_PARAM_STATIC_STRINGS));
     274                 :            : 
     275                 :            :   /**
     276                 :            :    * GTlsCertificate:pkcs11-uri: (nullable)
     277                 :            :    *
     278                 :            :    * A URI referencing the [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html)
     279                 :            :    * objects containing an X.509 certificate and optionally a private key.
     280                 :            :    *
     281                 :            :    * If %NULL, the certificate is either not backed by PKCS \#11 or the
     282                 :            :    * #GTlsBackend does not support PKCS \#11.
     283                 :            :    *
     284                 :            :    * Since: 2.68
     285                 :            :    */
     286                 :          2 :   g_object_class_install_property (gobject_class, PROP_PKCS11_URI,
     287                 :            :                                    g_param_spec_string ("pkcs11-uri", NULL, NULL,
     288                 :            :                                                         NULL,
     289                 :            :                                                         G_PARAM_READWRITE |
     290                 :            :                                                           G_PARAM_CONSTRUCT_ONLY |
     291                 :            :                                                           G_PARAM_STATIC_STRINGS));
     292                 :            : 
     293                 :            :   /**
     294                 :            :    * GTlsCertificate:private-key-pkcs11-uri: (nullable)
     295                 :            :    *
     296                 :            :    * A URI referencing a [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html)
     297                 :            :    * object containing a private key.
     298                 :            :    *
     299                 :            :    * Since: 2.68
     300                 :            :    */
     301                 :          2 :   g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PKCS11_URI,
     302                 :            :                                    g_param_spec_string ("private-key-pkcs11-uri", NULL, NULL,
     303                 :            :                                                         NULL,
     304                 :            :                                                         G_PARAM_READWRITE |
     305                 :            :                                                           G_PARAM_CONSTRUCT_ONLY |
     306                 :            :                                                           G_PARAM_STATIC_STRINGS));
     307                 :            : 
     308                 :            :   /**
     309                 :            :    * GTlsCertificate:not-valid-before: (nullable)
     310                 :            :    *
     311                 :            :    * The time at which this cert is considered to be valid,
     312                 :            :    * %NULL if unavailable.
     313                 :            :    *
     314                 :            :    * Since: 2.70
     315                 :            :    */
     316                 :          2 :   g_object_class_install_property (gobject_class, PROP_NOT_VALID_BEFORE,
     317                 :            :                                    g_param_spec_boxed ("not-valid-before", NULL, NULL,
     318                 :            :                                                        G_TYPE_DATE_TIME,
     319                 :            :                                                        G_PARAM_READABLE |
     320                 :            :                                                          G_PARAM_STATIC_STRINGS));
     321                 :            : 
     322                 :            :   /**
     323                 :            :    * GTlsCertificate:not-valid-after: (nullable)
     324                 :            :    *
     325                 :            :    * The time at which this cert is no longer valid,
     326                 :            :    * %NULL if unavailable.
     327                 :            :    *
     328                 :            :    * Since: 2.70
     329                 :            :    */
     330                 :          2 :   g_object_class_install_property (gobject_class, PROP_NOT_VALID_AFTER,
     331                 :            :                                    g_param_spec_boxed ("not-valid-after", NULL, NULL,
     332                 :            :                                                        G_TYPE_DATE_TIME,
     333                 :            :                                                        G_PARAM_READABLE |
     334                 :            :                                                          G_PARAM_STATIC_STRINGS));
     335                 :            : 
     336                 :            :   /**
     337                 :            :    * GTlsCertificate:subject-name: (nullable)
     338                 :            :    *
     339                 :            :    * The subject from the cert,
     340                 :            :    * %NULL if unavailable.
     341                 :            :    *
     342                 :            :    * Since: 2.70
     343                 :            :    */
     344                 :          2 :   g_object_class_install_property (gobject_class, PROP_SUBJECT_NAME,
     345                 :            :                                    g_param_spec_string ("subject-name", NULL, NULL,
     346                 :            :                                                         NULL,
     347                 :            :                                                         G_PARAM_READABLE |
     348                 :            :                                                           G_PARAM_STATIC_STRINGS));
     349                 :            :   /**
     350                 :            :    * GTlsCertificate:issuer-name: (nullable)
     351                 :            :    *
     352                 :            :    * The issuer from the certificate,
     353                 :            :    * %NULL if unavailable.
     354                 :            :    *
     355                 :            :    * Since: 2.70
     356                 :            :    */
     357                 :          2 :   g_object_class_install_property (gobject_class, PROP_ISSUER_NAME,
     358                 :            :                                    g_param_spec_string ("issuer-name", NULL, NULL,
     359                 :            :                                                         NULL,
     360                 :            :                                                         G_PARAM_READABLE |
     361                 :            :                                                           G_PARAM_STATIC_STRINGS));
     362                 :            : 
     363                 :            :   /**
     364                 :            :    * GTlsCertificate:dns-names: (nullable) (element-type GBytes) (transfer container)
     365                 :            :    *
     366                 :            :    * The DNS names from the certificate's Subject Alternative Names (SANs),
     367                 :            :    * %NULL if unavailable.
     368                 :            :    *
     369                 :            :    * Since: 2.70
     370                 :            :    */
     371                 :          2 :   g_object_class_install_property (gobject_class, PROP_DNS_NAMES,
     372                 :            :                                    g_param_spec_boxed ("dns-names", NULL, NULL,
     373                 :            :                                                        G_TYPE_PTR_ARRAY,
     374                 :            :                                                        G_PARAM_READABLE |
     375                 :            :                                                          G_PARAM_STATIC_STRINGS));
     376                 :            : 
     377                 :            :   /**
     378                 :            :    * GTlsCertificate:ip-addresses: (nullable) (element-type GInetAddress) (transfer container)
     379                 :            :    *
     380                 :            :    * The IP addresses from the certificate's Subject Alternative Names (SANs),
     381                 :            :    * %NULL if unavailable.
     382                 :            :    *
     383                 :            :    * Since: 2.70
     384                 :            :    */
     385                 :          2 :   g_object_class_install_property (gobject_class, PROP_IP_ADDRESSES,
     386                 :            :                                    g_param_spec_boxed ("ip-addresses", NULL, NULL,
     387                 :            :                                                        G_TYPE_PTR_ARRAY,
     388                 :            :                                                        G_PARAM_READABLE |
     389                 :            :                                                          G_PARAM_STATIC_STRINGS));
     390                 :          2 : }
     391                 :            : 
     392                 :            : static GTlsCertificate *
     393                 :         15 : g_tls_certificate_new_internal (const gchar      *certificate_pem,
     394                 :            :                                 const gchar      *private_key_pem,
     395                 :            :                                 GTlsCertificate  *issuer,
     396                 :            :                                 GError          **error)
     397                 :            : {
     398                 :            :   GObject *cert;
     399                 :            :   GTlsBackend *backend;
     400                 :            : 
     401                 :         15 :   backend = g_tls_backend_get_default ();
     402                 :            : 
     403                 :         15 :   cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
     404                 :            :                          NULL, error,
     405                 :            :                          "certificate-pem", certificate_pem,
     406                 :            :                          "private-key-pem", private_key_pem,
     407                 :            :                          "issuer", issuer,
     408                 :            :                          NULL);
     409                 :            : 
     410                 :         15 :   return G_TLS_CERTIFICATE (cert);
     411                 :            : }
     412                 :            : 
     413                 :            : #define PEM_CERTIFICATE_HEADER     "-----BEGIN CERTIFICATE-----"
     414                 :            : #define PEM_CERTIFICATE_FOOTER     "-----END CERTIFICATE-----"
     415                 :            : #define PEM_PRIVKEY_HEADER_BEGIN   "-----BEGIN "
     416                 :            : #define PEM_PRIVKEY_HEADER_END     "PRIVATE KEY-----"
     417                 :            : #define PEM_PRIVKEY_FOOTER_BEGIN   "-----END "
     418                 :            : #define PEM_PRIVKEY_FOOTER_END     "PRIVATE KEY-----"
     419                 :            : #define PEM_PKCS8_ENCRYPTED_HEADER "-----BEGIN ENCRYPTED PRIVATE KEY-----"
     420                 :            : 
     421                 :            : static gchar *
     422                 :         18 : parse_private_key (const gchar *data,
     423                 :            :                    gsize data_len,
     424                 :            :                    gboolean required,
     425                 :            :                    GError **error)
     426                 :            : {
     427                 :         18 :   const gchar *header_start = NULL, *header_end, *footer_start = NULL, *footer_end;
     428                 :         18 :   const gchar *data_end = data + data_len;
     429                 :            : 
     430                 :         18 :   header_end = g_strstr_len (data, data_len, PEM_PRIVKEY_HEADER_END);
     431         [ +  + ]:         18 :   if (header_end)
     432                 :         14 :     header_start = g_strrstr_len (data, header_end - data, PEM_PRIVKEY_HEADER_BEGIN);
     433                 :            : 
     434         [ +  + ]:         18 :   if (!header_start)
     435                 :            :     {
     436         [ +  + ]:          5 :       if (required)
     437                 :          2 :         g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
     438                 :            :                              _("No PEM-encoded private key found"));
     439                 :            : 
     440                 :          5 :       return NULL;
     441                 :            :     }
     442                 :            : 
     443                 :         13 :   header_end += strlen (PEM_PRIVKEY_HEADER_END);
     444                 :            : 
     445         [ +  + ]:         13 :   if (strncmp (header_start, PEM_PKCS8_ENCRYPTED_HEADER, header_end - header_start) == 0)
     446                 :            :     {
     447                 :          1 :       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
     448                 :            :                            _("Cannot decrypt PEM-encoded private key"));
     449                 :          1 :       return NULL;
     450                 :            :     }
     451                 :            : 
     452                 :         12 :   footer_end = g_strstr_len (header_end, data_len - (header_end - data), PEM_PRIVKEY_FOOTER_END);
     453         [ +  + ]:         12 :   if (footer_end)
     454                 :         10 :     footer_start = g_strrstr_len (header_end, footer_end - header_end, PEM_PRIVKEY_FOOTER_BEGIN);
     455                 :            : 
     456         [ +  + ]:         12 :   if (!footer_start)
     457                 :            :     {
     458                 :          2 :       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
     459                 :            :                            _("Could not parse PEM-encoded private key"));
     460                 :          2 :       return NULL;
     461                 :            :     }
     462                 :            : 
     463                 :         10 :   footer_end += strlen (PEM_PRIVKEY_FOOTER_END);
     464                 :            : 
     465   [ +  +  +  +  :         21 :   while ((footer_end < data_end) && (*footer_end == '\r' || *footer_end == '\n'))
                   +  + ]
     466                 :         11 :     footer_end++;
     467                 :            : 
     468                 :         10 :   return g_strndup (header_start, footer_end - header_start);
     469                 :            : }
     470                 :            : 
     471                 :            : 
     472                 :            : static gchar *
     473                 :         21 : parse_next_pem_certificate (const gchar **data,
     474                 :            :                             const gchar  *data_end,
     475                 :            :                             gboolean      required,
     476                 :            :                             GError      **error)
     477                 :            : {
     478                 :            :   const gchar *start, *end;
     479                 :            : 
     480                 :         21 :   start = g_strstr_len (*data, data_end - *data, PEM_CERTIFICATE_HEADER);
     481         [ +  + ]:         21 :   if (!start)
     482                 :            :     {
     483         [ +  + ]:          6 :       if (required)
     484                 :            :         {
     485                 :          3 :           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
     486                 :            :                                _("No PEM-encoded certificate found"));
     487                 :            :         }
     488                 :          6 :       return NULL;
     489                 :            :     }
     490                 :            : 
     491                 :         15 :   end = g_strstr_len (start, data_end - start, PEM_CERTIFICATE_FOOTER);
     492         [ -  + ]:         15 :   if (!end)
     493                 :            :     {
     494                 :          0 :       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
     495                 :            :                            _("Could not parse PEM-encoded certificate"));
     496                 :          0 :       return NULL;
     497                 :            :     }
     498                 :         15 :   end += strlen (PEM_CERTIFICATE_FOOTER);
     499   [ +  +  +  +  :         31 :   while ((end < data_end) && (*end == '\r' || *end == '\n'))
                   +  + ]
     500                 :         16 :     end++;
     501                 :            : 
     502                 :         15 :   *data = end;
     503                 :            : 
     504                 :         15 :   return g_strndup (start, end - start);
     505                 :            : }
     506                 :            : 
     507                 :            : static GSList *
     508                 :         13 : parse_and_create_certificate_list (const gchar  *data,
     509                 :            :                                    gsize         data_len,
     510                 :            :                                    GError      **error)
     511                 :            : {
     512                 :         13 :   GSList *first_pem_list = NULL, *pem_list = NULL;
     513                 :            :   gchar *first_pem;
     514                 :            :   const gchar *p, *end;
     515                 :            : 
     516                 :         13 :   p = data;
     517                 :         13 :   end = p + data_len;
     518                 :            : 
     519                 :            :   /* Make sure we can load, at least, one certificate. */
     520                 :         13 :   first_pem = parse_next_pem_certificate (&p, end, TRUE, error);
     521         [ +  + ]:         13 :   if (!first_pem)
     522                 :          3 :     return NULL;
     523                 :            : 
     524                 :            :   /* Create a list with a single element. If we load more certificates
     525                 :            :    * below, we will concatenate the two lists at the end. */
     526                 :         10 :   first_pem_list = g_slist_prepend (first_pem_list, first_pem);
     527                 :            : 
     528                 :            :   /* If we read one certificate successfully, let's see if we can read
     529                 :            :    * some more. If not, we will simply return a list with the first one.
     530                 :            :    */
     531   [ +  +  +  -  :         12 :   while (p < end && p && *p)
                   +  - ]
     532                 :            :     {
     533                 :            :       gchar *cert_pem;
     534                 :          4 :       GError *my_error = NULL;
     535                 :            : 
     536                 :          4 :       cert_pem = parse_next_pem_certificate (&p, end, FALSE, &my_error);
     537         [ -  + ]:          4 :       if (my_error)
     538                 :            :         {
     539                 :          0 :           g_slist_free_full (pem_list, g_free);
     540                 :          0 :           g_error_free (my_error);
     541                 :          0 :           return first_pem_list;
     542                 :            :         }
     543         [ +  + ]:          4 :       else if (!cert_pem)
     544                 :            :         {
     545                 :          2 :           break;
     546                 :            :         }
     547                 :            : 
     548                 :          2 :       pem_list = g_slist_prepend (pem_list, cert_pem);
     549                 :            :     }
     550                 :            : 
     551                 :         10 :   pem_list = g_slist_concat (pem_list, first_pem_list);
     552                 :            : 
     553                 :         10 :   return pem_list;
     554                 :            : }
     555                 :            : 
     556                 :            : static GTlsCertificate *
     557                 :         10 : create_certificate_chain_from_list (GSList       *pem_list,
     558                 :            :                                     const gchar  *key_pem)
     559                 :            : {
     560                 :         10 :   GTlsCertificate *cert = NULL, *issuer = NULL, *root = NULL;
     561                 :            :   GTlsCertificateFlags flags;
     562                 :            :   GSList *pem;
     563                 :            : 
     564                 :         10 :   pem = pem_list;
     565         [ +  + ]:         22 :   while (pem)
     566                 :            :     {
     567                 :         12 :       const gchar *key = NULL;
     568                 :            : 
     569                 :            :       /* Private key belongs only to the first certificate. */
     570         [ +  + ]:         12 :       if (!pem->next)
     571                 :         10 :         key = key_pem;
     572                 :            : 
     573                 :            :       /* We assume that the whole file is a certificate chain, so we use
     574                 :            :        * each certificate as the issuer of the next one (list is in
     575                 :            :        * reverse order).
     576                 :            :        */
     577                 :         12 :       issuer = cert;
     578                 :         12 :       cert = g_tls_certificate_new_internal (pem->data, key, issuer, NULL);
     579         [ +  + ]:         12 :       if (issuer)
     580                 :          2 :         g_object_unref (issuer);
     581                 :            : 
     582         [ -  + ]:         12 :       if (!cert)
     583                 :          0 :         return NULL;
     584                 :            : 
     585                 :            :       /* root will point to the last certificate in the file. */
     586         [ +  + ]:         12 :       if (!root)
     587                 :         10 :         root = g_object_ref (cert);
     588                 :            : 
     589         [ +  - ]:         12 :       pem = g_slist_next (pem);
     590                 :            :     }
     591                 :            : 
     592                 :            :   /* Verify that the certificates form a chain. (We don't care at this
     593                 :            :    * point if there are other problems with it.)
     594                 :            :    */
     595                 :         10 :   flags = g_tls_certificate_verify (cert, NULL, root);
     596         [ -  + ]:         10 :   if (flags & G_TLS_CERTIFICATE_UNKNOWN_CA)
     597                 :            :     {
     598                 :            :       /* It wasn't a chain, it's just a bunch of unrelated certs. */
     599                 :          0 :       g_clear_object (&cert);
     600                 :            :     }
     601                 :            : 
     602                 :         10 :   g_clear_object (&root);
     603                 :            : 
     604                 :         10 :   return cert;
     605                 :            : }
     606                 :            : 
     607                 :            : static GTlsCertificate *
     608                 :         13 : parse_and_create_certificate (const gchar  *data,
     609                 :            :                               gsize         data_len,
     610                 :            :                               const gchar  *key_pem,
     611                 :            :                               GError      **error)
     612                 :            : 
     613                 :            : {
     614                 :            :   GSList *pem_list;
     615                 :            :   GTlsCertificate *cert;
     616                 :            : 
     617                 :         13 :   pem_list = parse_and_create_certificate_list (data, data_len, error);
     618         [ +  + ]:         13 :   if (!pem_list)
     619                 :          3 :     return NULL;
     620                 :            : 
     621                 :            :   /* We don't pass the error here because, if it fails, we still want to
     622                 :            :    * load and return the first certificate.
     623                 :            :    */
     624                 :         10 :   cert = create_certificate_chain_from_list (pem_list, key_pem);
     625         [ -  + ]:         10 :   if (!cert)
     626                 :            :     {
     627                 :          0 :       GSList *last = NULL;
     628                 :            : 
     629                 :            :       /* Get the first certificate (which is the last one as the list is
     630                 :            :        * in reverse order).
     631                 :            :        */
     632                 :          0 :       last = g_slist_last (pem_list);
     633                 :            : 
     634                 :          0 :       cert = g_tls_certificate_new_internal (last->data, key_pem, NULL, error);
     635                 :            :     }
     636                 :            : 
     637                 :         10 :   g_slist_free_full (pem_list, g_free);
     638                 :            : 
     639                 :         10 :   return cert;
     640                 :            : }
     641                 :            : 
     642                 :            : /**
     643                 :            :  * g_tls_certificate_new_from_pem:
     644                 :            :  * @data: PEM-encoded certificate data
     645                 :            :  * @length: the length of @data, or -1 if it's 0-terminated.
     646                 :            :  * @error: #GError for error reporting, or %NULL to ignore.
     647                 :            :  *
     648                 :            :  * Creates a #GTlsCertificate from the PEM-encoded data in @data. If
     649                 :            :  * @data includes both a certificate and a private key, then the
     650                 :            :  * returned certificate will include the private key data as well. (See
     651                 :            :  * the #GTlsCertificate:private-key-pem property for information about
     652                 :            :  * supported formats.)
     653                 :            :  *
     654                 :            :  * The returned certificate will be the first certificate found in
     655                 :            :  * @data. As of GLib 2.44, if @data contains more certificates it will
     656                 :            :  * try to load a certificate chain. All certificates will be verified in
     657                 :            :  * the order found (top-level certificate should be the last one in the
     658                 :            :  * file) and the #GTlsCertificate:issuer property of each certificate
     659                 :            :  * will be set accordingly if the verification succeeds. If any
     660                 :            :  * certificate in the chain cannot be verified, the first certificate in
     661                 :            :  * the file will still be returned.
     662                 :            :  *
     663                 :            :  * Returns: the new certificate, or %NULL if @data is invalid
     664                 :            :  *
     665                 :            :  * Since: 2.28
     666                 :            :  */
     667                 :            : GTlsCertificate *
     668                 :          9 : g_tls_certificate_new_from_pem  (const gchar  *data,
     669                 :            :                                  gssize        length,
     670                 :            :                                  GError      **error)
     671                 :            : {
     672                 :          9 :   GError *child_error = NULL;
     673                 :            :   gchar *key_pem;
     674                 :            :   GTlsCertificate *cert;
     675                 :            : 
     676                 :          9 :   g_return_val_if_fail (data != NULL, NULL);
     677                 :          9 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     678                 :            : 
     679         [ +  + ]:          9 :   if (length == -1)
     680                 :          5 :     length = strlen (data);
     681                 :            : 
     682                 :          9 :   key_pem = parse_private_key (data, length, FALSE, &child_error);
     683         [ +  + ]:          9 :   if (child_error != NULL)
     684                 :            :     {
     685                 :          1 :       g_propagate_error (error, child_error);
     686                 :          1 :       return NULL;
     687                 :            :     }
     688                 :            : 
     689                 :          8 :   cert = parse_and_create_certificate (data, length, key_pem, error);
     690                 :          8 :   g_free (key_pem);
     691                 :            : 
     692                 :          8 :   return cert;
     693                 :            : }
     694                 :            : 
     695                 :            : /**
     696                 :            :  * g_tls_certificate_new_from_pkcs12:
     697                 :            :  * @data: (array length=length): DER-encoded PKCS #12 format certificate data
     698                 :            :  * @length: the length of @data
     699                 :            :  * @password: (nullable): optional password for encrypted certificate data
     700                 :            :  * @error: #GError for error reporting, or %NULL to ignore.
     701                 :            :  *
     702                 :            :  * Creates a #GTlsCertificate from the data in @data. It must contain
     703                 :            :  * a certificate and matching private key.
     704                 :            :  *
     705                 :            :  * If extra certificates are included they will be verified as a chain
     706                 :            :  * and the #GTlsCertificate:issuer property will be set.
     707                 :            :  * All other data will be ignored.
     708                 :            :  *
     709                 :            :  * You can pass as single password for all of the data which will be
     710                 :            :  * used both for the PKCS #12 container as well as encrypted
     711                 :            :  * private keys. If decryption fails it will error with
     712                 :            :  * %G_TLS_ERROR_BAD_CERTIFICATE_PASSWORD.
     713                 :            :  *
     714                 :            :  * This constructor requires support in the current #GTlsBackend.
     715                 :            :  * If support is missing it will error with
     716                 :            :  * %G_IO_ERROR_NOT_SUPPORTED.
     717                 :            :  *
     718                 :            :  * Other parsing failures will error with %G_TLS_ERROR_BAD_CERTIFICATE.
     719                 :            :  *
     720                 :            :  * Returns: the new certificate, or %NULL if @data is invalid
     721                 :            :  *
     722                 :            :  * Since: 2.72
     723                 :            :  */
     724                 :            : GTlsCertificate *
     725                 :          3 : g_tls_certificate_new_from_pkcs12 (const guint8  *data,
     726                 :            :                                    gsize          length,
     727                 :            :                                    const gchar   *password,
     728                 :            :                                    GError       **error)
     729                 :            : {
     730                 :            :   GObject *cert;
     731                 :            :   GTlsBackend *backend;
     732                 :            :   GByteArray *bytes;
     733                 :            : 
     734                 :          3 :   g_return_val_if_fail (data != NULL || length == 0, NULL);
     735                 :          3 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     736                 :            : 
     737                 :          3 :   backend = g_tls_backend_get_default ();
     738                 :            : 
     739                 :          3 :   bytes = g_byte_array_new ();
     740                 :          3 :   g_byte_array_append (bytes, data, length);
     741                 :            : 
     742                 :          3 :   cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
     743                 :            :                          NULL, error,
     744                 :            :                          "pkcs12-data", bytes,
     745                 :            :                          "password", password,
     746                 :            :                          NULL);
     747                 :            : 
     748                 :          3 :   g_byte_array_unref (bytes);
     749                 :            : 
     750         [ +  - ]:          3 :   if (cert)
     751                 :            :     {
     752                 :          3 :       GTlsCertificatePrivate *priv = g_tls_certificate_get_instance_private (G_TLS_CERTIFICATE (cert));
     753                 :            : 
     754         [ +  - ]:          3 :       if (priv->pkcs12_properties_not_overridden)
     755                 :            :         {
     756                 :          3 :           g_clear_object (&cert);
     757                 :          3 :           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
     758                 :            :                                _("The current TLS backend does not support PKCS #12"));
     759                 :          3 :           return NULL;
     760                 :            :         }
     761                 :            :     }
     762                 :            : 
     763                 :          0 :   return G_TLS_CERTIFICATE (cert);
     764                 :            : }
     765                 :            : 
     766                 :            : /**
     767                 :            :  * g_tls_certificate_new_from_file_with_password:
     768                 :            :  * @file: (type filename): file containing a certificate to import
     769                 :            :  * @password: (not nullable): password for PKCS #12 files
     770                 :            :  * @error: #GError for error reporting, or %NULL to ignore
     771                 :            :  *
     772                 :            :  * Creates a #GTlsCertificate from the data in @file.
     773                 :            :  *
     774                 :            :  * If @file cannot be read or parsed, the function will return %NULL and
     775                 :            :  * set @error.
     776                 :            :  *
     777                 :            :  * Any unknown file types will error with %G_IO_ERROR_NOT_SUPPORTED.
     778                 :            :  * Currently only `.p12` and `.pfx` files are supported.
     779                 :            :  * See g_tls_certificate_new_from_pkcs12() for more details.
     780                 :            :  *
     781                 :            :  * Returns: the new certificate, or %NULL on error
     782                 :            :  *
     783                 :            :  * Since: 2.72
     784                 :            :  */
     785                 :            : GTlsCertificate *
     786                 :          1 : g_tls_certificate_new_from_file_with_password (const gchar  *file,
     787                 :            :                                                const gchar  *password,
     788                 :            :                                                GError      **error)
     789                 :            : {
     790                 :            :   GTlsCertificate *cert;
     791                 :            :   gchar *contents;
     792                 :            :   gsize length;
     793                 :            : 
     794                 :          1 :   g_return_val_if_fail (file != NULL, NULL);
     795                 :          1 :   g_return_val_if_fail (password != NULL, NULL);
     796                 :          1 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     797                 :            : 
     798   [ +  -  -  +  :          1 :   if (!g_str_has_suffix (file, ".p12") && !g_str_has_suffix (file, ".pfx"))
          +  -  -  +  -  
          -  -  -  -  -  
                   -  - ]
     799                 :            :     {
     800                 :          0 :       g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
     801                 :            :                    "The file type of \"%s\" is unknown. Only .p12 and .pfx files are supported currently.", file);
     802                 :          0 :       return NULL;
     803                 :            :     }
     804                 :            : 
     805         [ -  + ]:          1 :   if (!g_file_get_contents (file, &contents, &length, error))
     806                 :          0 :     return NULL;
     807                 :            : 
     808                 :          1 :   cert = g_tls_certificate_new_from_pkcs12 ((guint8 *)contents, length, password, error);
     809                 :            : 
     810                 :          1 :   g_free (contents);
     811                 :          1 :   return cert;
     812                 :            : }
     813                 :            : 
     814                 :            : /**
     815                 :            :  * g_tls_certificate_new_from_file:
     816                 :            :  * @file: (type filename): file containing a certificate to import
     817                 :            :  * @error: #GError for error reporting, or %NULL to ignore
     818                 :            :  *
     819                 :            :  * Creates a #GTlsCertificate from the data in @file.
     820                 :            :  *
     821                 :            :  * As of 2.72, if the filename ends in `.p12` or `.pfx` the data is loaded by
     822                 :            :  * g_tls_certificate_new_from_pkcs12() otherwise it is loaded by
     823                 :            :  * g_tls_certificate_new_from_pem(). See those functions for
     824                 :            :  * exact details.
     825                 :            :  *
     826                 :            :  * If @file cannot be read or parsed, the function will return %NULL and
     827                 :            :  * set @error.
     828                 :            :  *
     829                 :            :  * Returns: the new certificate, or %NULL on error
     830                 :            :  *
     831                 :            :  * Since: 2.28
     832                 :            :  */
     833                 :            : GTlsCertificate *
     834                 :          2 : g_tls_certificate_new_from_file (const gchar  *file,
     835                 :            :                                  GError      **error)
     836                 :            : {
     837                 :            :   GTlsCertificate *cert;
     838                 :            :   gchar *contents;
     839                 :            :   gsize length;
     840                 :            : 
     841                 :          2 :   g_return_val_if_fail (file != NULL, NULL);
     842                 :          2 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     843                 :            : 
     844         [ -  + ]:          2 :   if (!g_file_get_contents (file, &contents, &length, error))
     845                 :          0 :     return NULL;
     846                 :            : 
     847   [ +  -  -  +  :          2 :   if (g_str_has_suffix (file, ".p12") || g_str_has_suffix (file, ".pfx"))
          +  -  +  +  +  
          -  -  +  +  -  
                   -  + ]
     848                 :          1 :     cert = g_tls_certificate_new_from_pkcs12 ((guint8 *)contents, length, NULL, error);
     849                 :            :   else
     850                 :          1 :     cert = g_tls_certificate_new_from_pem (contents, length, error);
     851                 :            : 
     852                 :          2 :   g_free (contents);
     853                 :          2 :   return cert;
     854                 :            : }
     855                 :            : 
     856                 :            : /**
     857                 :            :  * g_tls_certificate_new_from_files:
     858                 :            :  * @cert_file: (type filename): file containing one or more PEM-encoded
     859                 :            :  *     certificates to import
     860                 :            :  * @key_file: (type filename): file containing a PEM-encoded private key
     861                 :            :  *     to import
     862                 :            :  * @error: #GError for error reporting, or %NULL to ignore.
     863                 :            :  *
     864                 :            :  * Creates a #GTlsCertificate from the PEM-encoded data in @cert_file
     865                 :            :  * and @key_file. The returned certificate will be the first certificate
     866                 :            :  * found in @cert_file. As of GLib 2.44, if @cert_file contains more
     867                 :            :  * certificates it will try to load a certificate chain. All
     868                 :            :  * certificates will be verified in the order found (top-level
     869                 :            :  * certificate should be the last one in the file) and the
     870                 :            :  * #GTlsCertificate:issuer property of each certificate will be set
     871                 :            :  * accordingly if the verification succeeds. If any certificate in the
     872                 :            :  * chain cannot be verified, the first certificate in the file will
     873                 :            :  * still be returned.
     874                 :            :  *
     875                 :            :  * If either file cannot be read or parsed, the function will return
     876                 :            :  * %NULL and set @error. Otherwise, this behaves like
     877                 :            :  * g_tls_certificate_new_from_pem().
     878                 :            :  *
     879                 :            :  * Returns: the new certificate, or %NULL on error
     880                 :            :  *
     881                 :            :  * Since: 2.28
     882                 :            :  */
     883                 :            : GTlsCertificate *
     884                 :          9 : g_tls_certificate_new_from_files (const gchar  *cert_file,
     885                 :            :                                   const gchar  *key_file,
     886                 :            :                                   GError      **error)
     887                 :            : {
     888                 :            :   GTlsCertificate *cert;
     889                 :            :   gchar *cert_data, *key_data;
     890                 :            :   gsize cert_len, key_len;
     891                 :            :   gchar *key_pem;
     892                 :            : 
     893         [ -  + ]:          9 :   if (!g_file_get_contents (key_file, &key_data, &key_len, error))
     894                 :          0 :     return NULL;
     895                 :            : 
     896                 :          9 :   key_pem = parse_private_key (key_data, key_len, TRUE, error);
     897                 :          9 :   g_free (key_data);
     898         [ +  + ]:          9 :   if (!key_pem)
     899                 :          4 :     return NULL;
     900                 :            : 
     901         [ -  + ]:          5 :   if (!g_file_get_contents (cert_file, &cert_data, &cert_len, error))
     902                 :            :     {
     903                 :          0 :       g_free (key_pem);
     904                 :          0 :       return NULL;
     905                 :            :     }
     906                 :            : 
     907                 :          5 :   cert = parse_and_create_certificate (cert_data, cert_len, key_pem, error);
     908                 :          5 :   g_free (cert_data);
     909                 :          5 :   g_free (key_pem);
     910                 :          5 :   return cert;
     911                 :            : }
     912                 :            : 
     913                 :            : /**
     914                 :            :  * g_tls_certificate_new_from_pkcs11_uris:
     915                 :            :  * @pkcs11_uri: A PKCS \#11 URI
     916                 :            :  * @private_key_pkcs11_uri: (nullable): A PKCS \#11 URI
     917                 :            :  * @error: #GError for error reporting, or %NULL to ignore.
     918                 :            :  *
     919                 :            :  * Creates a #GTlsCertificate from a
     920                 :            :  * [PKCS \#11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html) URI.
     921                 :            :  *
     922                 :            :  * An example @pkcs11_uri would be `pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01`
     923                 :            :  *
     924                 :            :  * Where the token’s layout is:
     925                 :            :  *
     926                 :            :  * |[
     927                 :            :  * Object 0:
     928                 :            :  *   URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=private%20key;type=private
     929                 :            :  *   Type: Private key (RSA-2048)
     930                 :            :  *   ID: 01
     931                 :            :  *
     932                 :            :  * Object 1:
     933                 :            :  *   URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=Certificate%20for%20Authentication;type=cert
     934                 :            :  *   Type: X.509 Certificate (RSA-2048)
     935                 :            :  *   ID: 01
     936                 :            :  * ]|
     937                 :            :  *
     938                 :            :  * In this case the certificate and private key would both be detected and used as expected.
     939                 :            :  * @pkcs_uri may also just reference an X.509 certificate object and then optionally
     940                 :            :  * @private_key_pkcs11_uri allows using a private key exposed under a different URI.
     941                 :            :  *
     942                 :            :  * Note that the private key is not accessed until usage and may fail or require a PIN later.
     943                 :            :  *
     944                 :            :  * Returns: (transfer full): the new certificate, or %NULL on error
     945                 :            :  *
     946                 :            :  * Since: 2.68
     947                 :            :  */
     948                 :            : GTlsCertificate *
     949                 :          8 : g_tls_certificate_new_from_pkcs11_uris (const gchar  *pkcs11_uri,
     950                 :            :                                         const gchar  *private_key_pkcs11_uri,
     951                 :            :                                         GError      **error)
     952                 :            : {
     953                 :            :   GObject *cert;
     954                 :            :   GTlsBackend *backend;
     955                 :            : 
     956                 :          8 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     957                 :          8 :   g_return_val_if_fail (pkcs11_uri, NULL);
     958                 :            : 
     959                 :          8 :   backend = g_tls_backend_get_default ();
     960                 :            : 
     961                 :          8 :   cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
     962                 :            :                          NULL, error,
     963                 :            :                          "pkcs11-uri", pkcs11_uri,
     964                 :            :                          "private-key-pkcs11-uri", private_key_pkcs11_uri,
     965                 :            :                          NULL);
     966                 :            : 
     967         [ +  - ]:          8 :   if (cert != NULL)
     968                 :            :     {
     969                 :            :       gchar *objects_uri;
     970                 :            : 
     971                 :            :       /* Old implementations might not override this property */
     972                 :          8 :       g_object_get (cert, "pkcs11-uri", &objects_uri, NULL);
     973         [ +  + ]:          8 :       if (objects_uri == NULL)
     974                 :            :         {
     975                 :          1 :           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("This GTlsBackend does not support creating PKCS #11 certificates"));
     976                 :          1 :           g_object_unref (cert);
     977                 :          1 :           return NULL;
     978                 :            :         }
     979                 :          7 :       g_free (objects_uri);
     980                 :            :     }
     981                 :            : 
     982                 :          7 :   return G_TLS_CERTIFICATE (cert);
     983                 :            : }
     984                 :            : 
     985                 :            : /**
     986                 :            :  * g_tls_certificate_list_new_from_file:
     987                 :            :  * @file: (type filename): file containing PEM-encoded certificates to import
     988                 :            :  * @error: #GError for error reporting, or %NULL to ignore.
     989                 :            :  *
     990                 :            :  * Creates one or more #GTlsCertificates from the PEM-encoded
     991                 :            :  * data in @file. If @file cannot be read or parsed, the function will
     992                 :            :  * return %NULL and set @error. If @file does not contain any
     993                 :            :  * PEM-encoded certificates, this will return an empty list and not
     994                 :            :  * set @error.
     995                 :            :  *
     996                 :            :  * Returns: (element-type Gio.TlsCertificate) (transfer full): a
     997                 :            :  * #GList containing #GTlsCertificate objects. You must free the list
     998                 :            :  * and its contents when you are done with it.
     999                 :            :  *
    1000                 :            :  * Since: 2.28
    1001                 :            :  */
    1002                 :            : GList *
    1003                 :          2 : g_tls_certificate_list_new_from_file (const gchar  *file,
    1004                 :            :                                       GError      **error)
    1005                 :            : {
    1006                 :          2 :   GQueue queue = G_QUEUE_INIT;
    1007                 :            :   gchar *contents, *end;
    1008                 :            :   const gchar *p;
    1009                 :            :   gsize length;
    1010                 :            : 
    1011         [ -  + ]:          2 :   if (!g_file_get_contents (file, &contents, &length, error))
    1012                 :          0 :     return NULL;
    1013                 :            : 
    1014                 :          2 :   end = contents + length;
    1015                 :          2 :   p = contents;
    1016   [ +  -  +  + ]:          5 :   while (p && *p)
    1017                 :            :     {
    1018                 :            :       gchar *cert_pem;
    1019                 :          4 :       GTlsCertificate *cert = NULL;
    1020                 :          4 :       GError *parse_error = NULL;
    1021                 :            : 
    1022                 :          4 :       cert_pem = parse_next_pem_certificate (&p, end, FALSE, &parse_error);
    1023         [ +  + ]:          4 :       if (cert_pem)
    1024                 :            :         {
    1025                 :          3 :           cert = g_tls_certificate_new_internal (cert_pem, NULL, NULL, &parse_error);
    1026                 :          3 :           g_free (cert_pem);
    1027                 :            :         }
    1028         [ +  + ]:          4 :       if (!cert)
    1029                 :            :         {
    1030         [ -  + ]:          1 :           if (parse_error)
    1031                 :            :             {
    1032                 :          0 :               g_propagate_error (error, parse_error);
    1033                 :          0 :               g_list_free_full (queue.head, g_object_unref);
    1034                 :          0 :               queue.head = NULL;
    1035                 :            :             }
    1036                 :          1 :           break;
    1037                 :            :         }
    1038                 :          3 :       g_queue_push_tail (&queue, cert);
    1039                 :            :     }
    1040                 :            : 
    1041                 :          2 :   g_free (contents);
    1042                 :          2 :   return queue.head;
    1043                 :            : }
    1044                 :            : 
    1045                 :            : 
    1046                 :            : /**
    1047                 :            :  * g_tls_certificate_get_issuer:
    1048                 :            :  * @cert: a #GTlsCertificate
    1049                 :            :  *
    1050                 :            :  * Gets the #GTlsCertificate representing @cert's issuer, if known
    1051                 :            :  *
    1052                 :            :  * Returns: (nullable) (transfer none): The certificate of @cert's issuer,
    1053                 :            :  * or %NULL if @cert is self-signed or signed with an unknown
    1054                 :            :  * certificate.
    1055                 :            :  *
    1056                 :            :  * Since: 2.28
    1057                 :            :  */
    1058                 :            : GTlsCertificate *
    1059                 :          3 : g_tls_certificate_get_issuer (GTlsCertificate  *cert)
    1060                 :            : {
    1061                 :            :   GTlsCertificate *issuer;
    1062                 :            : 
    1063                 :          3 :   g_object_get (G_OBJECT (cert), "issuer", &issuer, NULL);
    1064         [ +  + ]:          3 :   if (issuer)
    1065                 :          2 :     g_object_unref (issuer);
    1066                 :            : 
    1067                 :          3 :   return issuer;
    1068                 :            : }
    1069                 :            : 
    1070                 :            : /**
    1071                 :            :  * g_tls_certificate_verify:
    1072                 :            :  * @cert: a #GTlsCertificate
    1073                 :            :  * @identity: (nullable): the expected peer identity
    1074                 :            :  * @trusted_ca: (nullable): the certificate of a trusted authority
    1075                 :            :  *
    1076                 :            :  * This verifies @cert and returns a set of #GTlsCertificateFlags
    1077                 :            :  * indicating any problems found with it. This can be used to verify a
    1078                 :            :  * certificate outside the context of making a connection, or to
    1079                 :            :  * check a certificate against a CA that is not part of the system
    1080                 :            :  * CA database.
    1081                 :            :  *
    1082                 :            :  * If @cert is valid, %G_TLS_CERTIFICATE_NO_FLAGS is returned.
    1083                 :            :  *
    1084                 :            :  * If @identity is not %NULL, @cert's name(s) will be compared against
    1085                 :            :  * it, and %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the return
    1086                 :            :  * value if it does not match. If @identity is %NULL, that bit will
    1087                 :            :  * never be set in the return value.
    1088                 :            :  *
    1089                 :            :  * If @trusted_ca is not %NULL, then @cert (or one of the certificates
    1090                 :            :  * in its chain) must be signed by it, or else
    1091                 :            :  * %G_TLS_CERTIFICATE_UNKNOWN_CA will be set in the return value. If
    1092                 :            :  * @trusted_ca is %NULL, that bit will never be set in the return
    1093                 :            :  * value.
    1094                 :            :  *
    1095                 :            :  * GLib guarantees that if certificate verification fails, at least one
    1096                 :            :  * error will be set in the return value, but it does not guarantee
    1097                 :            :  * that all possible errors will be set. Accordingly, you may not safely
    1098                 :            :  * decide to ignore any particular type of error. For example, it would
    1099                 :            :  * be incorrect to mask %G_TLS_CERTIFICATE_EXPIRED if you want to allow
    1100                 :            :  * expired certificates, because this could potentially be the only
    1101                 :            :  * error flag set even if other problems exist with the certificate.
    1102                 :            :  *
    1103                 :            :  * Because TLS session context is not used, #GTlsCertificate may not
    1104                 :            :  * perform as many checks on the certificates as #GTlsConnection would.
    1105                 :            :  * For example, certificate constraints may not be honored, and
    1106                 :            :  * revocation checks may not be performed. The best way to verify TLS
    1107                 :            :  * certificates used by a TLS connection is to let #GTlsConnection
    1108                 :            :  * handle the verification.
    1109                 :            :  *
    1110                 :            :  * Returns: the appropriate #GTlsCertificateFlags
    1111                 :            :  *
    1112                 :            :  * Since: 2.28
    1113                 :            :  */
    1114                 :            : GTlsCertificateFlags
    1115                 :         10 : g_tls_certificate_verify (GTlsCertificate     *cert,
    1116                 :            :                           GSocketConnectable  *identity,
    1117                 :            :                           GTlsCertificate     *trusted_ca)
    1118                 :            : {
    1119                 :         10 :   return G_TLS_CERTIFICATE_GET_CLASS (cert)->verify (cert, identity, trusted_ca);
    1120                 :            : }
    1121                 :            : 
    1122                 :            : /**
    1123                 :            :  * g_tls_certificate_is_same:
    1124                 :            :  * @cert_one: first certificate to compare
    1125                 :            :  * @cert_two: second certificate to compare
    1126                 :            :  *
    1127                 :            :  * Check if two #GTlsCertificate objects represent the same certificate.
    1128                 :            :  * The raw DER byte data of the two certificates are checked for equality.
    1129                 :            :  * This has the effect that two certificates may compare equal even if
    1130                 :            :  * their #GTlsCertificate:issuer, #GTlsCertificate:private-key, or
    1131                 :            :  * #GTlsCertificate:private-key-pem properties differ.
    1132                 :            :  *
    1133                 :            :  * Returns: whether the same or not
    1134                 :            :  *
    1135                 :            :  * Since: 2.34
    1136                 :            :  */
    1137                 :            : gboolean
    1138                 :          0 : g_tls_certificate_is_same (GTlsCertificate     *cert_one,
    1139                 :            :                            GTlsCertificate     *cert_two)
    1140                 :            : {
    1141                 :            :   GByteArray *b1, *b2;
    1142                 :            :   gboolean equal;
    1143                 :            : 
    1144                 :          0 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_one), FALSE);
    1145                 :          0 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_two), FALSE);
    1146                 :            : 
    1147                 :          0 :   g_object_get (cert_one, "certificate", &b1, NULL);
    1148                 :          0 :   g_object_get (cert_two, "certificate", &b2, NULL);
    1149                 :            : 
    1150         [ #  # ]:          0 :   equal = (b1->len == b2->len &&
    1151         [ #  # ]:          0 :            memcmp (b1->data, b2->data, b1->len) == 0);
    1152                 :            : 
    1153                 :          0 :   g_byte_array_unref (b1);
    1154                 :          0 :   g_byte_array_unref (b2);
    1155                 :            : 
    1156                 :          0 :   return equal;
    1157                 :            : }
    1158                 :            : 
    1159                 :            : 
    1160                 :            : /**
    1161                 :            :  * g_tls_certificate_get_not_valid_before:
    1162                 :            :  * @cert: a #GTlsCertificate
    1163                 :            :  *
    1164                 :            :  * Returns the time at which the certificate became or will become valid.
    1165                 :            :  *
    1166                 :            :  * Returns: (nullable) (transfer full): The not-valid-before date, or %NULL if it's not available.
    1167                 :            :  *
    1168                 :            :  * Since: 2.70
    1169                 :            :  */
    1170                 :            : GDateTime *
    1171                 :          1 : g_tls_certificate_get_not_valid_before (GTlsCertificate *cert)
    1172                 :            : {
    1173                 :          1 :   GDateTime *not_valid_before = NULL;
    1174                 :            : 
    1175                 :          1 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
    1176                 :            : 
    1177                 :          1 :   g_object_get (G_OBJECT (cert), "not-valid-before", &not_valid_before, NULL);
    1178                 :            : 
    1179                 :          1 :   return g_steal_pointer (&not_valid_before);
    1180                 :            : }
    1181                 :            : 
    1182                 :            : /**
    1183                 :            :  * g_tls_certificate_get_not_valid_after:
    1184                 :            :  * @cert: a #GTlsCertificate
    1185                 :            :  *
    1186                 :            :  * Returns the time at which the certificate became or will become invalid.
    1187                 :            :  *
    1188                 :            :  * Returns: (nullable) (transfer full): The not-valid-after date, or %NULL if it's not available.
    1189                 :            :  *
    1190                 :            :  * Since: 2.70
    1191                 :            :  */
    1192                 :            : GDateTime *
    1193                 :          1 : g_tls_certificate_get_not_valid_after (GTlsCertificate *cert)
    1194                 :            : {
    1195                 :          1 :   GDateTime *not_valid_after = NULL;
    1196                 :            : 
    1197                 :          1 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
    1198                 :            : 
    1199                 :          1 :   g_object_get (G_OBJECT (cert), "not-valid-after", &not_valid_after, NULL);
    1200                 :            : 
    1201                 :          1 :   return g_steal_pointer (&not_valid_after);
    1202                 :            : }
    1203                 :            : 
    1204                 :            : /**
    1205                 :            :  * g_tls_certificate_get_subject_name:
    1206                 :            :  * @cert: a #GTlsCertificate
    1207                 :            :  *
    1208                 :            :  * Returns the subject name from the certificate.
    1209                 :            :  *
    1210                 :            :  * Returns: (nullable) (transfer full): The subject name, or %NULL if it's not available.
    1211                 :            :  *
    1212                 :            :  * Since: 2.70
    1213                 :            :  */
    1214                 :            : gchar *
    1215                 :          1 : g_tls_certificate_get_subject_name (GTlsCertificate *cert)
    1216                 :            : {
    1217                 :          1 :   gchar *subject_name = NULL;
    1218                 :            : 
    1219                 :          1 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
    1220                 :            : 
    1221                 :          1 :   g_object_get (G_OBJECT (cert), "subject-name", &subject_name, NULL);
    1222                 :            : 
    1223                 :          1 :   return g_steal_pointer (&subject_name);
    1224                 :            : }
    1225                 :            : 
    1226                 :            : /**
    1227                 :            :  * g_tls_certificate_get_issuer_name:
    1228                 :            :  * @cert: a #GTlsCertificate
    1229                 :            :  *
    1230                 :            :  * Returns the issuer name from the certificate.
    1231                 :            :  *
    1232                 :            :  * Returns: (nullable) (transfer full): The issuer name, or %NULL if it's not available.
    1233                 :            :  *
    1234                 :            :  * Since: 2.70
    1235                 :            :  */
    1236                 :            : gchar *
    1237                 :          1 : g_tls_certificate_get_issuer_name (GTlsCertificate *cert)
    1238                 :            : {
    1239                 :          1 :   gchar *issuer_name = NULL;
    1240                 :            : 
    1241                 :          1 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
    1242                 :            : 
    1243                 :          1 :   g_object_get (G_OBJECT (cert), "issuer-name", &issuer_name, NULL);
    1244                 :            : 
    1245                 :          1 :   return g_steal_pointer (&issuer_name);
    1246                 :            : }
    1247                 :            : 
    1248                 :            : /**
    1249                 :            :  * g_tls_certificate_get_dns_names:
    1250                 :            :  * @cert: a #GTlsCertificate
    1251                 :            :  *
    1252                 :            :  * Gets the value of #GTlsCertificate:dns-names.
    1253                 :            :  *
    1254                 :            :  * Returns: (nullable) (element-type GBytes) (transfer container): A #GPtrArray of
    1255                 :            :  * #GBytes elements, or %NULL if it's not available.
    1256                 :            :  *
    1257                 :            :  * Since: 2.70
    1258                 :            :  */
    1259                 :            : GPtrArray *
    1260                 :          1 : g_tls_certificate_get_dns_names (GTlsCertificate *cert)
    1261                 :            : {
    1262                 :          1 :   GPtrArray *dns_names = NULL;
    1263                 :            : 
    1264                 :          1 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
    1265                 :            : 
    1266                 :          1 :   g_object_get (G_OBJECT (cert), "dns-names", &dns_names, NULL);
    1267                 :            : 
    1268                 :          1 :   return g_steal_pointer (&dns_names);
    1269                 :            : }
    1270                 :            : 
    1271                 :            : /**
    1272                 :            :  * g_tls_certificate_get_ip_addresses:
    1273                 :            :  * @cert: a #GTlsCertificate
    1274                 :            :  *
    1275                 :            :  * Gets the value of #GTlsCertificate:ip-addresses.
    1276                 :            :  *
    1277                 :            :  * Returns: (nullable) (element-type GInetAddress) (transfer container): A #GPtrArray
    1278                 :            :  * of #GInetAddress elements, or %NULL if it's not available.
    1279                 :            :  *
    1280                 :            :  * Since: 2.70
    1281                 :            :  */
    1282                 :            : GPtrArray *
    1283                 :          1 : g_tls_certificate_get_ip_addresses (GTlsCertificate *cert)
    1284                 :            : {
    1285                 :          1 :   GPtrArray *ip_addresses = NULL;
    1286                 :            : 
    1287                 :          1 :   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
    1288                 :            : 
    1289                 :          1 :   g_object_get (G_OBJECT (cert), "ip-addresses", &ip_addresses, NULL);
    1290                 :            : 
    1291                 :          1 :   return g_steal_pointer (&ip_addresses);
    1292                 :            : }

Generated by: LCOV version 1.14