[glib/mcatanzaro/readable-private-key] gtlscertificate: make private key properties readable




commit 24e9a03e8dbde3f21de7d0f8dbc5636e688a4075
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Thu May 6 12:04:29 2021 -0500

    gtlscertificate: make private key properties readable
    
    WebKit wants these private key properties to be readable in order to
    implement a deserialization function. Currently they are read-only
    because at the time GTlsCertificate was originally designed, the plan
    was to support PKCS#11-backed private keys: private keys that are stored
    on a smartcard, where the private key is completely unreadable. The
    design goal was to support both memory-backed and smartcard-backed
    private keys with the same GTlsCertificate API, abstracting away the
    implementation differences such that code using GTlsCertificate doesn't
    need to know the difference.
    
    The original PKCS#11 implementation was never fully baked and at some
    point in the past I deleted it all. It has since been replaced with a
    new implementation, including a GTlsCertificate:private-key-pkcs11-uri
    property, which is readable. So our current API already exposes the
    differences between normal private keys and PKCS#11-backed private keys.
    The point of making the private-key and private-key-pem properties
    write-only was to avoid exposing this difference.
    
    Do we have to make this API function readable? No, because WebKit could
    be just as well served if we were to expose serialize and deserialize
    functions instead. But WebKit needs to support serializing and
    deserializing the non-private portion of GTlsCertificate with older
    versions of GLib anyway, so we can do whatever is nicest for GLib. And I
    think making this property readable is nicest, since the original design
    reason for it to not be readable is now obsolete. The disadvantage to
    this approach is that it's now possible for an application to read the
    private-key or private-key-pem property, receive NULL, and think "this
    certificate must not have a private key," which would be incorrect if
    the private-key-pkcs11-uri property is set. That seems like a minor
    risk, but it should be documented.

 gio/gtlscertificate.c | 50 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 34 insertions(+), 16 deletions(-)
---
diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c
index ae9e88016..336ba001f 100644
--- a/gio/gtlscertificate.c
+++ b/gio/gtlscertificate.c
@@ -78,6 +78,8 @@ g_tls_certificate_get_property (GObject    *object,
 {
   switch (prop_id)
     {
+    case PROP_PRIVATE_KEY:
+    case PROP_PRIVATE_KEY_PEM:
     case PROP_PKCS11_URI:
     case PROP_PRIVATE_KEY_PKCS11_URI:
       /* Subclasses must override this property but this allows older backends to not fatally error */
@@ -148,17 +150,25 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));
   /**
-   * GTlsCertificate:private-key:
+   * GTlsCertificate:private-key: (nullable)
    *
    * The DER (binary) encoded representation of the certificate's
    * private key, in either PKCS#1 format or unencrypted PKCS#8
-   * format. This property (or the #GTlsCertificate:private-key-pem
-   * property) can be set when constructing a key (eg, from a file),
-   * but cannot be read.
+   * format. PKCS#8 format is supported since 2.32; earlier releases
+   * only support PKCS#1. You can use the `openssl rsa` tool to convert
+   * PKCS#8 keys to PKCS#1.
    *
-   * PKCS#8 format is supported since 2.32; earlier releases only
-   * support PKCS#1. You can use the `openssl rsa`
-   * tool to convert PKCS#8 keys to PKCS#1.
+   * This property (or the #GTlsCertificate:private-key-pem property)
+   * can be set when constructing a key (e.g., from a file). Since
+   * GLib 2.70, it is now also readable; however, be aware that if the
+   * private key is backed by a PKCS#11 URI -- for example, if it is
+   * stored on a smartcard -- then this property will be %NULL. If so,
+   * the private key must be referenced via its PKCS#11 URI,
+   * GTlsCertificate:private-key-pkcs11-uri. You must check both
+   * properties to see if the certificate really has a private key.
+   *
+   * When this property is read, the output format will be unencrypted
+   * PKCS#8.
    *
    * Since: 2.28
    */
@@ -167,23 +177,31 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
                                                       P_("Private key"),
                                                       P_("The DER representation of the certificate’s 
private key"),
                                                       G_TYPE_BYTE_ARRAY,
-                                                      G_PARAM_WRITABLE |
+                                                      G_PARAM_READWRITE |
                                                       G_PARAM_CONSTRUCT_ONLY |
                                                       G_PARAM_STATIC_STRINGS));
   /**
-   * GTlsCertificate:private-key-pem:
+   * GTlsCertificate:private-key-pem: (nullable)
    *
    * The PEM (ASCII) encoded representation of the certificate's
    * private key in either PKCS#1 format ("`BEGIN RSA PRIVATE
    * KEY`") or unencrypted PKCS#8 format ("`BEGIN
-   * PRIVATE KEY`"). This property (or the
-   * #GTlsCertificate:private-key property) can be set when
-   * constructing a key (eg, from a file), but cannot be read.
-   *
-   * PKCS#8 format is supported since 2.32; earlier releases only
-   * support PKCS#1. You can use the `openssl rsa`
+   * PRIVATE KEY`"). PKCS#8 format is supported since 2.32; earlier
+   * releases only support PKCS#1. You can use the `openssl rsa`
    * tool to convert PKCS#8 keys to PKCS#1.
    *
+   * This property (or the #GTlsCertificate:private-key property)
+   * can be set when constructing a key (e.g., from a file). Since
+   * GLib 2.70, it is now also readable; however, be aware that if the
+   * private key is backed by a PKCS#11 URI -- for example, if it is
+   * stored on a smartcard -- then this property will be %NULL. If so,
+   * the private key must be referenced via its PKCS#11 URI,
+   * GTlsCertificate:private-key-pkcs11-uri. You must check both
+   * properties to see if the certificate really has a private key.
+   *
+   * When this property is read, the output format will be unencrypted
+   * PKCS#8.
+   *
    * Since: 2.28
    */
   g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PEM,
@@ -191,7 +209,7 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
                                                        P_("Private key (PEM)"),
                                                        P_("The PEM representation of the certificate’s 
private key"),
                                                        NULL,
-                                                       G_PARAM_WRITABLE |
+                                                       G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));
   /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]