Tizen 2.0 Release
[external/libgnutls26.git] / lib / pkcs11_secret.c
1 /*
2  * GnuTLS PKCS#11 support
3  * Copyright (C) 2010 Free Software Foundation
4  * 
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the Free
19  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA 02111-1307, USA
21 */
22
23 #include <gnutls_int.h>
24 #include <gnutls/pkcs11.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_datum.h>
29 #include <pkcs11_int.h>
30 #include <random.h>
31
32 /**
33  * gnutls_pkcs11_copy_secret_key:
34  * @token_url: A PKCS #11 URL specifying a token
35  * @key: The raw key
36  * @label: A name to be used for the stored data
37  * @key_usage: One of GNUTLS_KEY_*
38  * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
39  *
40  * This function will copy a raw secret (symmetric) key into a PKCS #11 
41  * token specified by a URL. The key can be marked as sensitive or not.
42  *
43  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
44  *   negative error value.
45  **/
46 int
47 gnutls_pkcs11_copy_secret_key (const char *token_url, gnutls_datum_t * key,
48                                const char *label,
49                                unsigned int key_usage, unsigned int flags
50                                /* GNUTLS_PKCS11_OBJ_FLAG_* */ )
51 {
52   int ret;
53   struct ck_function_list *module;
54   ck_session_handle_t pks;
55   struct p11_kit_uri *info = NULL;
56   ck_rv_t rv;
57   struct ck_attribute a[12];
58   ck_object_class_t class = CKO_SECRET_KEY;
59   ck_object_handle_t obj;
60   ck_key_type_t keytype = CKK_GENERIC_SECRET;
61   ck_bool_t tval = 1;
62   int a_val;
63   opaque id[16];
64
65   ret = pkcs11_url_to_info (token_url, &info);
66   if (ret < 0)
67     {
68       gnutls_assert ();
69       return ret;
70     }
71
72   /* generate a unique ID */
73   ret = _gnutls_rnd (GNUTLS_RND_NONCE, id, sizeof (id));
74   if (ret < 0)
75     {
76       gnutls_assert ();
77       return ret;
78     }
79
80   ret =
81     pkcs11_open_session (&module, &pks, info,
82                          SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
83   p11_kit_uri_free (info);
84
85   if (ret < 0)
86     {
87       gnutls_assert ();
88       return ret;
89     }
90
91   /* FIXME: copy key usage flags */
92
93   a[0].type = CKA_CLASS;
94   a[0].value = &class;
95   a[0].value_len = sizeof (class);
96   a[1].type = CKA_VALUE;
97   a[1].value = key->data;
98   a[1].value_len = key->size;
99   a[2].type = CKA_TOKEN;
100   a[2].value = &tval;
101   a[2].value_len = sizeof (tval);
102   a[3].type = CKA_PRIVATE;
103   a[3].value = &tval;
104   a[3].value_len = sizeof (tval);
105   a[4].type = CKA_KEY_TYPE;
106   a[4].value = &keytype;
107   a[4].value_len = sizeof (keytype);
108   a[5].type = CKA_ID;
109   a[5].value = id;
110   a[5].value_len = sizeof (id);
111
112   a_val = 6;
113
114   if (label)
115     {
116       a[a_val].type = CKA_LABEL;
117       a[a_val].value = (void *) label;
118       a[a_val].value_len = strlen (label);
119       a_val++;
120     }
121
122   if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE)
123     tval = 1;
124   else
125     tval = 0;
126
127   a[a_val].type = CKA_SENSITIVE;
128   a[a_val].value = &tval;
129   a[a_val].value_len = sizeof (tval);
130   a_val++;
131
132   rv = pkcs11_create_object (module, pks, a, a_val, &obj);
133   if (rv != CKR_OK)
134     {
135       gnutls_assert ();
136       _gnutls_debug_log ("pkcs11: %s\n", pkcs11_strerror (rv));
137       ret = pkcs11_rv_to_err (rv);
138       goto cleanup;
139     }
140
141   /* generated! 
142    */
143
144   ret = 0;
145
146 cleanup:
147   pkcs11_close_session (module, pks);
148
149   return ret;
150
151 }