|
Packit |
b00eeb |
/*
|
|
Packit |
b00eeb |
* gnome-keyring
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Copyright (C) 2010 Collabora Ltd
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
b00eeb |
* it under the terms of the GNU Lesser General Public License as
|
|
Packit |
b00eeb |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
b00eeb |
* the License, or (at your option) any later version.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
b00eeb |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
b00eeb |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
b00eeb |
* Lesser General Public License for more details.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b00eeb |
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Author: Stef Walter <stefw@collabora.co.uk>
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include "config.h"
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include "gcr-pkcs11-certificate.h"
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include "gcr-certificate.h"
|
|
Packit |
b00eeb |
#include "gcr-internal.h"
|
|
Packit |
b00eeb |
#include "gcr-library.h"
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include <gck/gck.h>
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include <string.h>
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* SECTION:gcr-pkcs11-certificate
|
|
Packit |
b00eeb |
* @title: GcrPkcs11Certificate
|
|
Packit |
b00eeb |
* @short_description: A certificate loaded from PKCS\#11 storage
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* A #GcrPkcs11Certificate is a certificate loaded from a PKCS\#11 storage.
|
|
Packit |
b00eeb |
* It is also a valid #GckObject and can be used as such.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Use gcr_pkcs11_certificate_lookup_issuer() to lookup the issuer of a given
|
|
Packit |
b00eeb |
* certificate in the PKCS\#11 store.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Various common PKCS\#11 certificate attributes are automatically loaded and
|
|
Packit |
b00eeb |
* are available via gcr_pkcs11_certificate_get_attributes().
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* GcrPkcs11Certificate:
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* A certificate loaded from PKCS\#11 storage.
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* GcrPkcs11CertificateClass:
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* The class for #GcrPkcs11Certificate.
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
enum {
|
|
Packit |
b00eeb |
PROP_0,
|
|
Packit |
b00eeb |
PROP_ATTRIBUTES
|
|
Packit |
b00eeb |
};
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
struct _GcrPkcs11CertificatePrivate {
|
|
Packit |
b00eeb |
GckAttributes *attrs;
|
|
Packit |
b00eeb |
};
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void gcr_certificate_iface (GcrCertificateIface *iface);
|
|
Packit |
b00eeb |
G_DEFINE_TYPE_WITH_CODE (GcrPkcs11Certificate, gcr_pkcs11_certificate, GCK_TYPE_OBJECT,
|
|
Packit |
b00eeb |
GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
|
|
Packit |
b00eeb |
G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_certificate_iface);
|
|
Packit |
b00eeb |
);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
typedef struct {
|
|
Packit |
b00eeb |
GckAttributes *search;
|
|
Packit |
b00eeb |
GcrCertificate *result;
|
|
Packit |
b00eeb |
} lookup_issuer_closure;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
lookup_issuer_free (gpointer data)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
lookup_issuer_closure *closure = data;
|
|
Packit |
b00eeb |
gck_attributes_unref (closure->search);
|
|
Packit |
b00eeb |
g_clear_object (&closure->result);
|
|
Packit |
b00eeb |
g_free (closure);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static GckAttributes *
|
|
Packit |
b00eeb |
prepare_lookup_certificate_issuer (GcrCertificate *cert)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GckBuilder builder = GCK_BUILDER_INIT;
|
|
Packit |
b00eeb |
gpointer data;
|
|
Packit |
b00eeb |
gsize n_data;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
|
|
Packit |
b00eeb |
gck_builder_add_ulong (&builder, CKA_CERTIFICATE_TYPE, CKC_X_509);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
data = gcr_certificate_get_issuer_raw (cert, &n_data);
|
|
Packit |
b00eeb |
gck_builder_add_data (&builder, CKA_SUBJECT, data, n_data);
|
|
Packit |
b00eeb |
g_free (data);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
return gck_attributes_ref_sink (gck_builder_end (&builder));
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static GcrCertificate*
|
|
Packit |
b00eeb |
perform_lookup_certificate (GckAttributes *search,
|
|
Packit |
b00eeb |
GCancellable *cancellable,
|
|
Packit |
b00eeb |
GError **error)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GcrCertificate *cert;
|
|
Packit |
b00eeb |
GckObject *object;
|
|
Packit |
b00eeb |
GckAttributes *attrs;
|
|
Packit |
b00eeb |
GckModule *module;
|
|
Packit |
b00eeb |
GckSession *session;
|
|
Packit |
b00eeb |
GckEnumerator *en;
|
|
Packit |
b00eeb |
GList *modules;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (!gcr_pkcs11_initialize (cancellable, error))
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
modules = gcr_pkcs11_get_modules ();
|
|
Packit |
b00eeb |
en = gck_modules_enumerate_objects (modules, search, 0);
|
|
Packit |
b00eeb |
gck_list_unref_free (modules);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
object = gck_enumerator_next (en, cancellable, error);
|
|
Packit |
b00eeb |
g_object_unref (en);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (object == NULL)
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/*
|
|
Packit |
b00eeb |
* Only the CKA_VALUE, CKA_CLASS and CKA_CERTIFICATE_TYPE
|
|
Packit |
b00eeb |
* is strictly necessary here, but we get more attrs.
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
attrs = gck_object_get (object, cancellable, error,
|
|
Packit |
b00eeb |
CKA_VALUE, CKA_LABEL,
|
|
Packit |
b00eeb |
CKA_ID, CKA_CLASS,
|
|
Packit |
b00eeb |
CKA_CERTIFICATE_TYPE,
|
|
Packit |
b00eeb |
CKA_ISSUER,
|
|
Packit |
b00eeb |
CKA_SERIAL_NUMBER,
|
|
Packit |
b00eeb |
GCK_INVALID);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (attrs == NULL) {
|
|
Packit |
b00eeb |
g_object_unref (object);
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
module = gck_object_get_module (object);
|
|
Packit |
b00eeb |
session = gck_object_get_session (object);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
cert = g_object_new (GCR_TYPE_PKCS11_CERTIFICATE,
|
|
Packit |
b00eeb |
"module", module,
|
|
Packit |
b00eeb |
"handle", gck_object_get_handle (object),
|
|
Packit |
b00eeb |
"session", session,
|
|
Packit |
b00eeb |
"attributes", attrs,
|
|
Packit |
b00eeb |
NULL);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_object_unref (module);
|
|
Packit |
b00eeb |
g_object_unref (session);
|
|
Packit |
b00eeb |
g_object_unref (object);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gck_attributes_unref (attrs);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
return cert;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
thread_lookup_certificate (GSimpleAsyncResult *res, GObject *object, GCancellable *cancel)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
lookup_issuer_closure *closure;
|
|
Packit |
b00eeb |
GError *error = NULL;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
closure = g_simple_async_result_get_op_res_gpointer (res);
|
|
Packit |
b00eeb |
closure->result = perform_lookup_certificate (closure->search, cancel, &error);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (error != NULL) {
|
|
Packit |
b00eeb |
g_simple_async_result_set_from_error (res, error);
|
|
Packit |
b00eeb |
g_clear_error (&error);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/* ----------------------------------------------------------------------------
|
|
Packit |
b00eeb |
* OBJECT
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static GObject*
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_constructor (GType type, guint n_props, GObjectConstructParam *props)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
gpointer obj = G_OBJECT_CLASS (gcr_pkcs11_certificate_parent_class)->constructor (type, n_props, props);
|
|
Packit |
b00eeb |
GckAttributes *attrs;
|
|
Packit |
b00eeb |
const GckAttribute *attr;
|
|
Packit |
b00eeb |
gulong value;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
attrs = gcr_pkcs11_certificate_get_attributes (obj);
|
|
Packit |
b00eeb |
g_return_val_if_fail (attrs, NULL);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &value) ||
|
|
Packit |
b00eeb |
value != CKO_CERTIFICATE) {
|
|
Packit |
b00eeb |
g_warning ("attributes don't contain a certificate with: %s",
|
|
Packit |
b00eeb |
"CKA_CLASS == CKO_CERTIFICATE");
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (!gck_attributes_find_ulong (attrs, CKA_CERTIFICATE_TYPE, &value) ||
|
|
Packit |
b00eeb |
value != CKC_X_509) {
|
|
Packit |
b00eeb |
g_warning ("attributes don't contain a certificate with: %s",
|
|
Packit |
b00eeb |
"CKA_CERTIFICATE_TYPE == CKC_X_509");
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
attr = gck_attributes_find (attrs, CKA_VALUE);
|
|
Packit |
b00eeb |
if (!attr || !attr->value || attr->length == 0 || attr->length == G_MAXULONG) {
|
|
Packit |
b00eeb |
g_warning ("attributes don't contain a valid: CKA_VALUE");
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
return obj;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_init (GcrPkcs11Certificate *self)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_PKCS11_CERTIFICATE, GcrPkcs11CertificatePrivate);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_set_property (GObject *obj, guint prop_id, const GValue *value,
|
|
Packit |
b00eeb |
GParamSpec *pspec)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (obj);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
switch (prop_id) {
|
|
Packit |
b00eeb |
case PROP_ATTRIBUTES:
|
|
Packit |
b00eeb |
g_return_if_fail (self->pv->attrs == NULL);
|
|
Packit |
b00eeb |
self->pv->attrs = g_value_dup_boxed (value);
|
|
Packit |
b00eeb |
g_return_if_fail (self->pv->attrs != NULL);
|
|
Packit |
b00eeb |
break;
|
|
Packit |
b00eeb |
default:
|
|
Packit |
b00eeb |
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
|
|
Packit |
b00eeb |
break;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_get_property (GObject *obj, guint prop_id, GValue *value,
|
|
Packit |
b00eeb |
GParamSpec *pspec)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (obj);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
switch (prop_id) {
|
|
Packit |
b00eeb |
case PROP_ATTRIBUTES:
|
|
Packit |
b00eeb |
g_value_set_boxed (value, gcr_pkcs11_certificate_get_attributes (self));
|
|
Packit |
b00eeb |
break;
|
|
Packit |
b00eeb |
default:
|
|
Packit |
b00eeb |
gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
|
|
Packit |
b00eeb |
break;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_finalize (GObject *obj)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (obj);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gck_attributes_unref (self->pv->attrs);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
G_OBJECT_CLASS (gcr_pkcs11_certificate_parent_class)->finalize (obj);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_class_init (GcrPkcs11CertificateClass *klass)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gobject_class->constructor = gcr_pkcs11_certificate_constructor;
|
|
Packit |
b00eeb |
gobject_class->get_property = gcr_pkcs11_certificate_get_property;
|
|
Packit |
b00eeb |
gobject_class->set_property = gcr_pkcs11_certificate_set_property;
|
|
Packit |
b00eeb |
gobject_class->finalize = gcr_pkcs11_certificate_finalize;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* GcrPkcs11Certificate:attributes:
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Automatically loaded attributes for this certificate.
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
|
|
Packit |
b00eeb |
g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the renderer",
|
|
Packit |
b00eeb |
GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_type_class_add_private (gobject_class, sizeof (GcrPkcs11CertificatePrivate));
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gcr_certificate_mixin_class_init (gobject_class);
|
|
Packit |
b00eeb |
_gcr_initialize_library ();
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static const guchar *
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_get_der_data (GcrCertificate *cert,
|
|
Packit |
b00eeb |
gsize *n_data)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GcrPkcs11Certificate *self = GCR_PKCS11_CERTIFICATE (cert);
|
|
Packit |
b00eeb |
const GckAttribute *attr;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
|
|
Packit |
b00eeb |
g_return_val_if_fail (n_data, NULL);
|
|
Packit |
b00eeb |
g_return_val_if_fail (self->pv->attrs, NULL);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
attr = gck_attributes_find (self->pv->attrs, CKA_VALUE);
|
|
Packit |
b00eeb |
g_return_val_if_fail (attr && attr->length != 0 && attr->length != G_MAXULONG, NULL);
|
|
Packit |
b00eeb |
*n_data = attr->length;
|
|
Packit |
b00eeb |
return attr->value;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static void
|
|
Packit |
b00eeb |
gcr_certificate_iface (GcrCertificateIface *iface)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
iface->get_der_data = gcr_pkcs11_certificate_get_der_data;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/* -----------------------------------------------------------------------------
|
|
Packit |
b00eeb |
* PUBLIC
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* gcr_pkcs11_certificate_get_attributes:
|
|
Packit |
b00eeb |
* @self: A #GcrPkcs11Certificate
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Access the automatically loaded attributes for this certificate.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Returns: (transfer none): the certificate attributes
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
GckAttributes *
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_get_attributes (GcrPkcs11Certificate *self)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
g_return_val_if_fail (GCR_IS_PKCS11_CERTIFICATE (self), NULL);
|
|
Packit |
b00eeb |
return self->pv->attrs;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* gcr_pkcs11_certificate_lookup_issuer:
|
|
Packit |
b00eeb |
* @certificate: a #GcrCertificate
|
|
Packit |
b00eeb |
* @cancellable: a #GCancellable
|
|
Packit |
b00eeb |
* @error: a #GError, or NULL
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Lookup a the issuer of a @certificate in the PKCS\#11 storage. The
|
|
Packit |
b00eeb |
* lookup is done using the issuer DN of the certificate. No certificate chain
|
|
Packit |
b00eeb |
* verification is done. Use a crypto library to make trust decisions.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* This call may block, see gcr_pkcs11_certificate_lookup_issuer() for the
|
|
Packit |
b00eeb |
* non-blocking version.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Will return %NULL if no issuer certificate is found. Use @error to determine
|
|
Packit |
b00eeb |
* if an error occurred.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Returns: (transfer full): a new #GcrPkcs11Certificate, or %NULL
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
GcrCertificate *
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_lookup_issuer (GcrCertificate *certificate, GCancellable *cancellable,
|
|
Packit |
b00eeb |
GError **error)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GckAttributes *search;
|
|
Packit |
b00eeb |
GcrCertificate *issuer;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), NULL);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (!gcr_pkcs11_initialize (cancellable, error))
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
search = prepare_lookup_certificate_issuer (certificate);
|
|
Packit |
b00eeb |
g_return_val_if_fail (search, FALSE);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
issuer = perform_lookup_certificate (search, cancellable, error);
|
|
Packit |
b00eeb |
gck_attributes_unref (search);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
return issuer;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* gcr_pkcs11_certificate_lookup_issuer_async:
|
|
Packit |
b00eeb |
* @certificate: a #GcrCertificate
|
|
Packit |
b00eeb |
* @cancellable: a #GCancellable
|
|
Packit |
b00eeb |
* @callback: a #GAsyncReadyCallback to call when the operation completes
|
|
Packit |
b00eeb |
* @user_data: the data to pass to callback function
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Lookup a the issuer of a @certificate in the PKCS\#11 storage. The
|
|
Packit |
b00eeb |
* lookup is done using the issuer DN of the certificate. No certificate chain
|
|
Packit |
b00eeb |
* verification is done. Use a crypto library to make trust decisions.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* When the operation is finished, callback will be called. You can then call
|
|
Packit |
b00eeb |
* gcr_pkcs11_certificate_lookup_issuer_finish() to get the result of the
|
|
Packit |
b00eeb |
* operation.
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
void
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_lookup_issuer_async (GcrCertificate *certificate, GCancellable *cancellable,
|
|
Packit |
b00eeb |
GAsyncReadyCallback callback, gpointer user_data)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GSimpleAsyncResult *async;
|
|
Packit |
b00eeb |
lookup_issuer_closure *closure;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_return_if_fail (GCR_IS_CERTIFICATE (certificate));
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
async = g_simple_async_result_new (G_OBJECT (certificate), callback, user_data,
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_lookup_issuer_async);
|
|
Packit |
b00eeb |
closure = g_new0 (lookup_issuer_closure, 1);
|
|
Packit |
b00eeb |
closure->search = prepare_lookup_certificate_issuer (certificate);
|
|
Packit |
b00eeb |
g_return_if_fail (closure->search);
|
|
Packit |
b00eeb |
g_simple_async_result_set_op_res_gpointer (async, closure, lookup_issuer_free);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_simple_async_result_run_in_thread (async, thread_lookup_certificate,
|
|
Packit |
b00eeb |
G_PRIORITY_DEFAULT, cancellable);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_object_unref (async);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/**
|
|
Packit |
b00eeb |
* gcr_pkcs11_certificate_lookup_issuer_finish:
|
|
Packit |
b00eeb |
* @result: the #GAsyncResult passed to the callback
|
|
Packit |
b00eeb |
* @error: a #GError, or NULL
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Finishes an asynchronous operation started by
|
|
Packit |
b00eeb |
* gcr_pkcs11_certificate_lookup_issuer_async().
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Will return %NULL if no issuer certificate is found. Use @error to determine
|
|
Packit |
b00eeb |
* if an error occurred.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Returns: (transfer full): a new #GcrPkcs11Certificate, or %NULL
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
GcrCertificate *
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_lookup_issuer_finish (GAsyncResult *result, GError **error)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
lookup_issuer_closure *closure;
|
|
Packit |
b00eeb |
GObject *source;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
source = g_async_result_get_source_object (result);
|
|
Packit |
b00eeb |
g_return_val_if_fail (g_simple_async_result_is_valid (result, source,
|
|
Packit |
b00eeb |
gcr_pkcs11_certificate_lookup_issuer_async), NULL);
|
|
Packit |
b00eeb |
g_object_unref (source);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
|
|
Packit |
b00eeb |
return NULL;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
closure = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
|
|
Packit |
b00eeb |
if (closure->result != NULL)
|
|
Packit |
b00eeb |
g_object_ref (closure->result);
|
|
Packit |
b00eeb |
return closure->result;
|
|
Packit |
b00eeb |
}
|