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", ¬_valid_before, NULL);
1178 : :
1179 : 1 : return g_steal_pointer (¬_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", ¬_valid_after, NULL);
1200 : :
1201 : 1 : return g_steal_pointer (¬_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 : : }
|