|
Packit Service |
f02b19 |
/*
|
|
Packit Service |
f02b19 |
* gnome-keyring
|
|
Packit Service |
f02b19 |
*
|
|
Packit Service |
f02b19 |
* Copyright (C) 2011 Collabora Ltd.
|
|
Packit Service |
f02b19 |
*
|
|
Packit Service |
f02b19 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
f02b19 |
* it under the terms of the GNU Lesser General Public License as
|
|
Packit Service |
f02b19 |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
f02b19 |
* the License, or (at your option) any later version.
|
|
Packit Service |
f02b19 |
*
|
|
Packit Service |
f02b19 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit Service |
f02b19 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
f02b19 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
f02b19 |
* Lesser General Public License for more details.
|
|
Packit Service |
f02b19 |
*
|
|
Packit Service |
f02b19 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
f02b19 |
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
f02b19 |
*
|
|
Packit Service |
f02b19 |
* Author: Stef Walter <stefw@collabora.co.uk>
|
|
Packit Service |
f02b19 |
*/
|
|
Packit Service |
f02b19 |
#include "config.h"
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
#include "gcr-subject-public-key.h"
|
|
Packit Service |
f02b19 |
#include "gcr-types.h"
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
#include "gcr/gcr-oids.h"
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
#include "egg/egg-asn1x.h"
|
|
Packit Service |
f02b19 |
#include "egg/egg-asn1-defs.h"
|
|
Packit Service |
f02b19 |
#include "egg/egg-error.h"
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
#include <glib/gi18n-lib.h>
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
#include <gcrypt.h>
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
check_object_basics (GckBuilder *builder,
|
|
Packit Service |
f02b19 |
gulong *klass,
|
|
Packit Service |
f02b19 |
gulong *type)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
g_assert (klass != NULL);
|
|
Packit Service |
f02b19 |
g_assert (type != NULL);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!gck_builder_find_ulong (builder, CKA_CLASS, klass))
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (*klass == CKO_PUBLIC_KEY || *klass == CKO_PRIVATE_KEY)
|
|
Packit Service |
f02b19 |
return gck_builder_find_ulong (builder, CKA_KEY_TYPE, type);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
else if (*klass == CKO_CERTIFICATE)
|
|
Packit Service |
f02b19 |
return gck_builder_find_ulong (builder, CKA_CERTIFICATE_TYPE, type);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
*type = GCK_INVALID;
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
load_object_basics (GckObject *object,
|
|
Packit Service |
f02b19 |
GckBuilder *builder,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
gulong *klass,
|
|
Packit Service |
f02b19 |
gulong *type,
|
|
Packit Service |
f02b19 |
GError **lerror)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gulong attr_types[] = { CKA_CLASS, CKA_KEY_TYPE, CKA_CERTIFICATE_TYPE };
|
|
Packit Service |
f02b19 |
GckAttributes *attrs;
|
|
Packit Service |
f02b19 |
GError *error = NULL;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_assert (klass != NULL);
|
|
Packit Service |
f02b19 |
g_assert (type != NULL);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (check_object_basics (builder, klass, type)) {
|
|
Packit Service |
f02b19 |
g_debug ("already loaded: class = %lu, type = %lu", *klass, *type);
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
|
|
Packit Service |
f02b19 |
cancellable, &error);
|
|
Packit Service |
f02b19 |
if (error != NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't load: %s", error->message);
|
|
Packit Service |
f02b19 |
g_propagate_error (lerror, error);
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_builder_set_all (builder, attrs);
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attrs);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!check_object_basics (builder, klass, type))
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_debug ("loaded: class = %lu, type = %lu", *klass, *type);
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
check_x509_attributes (GckBuilder *builder)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *value = gck_builder_find (builder, CKA_VALUE);
|
|
Packit Service |
f02b19 |
return (value && !gck_attribute_is_invalid (value));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
load_x509_attributes (GckObject *object,
|
|
Packit Service |
f02b19 |
GckBuilder *builder,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GError **lerror)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gulong attr_types[] = { CKA_VALUE };
|
|
Packit Service |
f02b19 |
GckAttributes *attrs;
|
|
Packit Service |
f02b19 |
GError *error = NULL;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (check_x509_attributes (builder)) {
|
|
Packit Service |
f02b19 |
g_debug ("already loaded");
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
|
|
Packit Service |
f02b19 |
cancellable, &error);
|
|
Packit Service |
f02b19 |
if (error != NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't load: %s", error->message);
|
|
Packit Service |
f02b19 |
g_propagate_error (lerror, error);
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_builder_set_all (builder, attrs);
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attrs);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return check_x509_attributes (builder);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
check_rsa_attributes (GckBuilder *builder)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *modulus;
|
|
Packit Service |
f02b19 |
const GckAttribute *exponent;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
modulus = gck_builder_find (builder, CKA_MODULUS);
|
|
Packit Service |
f02b19 |
exponent = gck_builder_find (builder, CKA_PUBLIC_EXPONENT);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return (modulus && !gck_attribute_is_invalid (modulus) &&
|
|
Packit Service |
f02b19 |
exponent && !gck_attribute_is_invalid (exponent));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
load_rsa_attributes (GckObject *object,
|
|
Packit Service |
f02b19 |
GckBuilder *builder,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GError **lerror)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gulong attr_types[] = { CKA_MODULUS, CKA_PUBLIC_EXPONENT };
|
|
Packit Service |
f02b19 |
GckAttributes *attrs;
|
|
Packit Service |
f02b19 |
GError *error = NULL;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (check_rsa_attributes (builder)) {
|
|
Packit Service |
f02b19 |
g_debug ("rsa attributes already loaded");
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
|
|
Packit Service |
f02b19 |
cancellable, &error);
|
|
Packit Service |
f02b19 |
if (error != NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't load rsa attributes: %s", error->message);
|
|
Packit Service |
f02b19 |
g_propagate_error (lerror, error);
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_builder_set_all (builder, attrs);
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attrs);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return check_rsa_attributes (builder);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static GckObject *
|
|
Packit Service |
f02b19 |
lookup_public_key (GckObject *object,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GError **lerror)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GckBuilder builder = GCK_BUILDER_INIT;
|
|
Packit Service |
f02b19 |
gulong attr_types[] = { CKA_ID };
|
|
Packit Service |
f02b19 |
GckAttributes *attrs;
|
|
Packit Service |
f02b19 |
GError *error = NULL;
|
|
Packit Service |
f02b19 |
GckSession *session;
|
|
Packit Service |
f02b19 |
GckObject *result;
|
|
Packit Service |
f02b19 |
const GckAttribute *id;
|
|
Packit Service |
f02b19 |
GList *objects;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
|
|
Packit Service |
f02b19 |
cancellable, &error);
|
|
Packit Service |
f02b19 |
if (error != NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't load private key id: %s", error->message);
|
|
Packit Service |
f02b19 |
g_propagate_error (lerror, error);
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
id = gck_attributes_find (attrs, CKA_ID);
|
|
Packit Service |
f02b19 |
if (id == NULL || gck_attribute_is_invalid (id)) {
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attrs);
|
|
Packit Service |
f02b19 |
g_debug ("couldn't load private key id");
|
|
Packit Service |
f02b19 |
g_set_error_literal (lerror, GCK_ERROR, CKR_ATTRIBUTE_TYPE_INVALID,
|
|
Packit Service |
f02b19 |
gck_message_from_rv (CKR_ATTRIBUTE_TYPE_INVALID));
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
|
|
Packit Service |
f02b19 |
gck_builder_add_attribute (&builder, id);
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attrs);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
session = gck_object_get_session (object);
|
|
Packit Service |
f02b19 |
objects = gck_session_find_objects (session, gck_builder_end (&builder), cancellable, &error);
|
|
Packit Service |
f02b19 |
g_object_unref (session);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (error != NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't lookup public key: %s", error->message);
|
|
Packit Service |
f02b19 |
g_propagate_error (lerror, error);
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!objects)
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
result = g_object_ref (objects->data);
|
|
Packit Service |
f02b19 |
gck_list_unref_free (objects);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return result;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
check_dsa_attributes (GckBuilder *builder)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *prime;
|
|
Packit Service |
f02b19 |
const GckAttribute *subprime;
|
|
Packit Service |
f02b19 |
const GckAttribute *base;
|
|
Packit Service |
f02b19 |
const GckAttribute *value;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
prime = gck_builder_find (builder, CKA_PRIME);
|
|
Packit Service |
f02b19 |
subprime = gck_builder_find (builder, CKA_SUBPRIME);
|
|
Packit Service |
f02b19 |
base = gck_builder_find (builder, CKA_BASE);
|
|
Packit Service |
f02b19 |
value = gck_builder_find (builder, CKA_VALUE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return (prime && !gck_attribute_is_invalid (prime) &&
|
|
Packit Service |
f02b19 |
subprime && !gck_attribute_is_invalid (subprime) &&
|
|
Packit Service |
f02b19 |
base && !gck_attribute_is_invalid (base) &&
|
|
Packit Service |
f02b19 |
value && !gck_attribute_is_invalid (value));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
load_dsa_attributes (GckObject *object,
|
|
Packit Service |
f02b19 |
GckBuilder *builder,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GError **lerror)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gulong attr_types[] = { CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_VALUE };
|
|
Packit Service |
f02b19 |
GError *error = NULL;
|
|
Packit Service |
f02b19 |
GckAttributes *loaded;
|
|
Packit Service |
f02b19 |
GckObject *publi;
|
|
Packit Service |
f02b19 |
gulong klass;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (check_dsa_attributes (builder))
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!gck_builder_find_ulong (builder, CKA_CLASS, &klass))
|
|
Packit Service |
f02b19 |
g_return_val_if_reached (FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* If it's a private key, find the public one */
|
|
Packit Service |
f02b19 |
if (klass == CKO_PRIVATE_KEY)
|
|
Packit Service |
f02b19 |
publi = lookup_public_key (object, cancellable, lerror);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
else
|
|
Packit Service |
f02b19 |
publi = g_object_ref (object);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!publi)
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
loaded = gck_object_cache_lookup (publi, attr_types, G_N_ELEMENTS (attr_types),
|
|
Packit Service |
f02b19 |
cancellable, &error);
|
|
Packit Service |
f02b19 |
g_object_unref (publi);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (error != NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't load rsa attributes: %s", error->message);
|
|
Packit Service |
f02b19 |
g_propagate_error (lerror, error);
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* We've made sure to load info from the public key, so change class */
|
|
Packit Service |
f02b19 |
gck_builder_set_ulong (builder, CKA_CLASS, CKO_PUBLIC_KEY);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_builder_set_all (builder, loaded);
|
|
Packit Service |
f02b19 |
gck_attributes_unref (loaded);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return check_dsa_attributes (builder);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
check_ec_attributes (GckBuilder *builder)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *ec_params;
|
|
Packit Service |
f02b19 |
const GckAttribute *ec_point;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
ec_params = gck_builder_find (builder, CKA_EC_PARAMS);
|
|
Packit Service |
f02b19 |
ec_point = gck_builder_find (builder, CKA_EC_POINT);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return (ec_params && !gck_attribute_is_invalid (ec_params) &&
|
|
Packit Service |
f02b19 |
ec_point && !gck_attribute_is_invalid (ec_point));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
load_ec_attributes (GckObject *object,
|
|
Packit Service |
f02b19 |
GckBuilder *builder,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GError **lerror)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gulong attr_types[] = { CKA_EC_PARAMS, CKA_EC_POINT };
|
|
Packit Service |
f02b19 |
GckAttributes *attrs;
|
|
Packit Service |
f02b19 |
GError *error = NULL;
|
|
Packit Service |
f02b19 |
GckObject *publi;
|
|
Packit Service |
f02b19 |
gulong klass;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (check_ec_attributes (builder)) {
|
|
Packit Service |
f02b19 |
g_debug ("ec attributes already loaded");
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!gck_builder_find_ulong (builder, CKA_CLASS, &klass))
|
|
Packit Service |
f02b19 |
g_return_val_if_reached (FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* If it's a private key, find the public one */
|
|
Packit Service |
f02b19 |
if (klass == CKO_PRIVATE_KEY)
|
|
Packit Service |
f02b19 |
publi = lookup_public_key (object, cancellable, lerror);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
else
|
|
Packit Service |
f02b19 |
publi = g_object_ref (object);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!publi)
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attrs = gck_object_cache_lookup (publi, attr_types, G_N_ELEMENTS (attr_types),
|
|
Packit Service |
f02b19 |
cancellable, &error);
|
|
Packit Service |
f02b19 |
g_object_unref (publi);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (error != NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't load ec attributes: %s", error->message);
|
|
Packit Service |
f02b19 |
g_propagate_error (lerror, error);
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_builder_set_all (builder, attrs);
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attrs);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return check_ec_attributes (builder);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
load_attributes (GckObject *object,
|
|
Packit Service |
f02b19 |
GckBuilder *builder,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GError **lerror)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gboolean ret = FALSE;
|
|
Packit Service |
f02b19 |
gulong klass;
|
|
Packit Service |
f02b19 |
gulong type;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!load_object_basics (object, builder, cancellable,
|
|
Packit Service |
f02b19 |
&klass, &type, lerror))
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
switch (klass) {
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
case CKO_CERTIFICATE:
|
|
Packit Service |
f02b19 |
switch (type) {
|
|
Packit Service |
f02b19 |
case CKC_X_509:
|
|
Packit Service |
f02b19 |
ret = load_x509_attributes (object, builder, cancellable, lerror);
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
default:
|
|
Packit Service |
f02b19 |
g_debug ("unsupported certificate type: %lu", type);
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
case CKO_PUBLIC_KEY:
|
|
Packit Service |
f02b19 |
case CKO_PRIVATE_KEY:
|
|
Packit Service |
f02b19 |
switch (type) {
|
|
Packit Service |
f02b19 |
case CKK_RSA:
|
|
Packit Service |
f02b19 |
ret = load_rsa_attributes (object, builder, cancellable, lerror);
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
case CKK_DSA:
|
|
Packit Service |
f02b19 |
ret = load_dsa_attributes (object, builder, cancellable, lerror);
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
case CKK_EC:
|
|
Packit Service |
f02b19 |
ret = load_ec_attributes (object, builder, cancellable, lerror);
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
default:
|
|
Packit Service |
f02b19 |
g_debug ("unsupported key type: %lu", type);
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
default:
|
|
Packit Service |
f02b19 |
g_debug ("unsupported class: %lu", type);
|
|
Packit Service |
f02b19 |
break;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (ret == FALSE && lerror != NULL && *lerror == NULL) {
|
|
Packit Service |
f02b19 |
g_set_error_literal (lerror, GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED,
|
|
Packit Service |
f02b19 |
_("Unrecognized or unavailable attributes for key"));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return ret;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
check_attributes (GckBuilder *builder)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gulong klass;
|
|
Packit Service |
f02b19 |
gulong type;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!check_object_basics (builder, &klass, &type))
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
switch (klass) {
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
case CKO_CERTIFICATE:
|
|
Packit Service |
f02b19 |
switch (type) {
|
|
Packit Service |
f02b19 |
case CKC_X_509:
|
|
Packit Service |
f02b19 |
return check_x509_attributes (builder);
|
|
Packit Service |
f02b19 |
default:
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
case CKO_PUBLIC_KEY:
|
|
Packit Service |
f02b19 |
case CKO_PRIVATE_KEY:
|
|
Packit Service |
f02b19 |
switch (type) {
|
|
Packit Service |
f02b19 |
case CKK_RSA:
|
|
Packit Service |
f02b19 |
return check_rsa_attributes (builder);
|
|
Packit Service |
f02b19 |
case CKK_DSA:
|
|
Packit Service |
f02b19 |
return check_dsa_attributes (builder);
|
|
Packit Service |
f02b19 |
case CKK_EC:
|
|
Packit Service |
f02b19 |
return check_ec_attributes (builder);
|
|
Packit Service |
f02b19 |
default:
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
default:
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static void
|
|
Packit Service |
f02b19 |
lookup_attributes (GckObject *object,
|
|
Packit Service |
f02b19 |
GckBuilder *builder)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GckObjectCache *oakey;
|
|
Packit Service |
f02b19 |
GckAttributes *attrs;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (GCK_IS_OBJECT_CACHE (object)) {
|
|
Packit Service |
f02b19 |
oakey = GCK_OBJECT_CACHE (object);
|
|
Packit Service |
f02b19 |
attrs = gck_object_cache_get_attributes (oakey);
|
|
Packit Service |
f02b19 |
if (attrs != NULL) {
|
|
Packit Service |
f02b19 |
gck_builder_add_all (builder, attrs);
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attrs);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
GNode *
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_load (GckObject *key,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GError **error)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GckBuilder builder = GCK_BUILDER_INIT;
|
|
Packit Service |
f02b19 |
GckAttributes *attributes;
|
|
Packit Service |
f02b19 |
GNode *asn;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (GCK_IS_OBJECT (key), NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
lookup_attributes (key, &builder);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!check_attributes (&builder)) {
|
|
Packit Service |
f02b19 |
if (!load_attributes (key, &builder, cancellable, error)) {
|
|
Packit Service |
f02b19 |
gck_builder_clear (&builder);
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attributes = gck_builder_end (&builder);
|
|
Packit Service |
f02b19 |
asn = _gcr_subject_public_key_for_attributes (attributes);
|
|
Packit Service |
f02b19 |
if (asn == NULL) {
|
|
Packit Service |
f02b19 |
g_set_error_literal (error, GCK_ERROR, CKR_TEMPLATE_INCONSISTENT,
|
|
Packit Service |
f02b19 |
_("Couldn’t build public key"));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attributes);
|
|
Packit Service |
f02b19 |
return asn;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
typedef struct {
|
|
Packit Service |
f02b19 |
GckObject *object;
|
|
Packit Service |
f02b19 |
GckBuilder builder;
|
|
Packit Service |
f02b19 |
} LoadClosure;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static void
|
|
Packit Service |
f02b19 |
load_closure_free (gpointer data)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
LoadClosure *closure = data;
|
|
Packit Service |
f02b19 |
g_object_unref (closure->object);
|
|
Packit Service |
f02b19 |
gck_builder_clear (&closure->builder);
|
|
Packit Service |
f02b19 |
g_slice_free (LoadClosure, closure);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static void
|
|
Packit Service |
f02b19 |
thread_key_attributes (GSimpleAsyncResult *res,
|
|
Packit Service |
f02b19 |
GObject *object,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
LoadClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
|
|
Packit Service |
f02b19 |
GError *error = NULL;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!load_attributes (closure->object, &closure->builder, cancellable, &error))
|
|
Packit Service |
f02b19 |
g_simple_async_result_take_error (res, error);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
void
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_load_async (GckObject *key,
|
|
Packit Service |
f02b19 |
GCancellable *cancellable,
|
|
Packit Service |
f02b19 |
GAsyncReadyCallback callback,
|
|
Packit Service |
f02b19 |
gpointer user_data)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GSimpleAsyncResult *res;
|
|
Packit Service |
f02b19 |
LoadClosure *closure;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_return_if_fail (GCK_IS_OBJECT (key));
|
|
Packit Service |
f02b19 |
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
res = g_simple_async_result_new (NULL, callback, user_data,
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_load_async);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
closure = g_slice_new0 (LoadClosure);
|
|
Packit Service |
f02b19 |
closure->object = g_object_ref (key);
|
|
Packit Service |
f02b19 |
lookup_attributes (key, &closure->builder);
|
|
Packit Service |
f02b19 |
g_simple_async_result_set_op_res_gpointer (res, closure, load_closure_free);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (check_attributes (&closure->builder)) {
|
|
Packit Service |
f02b19 |
g_simple_async_result_complete_in_idle (res);
|
|
Packit Service |
f02b19 |
g_object_unref (res);
|
|
Packit Service |
f02b19 |
return;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_simple_async_result_run_in_thread (res, thread_key_attributes,
|
|
Packit Service |
f02b19 |
G_PRIORITY_DEFAULT, cancellable);
|
|
Packit Service |
f02b19 |
g_object_unref (res);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
GNode *
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_load_finish (GAsyncResult *result,
|
|
Packit Service |
f02b19 |
GError **error)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GckAttributes *attributes;
|
|
Packit Service |
f02b19 |
GSimpleAsyncResult *res;
|
|
Packit Service |
f02b19 |
LoadClosure *closure;
|
|
Packit Service |
f02b19 |
GNode *asn;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_load_async), NULL);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
res = G_SIMPLE_ASYNC_RESULT (result);
|
|
Packit Service |
f02b19 |
if (g_simple_async_result_propagate_error (res, error))
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
closure = g_simple_async_result_get_op_res_gpointer (res);
|
|
Packit Service |
f02b19 |
attributes = gck_attributes_ref_sink (gck_builder_end (&closure->builder));
|
|
Packit Service |
f02b19 |
asn = _gcr_subject_public_key_for_attributes (attributes);
|
|
Packit Service |
f02b19 |
if (asn == NULL) {
|
|
Packit Service |
f02b19 |
g_set_error_literal (error, GCK_ERROR, CKR_TEMPLATE_INCONSISTENT,
|
|
Packit Service |
f02b19 |
_("Couldn’t build public key"));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gck_attributes_unref (attributes);
|
|
Packit Service |
f02b19 |
return asn;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
rsa_subject_public_key_from_attributes (GckAttributes *attrs,
|
|
Packit Service |
f02b19 |
GNode *info_asn)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *modulus;
|
|
Packit Service |
f02b19 |
const GckAttribute *exponent;
|
|
Packit Service |
f02b19 |
GNode *key_asn;
|
|
Packit Service |
f02b19 |
GNode *params_asn;
|
|
Packit Service |
f02b19 |
GBytes *key;
|
|
Packit Service |
f02b19 |
GBytes *usg;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
modulus = gck_attributes_find (attrs, CKA_MODULUS);
|
|
Packit Service |
f02b19 |
exponent = gck_attributes_find (attrs, CKA_PUBLIC_EXPONENT);
|
|
Packit Service |
f02b19 |
if (modulus == NULL || gck_attribute_is_invalid (modulus) ||
|
|
Packit Service |
f02b19 |
exponent == NULL || gck_attribute_is_invalid (exponent))
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
key_asn = egg_asn1x_create (pk_asn1_tab, "RSAPublicKey");
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (key_asn, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
params_asn = egg_asn1x_create (pk_asn1_tab, "RSAParameters");
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (params_asn, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
usg = g_bytes_new_with_free_func (modulus->value, modulus->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attrs));
|
|
Packit Service |
f02b19 |
egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "modulus", NULL), usg);
|
|
Packit Service |
f02b19 |
g_bytes_unref (usg);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
usg = g_bytes_new_with_free_func (exponent->value, exponent->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attrs));
|
|
Packit Service |
f02b19 |
egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "publicExponent", NULL), usg);
|
|
Packit Service |
f02b19 |
g_bytes_unref (usg);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
key = egg_asn1x_encode (key_asn, NULL);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (key_asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_set_null (params_asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
|
|
Packit Service |
f02b19 |
key, g_bytes_get_size (key) * 8);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_RSA);
|
|
Packit Service |
f02b19 |
egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (params_asn);
|
|
Packit Service |
f02b19 |
g_bytes_unref (key);
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
dsa_subject_public_key_from_private (GNode *key_asn,
|
|
Packit Service |
f02b19 |
const GckAttribute *ap,
|
|
Packit Service |
f02b19 |
const GckAttribute *aq,
|
|
Packit Service |
f02b19 |
const GckAttribute *ag,
|
|
Packit Service |
f02b19 |
const GckAttribute *ax)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gcry_mpi_t mp, mq, mg, mx, my;
|
|
Packit Service |
f02b19 |
size_t n_buffer;
|
|
Packit Service |
f02b19 |
gcry_error_t gcry;
|
|
Packit Service |
f02b19 |
unsigned char *buffer;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gcry = gcry_mpi_scan (&mp, GCRYMPI_FMT_USG, ap->value, ap->length, NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (gcry == 0, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gcry = gcry_mpi_scan (&mq, GCRYMPI_FMT_USG, aq->value, aq->length, NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (gcry == 0, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gcry = gcry_mpi_scan (&mg, GCRYMPI_FMT_USG, ag->value, ag->length, NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (gcry == 0, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gcry = gcry_mpi_scan (&mx, GCRYMPI_FMT_USG, ax->value, ax->length, NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (gcry == 0, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Calculate the public part from the private */
|
|
Packit Service |
f02b19 |
my = gcry_mpi_snew (gcry_mpi_get_nbits (mx));
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (my, FALSE);
|
|
Packit Service |
f02b19 |
gcry_mpi_powm (my, mg, mx, mp);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gcry = gcry_mpi_aprint (GCRYMPI_FMT_STD, &buffer, &n_buffer, my);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (gcry == 0, FALSE);
|
|
Packit Service |
f02b19 |
egg_asn1x_take_integer_as_raw (key_asn, g_bytes_new_with_free_func (buffer, n_buffer,
|
|
Packit Service |
f02b19 |
gcry_free, buffer));
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
gcry_mpi_release (mp);
|
|
Packit Service |
f02b19 |
gcry_mpi_release (mq);
|
|
Packit Service |
f02b19 |
gcry_mpi_release (mg);
|
|
Packit Service |
f02b19 |
gcry_mpi_release (mx);
|
|
Packit Service |
f02b19 |
gcry_mpi_release (my);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
dsa_subject_public_key_from_attributes (GckAttributes *attrs,
|
|
Packit Service |
f02b19 |
gulong klass,
|
|
Packit Service |
f02b19 |
GNode *info_asn)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *value, *g, *q, *p;
|
|
Packit Service |
f02b19 |
GNode *key_asn, *params_asn;
|
|
Packit Service |
f02b19 |
GBytes *key;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
p = gck_attributes_find (attrs, CKA_PRIME);
|
|
Packit Service |
f02b19 |
q = gck_attributes_find (attrs, CKA_SUBPRIME);
|
|
Packit Service |
f02b19 |
g = gck_attributes_find (attrs, CKA_BASE);
|
|
Packit Service |
f02b19 |
value = gck_attributes_find (attrs, CKA_VALUE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (p == NULL || gck_attribute_is_invalid (p) ||
|
|
Packit Service |
f02b19 |
q == NULL || gck_attribute_is_invalid (q) ||
|
|
Packit Service |
f02b19 |
g == NULL || gck_attribute_is_invalid (g) ||
|
|
Packit Service |
f02b19 |
value == NULL || gck_attribute_is_invalid (value))
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
key_asn = egg_asn1x_create (pk_asn1_tab, "DSAPublicPart");
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (key_asn, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
params_asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters");
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (params_asn, FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "p", NULL),
|
|
Packit Service |
f02b19 |
g_bytes_new_with_free_func (p->value, p->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attrs)));
|
|
Packit Service |
f02b19 |
egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "q", NULL),
|
|
Packit Service |
f02b19 |
g_bytes_new_with_free_func (q->value, q->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attrs)));
|
|
Packit Service |
f02b19 |
egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "g", NULL),
|
|
Packit Service |
f02b19 |
g_bytes_new_with_free_func (g->value, g->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attrs)));
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Are these attributes for a public or private key? */
|
|
Packit Service |
f02b19 |
if (klass == CKO_PRIVATE_KEY) {
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* We need to calculate the public from the private key */
|
|
Packit Service |
f02b19 |
if (!dsa_subject_public_key_from_private (key_asn, p, q, g, value))
|
|
Packit Service |
f02b19 |
g_return_val_if_reached (FALSE);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
} else if (klass == CKO_PUBLIC_KEY) {
|
|
Packit Service |
f02b19 |
egg_asn1x_take_integer_as_usg (key_asn,
|
|
Packit Service |
f02b19 |
g_bytes_new_with_free_func (value->value, value->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attrs)));
|
|
Packit Service |
f02b19 |
} else {
|
|
Packit Service |
f02b19 |
g_assert_not_reached ();
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
key = egg_asn1x_encode (key_asn, NULL);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (key_asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
|
|
Packit Service |
f02b19 |
key, g_bytes_get_size (key) * 8);
|
|
Packit Service |
f02b19 |
egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_DSA);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_bytes_unref (key);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (params_asn);
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static gboolean
|
|
Packit Service |
f02b19 |
ec_subject_public_key_from_attributes (GckAttributes *attrs,
|
|
Packit Service |
f02b19 |
gulong klass,
|
|
Packit Service |
f02b19 |
GNode *info_asn)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *ec_params, *ec_point;
|
|
Packit Service |
f02b19 |
GNode *params_asn, *point_asn;
|
|
Packit Service |
f02b19 |
GBytes *bytes, *key_bytes;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
ec_params = gck_attributes_find (attrs, CKA_EC_PARAMS);
|
|
Packit Service |
f02b19 |
ec_point = gck_attributes_find (attrs, CKA_EC_POINT);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (ec_params == NULL || gck_attribute_is_invalid (ec_params) ||
|
|
Packit Service |
f02b19 |
ec_point == NULL || gck_attribute_is_invalid (ec_point))
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
bytes = g_bytes_new_with_free_func (ec_params->value, ec_params->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref, gck_attributes_ref (attrs));
|
|
Packit Service |
f02b19 |
params_asn = egg_asn1x_create_and_decode (pk_asn1_tab, "ECParameters", bytes);
|
|
Packit Service |
f02b19 |
g_bytes_unref (bytes);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (params_asn == NULL)
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
bytes = g_bytes_new_with_free_func (ec_point->value, ec_point->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref, gck_attributes_ref (attrs));
|
|
Packit Service |
f02b19 |
point_asn = egg_asn1x_create_and_decode (pk_asn1_tab, "ECPoint", bytes);
|
|
Packit Service |
f02b19 |
g_bytes_unref (bytes);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (point_asn == NULL) {
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (params_asn);
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
key_bytes = egg_asn1x_get_string_as_bytes (point_asn);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (point_asn);
|
|
Packit Service |
f02b19 |
if (key_bytes == NULL) {
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (params_asn);
|
|
Packit Service |
f02b19 |
return FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
|
|
Packit Service |
f02b19 |
key_bytes, g_bytes_get_size (key_bytes) * 8);
|
|
Packit Service |
f02b19 |
egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_EC);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_bytes_unref (key_bytes);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (params_asn);
|
|
Packit Service |
f02b19 |
return TRUE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static GNode *
|
|
Packit Service |
f02b19 |
cert_subject_public_key_from_attributes (GckAttributes *attributes)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *attr;
|
|
Packit Service |
f02b19 |
GBytes *bytes;
|
|
Packit Service |
f02b19 |
GNode *cert;
|
|
Packit Service |
f02b19 |
GNode *asn;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attr = gck_attributes_find (attributes, CKA_VALUE);
|
|
Packit Service |
f02b19 |
if (attr == NULL || gck_attribute_is_invalid (attr)) {
|
|
Packit Service |
f02b19 |
g_debug ("no value attribute for certificate");
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
bytes = g_bytes_new_with_free_func (attr->value, attr->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attributes));
|
|
Packit Service |
f02b19 |
cert = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes);
|
|
Packit Service |
f02b19 |
g_bytes_unref (bytes);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (cert == NULL) {
|
|
Packit Service |
f02b19 |
g_debug ("couldn't parse certificate value");
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
asn = egg_asn1x_node (cert, "tbsCertificate", "subjectPublicKeyInfo", NULL);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (asn != NULL, NULL);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Remove the subject public key out of the certificate */
|
|
Packit Service |
f02b19 |
g_node_unlink (asn);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (cert);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return asn;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
GNode *
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_for_attributes (GckAttributes *attributes)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gboolean ret = FALSE;
|
|
Packit Service |
f02b19 |
gulong key_type;
|
|
Packit Service |
f02b19 |
gulong klass;
|
|
Packit Service |
f02b19 |
GNode *asn = NULL;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!gck_attributes_find_ulong (attributes, CKA_CLASS, &klass)) {
|
|
Packit Service |
f02b19 |
g_debug ("no class in attributes");
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (klass == CKO_CERTIFICATE) {
|
|
Packit Service |
f02b19 |
return cert_subject_public_key_from_attributes (attributes);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
} else if (klass == CKO_PUBLIC_KEY || klass == CKO_PRIVATE_KEY) {
|
|
Packit Service |
f02b19 |
if (!gck_attributes_find_ulong (attributes, CKA_KEY_TYPE, &key_type)) {
|
|
Packit Service |
f02b19 |
g_debug ("no key type in attributes");
|
|
Packit Service |
f02b19 |
return NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
asn = egg_asn1x_create (pkix_asn1_tab, "SubjectPublicKeyInfo");
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (asn, NULL);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (key_type == CKK_RSA) {
|
|
Packit Service |
f02b19 |
ret = rsa_subject_public_key_from_attributes (attributes, asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
} else if (key_type == CKK_DSA) {
|
|
Packit Service |
f02b19 |
ret = dsa_subject_public_key_from_attributes (attributes, klass, asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
} else if (key_type == CKK_ECDSA) {
|
|
Packit Service |
f02b19 |
ret = ec_subject_public_key_from_attributes (attributes, klass, asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
} else {
|
|
Packit Service |
f02b19 |
g_debug ("unsupported key type: %lu", key_type);
|
|
Packit Service |
f02b19 |
ret = FALSE;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (ret == FALSE) {
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (asn);
|
|
Packit Service |
f02b19 |
asn = NULL;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return asn;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static guint
|
|
Packit Service |
f02b19 |
calculate_rsa_key_size (GBytes *data)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GNode *asn;
|
|
Packit Service |
f02b19 |
GBytes *content;
|
|
Packit Service |
f02b19 |
guint key_size;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (asn, 0);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
content = egg_asn1x_get_value_raw (egg_asn1x_node (asn, "modulus", NULL));
|
|
Packit Service |
f02b19 |
if (!content)
|
|
Packit Service |
f02b19 |
g_return_val_if_reached (0);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Removes the complement */
|
|
Packit Service |
f02b19 |
key_size = (g_bytes_get_size (content) / 2) * 2 * 8;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_bytes_unref (content);
|
|
Packit Service |
f02b19 |
return key_size;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static guint
|
|
Packit Service |
f02b19 |
attributes_rsa_key_size (GckAttributes *attrs)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *attr;
|
|
Packit Service |
f02b19 |
gulong bits;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attr = gck_attributes_find (attrs, CKA_MODULUS);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Calculate the bit length, and remove the complement */
|
|
Packit Service |
f02b19 |
if (attr != NULL)
|
|
Packit Service |
f02b19 |
return (attr->length / 2) * 2 * 8;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (gck_attributes_find_ulong (attrs, CKA_MODULUS_BITS, &bits))
|
|
Packit Service |
f02b19 |
return (gint)bits;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return 0;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static guint
|
|
Packit Service |
f02b19 |
calculate_dsa_params_size (GNode *params)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GNode *asn;
|
|
Packit Service |
f02b19 |
GBytes *content;
|
|
Packit Service |
f02b19 |
guint key_size;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
asn = egg_asn1x_get_any_as (params, pk_asn1_tab, "DSAParameters");
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (asn, 0);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
content = egg_asn1x_get_value_raw (egg_asn1x_node (asn, "p", NULL));
|
|
Packit Service |
f02b19 |
if (!content)
|
|
Packit Service |
f02b19 |
g_return_val_if_reached (0);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Removes the complement */
|
|
Packit Service |
f02b19 |
key_size = (g_bytes_get_size (content) / 2) * 2 * 8;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
g_bytes_unref (content);
|
|
Packit Service |
f02b19 |
return key_size;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static guint
|
|
Packit Service |
f02b19 |
attributes_dsa_key_size (GckAttributes *attrs)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
const GckAttribute *attr;
|
|
Packit Service |
f02b19 |
gulong bits;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attr = gck_attributes_find (attrs, CKA_PRIME);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Calculate the bit length, and remove the complement */
|
|
Packit Service |
f02b19 |
if (attr != NULL)
|
|
Packit Service |
f02b19 |
return (attr->length / 2) * 2 * 8;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (gck_attributes_find_ulong (attrs, CKA_PRIME_BITS, &bits))
|
|
Packit Service |
f02b19 |
return (gint)bits;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return 0;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static guint
|
|
Packit Service |
f02b19 |
named_curve_size (GNode *params)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GQuark oid;
|
|
Packit Service |
f02b19 |
guint size;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (params, "namedCurve", NULL));
|
|
Packit Service |
f02b19 |
if (oid == GCR_OID_EC_SECP192R1)
|
|
Packit Service |
f02b19 |
size = 192;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT163K1)
|
|
Packit Service |
f02b19 |
size = 163;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT163R2)
|
|
Packit Service |
f02b19 |
size = 163;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECP224R1)
|
|
Packit Service |
f02b19 |
size = 224;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT233K1)
|
|
Packit Service |
f02b19 |
size = 233;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT233R1)
|
|
Packit Service |
f02b19 |
size = 233;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECP256R1)
|
|
Packit Service |
f02b19 |
size = 256;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT283K1)
|
|
Packit Service |
f02b19 |
size = 283;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT283R1)
|
|
Packit Service |
f02b19 |
size = 283;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECP384R1)
|
|
Packit Service |
f02b19 |
size = 384;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT409K1)
|
|
Packit Service |
f02b19 |
size = 409;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT409R1)
|
|
Packit Service |
f02b19 |
size = 409;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECP521R1)
|
|
Packit Service |
f02b19 |
size = 521;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECP571K1)
|
|
Packit Service |
f02b19 |
size = 571;
|
|
Packit Service |
f02b19 |
else if (oid == GCR_OID_EC_SECT571R1)
|
|
Packit Service |
f02b19 |
size = 571;
|
|
Packit Service |
f02b19 |
else
|
|
Packit Service |
f02b19 |
size = 0;
|
|
Packit Service |
f02b19 |
return size;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static guint
|
|
Packit Service |
f02b19 |
calculate_ec_params_size (GNode *params)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GNode *asn;
|
|
Packit Service |
f02b19 |
guint size;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
asn = egg_asn1x_get_any_as (params, pk_asn1_tab, "ECParameters");
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (asn, 0);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
size = named_curve_size (asn);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (asn);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return size;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
static guint
|
|
Packit Service |
f02b19 |
attributes_ec_params_size (GckAttributes *attrs)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GNode *asn;
|
|
Packit Service |
f02b19 |
const GckAttribute *attr;
|
|
Packit Service |
f02b19 |
GBytes *bytes;
|
|
Packit Service |
f02b19 |
guint size = 0;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
attr = gck_attributes_find (attrs, CKA_EC_PARAMS);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Calculate the bit length, and remove the complement */
|
|
Packit Service |
f02b19 |
if (attr && !gck_attribute_is_invalid (attr)) {
|
|
Packit Service |
f02b19 |
bytes = g_bytes_new_with_free_func (attr->value, attr->length,
|
|
Packit Service |
f02b19 |
gck_attributes_unref,
|
|
Packit Service |
f02b19 |
gck_attributes_ref (attrs));
|
|
Packit Service |
f02b19 |
asn = egg_asn1x_create_and_decode (pk_asn1_tab, "ECParameters", bytes);
|
|
Packit Service |
f02b19 |
g_bytes_unref (bytes);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (asn)
|
|
Packit Service |
f02b19 |
size = named_curve_size (asn);
|
|
Packit Service |
f02b19 |
egg_asn1x_destroy (asn);
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return size;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
guint
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_calculate_size (GNode *subject_public_key)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
GBytes *key;
|
|
Packit Service |
f02b19 |
GNode *params;
|
|
Packit Service |
f02b19 |
guint key_size = 0;
|
|
Packit Service |
f02b19 |
guint n_bits;
|
|
Packit Service |
f02b19 |
GQuark oid;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* Figure out the algorithm */
|
|
Packit Service |
f02b19 |
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (subject_public_key,
|
|
Packit Service |
f02b19 |
"algorithm", "algorithm", NULL));
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (oid != 0, 0);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* RSA keys are stored in the main subjectPublicKey field */
|
|
Packit Service |
f02b19 |
if (oid == GCR_OID_PKIX1_RSA) {
|
|
Packit Service |
f02b19 |
key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (subject_public_key, "subjectPublicKey", NULL), &n_bits);
|
|
Packit Service |
f02b19 |
g_return_val_if_fail (key != NULL, 0);
|
|
Packit Service |
f02b19 |
key_size = calculate_rsa_key_size (key);
|
|
Packit Service |
f02b19 |
g_bytes_unref (key);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
/* The DSA key size is discovered by the prime in params */
|
|
Packit Service |
f02b19 |
} else if (oid == GCR_OID_PKIX1_DSA) {
|
|
Packit Service |
f02b19 |
params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
|
|
Packit Service |
f02b19 |
key_size = calculate_dsa_params_size (params);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
} else if (oid == GCR_OID_PKIX1_EC) {
|
|
Packit Service |
f02b19 |
params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
|
|
Packit Service |
f02b19 |
key_size = calculate_ec_params_size (params);
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
} else {
|
|
Packit Service |
f02b19 |
g_message ("unsupported key algorithm: %s", g_quark_to_string (oid));
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
return key_size;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
guint
|
|
Packit Service |
f02b19 |
_gcr_subject_public_key_attributes_size (GckAttributes *attrs)
|
|
Packit Service |
f02b19 |
{
|
|
Packit Service |
f02b19 |
gulong key_type;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
if (!gck_attributes_find_ulong (attrs, CKA_KEY_TYPE, &key_type))
|
|
Packit Service |
f02b19 |
return 0;
|
|
Packit Service |
f02b19 |
|
|
Packit Service |
f02b19 |
switch (key_type) {
|
|
Packit Service |
f02b19 |
case CKK_RSA:
|
|
Packit Service |
f02b19 |
return attributes_rsa_key_size (attrs);
|
|
Packit Service |
f02b19 |
case CKK_DSA:
|
|
Packit Service |
f02b19 |
return attributes_dsa_key_size (attrs);
|
|
Packit Service |
f02b19 |
case CKK_EC:
|
|
Packit Service |
f02b19 |
return attributes_ec_params_size (attrs);
|
|
Packit Service |
f02b19 |
default:
|
|
Packit Service |
f02b19 |
g_message ("unsupported key algorithm: %lu", key_type);
|
|
Packit Service |
f02b19 |
return 0;
|
|
Packit Service |
f02b19 |
}
|
|
Packit Service |
f02b19 |
}
|