GMenuModel: remove a type safety bug
[platform/upstream/glib.git] / gio / gtlscertificate.c
1 /* GIO - GLib Input, Output and Certificateing Library
2  *
3  * Copyright (C) 2010 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
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  * @see_also: #GTlsConnection
36  *
37  * A certificate used for TLS authentication and encryption.
38  * This can represent either a certificate only (eg, the certificate
39  * received by a client from a server), or the combination of
40  * a certificate and a private key (which is needed when acting as a
41  * #GTlsServerConnection).
42  *
43  * Since: 2.28
44  */
45
46 /**
47  * GTlsCertificate:
48  *
49  * Abstract base class for TLS certificate types.
50  *
51  * Since: 2.28
52  */
53
54 G_DEFINE_ABSTRACT_TYPE (GTlsCertificate, g_tls_certificate, G_TYPE_OBJECT);
55
56 enum
57 {
58   PROP_0,
59
60   PROP_CERTIFICATE,
61   PROP_CERTIFICATE_BYTES,
62   PROP_CERTIFICATE_PEM,
63   PROP_PRIVATE_KEY,
64   PROP_PRIVATE_KEY_BYTES,
65   PROP_PRIVATE_KEY_PEM,
66   PROP_ISSUER
67 };
68
69 static void
70 g_tls_certificate_init (GTlsCertificate *cert)
71 {
72 }
73
74 static void
75 g_tls_certificate_get_property (GObject    *object,
76                                 guint       prop_id,
77                                 GValue     *value,
78                                 GParamSpec *pspec)
79 {
80   G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
81 }
82
83 static void
84 g_tls_certificate_set_property (GObject      *object,
85                                 guint         prop_id,
86                                 const GValue *value,
87                                 GParamSpec   *pspec)
88 {
89   G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
90 }
91
92 static void
93 g_tls_certificate_class_init (GTlsCertificateClass *class)
94 {
95   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
96
97   gobject_class->set_property = g_tls_certificate_set_property;
98   gobject_class->get_property = g_tls_certificate_get_property;
99
100   /**
101    * GTlsCertificate:certificate:
102    *
103    * The DER (binary) encoded representation of the certificate.
104    * This property and the #GTlsCertificate:certificate-bytes contain
105    * the same data. The #GTlsCertificate:certificate-pem property
106    * represents the same data, just in different forms.
107    *
108    * Since: 2.28
109    */
110   g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
111                                    g_param_spec_boxed ("certificate",
112                                                        P_("Certificate"),
113                                                        P_("The DER representation of the certificate"),
114                                                        G_TYPE_BYTE_ARRAY,
115                                                        G_PARAM_READWRITE |
116                                                        G_PARAM_CONSTRUCT_ONLY |
117                                                        G_PARAM_STATIC_STRINGS));
118   /**
119    * GTlsCertificate:certificate-bytes:
120    *
121    * The DER (binary) encoded representation of the certificate as
122    * a #GBytes. The #GTlsCertificate:certificate property contains
123    * the same data. The #GTlsCertificate:certificate-pem property
124    * contains the same data as this property in a different form.
125    *
126    * Since: 2.34
127    */
128   g_object_class_install_property (gobject_class, PROP_CERTIFICATE_BYTES,
129                                    g_param_spec_boxed ("certificate-bytes",
130                                                        P_("Certificate Bytes"),
131                                                        P_("The DER representation of the certificate"),
132                                                        G_TYPE_BYTES,
133                                                        G_PARAM_READWRITE |
134                                                        G_PARAM_CONSTRUCT_ONLY |
135                                                        G_PARAM_STATIC_STRINGS));
136   /**
137    * GTlsCertificate:certificate-pem:
138    *
139    * The PEM (ASCII) encoded representation of the certificate.
140    * The #GTlsCertificate:certificate and #GTlsCertificate:certificate-bytes
141    * properties represent the same data, just in a different form.
142    *
143    * Since: 2.28
144    */
145   g_object_class_install_property (gobject_class, PROP_CERTIFICATE_PEM,
146                                    g_param_spec_string ("certificate-pem",
147                                                         P_("Certificate (PEM)"),
148                                                         P_("The PEM representation of the certificate"),
149                                                         NULL,
150                                                         G_PARAM_READWRITE |
151                                                         G_PARAM_CONSTRUCT_ONLY |
152                                                         G_PARAM_STATIC_STRINGS));
153   /**
154    * GTlsCertificate:private-key:
155    *
156    * The DER (binary) encoded representation of the certificate's
157    * private key, in either PKCS#1 format or unencrypted PKCS#8
158    * format. This property (or the #GTlsCertificate:private-key-pem
159    * property) can be set when constructing a key (eg, from a file),
160    * but cannot be read.
161    *
162    * PKCS#8 format is supported since 2.32; earlier releases only
163    * support PKCS#1. You can use the <literal>openssl rsa</literal>
164    * tool to convert PKCS#8 keys to PKCS#1.
165    *
166    * Since: 2.28
167    */
168   g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY,
169                                    g_param_spec_boxed ("private-key",
170                                                        P_("Private key"),
171                                                        P_("The DER representation of the certificate's private key"),
172                                                        G_TYPE_BYTE_ARRAY,
173                                                        G_PARAM_WRITABLE |
174                                                        G_PARAM_CONSTRUCT_ONLY |
175                                                        G_PARAM_STATIC_STRINGS));
176   /**
177    * GTlsCertificate:private-key-bytes:
178    *
179    * The DER (binary) encoded representation of the certificate's
180    * private key. This property and the #GtlsCertificate:private-key
181    * property contain the same data.
182    *
183    * Since: 2.34
184    */
185   g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_BYTES,
186                                    g_param_spec_boxed ("private-key-bytes",
187                                                        P_("Private key bytes"),
188                                                        P_("The DER representation of the certificate's private key"),
189                                                        G_TYPE_BYTES,
190                                                        G_PARAM_WRITABLE |
191                                                        G_PARAM_CONSTRUCT_ONLY |
192                                                        G_PARAM_STATIC_STRINGS));
193   /**
194    * GTlsCertificate:private-key-pem:
195    *
196    * The PEM (ASCII) encoded representation of the certificate's
197    * private key in either PKCS#1 format ("<literal>BEGIN RSA PRIVATE
198    * KEY</literal>") or unencrypted PKCS#8 format ("<literal>BEGIN
199    * PRIVATE KEY</literal>"). This property (or the
200    * #GTlsCertificate:private-key property) can be set when
201    * constructing a key (eg, from a file), but cannot be read.
202    *
203    * PKCS#8 format is supported since 2.32; earlier releases only
204    * support PKCS#1. You can use the <literal>openssl rsa</literal>
205    * tool to convert PKCS#8 keys to PKCS#1.
206    *
207    * Since: 2.28
208    */
209   g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PEM,
210                                    g_param_spec_string ("private-key-pem",
211                                                         P_("Private key (PEM)"),
212                                                         P_("The PEM representation of the certificate's private key"),
213                                                         NULL,
214                                                         G_PARAM_WRITABLE |
215                                                         G_PARAM_CONSTRUCT_ONLY |
216                                                         G_PARAM_STATIC_STRINGS));
217   /**
218    * GTlsCertificate:issuer:
219    *
220    * A #GTlsCertificate representing the entity that issued this
221    * certificate. If %NULL, this means that the certificate is either
222    * self-signed, or else the certificate of the issuer is not
223    * available.
224    *
225    * Since: 2.28
226    */
227   g_object_class_install_property (gobject_class, PROP_ISSUER,
228                                    g_param_spec_object ("issuer",
229                                                         P_("Issuer"),
230                                                         P_("The certificate for the issuing entity"),
231                                                         G_TYPE_TLS_CERTIFICATE,
232                                                         G_PARAM_READWRITE |
233                                                         G_PARAM_CONSTRUCT_ONLY |
234                                                         G_PARAM_STATIC_STRINGS));
235 }
236
237 static GTlsCertificate *
238 g_tls_certificate_new_internal (const gchar  *certificate_pem,
239                                 const gchar  *private_key_pem,
240                                 GError      **error)
241 {
242   GObject *cert;
243   GTlsBackend *backend;
244
245   backend = g_tls_backend_get_default ();
246
247   cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
248                          NULL, error,
249                          "certificate-pem", certificate_pem,
250                          "private-key-pem", private_key_pem,
251                          NULL);
252   return G_TLS_CERTIFICATE (cert);
253 }
254
255 #define PEM_CERTIFICATE_HEADER     "-----BEGIN CERTIFICATE-----"
256 #define PEM_CERTIFICATE_FOOTER     "-----END CERTIFICATE-----"
257 #define PEM_PKCS1_PRIVKEY_HEADER   "-----BEGIN RSA PRIVATE KEY-----"
258 #define PEM_PKCS1_PRIVKEY_FOOTER   "-----END RSA PRIVATE KEY-----"
259 #define PEM_PKCS8_PRIVKEY_HEADER   "-----BEGIN PRIVATE KEY-----"
260 #define PEM_PKCS8_PRIVKEY_FOOTER   "-----END PRIVATE KEY-----"
261 #define PEM_PKCS8_ENCRYPTED_HEADER "-----BEGIN ENCRYPTED PRIVATE KEY-----"
262 #define PEM_PKCS8_ENCRYPTED_FOOTER "-----END ENCRYPTED PRIVATE KEY-----"
263
264 static gchar *
265 parse_private_key (const gchar *data,
266                    gsize data_len,
267                    gboolean required,
268                    GError **error)
269 {
270   const gchar *start, *end, *footer;
271
272   start = g_strstr_len (data, data_len, PEM_PKCS1_PRIVKEY_HEADER);
273   if (start)
274     footer = PEM_PKCS1_PRIVKEY_FOOTER;
275   else
276     {
277       start = g_strstr_len (data, data_len, PEM_PKCS8_PRIVKEY_HEADER);
278       if (start)
279         footer = PEM_PKCS8_PRIVKEY_FOOTER;
280       else
281         {
282           start = g_strstr_len (data, data_len, PEM_PKCS8_ENCRYPTED_HEADER);
283           if (start)
284             {
285               g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
286                                    _("Cannot decrypt PEM-encoded private key"));
287             }
288           else if (required)
289             {
290               g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
291                                    _("No PEM-encoded private key found"));
292             }
293           return NULL;
294         }
295     }
296
297   end = g_strstr_len (start, data_len - (data - start), footer);
298   if (!end)
299     {
300       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
301                            _("Could not parse PEM-encoded private key"));
302       return NULL;
303     }
304   end += strlen (footer);
305   while (*end == '\r' || *end == '\n')
306     end++;
307
308   return g_strndup (start, end - start);
309 }
310
311
312 static gchar *
313 parse_next_pem_certificate (const gchar **data,
314                             const gchar  *data_end,
315                             gboolean      required,
316                             GError      **error)
317 {
318   const gchar *start, *end;
319
320   start = g_strstr_len (*data, data_end - *data, PEM_CERTIFICATE_HEADER);
321   if (!start)
322     {
323       if (required)
324         {
325           g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
326                                _("No PEM-encoded certificate found"));
327         }
328       return NULL;
329     }
330
331   end = g_strstr_len (start, data_end - start, PEM_CERTIFICATE_FOOTER);
332   if (!end)
333     {
334       g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
335                            _("Could not parse PEM-encoded certificate"));
336       return NULL;
337     }
338   end += strlen (PEM_CERTIFICATE_FOOTER);
339   while (*end == '\r' || *end == '\n')
340     end++;
341
342   *data = end;
343
344   return g_strndup (start, end - start);
345 }
346
347 /**
348  * g_tls_certificate_new_from_pem:
349  * @data: PEM-encoded certificate data
350  * @length: the length of @data, or -1 if it's 0-terminated.
351  * @error: #GError for error reporting, or %NULL to ignore.
352  *
353  * Creates a new #GTlsCertificate from the PEM-encoded data in @data.
354  * If @data includes both a certificate and a private key, then the
355  * returned certificate will include the private key data as well. (See
356  * the #GTlsCertificate:private-key-pem property for information about
357  * supported formats.)
358  *
359  * If @data includes multiple certificates, only the first one will be
360  * parsed.
361  *
362  * Return value: the new certificate, or %NULL if @data is invalid
363  *
364  * Since: 2.28
365  */
366 GTlsCertificate *
367 g_tls_certificate_new_from_pem  (const gchar  *data,
368                                  gssize        length,
369                                  GError      **error)
370 {
371   const gchar *data_end;
372   gchar *key_pem, *cert_pem;
373   GTlsCertificate *cert;
374
375   g_return_val_if_fail (data != NULL, NULL);
376
377   if (length == -1)
378     length = strlen (data);
379
380   data_end = data + length;
381
382   key_pem = parse_private_key (data, length, FALSE, error);
383   if (error && *error)
384     return NULL;
385
386   cert_pem = parse_next_pem_certificate (&data, data_end, TRUE, error);
387   if (error && *error)
388     {
389       g_free (key_pem);
390       return NULL;
391     }
392
393   cert = g_tls_certificate_new_internal (cert_pem, key_pem, error);
394   g_free (key_pem);
395   g_free (cert_pem);
396
397   return cert;
398 }
399
400 /**
401  * g_tls_certificate_new_from_file:
402  * @file: file containing a PEM-encoded certificate to import
403  * @error: #GError for error reporting, or %NULL to ignore.
404  *
405  * Creates a #GTlsCertificate from the PEM-encoded data in @file. If
406  * @file cannot be read or parsed, the function will return %NULL and
407  * set @error. Otherwise, this behaves like
408  * g_tls_certificate_new_from_pem().
409  *
410  * Return value: the new certificate, or %NULL on error
411  *
412  * Since: 2.28
413  */
414 GTlsCertificate *
415 g_tls_certificate_new_from_file (const gchar  *file,
416                                  GError      **error)
417 {
418   GTlsCertificate *cert;
419   gchar *contents;
420   gsize length;
421
422   if (!g_file_get_contents (file, &contents, &length, error))
423     return NULL;
424
425   cert = g_tls_certificate_new_from_pem (contents, length, error);
426   g_free (contents);
427   return cert;
428 }
429
430 /**
431  * g_tls_certificate_new_from_files:
432  * @cert_file: file containing a PEM-encoded certificate to import
433  * @key_file: file containing a PEM-encoded private key to import
434  * @error: #GError for error reporting, or %NULL to ignore.
435  *
436  * Creates a #GTlsCertificate from the PEM-encoded data in @cert_file
437  * and @key_file. If either file cannot be read or parsed, the
438  * function will return %NULL and set @error. Otherwise, this behaves
439  * like g_tls_certificate_new_from_pem().
440  *
441  * Return value: the new certificate, or %NULL on error
442  *
443  * Since: 2.28
444  */
445 GTlsCertificate *
446 g_tls_certificate_new_from_files (const gchar  *cert_file,
447                                   const gchar  *key_file,
448                                   GError      **error)
449 {
450   GTlsCertificate *cert;
451   gchar *cert_data, *key_data;
452   gsize cert_len, key_len;
453   gchar *cert_pem, *key_pem;
454   const gchar *p;
455
456   if (!g_file_get_contents (cert_file, &cert_data, &cert_len, error))
457     return NULL;
458   p = cert_data;
459   cert_pem = parse_next_pem_certificate (&p, p + cert_len, TRUE, error);
460   g_free (cert_data);
461   if (error && *error)
462     return NULL;
463
464   if (!g_file_get_contents (key_file, &key_data, &key_len, error))
465     {
466       g_free (cert_pem);
467       return NULL;
468     }
469   key_pem = parse_private_key (key_data, key_len, TRUE, error);
470   g_free (key_data);
471   if (error && *error)
472     {
473       g_free (cert_pem);
474       return NULL;
475     }
476
477   cert = g_tls_certificate_new_internal (cert_pem, key_pem, error);
478   g_free (cert_pem);
479   g_free (key_pem);
480   return cert;
481 }
482
483 /**
484  * g_tls_certificate_list_new_from_file:
485  * @file: file containing PEM-encoded certificates to import
486  * @error: #GError for error reporting, or %NULL to ignore.
487  *
488  * Creates one or more #GTlsCertificate<!-- -->s from the PEM-encoded
489  * data in @file. If @file cannot be read or parsed, the function will
490  * return %NULL and set @error. If @file does not contain any
491  * PEM-encoded certificates, this will return an empty list and not
492  * set @error.
493  *
494  * Return value: (element-type Gio.TlsCertificate) (transfer full): a
495  * #GList containing #GTlsCertificate objects. You must free the list
496  * and its contents when you are done with it.
497  *
498  * Since: 2.28
499  */
500 GList *
501 g_tls_certificate_list_new_from_file (const gchar  *file,
502                                       GError      **error)
503 {
504   GQueue queue = G_QUEUE_INIT;
505   gchar *contents, *end;
506   const gchar *p;
507   gsize length;
508
509   if (!g_file_get_contents (file, &contents, &length, error))
510     return NULL;
511
512   end = contents + length;
513   p = contents;
514   while (p && *p)
515     {
516       gchar *cert_pem;
517       GTlsCertificate *cert = NULL;
518
519       cert_pem = parse_next_pem_certificate (&p, end, FALSE, error);
520       if (cert_pem)
521         {
522           cert = g_tls_certificate_new_internal (cert_pem, NULL, error);
523           g_free (cert_pem);
524         }
525       if (!cert)
526         {
527           g_list_free_full (queue.head, g_object_unref);
528           queue.head = NULL;
529           break;
530         }
531       g_queue_push_tail (&queue, cert);
532     }
533
534   g_free (contents);
535   return queue.head;
536 }
537
538
539 /**
540  * g_tls_certificate_get_issuer:
541  * @cert: a #GTlsCertificate
542  *
543  * Gets the #GTlsCertificate representing @cert's issuer, if known
544  *
545  * Return value: (transfer none): The certificate of @cert's issuer,
546  * or %NULL if @cert is self-signed or signed with an unknown
547  * certificate.
548  *
549  * Since: 2.28
550  */
551 GTlsCertificate *
552 g_tls_certificate_get_issuer (GTlsCertificate  *cert)
553 {
554   GTlsCertificate *issuer;
555
556   g_object_get (G_OBJECT (cert), "issuer", &issuer, NULL);
557   if (issuer)
558     g_object_unref (issuer);
559
560   return issuer;
561 }
562
563 /**
564  * g_tls_certificate_verify:
565  * @cert: a #GTlsCertificate
566  * @identity: (allow-none): the expected peer identity
567  * @trusted_ca: (allow-none): the certificate of a trusted authority
568  *
569  * This verifies @cert and returns a set of #GTlsCertificateFlags
570  * indicating any problems found with it. This can be used to verify a
571  * certificate outside the context of making a connection, or to
572  * check a certificate against a CA that is not part of the system
573  * CA database.
574  *
575  * If @identity is not %NULL, @cert's name(s) will be compared against
576  * it, and %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the return
577  * value if it does not match. If @identity is %NULL, that bit will
578  * never be set in the return value.
579  *
580  * If @trusted_ca is not %NULL, then @cert (or one of the certificates
581  * in its chain) must be signed by it, or else
582  * %G_TLS_CERTIFICATE_UNKNOWN_CA will be set in the return value. If
583  * @trusted_ca is %NULL, that bit will never be set in the return
584  * value.
585  *
586  * (All other #GTlsCertificateFlags values will always be set or unset
587  * as appropriate.)
588  *
589  * Return value: the appropriate #GTlsCertificateFlags
590  *
591  * Since: 2.28
592  */
593 GTlsCertificateFlags
594 g_tls_certificate_verify (GTlsCertificate     *cert,
595                           GSocketConnectable  *identity,
596                           GTlsCertificate     *trusted_ca)
597 {
598   return G_TLS_CERTIFICATE_GET_CLASS (cert)->verify (cert, identity, trusted_ca);
599 }
600
601 /**
602  * g_tls_certificate_is_same:
603  * @cert_one: first certificate to compare
604  * @cert_two: second certificate to compare
605  *
606  * Check if two #GTlsCertificate objects represent the same certificate.
607  * The raw DER byte data of the two certificates are checked for equality.
608  * This has the effect that two certificates may compare equal even if
609  * their #GTlsCertificate:issuer, #GTlsCertificate:private-key, or
610  * #GTlsCertificate:private-key-pem properties differ.
611  *
612  * Return value: whether the same or not
613  *
614  * Since: 2.34
615  */
616 gboolean
617 g_tls_certificate_is_same (GTlsCertificate     *cert_one,
618                            GTlsCertificate     *cert_two)
619 {
620   GBytes *b1, *b2;
621   gboolean equal;
622
623   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_one), FALSE);
624   g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert_two), FALSE);
625
626   g_object_get (cert_one, "certificate-bytes", &b1, NULL);
627   g_object_get (cert_two, "certificate-bytes", &b2, NULL);
628
629   equal = g_bytes_equal (b1, b2);
630
631   g_bytes_unref (b1);
632   g_bytes_unref (b2);
633
634   return equal;
635 }