|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* GnuTLS PKCS#11 support
|
|
Packit Service |
4684c1 |
* Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Author: Nikos Mavrogiannopoulos, Stef Walter
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The GnuTLS is free software; you can redistribute it and/or
|
|
Packit Service |
4684c1 |
* modify it under the terms of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* as published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
4684c1 |
* the License, or (at your option) any later version.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This library is distributed in the hope that it will be useful, but
|
|
Packit Service |
4684c1 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4684c1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4684c1 |
* Lesser General Public License for more details.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
#include <gnutls/pkcs11.h>
|
|
Packit Service |
4684c1 |
#include <stdio.h>
|
|
Packit Service |
4684c1 |
#include <string.h>
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include <datum.h>
|
|
Packit Service |
4684c1 |
#include <pkcs11_int.h>
|
|
Packit Service |
4684c1 |
#include <random.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_pkcs11_copy_secret_key:
|
|
Packit Service |
4684c1 |
* @token_url: A PKCS #11 URL specifying a token
|
|
Packit Service |
4684c1 |
* @key: The raw key
|
|
Packit Service |
4684c1 |
* @label: A name to be used for the stored data
|
|
Packit Service |
4684c1 |
* @key_usage: One of GNUTLS_KEY_*
|
|
Packit Service |
4684c1 |
* @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will copy a raw secret (symmetric) key into a PKCS #11
|
|
Packit Service |
4684c1 |
* token specified by a URL. The key can be marked as sensitive or not.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 2.12.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_pkcs11_copy_secret_key(const char *token_url, gnutls_datum_t * key,
|
|
Packit Service |
4684c1 |
const char *label,
|
|
Packit Service |
4684c1 |
unsigned int key_usage, unsigned int flags
|
|
Packit Service |
4684c1 |
/* GNUTLS_PKCS11_OBJ_FLAG_* */ )
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
struct p11_kit_uri *info = NULL;
|
|
Packit Service |
4684c1 |
ck_rv_t rv;
|
|
Packit Service |
4684c1 |
struct ck_attribute a[12];
|
|
Packit Service |
4684c1 |
ck_object_class_t class = CKO_SECRET_KEY;
|
|
Packit Service |
4684c1 |
ck_object_handle_t ctx;
|
|
Packit Service |
4684c1 |
ck_key_type_t keytype = CKK_GENERIC_SECRET;
|
|
Packit Service |
4684c1 |
ck_bool_t tval = 1;
|
|
Packit Service |
4684c1 |
int a_val;
|
|
Packit Service |
4684c1 |
uint8_t id[16];
|
|
Packit Service |
4684c1 |
struct pkcs11_session_info sinfo;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
PKCS11_CHECK_INIT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&sinfo, 0, sizeof(sinfo));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = pkcs11_url_to_info(token_url, &info, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* generate a unique ID */
|
|
Packit Service |
4684c1 |
ret = gnutls_rnd(GNUTLS_RND_NONCE, id, sizeof(id));
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
pkcs11_open_session(&sinfo, NULL, info,
|
|
Packit Service |
4684c1 |
SESSION_WRITE |
|
|
Packit Service |
4684c1 |
pkcs11_obj_flags_to_int(flags));
|
|
Packit Service |
4684c1 |
p11_kit_uri_free(info);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* We do not copy key usage flags.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
a[0].type = CKA_CLASS;
|
|
Packit Service |
4684c1 |
a[0].value = &class;
|
|
Packit Service |
4684c1 |
a[0].value_len = sizeof(class);
|
|
Packit Service |
4684c1 |
a[1].type = CKA_VALUE;
|
|
Packit Service |
4684c1 |
a[1].value = key->data;
|
|
Packit Service |
4684c1 |
a[1].value_len = key->size;
|
|
Packit Service |
4684c1 |
a[2].type = CKA_TOKEN;
|
|
Packit Service |
4684c1 |
a[2].value = &tval;
|
|
Packit Service |
4684c1 |
a[2].value_len = sizeof(tval);
|
|
Packit Service |
4684c1 |
a[3].type = CKA_PRIVATE;
|
|
Packit Service |
4684c1 |
a[3].value = &tval;
|
|
Packit Service |
4684c1 |
a[3].value_len = sizeof(tval);
|
|
Packit Service |
4684c1 |
a[4].type = CKA_KEY_TYPE;
|
|
Packit Service |
4684c1 |
a[4].value = &keytype;
|
|
Packit Service |
4684c1 |
a[4].value_len = sizeof(keytype);
|
|
Packit Service |
4684c1 |
a[5].type = CKA_ID;
|
|
Packit Service |
4684c1 |
a[5].value = id;
|
|
Packit Service |
4684c1 |
a[5].value_len = sizeof(id);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
a_val = 6;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (label) {
|
|
Packit Service |
4684c1 |
a[a_val].type = CKA_LABEL;
|
|
Packit Service |
4684c1 |
a[a_val].value = (void *) label;
|
|
Packit Service |
4684c1 |
a[a_val].value_len = strlen(label);
|
|
Packit Service |
4684c1 |
a_val++;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_SENSITIVE))
|
|
Packit Service |
4684c1 |
tval = 1;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
tval = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
a[a_val].type = CKA_SENSITIVE;
|
|
Packit Service |
4684c1 |
a[a_val].value = &tval;
|
|
Packit Service |
4684c1 |
a[a_val].value_len = sizeof(tval);
|
|
Packit Service |
4684c1 |
a_val++;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx;;
|
|
Packit Service |
4684c1 |
if (rv != CKR_OK) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
|
|
Packit Service |
4684c1 |
ret = pkcs11_rv_to_err(rv);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* generated!
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
pkcs11_close_session(&sinfo);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|