|
Packit |
549fdc |
/*
|
|
Packit |
549fdc |
* GnuTLS PKCS#11 support
|
|
Packit |
549fdc |
* Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Authors: Nikos Mavrogiannopoulos, Stef Walter
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This library is free software; you can redistribute it and/or
|
|
Packit |
549fdc |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
549fdc |
* License as published by the Free Software Foundation; either
|
|
Packit |
549fdc |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
549fdc |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
549fdc |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
549fdc |
* Library General Public License for more details.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
549fdc |
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
Packit |
549fdc |
*/
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#include "gnutls_int.h"
|
|
Packit |
549fdc |
#include <gnutls/pkcs11.h>
|
|
Packit |
549fdc |
#include <stdio.h>
|
|
Packit |
549fdc |
#include <string.h>
|
|
Packit |
549fdc |
#include "errors.h"
|
|
Packit |
549fdc |
#include <datum.h>
|
|
Packit |
549fdc |
#include <pkcs11_int.h>
|
|
Packit |
549fdc |
#include "pkcs11x.h"
|
|
Packit |
549fdc |
#include <x509/common.h>
|
|
Packit |
549fdc |
#include "pk.h"
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
static const ck_bool_t tval = 1;
|
|
Packit |
549fdc |
static const ck_bool_t fval = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#define MAX_ASIZE 24
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
static void mark_flags(unsigned flags, struct ck_attribute *a, unsigned *a_val, unsigned trusted)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
static const unsigned long category = 2;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_CA) {
|
|
Packit |
549fdc |
a[*a_val].type = CKA_CERTIFICATE_CATEGORY;
|
|
Packit |
549fdc |
a[*a_val].value = (void *) &category;
|
|
Packit |
549fdc |
a[*a_val].value_len = sizeof(category);
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_DISTRUSTED) {
|
|
Packit |
549fdc |
if (trusted) {
|
|
Packit |
549fdc |
a[*a_val].type = CKA_X_DISTRUSTED;
|
|
Packit |
549fdc |
a[*a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[*a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: ignoring the distrusted flag as it is not valid on non-p11-kit-trust modules\n");
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED) {
|
|
Packit |
549fdc |
a[*a_val].type = CKA_TRUSTED;
|
|
Packit |
549fdc |
a[*a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[*a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_PRIVATE;
|
|
Packit |
549fdc |
a[*a_val].value = (void *) &fval;
|
|
Packit |
549fdc |
a[*a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE) {
|
|
Packit |
549fdc |
a[*a_val].type = CKA_PRIVATE;
|
|
Packit |
549fdc |
a[*a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[*a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
} else if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
|
|
Packit |
549fdc |
a[*a_val].type = CKA_PRIVATE;
|
|
Packit |
549fdc |
a[*a_val].value = (void *) &fval;
|
|
Packit |
549fdc |
a[*a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_copy_x509_crt2:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @crt: The certificate to copy
|
|
Packit |
549fdc |
* @label: The name to be used for the stored data
|
|
Packit |
549fdc |
* @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key
|
|
Packit |
549fdc |
* @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will copy a certificate into a PKCS #11 token specified by
|
|
Packit |
549fdc |
* a URL. Valid flags to mark the certificate: %GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED,
|
|
Packit |
549fdc |
* %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE, %GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE,
|
|
Packit |
549fdc |
* %GNUTLS_PKCS11_OBJ_FLAG_MARK_CA, %GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Since: 3.4.0
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
gnutls_pkcs11_copy_x509_crt2(const char *token_url,
|
|
Packit |
549fdc |
gnutls_x509_crt_t crt, const char *label,
|
|
Packit |
549fdc |
const gnutls_datum_t *cid,
|
|
Packit |
549fdc |
unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct p11_kit_uri *info = NULL;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
size_t der_size, id_size, serial_size;
|
|
Packit |
549fdc |
gnutls_datum_t serial_der = {NULL, 0};
|
|
Packit |
549fdc |
uint8_t *der = NULL;
|
|
Packit |
549fdc |
uint8_t serial[128];
|
|
Packit |
549fdc |
uint8_t id[20];
|
|
Packit |
549fdc |
struct ck_attribute a[MAX_ASIZE];
|
|
Packit |
549fdc |
ck_object_class_t class = CKO_CERTIFICATE;
|
|
Packit |
549fdc |
ck_certificate_type_t type = CKC_X_509;
|
|
Packit |
549fdc |
ck_object_handle_t ctx;
|
|
Packit |
549fdc |
unsigned a_val;
|
|
Packit |
549fdc |
struct pkcs11_session_info sinfo;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
pkcs11_open_session(&sinfo, NULL, info,
|
|
Packit |
549fdc |
SESSION_WRITE |
|
|
Packit |
549fdc |
pkcs11_obj_flags_to_int(flags));
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
der_size = 0;
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, NULL,
|
|
Packit |
549fdc |
&der_size);
|
|
Packit |
549fdc |
if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
der = gnutls_malloc(der_size);
|
|
Packit |
549fdc |
if (der == NULL) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
ret = GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, der,
|
|
Packit |
549fdc |
&der_size);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[0].type = CKA_CLASS;
|
|
Packit |
549fdc |
a[0].value = &class;
|
|
Packit |
549fdc |
a[0].value_len = sizeof(class);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[1].type = CKA_ID;
|
|
Packit |
549fdc |
if (cid == NULL || cid->size == 0) {
|
|
Packit |
549fdc |
id_size = sizeof(id);
|
|
Packit |
549fdc |
ret = gnutls_x509_crt_get_subject_key_id(crt, id, &id_size, NULL);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
id_size = sizeof(id);
|
|
Packit |
549fdc |
ret = gnutls_x509_crt_get_key_id(crt, 0, id, &id_size);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[1].value = id;
|
|
Packit |
549fdc |
a[1].value_len = id_size;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[1].value = cid->data;
|
|
Packit |
549fdc |
a[1].value_len = cid->size;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[2].type = CKA_VALUE;
|
|
Packit |
549fdc |
a[2].value = der;
|
|
Packit |
549fdc |
a[2].value_len = der_size;
|
|
Packit |
549fdc |
a[3].type = CKA_TOKEN;
|
|
Packit |
549fdc |
a[3].value = (void *) &tval;
|
|
Packit |
549fdc |
a[3].value_len = sizeof(tval);
|
|
Packit |
549fdc |
a[4].type = CKA_CERTIFICATE_TYPE;
|
|
Packit |
549fdc |
a[4].value = &type;
|
|
Packit |
549fdc |
a[4].value_len = sizeof(type);
|
|
Packit |
549fdc |
/* FIXME: copy key usage flags */
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a_val = 5;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_SUBJECT;
|
|
Packit |
549fdc |
a[a_val].value = crt->raw_dn.data;
|
|
Packit |
549fdc |
a[a_val].value_len = crt->raw_dn.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_ISSUER;
|
|
Packit |
549fdc |
a[a_val].value = crt->raw_issuer_dn.data;
|
|
Packit |
549fdc |
a[a_val].value_len = crt->raw_issuer_dn.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
serial_size = sizeof(serial);
|
|
Packit |
549fdc |
if (gnutls_x509_crt_get_serial(crt, serial, &serial_size) >= 0) {
|
|
Packit |
549fdc |
ret = _gnutls_x509_ext_gen_number(serial, serial_size, &serial_der);
|
|
Packit |
549fdc |
if (ret >= 0) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_SERIAL_NUMBER;
|
|
Packit |
549fdc |
a[a_val].value = (void *) serial_der.data;
|
|
Packit |
549fdc |
a[a_val].value_len = serial_der.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (label) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_LABEL;
|
|
Packit |
549fdc |
a[a_val].value = (void *) label;
|
|
Packit |
549fdc |
a[a_val].value_len = strlen(label);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
mark_flags(flags, a, &a_val, sinfo.trusted);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx;;
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* generated!
|
|
Packit |
549fdc |
*/
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
cleanup:
|
|
Packit |
549fdc |
gnutls_free(der);
|
|
Packit |
549fdc |
gnutls_free(serial_der.data);
|
|
Packit |
549fdc |
pkcs11_close_session(&sinfo);
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
static void clean_pubkey(struct ck_attribute *a, unsigned a_val)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
unsigned i;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
for (i=0;i
|
|
Packit |
549fdc |
switch(a[i].type) {
|
|
Packit |
549fdc |
case CKA_MODULUS:
|
|
Packit |
549fdc |
case CKA_PUBLIC_EXPONENT:
|
|
Packit |
549fdc |
case CKA_PRIME:
|
|
Packit |
549fdc |
case CKA_SUBPRIME:
|
|
Packit |
549fdc |
case CKA_VALUE:
|
|
Packit |
549fdc |
case CKA_BASE:
|
|
Packit |
549fdc |
case CKA_EC_PARAMS:
|
|
Packit |
549fdc |
case CKA_EC_POINT:
|
|
Packit |
549fdc |
gnutls_free(a[i].value);
|
|
Packit |
549fdc |
a[i].value = NULL;
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
static int add_pubkey(gnutls_pubkey_t pubkey, struct ck_attribute *a, unsigned *a_val)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_pk_algorithm_t pk;
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
switch (pk) {
|
|
Packit |
549fdc |
case GNUTLS_PK_RSA_PSS:
|
|
Packit |
549fdc |
case GNUTLS_PK_RSA: {
|
|
Packit |
549fdc |
gnutls_datum_t m, e;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* PKCS#11 defines integers as unsigned having most significant byte
|
|
Packit |
549fdc |
* first, e.g., 32768 = 0x80 0x00. This is interpreted literraly by
|
|
Packit |
549fdc |
* some HSMs which do not accept an integer with a leading zero */
|
|
Packit |
549fdc |
ret = gnutls_pubkey_export_rsa_raw2(pubkey, &m, &e, GNUTLS_EXPORT_FLAG_NO_LZ);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_MODULUS;
|
|
Packit |
549fdc |
a[*a_val].value = m.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = m.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_PUBLIC_EXPONENT;
|
|
Packit |
549fdc |
a[*a_val].value = e.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = e.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
case GNUTLS_PK_DSA: {
|
|
Packit |
549fdc |
gnutls_datum_t p, q, g, y;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_pubkey_export_dsa_raw2(pubkey, &p, &q, &g, &y, GNUTLS_EXPORT_FLAG_NO_LZ);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_PRIME;
|
|
Packit |
549fdc |
a[*a_val].value = p.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = p.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_SUBPRIME;
|
|
Packit |
549fdc |
a[*a_val].value = q.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = q.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_BASE;
|
|
Packit |
549fdc |
a[*a_val].value = g.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = g.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_VALUE;
|
|
Packit |
549fdc |
a[*a_val].value = y.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = y.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
case GNUTLS_PK_EC: {
|
|
Packit |
549fdc |
gnutls_datum_t params, point;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_pubkey_export_ecc_x962(pubkey, ¶ms, &point);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_EC_PARAMS;
|
|
Packit |
549fdc |
a[*a_val].value = params.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = params.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[*a_val].type = CKA_EC_POINT;
|
|
Packit |
549fdc |
a[*a_val].value = point.data;
|
|
Packit |
549fdc |
a[*a_val].value_len = point.size;
|
|
Packit |
549fdc |
(*a_val)++;
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
default:
|
|
Packit |
549fdc |
_gnutls_debug_log("requested writing public key of unsupported type %u\n", (unsigned)pk);
|
|
Packit |
549fdc |
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return 0;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_copy_pubkey:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @pubkey: The public key to copy
|
|
Packit |
549fdc |
* @label: The name to be used for the stored data
|
|
Packit |
549fdc |
* @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key
|
|
Packit |
549fdc |
* @key_usage: One of GNUTLS_KEY_*
|
|
Packit |
549fdc |
* @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will copy a public key object into a PKCS #11 token specified by
|
|
Packit |
549fdc |
* a URL. Valid flags to mark the key: %GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED,
|
|
Packit |
549fdc |
* %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE, %GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE,
|
|
Packit |
549fdc |
* %GNUTLS_PKCS11_OBJ_FLAG_MARK_CA, %GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Since: 3.4.6
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
gnutls_pkcs11_copy_pubkey(const char *token_url,
|
|
Packit |
549fdc |
gnutls_pubkey_t pubkey, const char *label,
|
|
Packit |
549fdc |
const gnutls_datum_t *cid,
|
|
Packit |
549fdc |
unsigned int key_usage, unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct p11_kit_uri *info = NULL;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
size_t id_size;
|
|
Packit |
549fdc |
uint8_t id[20];
|
|
Packit |
549fdc |
struct ck_attribute a[MAX_ASIZE];
|
|
Packit |
549fdc |
gnutls_pk_algorithm_t pk;
|
|
Packit |
549fdc |
ck_object_class_t class = CKO_PUBLIC_KEY;
|
|
Packit |
549fdc |
ck_object_handle_t ctx;
|
|
Packit |
549fdc |
unsigned a_val;
|
|
Packit |
549fdc |
ck_key_type_t type;
|
|
Packit |
549fdc |
struct pkcs11_session_info sinfo;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
pkcs11_open_session(&sinfo, NULL, info,
|
|
Packit |
549fdc |
SESSION_WRITE |
|
|
Packit |
549fdc |
pkcs11_obj_flags_to_int(flags));
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[0].type = CKA_CLASS;
|
|
Packit |
549fdc |
a[0].value = &class;
|
|
Packit |
549fdc |
a[0].value_len = sizeof(class);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[1].type = CKA_TOKEN;
|
|
Packit |
549fdc |
a[1].value = (void *) &tval;
|
|
Packit |
549fdc |
a[1].value_len = sizeof(tval);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a_val = 2;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = add_pubkey(pubkey, a, &a_val);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (label) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_LABEL;
|
|
Packit |
549fdc |
a[a_val].value = (void *) label;
|
|
Packit |
549fdc |
a[a_val].value_len = strlen(label);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
|
|
Packit |
549fdc |
type = pk_to_key_type(pk);
|
|
Packit |
549fdc |
FIX_KEY_USAGE(pk, key_usage);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_KEY_TYPE;
|
|
Packit |
549fdc |
a[a_val].value = &type;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(type);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_ID;
|
|
Packit |
549fdc |
if (cid == NULL || cid->size == 0) {
|
|
Packit |
549fdc |
id_size = sizeof(id);
|
|
Packit |
549fdc |
ret = gnutls_pubkey_get_key_id(pubkey, 0, id, &id_size);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].value = id;
|
|
Packit |
549fdc |
a[a_val].value_len = id_size;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].value = cid->data;
|
|
Packit |
549fdc |
a[a_val].value_len = cid->size;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
mark_flags(flags, a, &a_val, sinfo.trusted);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_VERIFY;
|
|
Packit |
549fdc |
if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&fval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (pk == GNUTLS_PK_RSA) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_ENCRYPT;
|
|
Packit |
549fdc |
if (key_usage & (GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_DECIPHER_ONLY)) {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&fval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx;;
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* generated!
|
|
Packit |
549fdc |
*/
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
cleanup:
|
|
Packit |
549fdc |
clean_pubkey(a, a_val);
|
|
Packit |
549fdc |
pkcs11_close_session(&sinfo);
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_copy_attached_extension:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @crt: An X.509 certificate object
|
|
Packit |
549fdc |
* @data: the attached extension
|
|
Packit |
549fdc |
* @label: A name to be used for the attached extension (may be %NULL)
|
|
Packit |
549fdc |
* @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will copy an the attached extension in @data for
|
|
Packit |
549fdc |
* the certificate provided in @crt in the PKCS #11 token specified
|
|
Packit |
549fdc |
* by the URL (typically a trust module). The extension must be in
|
|
Packit |
549fdc |
* RFC5280 Extension format.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Since: 3.3.8
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
gnutls_pkcs11_copy_attached_extension(const char *token_url,
|
|
Packit |
549fdc |
gnutls_x509_crt_t crt,
|
|
Packit |
549fdc |
gnutls_datum_t *data,
|
|
Packit |
549fdc |
const char *label,
|
|
Packit |
549fdc |
unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct p11_kit_uri *info = NULL;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
struct ck_attribute a[MAX_ASIZE];
|
|
Packit |
549fdc |
ck_object_handle_t ctx;
|
|
Packit |
549fdc |
unsigned a_vals;
|
|
Packit |
549fdc |
struct pkcs11_session_info sinfo;
|
|
Packit |
549fdc |
ck_object_class_t class;
|
|
Packit |
549fdc |
gnutls_datum_t spki = {NULL, 0};
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
pkcs11_open_session(&sinfo, NULL, info,
|
|
Packit |
549fdc |
SESSION_WRITE |
|
|
Packit |
549fdc |
pkcs11_obj_flags_to_int(flags));
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = x509_crt_to_raw_pubkey(crt, &spki);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
class = CKO_X_CERTIFICATE_EXTENSION;
|
|
Packit |
549fdc |
a_vals = 0;
|
|
Packit |
549fdc |
a[a_vals].type = CKA_CLASS;
|
|
Packit |
549fdc |
a[a_vals].value = &class;
|
|
Packit |
549fdc |
a[a_vals++].value_len = sizeof(class);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_vals].type = CKA_PUBLIC_KEY_INFO;
|
|
Packit |
549fdc |
a[a_vals].value = spki.data;
|
|
Packit |
549fdc |
a[a_vals++].value_len = spki.size;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_vals].type = CKA_VALUE;
|
|
Packit |
549fdc |
a[a_vals].value = data->data;
|
|
Packit |
549fdc |
a[a_vals++].value_len = data->size;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_vals].type = CKA_TOKEN;
|
|
Packit |
549fdc |
a[a_vals].value = (void *) &tval;
|
|
Packit |
549fdc |
a[a_vals++].value_len = sizeof(tval);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (label) {
|
|
Packit |
549fdc |
a[a_vals].type = CKA_LABEL;
|
|
Packit |
549fdc |
a[a_vals].value = (void *) label;
|
|
Packit |
549fdc |
a[a_vals++].value_len = strlen(label);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_vals, &ctx;;
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
cleanup:
|
|
Packit |
549fdc |
pkcs11_close_session(&sinfo);
|
|
Packit |
549fdc |
gnutls_free(spki.data);
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_copy_x509_privkey2:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @key: A private key
|
|
Packit |
549fdc |
* @label: A name to be used for the stored data
|
|
Packit |
549fdc |
* @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key
|
|
Packit |
549fdc |
* @key_usage: One of GNUTLS_KEY_*
|
|
Packit |
549fdc |
* @flags: One of GNUTLS_PKCS11_OBJ_* flags
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will copy a private key into a PKCS #11 token specified by
|
|
Packit |
549fdc |
* a URL. It is highly recommended flags to contain %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE
|
|
Packit |
549fdc |
* unless there is a strong reason not to.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Since: 3.4.0
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
gnutls_pkcs11_copy_x509_privkey2(const char *token_url,
|
|
Packit |
549fdc |
gnutls_x509_privkey_t key,
|
|
Packit |
549fdc |
const char *label,
|
|
Packit |
549fdc |
const gnutls_datum_t *cid,
|
|
Packit |
549fdc |
unsigned int key_usage, unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct p11_kit_uri *info = NULL;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
size_t id_size;
|
|
Packit |
549fdc |
uint8_t id[20];
|
|
Packit |
549fdc |
struct ck_attribute a[32];
|
|
Packit |
549fdc |
ck_object_class_t class = CKO_PRIVATE_KEY;
|
|
Packit |
549fdc |
ck_object_handle_t ctx;
|
|
Packit |
549fdc |
ck_key_type_t type;
|
|
Packit |
549fdc |
int a_val;
|
|
Packit |
549fdc |
gnutls_pk_algorithm_t pk;
|
|
Packit |
549fdc |
gnutls_datum_t p, q, g, y, x;
|
|
Packit |
549fdc |
gnutls_datum_t m, e, d, u, exp1, exp2;
|
|
Packit |
549fdc |
struct pkcs11_session_info sinfo;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
memset(&p, 0, sizeof(p));
|
|
Packit |
549fdc |
memset(&q, 0, sizeof(q));
|
|
Packit |
549fdc |
memset(&g, 0, sizeof(g));
|
|
Packit |
549fdc |
memset(&y, 0, sizeof(y));
|
|
Packit |
549fdc |
memset(&x, 0, sizeof(x));
|
|
Packit |
549fdc |
memset(&m, 0, sizeof(m));
|
|
Packit |
549fdc |
memset(&e, 0, sizeof(e));
|
|
Packit |
549fdc |
memset(&d, 0, sizeof(d));
|
|
Packit |
549fdc |
memset(&u, 0, sizeof(u));
|
|
Packit |
549fdc |
memset(&exp1, 0, sizeof(exp1));
|
|
Packit |
549fdc |
memset(&exp2, 0, sizeof(exp2));
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
pkcs11_open_session(&sinfo, NULL, info,
|
|
Packit |
549fdc |
SESSION_WRITE |
|
|
Packit |
549fdc |
pkcs11_obj_flags_to_int(flags));
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
pk = gnutls_x509_privkey_get_pk_algorithm(key);
|
|
Packit |
549fdc |
FIX_KEY_USAGE(pk, key_usage);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* FIXME: copy key usage flags */
|
|
Packit |
549fdc |
a_val = 0;
|
|
Packit |
549fdc |
a[a_val].type = CKA_CLASS;
|
|
Packit |
549fdc |
a[a_val].value = &class;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(class);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_ID;
|
|
Packit |
549fdc |
if (cid == NULL || cid->size == 0) {
|
|
Packit |
549fdc |
id_size = sizeof(id);
|
|
Packit |
549fdc |
ret = gnutls_x509_privkey_get_key_id(key, 0, id, &id_size);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].value = id;
|
|
Packit |
549fdc |
a[a_val].value_len = id_size;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].value = cid->data;
|
|
Packit |
549fdc |
a[a_val].value_len = cid->size;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_SIGN;
|
|
Packit |
549fdc |
if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&fval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (pk == GNUTLS_PK_RSA) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_DECRYPT;
|
|
Packit |
549fdc |
if (key_usage & (GNUTLS_KEY_ENCIPHER_ONLY|GNUTLS_KEY_DECIPHER_ONLY)) {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].value = (void*)&fval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_TOKEN;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* a private key is set always as private unless
|
|
Packit |
549fdc |
* requested otherwise
|
|
Packit |
549fdc |
*/
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_PRIVATE;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &fval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].type = CKA_PRIVATE;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_ALWAYS_AUTHENTICATE;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_EXTRACTABLE) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_EXTRACTABLE;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
(a_val)++;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].type = CKA_EXTRACTABLE;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &fval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
(a_val)++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (label) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_LABEL;
|
|
Packit |
549fdc |
a[a_val].value = (void *) label;
|
|
Packit |
549fdc |
a[a_val].value_len = strlen(label);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE) {
|
|
Packit |
549fdc |
a[a_val].type = CKA_SENSITIVE;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &tval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(tval);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
a[a_val].type = CKA_SENSITIVE;
|
|
Packit |
549fdc |
a[a_val].value = (void *) &fval;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(fval);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
switch (pk) {
|
|
Packit |
549fdc |
case GNUTLS_PK_RSA:
|
|
Packit |
549fdc |
case GNUTLS_PK_RSA_PSS:
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = _gnutls_params_get_rsa_raw(&key->params, &m, &e, &d, &p,
|
|
Packit |
549fdc |
&q, &u, &exp1, &exp2,
|
|
Packit |
549fdc |
GNUTLS_EXPORT_FLAG_NO_LZ);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
type = CKK_RSA;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_MODULUS;
|
|
Packit |
549fdc |
a[a_val].value = m.data;
|
|
Packit |
549fdc |
a[a_val].value_len = m.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_PUBLIC_EXPONENT;
|
|
Packit |
549fdc |
a[a_val].value = e.data;
|
|
Packit |
549fdc |
a[a_val].value_len = e.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_PRIVATE_EXPONENT;
|
|
Packit |
549fdc |
a[a_val].value = d.data;
|
|
Packit |
549fdc |
a[a_val].value_len = d.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_PRIME_1;
|
|
Packit |
549fdc |
a[a_val].value = p.data;
|
|
Packit |
549fdc |
a[a_val].value_len = p.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_PRIME_2;
|
|
Packit |
549fdc |
a[a_val].value = q.data;
|
|
Packit |
549fdc |
a[a_val].value_len = q.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_COEFFICIENT;
|
|
Packit |
549fdc |
a[a_val].value = u.data;
|
|
Packit |
549fdc |
a[a_val].value_len = u.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_EXPONENT_1;
|
|
Packit |
549fdc |
a[a_val].value = exp1.data;
|
|
Packit |
549fdc |
a[a_val].value_len = exp1.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_EXPONENT_2;
|
|
Packit |
549fdc |
a[a_val].value = exp2.data;
|
|
Packit |
549fdc |
a[a_val].value_len = exp2.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
case GNUTLS_PK_DSA:
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
ret = _gnutls_params_get_dsa_raw(&key->params, &p, &q, &g, &y, &x,
|
|
Packit |
549fdc |
GNUTLS_EXPORT_FLAG_NO_LZ);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
type = CKK_DSA;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_PRIME;
|
|
Packit |
549fdc |
a[a_val].value = p.data;
|
|
Packit |
549fdc |
a[a_val].value_len = p.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_SUBPRIME;
|
|
Packit |
549fdc |
a[a_val].value = q.data;
|
|
Packit |
549fdc |
a[a_val].value_len = q.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_BASE;
|
|
Packit |
549fdc |
a[a_val].value = g.data;
|
|
Packit |
549fdc |
a[a_val].value_len = g.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_VALUE;
|
|
Packit |
549fdc |
a[a_val].value = x.data;
|
|
Packit |
549fdc |
a[a_val].value_len = x.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
case GNUTLS_PK_EC:
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
_gnutls_x509_write_ecc_params(key->params.curve,
|
|
Packit |
549fdc |
&p);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
_gnutls_mpi_dprint(key->params.
|
|
Packit |
549fdc |
params[ECC_K], &x);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
type = CKK_ECDSA;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_EC_PARAMS;
|
|
Packit |
549fdc |
a[a_val].value = p.data;
|
|
Packit |
549fdc |
a[a_val].value_len = p.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_VALUE;
|
|
Packit |
549fdc |
a[a_val].value = x.data;
|
|
Packit |
549fdc |
a[a_val].value_len = x.size;
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
default:
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
ret = GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_val].type = CKA_KEY_TYPE;
|
|
Packit |
549fdc |
a[a_val].value = &type;
|
|
Packit |
549fdc |
a[a_val].value_len = sizeof(type);
|
|
Packit |
549fdc |
a_val++;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx;;
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
cleanup:
|
|
Packit |
549fdc |
switch (pk) {
|
|
Packit |
549fdc |
case GNUTLS_PK_RSA_PSS:
|
|
Packit |
549fdc |
case GNUTLS_PK_RSA:
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_free(m.data);
|
|
Packit |
549fdc |
gnutls_free(e.data);
|
|
Packit |
549fdc |
gnutls_free(d.data);
|
|
Packit |
549fdc |
gnutls_free(p.data);
|
|
Packit |
549fdc |
gnutls_free(q.data);
|
|
Packit |
549fdc |
gnutls_free(u.data);
|
|
Packit |
549fdc |
gnutls_free(exp1.data);
|
|
Packit |
549fdc |
gnutls_free(exp2.data);
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
case GNUTLS_PK_DSA:
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_free(p.data);
|
|
Packit |
549fdc |
gnutls_free(q.data);
|
|
Packit |
549fdc |
gnutls_free(g.data);
|
|
Packit |
549fdc |
gnutls_free(y.data);
|
|
Packit |
549fdc |
gnutls_free(x.data);
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
case GNUTLS_PK_EC:
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_free(p.data);
|
|
Packit |
549fdc |
gnutls_free(x.data);
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
default:
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
ret = GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
549fdc |
break;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (sinfo.pks != 0)
|
|
Packit |
549fdc |
pkcs11_close_session(&sinfo);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
struct delete_data_st {
|
|
Packit |
549fdc |
struct p11_kit_uri *info;
|
|
Packit |
549fdc |
unsigned int deleted; /* how many */
|
|
Packit |
549fdc |
};
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
static int
|
|
Packit |
549fdc |
delete_obj_url_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
|
|
Packit |
549fdc |
struct ck_token_info *tinfo,
|
|
Packit |
549fdc |
struct ck_info *lib_info, void *input)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
struct delete_data_st *find_data = input;
|
|
Packit |
549fdc |
struct ck_attribute a[4];
|
|
Packit |
549fdc |
struct ck_attribute *attr;
|
|
Packit |
549fdc |
ck_object_class_t class;
|
|
Packit |
549fdc |
ck_certificate_type_t type = (ck_certificate_type_t) - 1;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
ck_object_handle_t ctx;
|
|
Packit |
549fdc |
unsigned long count, a_vals;
|
|
Packit |
549fdc |
int found = 0, ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (tinfo == NULL) { /* we don't support multiple calls */
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* do not bother reading the token if basic fields do not match
|
|
Packit |
549fdc |
*/
|
|
Packit |
549fdc |
if (!p11_kit_uri_match_module_info(find_data->info, lib_info) ||
|
|
Packit |
549fdc |
!p11_kit_uri_match_token_info(find_data->info, tinfo)) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* Find objects with given class and type */
|
|
Packit |
549fdc |
class = CKO_CERTIFICATE; /* default */
|
|
Packit |
549fdc |
a_vals = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
attr = p11_kit_uri_get_attribute(find_data->info, CKA_CLASS);
|
|
Packit |
549fdc |
if (attr != NULL) {
|
|
Packit |
549fdc |
if (attr->value
|
|
Packit |
549fdc |
&& attr->value_len == sizeof(ck_object_class_t))
|
|
Packit |
549fdc |
class = *((ck_object_class_t *) attr->value);
|
|
Packit |
549fdc |
if (class == CKO_CERTIFICATE)
|
|
Packit |
549fdc |
type = CKC_X_509;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
a[a_vals].type = CKA_CLASS;
|
|
Packit |
549fdc |
a[a_vals].value = &class;
|
|
Packit |
549fdc |
a[a_vals].value_len = sizeof(class);
|
|
Packit |
549fdc |
a_vals++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
attr = p11_kit_uri_get_attribute(find_data->info, CKA_ID);
|
|
Packit |
549fdc |
if (attr != NULL) {
|
|
Packit |
549fdc |
memcpy(a + a_vals, attr, sizeof(struct ck_attribute));
|
|
Packit |
549fdc |
a_vals++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (type != (ck_certificate_type_t) - 1) {
|
|
Packit |
549fdc |
a[a_vals].type = CKA_CERTIFICATE_TYPE;
|
|
Packit |
549fdc |
a[a_vals].value = &type;
|
|
Packit |
549fdc |
a[a_vals].value_len = sizeof type;
|
|
Packit |
549fdc |
a_vals++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
attr = p11_kit_uri_get_attribute(find_data->info, CKA_LABEL);
|
|
Packit |
549fdc |
if (attr != NULL) {
|
|
Packit |
549fdc |
memcpy(a + a_vals, attr, sizeof(struct ck_attribute));
|
|
Packit |
549fdc |
a_vals++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
rv = pkcs11_find_objects_init(sinfo->module, sinfo->pks, a,
|
|
Packit |
549fdc |
a_vals);
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: FindObjectsInit failed.\n");
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
while (pkcs11_find_objects
|
|
Packit |
549fdc |
(sinfo->module, sinfo->pks, &ctx, 1, &count) == CKR_OK
|
|
Packit |
549fdc |
&& count == 1) {
|
|
Packit |
549fdc |
rv = pkcs11_destroy_object(sinfo->module, sinfo->pks, ctx);
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
_gnutls_debug_log
|
|
Packit |
549fdc |
("p11: Cannot destroy object: %s\n",
|
|
Packit |
549fdc |
pkcs11_strerror(rv));
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
find_data->deleted++;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
found = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (found == 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
cleanup:
|
|
Packit |
549fdc |
pkcs11_find_objects_final(sinfo);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_delete_url:
|
|
Packit |
549fdc |
* @object_url: The URL of the object to delete.
|
|
Packit |
549fdc |
* @flags: One of GNUTLS_PKCS11_OBJ_* flags
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will delete objects matching the given URL.
|
|
Packit |
549fdc |
* Note that not all tokens support the delete operation.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, the number of objects deleted is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Since: 2.12.0
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int gnutls_pkcs11_delete_url(const char *object_url, unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct delete_data_st find_data;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
memset(&find_data, 0, sizeof(find_data));
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(object_url, &find_data.info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
_pkcs11_traverse_tokens(delete_obj_url_cb, &find_data,
|
|
Packit |
549fdc |
find_data.info, NULL,
|
|
Packit |
549fdc |
SESSION_WRITE |
|
|
Packit |
549fdc |
pkcs11_obj_flags_to_int(flags));
|
|
Packit |
549fdc |
p11_kit_uri_free(find_data.info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return find_data.deleted;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_token_init:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @so_pin: Security Officer's PIN
|
|
Packit |
549fdc |
* @label: A name to be used for the token
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will initialize (format) a token. If the token is
|
|
Packit |
549fdc |
* at a factory defaults state the security officer's PIN given will be
|
|
Packit |
549fdc |
* set to be the default. Otherwise it should match the officer's PIN.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
gnutls_pkcs11_token_init(const char *token_url,
|
|
Packit |
549fdc |
const char *so_pin, const char *label)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct p11_kit_uri *info = NULL;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
struct ck_function_list *module;
|
|
Packit |
549fdc |
ck_slot_id_t slot;
|
|
Packit |
549fdc |
char flabel[32];
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_find_slot(&module, &slot, info, NULL, NULL, NULL);
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* so it seems memset has other uses than zeroing! */
|
|
Packit |
549fdc |
memset(flabel, ' ', sizeof(flabel));
|
|
Packit |
549fdc |
if (label != NULL)
|
|
Packit |
549fdc |
memcpy(flabel, label, strlen(label));
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
rv = pkcs11_init_token(module, slot, (uint8_t *) so_pin,
|
|
Packit |
549fdc |
strlen(so_pin), (uint8_t *) flabel);
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
|
|
Packit |
549fdc |
return pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_token_set_pin:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @oldpin: old user's PIN
|
|
Packit |
549fdc |
* @newpin: new user's PIN
|
|
Packit |
549fdc |
* @flags: one of #gnutls_pin_flag_t.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will modify or set a user's PIN for the given token.
|
|
Packit |
549fdc |
* If it is called to set a user pin for first time the oldpin must
|
|
Packit |
549fdc |
* be NULL.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
gnutls_pkcs11_token_set_pin(const char *token_url,
|
|
Packit |
549fdc |
const char *oldpin,
|
|
Packit |
549fdc |
const char *newpin, unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct p11_kit_uri *info = NULL;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
unsigned int ses_flags;
|
|
Packit |
549fdc |
struct pkcs11_session_info sinfo;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (((flags & GNUTLS_PIN_USER) && oldpin == NULL) ||
|
|
Packit |
549fdc |
(flags & GNUTLS_PIN_SO))
|
|
Packit |
549fdc |
ses_flags = SESSION_WRITE | SESSION_LOGIN | SESSION_SO;
|
|
Packit |
549fdc |
else
|
|
Packit |
549fdc |
ses_flags = SESSION_WRITE | SESSION_LOGIN;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_open_session(&sinfo, NULL, info, ses_flags);
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (oldpin == NULL) {
|
|
Packit |
549fdc |
rv = pkcs11_init_pin(sinfo.module, sinfo.pks,
|
|
Packit |
549fdc |
(uint8_t *) newpin, strlen(newpin));
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n",
|
|
Packit |
549fdc |
pkcs11_strerror(rv));
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto finish;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
rv = pkcs11_set_pin(sinfo.module, sinfo.pks,
|
|
Packit |
549fdc |
oldpin, strlen(oldpin),
|
|
Packit |
549fdc |
newpin, strlen(newpin));
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n",
|
|
Packit |
549fdc |
pkcs11_strerror(rv));
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto finish;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
finish:
|
|
Packit |
549fdc |
pkcs11_close_session(&sinfo);
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_token_get_random:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @len: The number of bytes of randomness to request
|
|
Packit |
549fdc |
* @rnddata: A pointer to the memory area to be filled with random data
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will get random data from the given token.
|
|
Packit |
549fdc |
* It will store rnddata and fill the memory pointed to by rnddata with
|
|
Packit |
549fdc |
* len random bytes from the token.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
gnutls_pkcs11_token_get_random(const char *token_url,
|
|
Packit |
549fdc |
void *rnddata, size_t len)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
struct p11_kit_uri *info = NULL;
|
|
Packit |
549fdc |
ck_rv_t rv;
|
|
Packit |
549fdc |
struct pkcs11_session_info sinfo;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
PKCS11_CHECK_INIT;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = pkcs11_open_session(&sinfo, NULL, info, 0);
|
|
Packit |
549fdc |
p11_kit_uri_free(info);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
rv = _gnutls_pkcs11_get_random(sinfo.module, sinfo.pks, rnddata, len);
|
|
Packit |
549fdc |
if (rv != CKR_OK) {
|
|
Packit |
549fdc |
gnutls_assert();
|
|
Packit |
549fdc |
_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
|
|
Packit |
549fdc |
ret = pkcs11_rv_to_err(rv);
|
|
Packit |
549fdc |
goto finish;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
finish:
|
|
Packit |
549fdc |
pkcs11_close_session(&sinfo);
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#if 0
|
|
Packit |
549fdc |
/* For documentation purposes */
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_copy_x509_crt:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @crt: A certificate
|
|
Packit |
549fdc |
* @label: A name to be used for the stored data
|
|
Packit |
549fdc |
* @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will copy a certificate into a PKCS #11 token specified by
|
|
Packit |
549fdc |
* a URL. The certificate can be marked as trusted or not.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Since: 2.12.0
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int gnutls_pkcs11_copy_x509_crt(const char *token_url,
|
|
Packit |
549fdc |
gnutls_x509_crt_t crt, const char *label,
|
|
Packit |
549fdc |
unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int x;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/**
|
|
Packit |
549fdc |
* gnutls_pkcs11_copy_x509_privkey:
|
|
Packit |
549fdc |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit |
549fdc |
* @key: A private key
|
|
Packit |
549fdc |
* @label: A name to be used for the stored data
|
|
Packit |
549fdc |
* @key_usage: One of GNUTLS_KEY_*
|
|
Packit |
549fdc |
* @flags: One of GNUTLS_PKCS11_OBJ_* flags
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This function will copy a private key into a PKCS #11 token specified by
|
|
Packit |
549fdc |
* a URL. It is highly recommended flags to contain %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE
|
|
Packit |
549fdc |
* unless there is a strong reason not to.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
549fdc |
* negative error value.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* Since: 2.12.0
|
|
Packit |
549fdc |
**/
|
|
Packit |
549fdc |
int gnutls_pkcs11_copy_x509_privkey(const char *token_url,
|
|
Packit |
549fdc |
gnutls_x509_privkey_t key,
|
|
Packit |
549fdc |
const char *label,
|
|
Packit |
549fdc |
unsigned int key_usage, unsigned int flags)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int x;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#endif
|