Blame lib/pkcs11_secret.c

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
}