gtlscertificate: Add support for PKCS #11 backed certificates

This reverts commit d58e5de9e9.
This commit is contained in:
Patrick Griffis
2020-09-25 12:40:14 -07:00
committed by Philip Withnall
parent 42961e819d
commit f9fc29f0b7
5 changed files with 195 additions and 4 deletions

View File

@@ -60,7 +60,9 @@ enum
PROP_CERTIFICATE_PEM,
PROP_PRIVATE_KEY,
PROP_PRIVATE_KEY_PEM,
PROP_ISSUER
PROP_ISSUER,
PROP_PKCS11_URI,
PROP_PRIVATE_KEY_PKCS11_URI,
};
static void
@@ -74,7 +76,16 @@ g_tls_certificate_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
switch (prop_id)
{
case PROP_PKCS11_URI:
case PROP_PRIVATE_KEY_PKCS11_URI:
/* Subclasses must override this property but this allows older backends to not fatally error */
g_value_set_static_string (value, NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
@@ -83,7 +94,15 @@ g_tls_certificate_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
switch (prop_id)
{
case PROP_PKCS11_URI:
case PROP_PRIVATE_KEY_PKCS11_URI:
/* Subclasses must override this property but this allows older backends to not fatally error */
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
@@ -193,6 +212,42 @@ g_tls_certificate_class_init (GTlsCertificateClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* GTlsCertificate:pkcs11-uri: (nullable)
*
* A URI referencing the PKCS \#11 objects containing an X.509 certificate
* and optionally a private key.
*
* If %NULL the certificate is either not backed by PKCS \#11 or the
* #GTlsBackend does not support PKCS \#11.
*
* Since: 2.68
*/
g_object_class_install_property (gobject_class, PROP_PKCS11_URI,
g_param_spec_string ("pkcs11-uri",
P_("PKCS #11 URI"),
P_("The PKCS #11 URI"),
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* GTlsCertificate:private-key-pkcs11-uri: (nullable)
*
* A URI referencing a PKCS \#11 object containing a private key.
*
* Since: 2.68
*/
g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY_PKCS11_URI,
g_param_spec_string ("private-key-pkcs11-uri",
P_("PKCS #11 URI"),
P_("The PKCS #11 URI for a private key"),
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}
static GTlsCertificate *
@@ -591,6 +646,77 @@ g_tls_certificate_new_from_files (const gchar *cert_file,
return cert;
}
/**
* g_tls_certificate_new_from_pkcs11_uris:
* @pkcs11_uri: A PKCS \#11 URI
* @private_key_pkcs11_uri: (nullable): A PKCS \#11 URI
* @error: #GError for error reporting, or %NULL to ignore.
*
* Creates a #GTlsCertificate from a PKCS \#11 URI.
*
* An example @pkcs11_uri would be `pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01`
*
* Where the tokens layout is:
*
* ```
* Object 0:
* URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=private%20key;type=private
* Type: Private key (RSA-2048)
* ID: 01
*
* Object 1:
* URL: pkcs11:model=Model;manufacturer=Manufacture;serial=1;token=My%20Client%20Certificate;id=%01;object=Certificate%20for%20Authentication;type=cert
* Type: X.509 Certificate (RSA-2048)
* ID: 01
* ```
*
* In this case the certificate and private key would both be detected and used as expected.
* @pkcs_uri may also just reference an X.509 certificate object and then optionally
* @private_key_pkcs11_uri allows using a private key exposed under a different URI.
*
* Note that the private key is not accessed until usage and may fail or require a PIN later.
*
* Returns: (transfer full): the new certificate, or %NULL on error
*
* Since: 2.68
*/
GTlsCertificate *
g_tls_certificate_new_from_pkcs11_uris (const gchar *pkcs11_uri,
const gchar *private_key_pkcs11_uri,
GError **error)
{
GObject *cert;
GTlsBackend *backend;
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
g_return_val_if_fail (pkcs11_uri, NULL);
backend = g_tls_backend_get_default ();
cert = g_initable_new (g_tls_backend_get_certificate_type (backend),
NULL, error,
"pkcs11-uri", pkcs11_uri,
"private-key-pkcs11-uri", private_key_pkcs11_uri,
NULL);
if (cert != NULL)
{
gchar *objects_uri;
/* Old implementations might not override this property */
g_object_get (cert, "pkcs11-uri", &objects_uri, NULL);
if (objects_uri == NULL)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("This GTlsBackend does not support creating PKCS #11 certificates"));
g_object_unref (cert);
return NULL;
}
g_free (objects_uri);
}
return G_TLS_CERTIFICATE (cert);
}
/**
* g_tls_certificate_list_new_from_file:
* @file: (type filename): file containing PEM-encoded certificates to import