1 /* GIO - GLib Input, Output and Certificateing Library
2 *
3 * Copyright (C) 2010 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "config.h"
20
21 #include "gtlscertificate.h"
22
23 #include <string.h>
24 #include "ginitable.h"
25 #include "gtlsbackend.h"
26 #include "gtlsconnection.h"
27 #include "glibintl.h"
28
29 /**
30 * SECTION:gtlscertificate
31 * @title: GTlsCertificate
32 * @short_description: TLS certificate
33 * @include: gio/gio.h
34 * @see_also: #GTlsConnection
35 *
36 * A certificate used for TLS authentication and encryption.
37 * This can represent either a certificate only (eg, the certificate
38 * received by a client from a server), or the combination of
39 * a certificate and a private key (which is needed when acting as a
40 * #GTlsServerConnection).
41 *
42 * Since: 2.28
43 */
44
45 /**
46 * GTlsCertificate:
47 *
48 * Abstract base class for TLS certificate types.
49 *
50 * Since: 2.28
51 */
52
53 G_DEFINE_ABSTRACT_TYPE (GTlsCertificate, g_tls_certificate, G_TYPE_OBJECT)
54
55 enum
56 {
57 PROP_0,
58
59 PROP_CERTIFICATE,
60 PROP_CERTIFICATE_PEM,
61 PROP_PRIVATE_KEY,
62 PROP_PRIVATE_KEY_PEM,
63 PROP_ISSUER,
64 PROP_PKCS11_URI,
65 PROP_PRIVATE_KEY_PKCS11_URI,
66 };
67
68 static void
g_tls_certificate_init(GTlsCertificate * cert)69 g_tls_certificate_init (GTlsCertificate *cert)
70 {
71 }
72
73 static void
g_tls_certificate_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)74 g_tls_certificate_get_property (GObject *object,
75 guint prop_id,
76 GValue *value,
77 GParamSpec *pspec)
78 {
79 switch (prop_id)
80 {
81 case PROP_PKCS11_URI:
82 case PROP_PRIVATE_KEY_PKCS11_URI:
83 /* Subclasses must override this property but this allows older backends to not fatally error */
84 g_value_set_static_string (value, NULL);
85 break;
86 default:
87 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
88 }
89 }
90
91 static void
g_tls_certificate_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)92 g_tls_certificate_set_property (GObject *object,
93 guint prop_id,
94 const GValue *value,
95 GParamSpec *pspec)
96 {
97 switch (prop_id)
98 {
99 case PROP_PKCS11_URI:
100 case PROP_PRIVATE_KEY_PKCS11_URI:
101 /* Subclasses must override this property but this allows older backends to not fatally error */
102 break;
103 default:
104 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
105 }
106 }
107
108 static void
g_tls_certificate_class_init(GTlsCertificateClass * class)109 g_tls_certificate_class_init (GTlsCertificateClass *class)
110 {
111 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
112
113 gobject_class->set_property = g_tls_certificate_set_property;
114 gobject_class->get_property = g_tls_certificate_get_property;
115
116 /**
117 * GTlsCertificate:certificate:
118 *
119 * The DER (binary) encoded representation of the certificate.
120 * This property and the #GTlsCertificate:certificate-pem property
121 * represent the same data, just in different forms.
122 *
123 * Since: 2.28
124 */
125 g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
126 g_param_spec_boxed ("certificate",
127 P_("Certificate"),
128 P_("The DER representation of the certificate"),
129 G_TYPE_BYTE_ARRAY,
130 G_PARAM_READWRITE |
131 G_PARAM_CONSTRUCT_ONLY |
132 G_PARAM_STATIC_STRINGS));
133 /**
134 * GTlsCertificate:certificate-pem:
135 *
136 * The PEM (ASCII) encoded representation of the certificate.
137 * This property and the #GTlsCertificate:certificate
138 * property represent the same data, just in different forms.
139 *
140 * Since: 2.28
141 */
142 g_object_class_install_property (gobject_class, PROP_CERTIFICATE_PEM,
143 g_param_spec_string ("certificate-pem",
144 P_("Certificate (PEM)"),
145 P_("The PEM representation of the certificate"),
146 NULL,
147 G_PARAM_READWRITE |
148 G_PARAM_CONSTRUCT_ONLY |
149 G_PARAM_STATIC_STRINGS));
150 /**
151 * GTlsCertificate:private-key:
152 *
153 * The DER (binary) encoded representation of the certificate's
154 * private key, in either PKCS#1 format or unencrypted PKCS#8
155 * format. This property (or the #GTlsCertificate:private-key-pem
156 * property) can be set when constructing a key (eg, from a file),
157 * but cannot be read.
158 *
159 * PKCS#8 format is supported since 2.32; earlier releases only
160 * support PKCS#1. You can use the `openssl rsa`
161 * tool to convert PKCS#8 keys to PKCS#1.
162 *
163 * Since: 2.28
164 */
165 g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY,
166 g_param_spec_boxed ("private-key",
167 P_("Private key"),
168 P_("The DER representation of the certificate’s private key"),
169 G_TYPE_BYTE_ARRAY,
170 G_PARAM_WRITABLE |
171 G_PARAM_CONSTRUCT_ONLY |
172 G_PARAM_STATIC_STRINGS));
173 /**
174 * GTlsCertificate:private-key-pem:
175 *
176 * The PEM (ASCII) encoded representation of the certificate's
177 * private key in either PKCS#1 format ("`BEGIN RSA PRIVATE
178 * KEY`") or unencrypted PKCS#8 format ("`BEGIN
179 * PRIVATE KEY`"). This property (or the
180 * #GTlsCertificate:private-key property) can be set when
181 * constructing a key (eg, from a file), but cannot be read.
182 *
183 * PKCS#8 format is supported since 2.32; earlier releases only
184 * support PKCS#1. You can use the `openssl rsa`
185 * tool to convert PKCS#8 keys to PKCS#1.
186 *
187 * Since: 2.28
188 */
189 g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PEM,
190 g_param_spec_string ("private-key-pem",
191 P_("Private key (PEM)"),
192 P_("The PEM representation of the certificate’s private key"),
193 NULL,
194 G_PARAM_WRITABLE |
195 G_PARAM_CONSTRUCT_ONLY |
196 G_PARAM_STATIC_STRINGS));
197 /**
198 * GTlsCertificate:issuer:
199 *
200 * A #GTlsCertificate representing the entity that issued this
201 * certificate. If %NULL, this means that the certificate is either
202 * self-signed, or else the certificate of the issuer is not
203 * available.
204 *
205 * Since: 2.28
206 */
207 g_object_class_install_property (gobject_class, PROP_ISSUER,
208 g_param_spec_object ("issuer",
209 P_("Issuer"),
210 P_("The certificate for the issuing entity"),
211 G_TYPE_TLS_CERTIFICATE,
212 G_PARAM_READWRITE |
213 G_PARAM_CONSTRUCT_ONLY |
214 G_PARAM_STATIC_STRINGS));
215
216 /**
217 * GTlsCertificate:pkcs11-uri: (nullable)
218 *
219 * A URI referencing the PKCS \#11 objects containing an X.509 certificate
220 * and optionally a private key.
221 *
222 * If %NULL the certificate is either not backed by PKCS \#11 or the
223 * #GTlsBackend does not support PKCS \#11.
224 *
225 * Since: 2.68
226 */
227 g_object_class_install_property (gobject_class, PROP_PKCS11_URI,
228 g_param_spec_string ("pkcs11-uri",
229 P_("PKCS #11 URI"),
230 P_("The PKCS #11 URI"),
231 NULL,
232 G_PARAM_READWRITE |
233 G_PARAM_CONSTRUCT_ONLY |
234 G_PARAM_STATIC_STRINGS));
235
236 /**
237 * GTlsCertificate:private-key-pkcs11-uri: (nullable)
238 *
239 * A URI referencing a PKCS \#11 object containing a private key.
240 *
241 * Since: 2.68
242 */
243 g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PKCS11_URI,
244 g_param_spec_string ("private-key-pkcs11-uri",
245 P_("PKCS #11 URI"),
246 P_("The PKCS #11 URI for a private key"),
247 NULL,
248 G_PARAM_READWRITE |
249 G_PARAM_CONSTRUCT_ONLY |
250 G_PARAM_STATIC_STRINGS));
251 }
252
253 static GTlsCertificate *
g_tls_certificate_new_internal(const gchar * certificate_pem,const gchar * private_key_pem,GTlsCertificate * issuer,GError ** error)254 g_tls_certificate_new_internal (const gchar *certificate_pem,
255 const gchar *private_key_pem,
256 GTlsCertificate *issuer,
257 GError **error)
258 {
259 GObject *cert;
260 GTlsBackend *backend;
261
262 backend = g_tls_backend_get_default ();
263
264 cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
265 NULL, error,
266 "certificate-pem", certificate_pem,
267 "private-key-pem", private_key_pem,
268 "issuer", issuer,
269 NULL);
270
271 return G_TLS_CERTIFICATE (cert);
272 }
273
274 #define PEM_CERTIFICATE_HEADER "-----BEGIN CERTIFICATE-----"
275 #define PEM_CERTIFICATE_FOOTER "-----END CERTIFICATE-----"
276 #define PEM_PRIVKEY_HEADER_BEGIN "-----BEGIN "
277 #define PEM_PRIVKEY_HEADER_END "PRIVATE KEY-----"
278 #define PEM_PRIVKEY_FOOTER_BEGIN "-----END "
279 #define PEM_PRIVKEY_FOOTER_END "PRIVATE KEY-----"
280 #define PEM_PKCS8_ENCRYPTED_HEADER "-----BEGIN ENCRYPTED PRIVATE KEY-----"
281
282 static gchar *
parse_private_key(const gchar * data,gsize data_len,gboolean required,GError ** error)283 parse_private_key (const gchar *data,
284 gsize data_len,
285 gboolean required,
286 GError **error)
287 {
288 const gchar *header_start = NULL, *header_end, *footer_start = NULL, *footer_end;
289
290 header_end = g_strstr_len (data, data_len, PEM_PRIVKEY_HEADER_END);
291 if (header_end)
292 header_start = g_strrstr_len (data, header_end - data, PEM_PRIVKEY_HEADER_BEGIN);
293
294 if (!header_start)
295 {
296 if (required)
297 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
298 _("No PEM-encoded private key found"));
299
300 return NULL;
301 }
302
303 header_end += strlen (PEM_PRIVKEY_HEADER_END);
304
305 if (strncmp (header_start, PEM_PKCS8_ENCRYPTED_HEADER, header_end - header_start) == 0)
306 {
307 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
308 _("Cannot decrypt PEM-encoded private key"));
309 return NULL;
310 }
311
312 footer_end = g_strstr_len (header_end, data_len - (header_end - data), PEM_PRIVKEY_FOOTER_END);
313 if (footer_end)
314 footer_start = g_strrstr_len (header_end, footer_end - header_end, PEM_PRIVKEY_FOOTER_BEGIN);
315
316 if (!footer_start)
317 {
318 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
319 _("Could not parse PEM-encoded private key"));
320 return NULL;
321 }
322
323 footer_end += strlen (PEM_PRIVKEY_FOOTER_END);
324
325 while (*footer_end == '\r' || *footer_end == '\n')
326 footer_end++;
327
328 return g_strndup (header_start, footer_end - header_start);
329 }
330
331
332 static gchar *
parse_next_pem_certificate(const gchar ** data,const gchar * data_end,gboolean required,GError ** error)333 parse_next_pem_certificate (const gchar **data,
334 const gchar *data_end,
335 gboolean required,
336 GError **error)
337 {
338 const gchar *start, *end;
339
340 start = g_strstr_len (*data, data_end - *data, PEM_CERTIFICATE_HEADER);
341 if (!start)
342 {
343 if (required)
344 {
345 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
346 _("No PEM-encoded certificate found"));
347 }
348 return NULL;
349 }
350
351 end = g_strstr_len (start, data_end - start, PEM_CERTIFICATE_FOOTER);
352 if (!end)
353 {
354 g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
355 _("Could not parse PEM-encoded certificate"));
356 return NULL;
357 }
358 end += strlen (PEM_CERTIFICATE_FOOTER);
359 while (*end == '\r' || *end == '\n')
360 end++;
361
362 *data = end;
363
364 return g_strndup (start, end - start);
365 }
366
367 static GSList *
parse_and_create_certificate_list(const gchar * data,gsize data_len,GError ** error)368 parse_and_create_certificate_list (const gchar *data,
369 gsize data_len,
370 GError **error)
371 {
372 GSList *first_pem_list = NULL, *pem_list = NULL;
373 gchar *first_pem;
374 const gchar *p, *end;
375
376 p = data;
377 end = p + data_len;
378
379 /* Make sure we can load, at least, one certificate. */
380 first_pem = parse_next_pem_certificate (&p, end, TRUE, error);
381 if (!first_pem)
382 return NULL;
383
384 /* Create a list with a single element. If we load more certificates
385 * below, we will concatenate the two lists at the end. */
386 first_pem_list = g_slist_prepend (first_pem_list, first_pem);
387
388 /* If we read one certificate successfully, let's see if we can read
389 * some more. If not, we will simply return a list with the first one.
390 */
391 while (p && *p)
392 {
393 gchar *cert_pem;
394 GError *error = NULL;
395
396 cert_pem = parse_next_pem_certificate (&p, end, FALSE, &error);
397 if (error)
398 {
399 g_slist_free_full (pem_list, g_free);
400 g_error_free (error);
401 return first_pem_list;
402 }
403 else if (!cert_pem)
404 {
405 break;
406 }
407
408 pem_list = g_slist_prepend (pem_list, cert_pem);
409 }
410
411 pem_list = g_slist_concat (pem_list, first_pem_list);
412
413 return pem_list;
414 }
415
416 static GTlsCertificate *
create_certificate_chain_from_list(GSList * pem_list,const gchar * key_pem)417 create_certificate_chain_from_list (GSList *pem_list,
418 const gchar *key_pem)
419 {
420 GTlsCertificate *cert = NULL, *issuer = NULL, *root = NULL;
421 GTlsCertificateFlags flags;
422 GSList *pem;
423
424 pem = pem_list;
425 while (pem)
426 {
427 const gchar *key = NULL;
428
429 /* Private key belongs only to the first certificate. */
430 if (!pem->next)
431 key = key_pem;
432
433 /* We assume that the whole file is a certificate chain, so we use
434 * each certificate as the issuer of the next one (list is in
435 * reverse order).
436 */
437 issuer = cert;
438 cert = g_tls_certificate_new_internal (pem->data, key, issuer, NULL);
439 if (issuer)
440 g_object_unref (issuer);
441
442 if (!cert)
443 return NULL;
444
445 /* root will point to the last certificate in the file. */
446 if (!root)
447 root = cert;
448
449 pem = g_slist_next (pem);
450 }
451
452 /* Verify that the certificates form a chain. (We don't care at this
453 * point if there are other problems with it.)
454 */
455 flags = g_tls_certificate_verify (cert, NULL, root);
456 if (flags & G_TLS_CERTIFICATE_UNKNOWN_CA)
457 {
458 /* It wasn't a chain, it's just a bunch of unrelated certs. */
459 g_clear_object (&cert);
460 }
461
462 return cert;
463 }
464
465 static GTlsCertificate *
parse_and_create_certificate(const gchar * data,gsize data_len,const gchar * key_pem,GError ** error)466 parse_and_create_certificate (const gchar *data,
467 gsize data_len,
468 const gchar *key_pem,
469 GError **error)
470
471 {
472 GSList *pem_list;
473 GTlsCertificate *cert;
474
475 pem_list = parse_and_create_certificate_list (data, data_len, error);
476 if (!pem_list)
477 return NULL;
478
479 /* We don't pass the error here because, if it fails, we still want to
480 * load and return the first certificate.
481 */
482 cert = create_certificate_chain_from_list (pem_list, key_pem);
483 if (!cert)
484 {
485 GSList *last = NULL;
486
487 /* Get the first certificate (which is the last one as the list is
488 * in reverse order).
489 */
490 last = g_slist_last (pem_list);
491
492 cert = g_tls_certificate_new_internal (last->data, key_pem, NULL, error);
493 }
494
495 g_slist_free_full (pem_list, g_free);
496
497 return cert;
498 }
499
500 /**
501 * g_tls_certificate_new_from_pem:
502 * @data: PEM-encoded certificate data
503 * @length: the length of @data, or -1 if it's 0-terminated.
504 * @error: #GError for error reporting, or %NULL to ignore.
505 *
506 * Creates a #GTlsCertificate from the PEM-encoded data in @data. If
507 * @data includes both a certificate and a private key, then the
508 * returned certificate will include the private key data as well. (See
509 * the #GTlsCertificate:private-key-pem property for information about
510 * supported formats.)
511 *
512 * The returned certificate will be the first certificate found in
513 * @data. As of GLib 2.44, if @data contains more certificates it will
514 * try to load a certificate chain. All certificates will be verified in
515 * the order found (top-level certificate should be the last one in the
516 * file) and the #GTlsCertificate:issuer property of each certificate
517 * will be set accordingly if the verification succeeds. If any
518 * certificate in the chain cannot be verified, the first certificate in
519 * the file will still be returned.
520 *
521 * Returns: the new certificate, or %NULL if @data is invalid
522 *
523 * Since: 2.28
524 */
525 GTlsCertificate *
g_tls_certificate_new_from_pem(const gchar * data,gssize length,GError ** error)526 g_tls_certificate_new_from_pem (const gchar *data,
527 gssize length,
528 GError **error)
529 {
530 GError *child_error = NULL;
531 gchar *key_pem;
532 GTlsCertificate *cert;
533
534 g_return_val_if_fail (data != NULL, NULL);
535 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
536
537 if (length == -1)
538 length = strlen (data);
539
540 key_pem = parse_private_key (data, length, FALSE, &child_error);
541 if (child_error != NULL)
542 {
543 g_propagate_error (error, child_error);
544 return NULL;
545 }
546
547 cert = parse_and_create_certificate (data, length, key_pem, error);
548 g_free (key_pem);
549
550 return cert;
551 }
552
553 /**
554 * g_tls_certificate_new_from_file:
555 * @file: (type filename): file containing a PEM-encoded certificate to import
556 * @error: #GError for error reporting, or %NULL to ignore.
557 *
558 * Creates a #GTlsCertificate from the PEM-encoded data in @file. The
559 * returned certificate will be the first certificate found in @file. As
560 * of GLib 2.44, if @file contains more certificates it will try to load
561 * a certificate chain. All certificates will be verified in the order
562 * found (top-level certificate should be the last one in the file) and
563 * the #GTlsCertificate:issuer property of each certificate will be set
564 * accordingly if the verification succeeds. If any certificate in the
565 * chain cannot be verified, the first certificate in the file will
566 * still be returned.
567 *
568 * If @file cannot be read or parsed, the function will return %NULL and
569 * set @error. Otherwise, this behaves like
570 * g_tls_certificate_new_from_pem().
571 *
572 * Returns: the new certificate, or %NULL on error
573 *
574 * Since: 2.28
575 */
576 GTlsCertificate *
g_tls_certificate_new_from_file(const gchar * file,GError ** error)577 g_tls_certificate_new_from_file (const gchar *file,
578 GError **error)
579 {
580 GTlsCertificate *cert;
581 gchar *contents;
582 gsize length;
583
584 if (!g_file_get_contents (file, &contents, &length, error))
585 return NULL;
586
587 cert = g_tls_certificate_new_from_pem (contents, length, error);
588 g_free (contents);
589 return cert;
590 }
591
592 /**
593 * g_tls_certificate_new_from_files:
594 * @cert_file: (type filename): file containing one or more PEM-encoded
595 * certificates to import
596 * @key_file: (type filename): file containing a PEM-encoded private key
597 * to import
598 * @error: #GError for error reporting, or %NULL to ignore.
599 *
600 * Creates a #GTlsCertificate from the PEM-encoded data in @cert_file
601 * and @key_file. The returned certificate will be the first certificate
602 * found in @cert_file. As of GLib 2.44, if @cert_file contains more
603 * certificates it will try to load a certificate chain. All
604 * certificates will be verified in the order found (top-level
605 * certificate should be the last one in the file) and the
606 * #GTlsCertificate:issuer property of each certificate will be set
607 * accordingly if the verification succeeds. If any certificate in the
608 * chain cannot be verified, the first certificate in the file will
609 * still be returned.
610 *
611 * If either file cannot be read or parsed, the function will return
612 * %NULL and set @error. Otherwise, this behaves like
613 * g_tls_certificate_new_from_pem().
614 *
615 * Returns: the new certificate, or %NULL on error
616 *
617 * Since: 2.28
618 */
619 GTlsCertificate *
g_tls_certificate_new_from_files(const gchar * cert_file,const gchar * key_file,GError ** error)620 g_tls_certificate_new_from_files (const gchar *cert_file,
621 const gchar *key_file,
622 GError **error)
623 {
624 GTlsCertificate *cert;
625 gchar *cert_data, *key_data;
626 gsize cert_len, key_len;
627 gchar *key_pem;
628
629 if (!g_file_get_contents (key_file, &key_data, &key_len, error))
630 return NULL;
631
632 key_pem = parse_private_key (key_data, key_len, TRUE, error);
633 g_free (key_data);
634 if (!key_pem)
635 return NULL;
636
637 if (!g_file_get_contents (cert_file, &cert_data, &cert_len, error))
638 {
639 g_free (key_pem);
640 return NULL;
641 }
642
643 cert = parse_and_create_certificate (cert_data, cert_len, key_pem, error);
644 g_free (cert_data);
645 g_free (key_pem);
646 return cert;
647 }
648
649 /**
650 * g_tls_certificate_new_from_pkcs11_uris:
651 * @pkcs11_uri: A PKCS \#11 URI
652 * @private_key_pkcs11_uri: (nullable): A PKCS \#11 URI
653 * @error: #GError for error reporting, or %NULL to ignore.
654 *
655 * Creates a #GTlsCertificate from a PKCS \#11 URI.
656 *
657 * An example @pkcs11_uri would be `pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01`
658 *
659 * Where the token’s layout is:
660 *
661 * ```
662 * Object 0:
663 * URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=private%20key;type=private
664 * Type: Private key (RSA-2048)
665 * ID: 01
666 *
667 * Object 1:
668 * URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=Certificate%20for%20Authentication;type=cert
669 * Type: X.509 Certificate (RSA-2048)
670 * ID: 01
671 * ```
672 *
673 * In this case the certificate and private key would both be detected and used as expected.
674 * @pkcs_uri may also just reference an X.509 certificate object and then optionally
675 * @private_key_pkcs11_uri allows using a private key exposed under a different URI.
676 *
677 * Note that the private key is not accessed until usage and may fail or require a PIN later.
678 *
679 * Returns: (transfer full): the new certificate, or %NULL on error
680 *
681 * Since: 2.68
682 */
683 GTlsCertificate *
g_tls_certificate_new_from_pkcs11_uris(const gchar * pkcs11_uri,const gchar * private_key_pkcs11_uri,GError ** error)684 g_tls_certificate_new_from_pkcs11_uris (const gchar *pkcs11_uri,
685 const gchar *private_key_pkcs11_uri,
686 GError **error)
687 {
688 GObject *cert;
689 GTlsBackend *backend;
690
691 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
692 g_return_val_if_fail (pkcs11_uri, NULL);
693
694 backend = g_tls_backend_get_default ();
695
696 cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
697 NULL, error,
698 "pkcs11-uri", pkcs11_uri,
699 "private-key-pkcs11-uri", private_key_pkcs11_uri,
700 NULL);
701
702 if (cert != NULL)
703 {
704 gchar *objects_uri;
705
706 /* Old implementations might not override this property */
707 g_object_get (cert, "pkcs11-uri", &objects_uri, NULL);
708 if (objects_uri == NULL)
709 {
710 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("This GTlsBackend does not support creating PKCS #11 certificates"));
711 g_object_unref (cert);
712 return NULL;
713 }
714 g_free (objects_uri);
715 }
716
717 return G_TLS_CERTIFICATE (cert);
718 }
719
720 /**
721 * g_tls_certificate_list_new_from_file:
722 * @file: (type filename): file containing PEM-encoded certificates to import
723 * @error: #GError for error reporting, or %NULL to ignore.
724 *
725 * Creates one or more #GTlsCertificates from the PEM-encoded
726 * data in @file. If @file cannot be read or parsed, the function will
727 * return %NULL and set @error. If @file does not contain any
728 * PEM-encoded certificates, this will return an empty list and not
729 * set @error.
730 *
731 * Returns: (element-type Gio.TlsCertificate) (transfer full): a
732 * #GList containing #GTlsCertificate objects. You must free the list
733 * and its contents when you are done with it.
734 *
735 * Since: 2.28
736 */
737 GList *
g_tls_certificate_list_new_from_file(const gchar * file,GError ** error)738 g_tls_certificate_list_new_from_file (const gchar *file,
739 GError **error)
740 {
741 GQueue queue = G_QUEUE_INIT;
742 gchar *contents, *end;
743 const gchar *p;
744 gsize length;
745
746 if (!g_file_get_contents (file, &contents, &length, error))
747 return NULL;
748
749 end = contents + length;
750 p = contents;
751 while (p && *p)
752 {
753 gchar *cert_pem;
754 GTlsCertificate *cert = NULL;
755 GError *parse_error = NULL;
756
757 cert_pem = parse_next_pem_certificate (&p, end, FALSE, &parse_error);
758 if (cert_pem)
759 {
760 cert = g_tls_certificate_new_internal (cert_pem, NULL, NULL, &parse_error);
761 g_free (cert_pem);
762 }
763 if (!cert)
764 {
765 if (parse_error)
766 {
767 g_propagate_error (error, parse_error);
768 g_list_free_full (queue.head, g_object_unref);
769 queue.head = NULL;
770 }
771 break;
772 }
773 g_queue_push_tail (&queue, cert);
774 }
775
776 g_free (contents);
777 return queue.head;
778 }
779
780
781 /**
782 * g_tls_certificate_get_issuer:
783 * @cert: a #GTlsCertificate
784 *
785 * Gets the #GTlsCertificate representing @cert's issuer, if known
786 *
787 * Returns: (nullable) (transfer none): The certificate of @cert's issuer,
788 * or %NULL if @cert is self-signed or signed with an unknown
789 * certificate.
790 *
791 * Since: 2.28
792 */
793 GTlsCertificate *
g_tls_certificate_get_issuer(GTlsCertificate * cert)794 g_tls_certificate_get_issuer (GTlsCertificate *cert)
795 {
796 GTlsCertificate *issuer;
797
798 g_object_get (G_OBJECT (cert), "issuer", &issuer, NULL);
799 if (issuer)
800 g_object_unref (issuer);
801
802 return issuer;
803 }
804
805 /**
806 * g_tls_certificate_verify:
807 * @cert: a #GTlsCertificate
808 * @identity: (nullable): the expected peer identity
809 * @trusted_ca: (nullable): the certificate of a trusted authority
810 *
811 * This verifies @cert and returns a set of #GTlsCertificateFlags
812 * indicating any problems found with it. This can be used to verify a
813 * certificate outside the context of making a connection, or to
814 * check a certificate against a CA that is not part of the system
815 * CA database.
816 *
817 * If @identity is not %NULL, @cert's name(s) will be compared against
818 * it, and %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the return
819 * value if it does not match. If @identity is %NULL, that bit will
820 * never be set in the return value.
821 *
822 * If @trusted_ca is not %NULL, then @cert (or one of the certificates
823 * in its chain) must be signed by it, or else
824 * %G_TLS_CERTIFICATE_UNKNOWN_CA will be set in the return value. If
825 * @trusted_ca is %NULL, that bit will never be set in the return
826 * value.
827 *
828 * (All other #GTlsCertificateFlags values will always be set or unset
829 * as appropriate.)
830 *
831 * Returns: the appropriate #GTlsCertificateFlags
832 *
833 * Since: 2.28
834 */
835 GTlsCertificateFlags
g_tls_certificate_verify(GTlsCertificate * cert,GSocketConnectable * identity,GTlsCertificate * trusted_ca)836 g_tls_certificate_verify (GTlsCertificate *cert,
837 GSocketConnectable *identity,
838 GTlsCertificate *trusted_ca)
839 {
840 return G_TLS_CERTIFICATE_GET_CLASS (cert)->verify (cert, identity, trusted_ca);
841 }
842
843 /**
844 * g_tls_certificate_is_same:
845 * @cert_one: first certificate to compare
846 * @cert_two: second certificate to compare
847 *
848 * Check if two #GTlsCertificate objects represent the same certificate.
849 * The raw DER byte data of the two certificates are checked for equality.
850 * This has the effect that two certificates may compare equal even if
851 * their #GTlsCertificate:issuer, #GTlsCertificate:private-key, or
852 * #GTlsCertificate:private-key-pem properties differ.
853 *
854 * Returns: whether the same or not
855 *
856 * Since: 2.34
857 */
858 gboolean
g_tls_certificate_is_same(GTlsCertificate * cert_one,GTlsCertificate * cert_two)859 g_tls_certificate_is_same (GTlsCertificate *cert_one,
860 GTlsCertificate *cert_two)
861 {
862 GByteArray *b1, *b2;
863 gboolean equal;
864
865 g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_one), FALSE);
866 g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_two), FALSE);
867
868 g_object_get (cert_one, "certificate", &b1, NULL);
869 g_object_get (cert_two, "certificate", &b2, NULL);
870
871 equal = (b1->len == b2->len &&
872 memcmp (b1->data, b2->data, b1->len) == 0);
873
874 g_byte_array_unref (b1);
875 g_byte_array_unref (b2);
876
877 return equal;
878 }
879