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