1/*
2 * GnuTLS PKCS#11 support
3 * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4 * Copyright (C) 2012 Nikos Mavrogiannopoulos
5 *
6 * Author: Nikos Mavrogiannopoulos
7 *
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
20 */
21
22#include <gnutls_int.h>
23#include <gnutls/pkcs11.h>
24#include <stdio.h>
25#include <string.h>
26#include <gnutls_errors.h>
27#include <gnutls_datum.h>
28#include <pkcs11_int.h>
29#include <gnutls/abstract.h>
30#include <gnutls_pk.h>
31#include <x509_int.h>
32#include <openpgp/openpgp_int.h>
33#include <openpgp/gnutls_openpgp.h>
34#include <gnutls_sig.h>
35#include <algorithms.h>
36#include <abstract_int.h>
37
38/**
39 * gnutls_privkey_get_type:
40 * @key: should contain a #gnutls_privkey_t structure
41 *
42 * This function will return the type of the private key. This is
43 * actually the type of the subsystem used to set this private key.
44 *
45 * Returns: a member of the #gnutls_privkey_type_t enumeration on
46 * success, or a negative error code on error.
47 *
48 * Since: 2.12.0
49 **/
50gnutls_privkey_type_t
51gnutls_privkey_get_type (gnutls_privkey_t key)
52{
53 return key->type;
54}
55
56/**
57 * gnutls_privkey_get_pk_algorithm:
58 * @key: should contain a #gnutls_privkey_t structure
59 * @bits: If set will return the number of bits of the parameters (may be NULL)
60 *
61 * This function will return the public key algorithm of a private
62 * key and if possible will return a number of bits that indicates
63 * the security parameter of the key.
64 *
65 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
66 * success, or a negative error code on error.
67 *
68 * Since: 2.12.0
69 **/
70int
71gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
72{
73 switch (key->type)
74 {
75#ifdef ENABLE_OPENPGP
76 case GNUTLS_PRIVKEY_OPENPGP:
77 return gnutls_openpgp_privkey_get_pk_algorithm (key->key.openpgp, bits);
78#endif
79#ifdef ENABLE_PKCS11
80 case GNUTLS_PRIVKEY_PKCS11:
81 return gnutls_pkcs11_privkey_get_pk_algorithm (key->key.pkcs11, bits);
82#endif
83 case GNUTLS_PRIVKEY_X509:
84 if (bits)
85 *bits = _gnutls_mpi_get_nbits (key->key.x509->params.params[0]);
86 return gnutls_x509_privkey_get_pk_algorithm (key->key.x509);
87 case GNUTLS_PRIVKEY_EXT:
88 if (bits)
89 *bits = 0;
90 return key->pk_algorithm;
91 default:
92 gnutls_assert ();
93 return GNUTLS_E_INVALID_REQUEST;
94 }
95
96}
97
98static int
99privkey_to_pubkey (gnutls_pk_algorithm_t pk,
100 const gnutls_pk_params_st* priv,
101 gnutls_pk_params_st* pub)
102{
103 int ret;
104
105 switch (pk)
106 {
107 case GNUTLS_PK_RSA:
108 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
109 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
110
111 pub->params_nr = RSA_PUBLIC_PARAMS;
112
113 if (pub->params[0] == NULL || pub->params[1] == NULL)
114 {
115 gnutls_assert ();
116 ret = GNUTLS_E_MEMORY_ERROR;
117 goto cleanup;
118 }
119
120 break;
121 case GNUTLS_PK_DSA:
122 pub->params[0] = _gnutls_mpi_copy (priv->params[0]);
123 pub->params[1] = _gnutls_mpi_copy (priv->params[1]);
124 pub->params[2] = _gnutls_mpi_copy (priv->params[2]);
125 pub->params[3] = _gnutls_mpi_copy (priv->params[3]);
126
127 pub->params_nr = DSA_PUBLIC_PARAMS;
128
129 if (pub->params[0] == NULL || pub->params[1] == NULL ||
130 pub->params[2] == NULL || pub->params[3] == NULL)
131 {
132 gnutls_assert ();
133 ret = GNUTLS_E_MEMORY_ERROR;
134 goto cleanup;
135 }
136
137 break;
138 case GNUTLS_PK_EC:
139 pub->params[ECC_X] = _gnutls_mpi_copy (priv->params[ECC_X]);
140 pub->params[ECC_Y] = _gnutls_mpi_copy (priv->params[ECC_Y]);
141
142 pub->params_nr = ECC_PUBLIC_PARAMS;
143 pub->flags = priv->flags;
144
145 if (pub->params[ECC_X] == NULL || pub->params[ECC_Y] == NULL)
146 {
147 gnutls_assert ();
148 ret = GNUTLS_E_MEMORY_ERROR;
149 goto cleanup;
150 }
151
152 break;
153 default:
154 gnutls_assert ();
155 return GNUTLS_E_INVALID_REQUEST;
156 }
157
158 return 0;
159cleanup:
160 gnutls_pk_params_release(pub);
161 return ret;
162}
163
164
165/* Returns the public key of the private key (if possible)
166 */
167int
168_gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
169 gnutls_pk_params_st * params)
170{
171 int ret;
172 gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL);
173
174 switch (key->type)
175 {
176#ifdef ENABLE_OPENPGP
177 case GNUTLS_PRIVKEY_OPENPGP:
178 {
179 gnutls_pk_params_st tmp_params;
180 uint32_t kid[2];
181 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
182
183 ret =
184 gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp,
185 keyid);
186 if (ret == 0)
187 {
188 KEYID_IMPORT (kid, keyid);
189 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid,
190 &tmp_params);
191 }
192 else
193 ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL,
194 &tmp_params);
195
196 if (ret < 0)
197 {
198 gnutls_assert ();
199 return ret;
200 }
201
202 ret = privkey_to_pubkey (pk,
203 &tmp_params,
204 params);
205
206 gnutls_pk_params_release(&tmp_params);
207 }
208
209 break;
210#endif
211 case GNUTLS_PRIVKEY_X509:
212 ret = privkey_to_pubkey (pk,
213 &key->key.x509->params,
214 params);
215 break;
216 default:
217 gnutls_assert ();
218 return GNUTLS_E_INVALID_REQUEST;
219 }
220
221 return ret;
222}
223
224/**
225 * gnutls_privkey_init:
226 * @key: The structure to be initialized
227 *
228 * This function will initialize an private key structure.
229 *
230 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
231 * negative error value.
232 *
233 * Since: 2.12.0
234 **/
235int
236gnutls_privkey_init (gnutls_privkey_t * key)
237{
238 *key = gnutls_calloc (1, sizeof (struct gnutls_privkey_st));
239 if (*key == NULL)
240 {
241 gnutls_assert ();
242 return GNUTLS_E_MEMORY_ERROR;
243 }
244
245 return 0;
246}
247
248/**
249 * gnutls_privkey_deinit:
250 * @key: The structure to be deinitialized
251 *
252 * This function will deinitialize a private key structure.
253 *
254 * Since: 2.12.0
255 **/
256void
257gnutls_privkey_deinit (gnutls_privkey_t key)
258{
259 if (key == NULL) return;
260
261 if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
262 switch (key->type)
263 {
264#ifdef ENABLE_OPENPGP
265 case GNUTLS_PRIVKEY_OPENPGP:
266 gnutls_openpgp_privkey_deinit (key->key.openpgp);
267 break;
268#endif
269#ifdef ENABLE_PKCS11
270 case GNUTLS_PRIVKEY_PKCS11:
271 gnutls_pkcs11_privkey_deinit (key->key.pkcs11);
272 break;
273#endif
274 case GNUTLS_PRIVKEY_X509:
275 gnutls_x509_privkey_deinit (key->key.x509);
276 break;
277 case GNUTLS_PRIVKEY_EXT:
278 if (key->key.ext.deinit_func != NULL)
279 key->key.ext.deinit_func(key, key->key.ext.userdata);
280 break;
281 default:
282 break;
283 }
284 gnutls_free (key);
285}
286
287/* will fail if the private key contains an actual key.
288 */
289static int check_if_clean(gnutls_privkey_t key)
290{
291 if (key->type != 0)
292 return GNUTLS_E_INVALID_REQUEST;
293
294 return 0;
295}
296
297#ifdef ENABLE_PKCS11
298
299/**
300 * gnutls_privkey_import_pkcs11:
301 * @pkey: The private key
302 * @key: The private key to be imported
303 * @flags: Flags for the import
304 *
305 * This function will import the given private key to the abstract
306 * #gnutls_privkey_t structure.
307 *
308 * The #gnutls_pkcs11_privkey_t object must not be deallocated
309 * during the lifetime of this structure.
310 *
311 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
312 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
313 *
314 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
315 * negative error value.
316 *
317 * Since: 2.12.0
318 **/
319int
320gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey,
321 gnutls_pkcs11_privkey_t key, unsigned int flags)
322{
323int ret;
324
325 ret = check_if_clean(pkey);
326 if (ret < 0)
327 {
328 gnutls_assert();
329 return ret;
330 }
331
332 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
333 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
334
335 pkey->key.pkcs11 = key;
336 pkey->type = GNUTLS_PRIVKEY_PKCS11;
337 pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm (key, NULL);
338 pkey->flags = flags;
339
340 if (pkey->pin.data)
341 gnutls_pkcs11_privkey_set_pin_function(key, pkey->pin.cb, pkey->pin.data);
342
343 return 0;
344}
345
346/**
347 * gnutls_privkey_import_pkcs11_url:
348 * @key: A key of type #gnutls_pubkey_t
349 * @url: A PKCS 11 url
350 *
351 * This function will import a PKCS 11 private key to a #gnutls_private_key_t
352 * structure.
353 *
354 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
355 * negative error value.
356 *
357 * Since: 3.1.0
358 **/
359int
360gnutls_privkey_import_pkcs11_url (gnutls_privkey_t key, const char *url)
361{
362 gnutls_pkcs11_privkey_t pkey;
363 int ret;
364
365 ret = gnutls_pkcs11_privkey_init (&pkey);
366 if (ret < 0)
367 {
368 gnutls_assert ();
369 return ret;
370 }
371
372 if (key->pin.cb)
373 gnutls_pkcs11_privkey_set_pin_function(pkey, key->pin.cb, key->pin.data);
374
375 ret = gnutls_pkcs11_privkey_import_url (pkey, url, 0);
376 if (ret < 0)
377 {
378 gnutls_assert ();
379 goto cleanup;
380 }
381
382 ret = gnutls_privkey_import_pkcs11 (key, pkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
383 if (ret < 0)
384 {
385 gnutls_assert ();
386 goto cleanup;
387 }
388
389 return 0;
390
391cleanup:
392 gnutls_pkcs11_privkey_deinit (pkey);
393
394 return ret;
395}
396
397#endif /* ENABLE_PKCS11 */
398
399/**
400 * gnutls_privkey_import_ext:
401 * @pkey: The private key
402 * @pk: The public key algorithm
403 * @userdata: private data to be provided to the callbacks
404 * @sign_func: callback for signature operations
405 * @decrypt_func: callback for decryption operations
406 * @flags: Flags for the import
407 *
408 * This function will associate the given callbacks with the
409 * #gnutls_privkey_t structure. At least one of the two callbacks
410 * must be non-null.
411 *
412 * See also gnutls_privkey_import_ext2().
413 *
414 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
415 * negative error value.
416 *
417 * Since: 3.0
418 **/
419int
420gnutls_privkey_import_ext (gnutls_privkey_t pkey,
421 gnutls_pk_algorithm_t pk,
422 void* userdata,
423 gnutls_privkey_sign_func sign_func,
424 gnutls_privkey_decrypt_func decrypt_func,
425 unsigned int flags)
426{
427 return gnutls_privkey_import_ext2( pkey, pk, userdata, sign_func, decrypt_func,
428 NULL, flags);
429}
430
431/**
432 * gnutls_privkey_import_ext2:
433 * @pkey: The private key
434 * @pk: The public key algorithm
435 * @userdata: private data to be provided to the callbacks
436 * @sign_func: callback for signature operations
437 * @decrypt_func: callback for decryption operations
438 * @deinit_func: a deinitialization function
439 * @flags: Flags for the import
440 *
441 * This function will associate the given callbacks with the
442 * #gnutls_privkey_t structure. At least one of the two callbacks
443 * must be non-null. If a deinitialization function is provided
444 * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
445 *
446 * Note that the signing function is supposed to "raw" sign data, i.e.,
447 * without any hashing or preprocessing. In case of RSA the DigestInfo
448 * will be provided, and the signing function is expected to do the PKCS #1
449 * 1.5 padding and the exponentiation.
450 *
451 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
452 * negative error value.
453 *
454 * Since: 3.1
455 **/
456int
457gnutls_privkey_import_ext2 (gnutls_privkey_t pkey,
458 gnutls_pk_algorithm_t pk,
459 void* userdata,
460 gnutls_privkey_sign_func sign_func,
461 gnutls_privkey_decrypt_func decrypt_func,
462 gnutls_privkey_deinit_func deinit_func,
463 unsigned int flags)
464{
465int ret;
466
467 ret = check_if_clean(pkey);
468 if (ret < 0)
469 {
470 gnutls_assert();
471 return ret;
472 }
473
474 if (sign_func == NULL && decrypt_func == NULL)
475 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
476
477 pkey->key.ext.sign_func = sign_func;
478 pkey->key.ext.decrypt_func = decrypt_func;
479 pkey->key.ext.deinit_func = deinit_func;
480 pkey->key.ext.userdata = userdata;
481 pkey->type = GNUTLS_PRIVKEY_EXT;
482 pkey->pk_algorithm = pk;
483 pkey->flags = flags;
484
485 /* Ensure gnutls_privkey_deinit() calls the deinit_func */
486 if (deinit_func)
487 pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
488
489 return 0;
490}
491
492/**
493 * gnutls_privkey_import_x509:
494 * @pkey: The private key
495 * @key: The private key to be imported
496 * @flags: Flags for the import
497 *
498 * This function will import the given private key to the abstract
499 * #gnutls_privkey_t structure.
500 *
501 * The #gnutls_x509_privkey_t object must not be deallocated
502 * during the lifetime of this structure.
503 *
504 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
505 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
506 *
507 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
508 * negative error value.
509 *
510 * Since: 2.12.0
511 **/
512int
513gnutls_privkey_import_x509 (gnutls_privkey_t pkey,
514 gnutls_x509_privkey_t key, unsigned int flags)
515{
516int ret;
517
518 ret = check_if_clean(pkey);
519 if (ret < 0)
520 {
521 gnutls_assert();
522 return ret;
523 }
524
525 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
526 {
527 ret = gnutls_x509_privkey_init(&pkey->key.x509);
528 if (ret < 0)
529 return gnutls_assert_val(ret);
530
531 ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
532 if (ret < 0)
533 {
534 gnutls_x509_privkey_deinit(pkey->key.x509);
535 return gnutls_assert_val(ret);
536 }
537 }
538 else
539 pkey->key.x509 = key;
540
541 pkey->type = GNUTLS_PRIVKEY_X509;
542 pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm (key);
543 pkey->flags = flags;
544
545 return 0;
546}
547
548#ifdef ENABLE_OPENPGP
549/**
550 * gnutls_privkey_import_openpgp:
551 * @pkey: The private key
552 * @key: The private key to be imported
553 * @flags: Flags for the import
554 *
555 * This function will import the given private key to the abstract
556 * #gnutls_privkey_t structure.
557 *
558 * The #gnutls_openpgp_privkey_t object must not be deallocated
559 * during the lifetime of this structure. The subkey set as
560 * preferred will be used, or the master key otherwise.
561 *
562 * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
563 * and %GNUTLS_PRIVKEY_IMPORT_COPY.
564 *
565 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
566 * negative error value.
567 *
568 * Since: 2.12.0
569 **/
570int
571gnutls_privkey_import_openpgp (gnutls_privkey_t pkey,
572 gnutls_openpgp_privkey_t key,
573 unsigned int flags)
574{
575int ret, idx;
576uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
577
578 ret = check_if_clean(pkey);
579 if (ret < 0)
580 {
581 gnutls_assert();
582 return ret;
583 }
584
585 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
586 {
587 ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp);
588 if (ret < 0)
589 return gnutls_assert_val(ret);
590
591 ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key);
592 if (ret < 0)
593 {
594 gnutls_openpgp_privkey_deinit(pkey->key.openpgp);
595 return gnutls_assert_val(ret);
596 }
597 }
598 else
599 pkey->key.openpgp = key;
600
601 pkey->type = GNUTLS_PRIVKEY_OPENPGP;
602
603 ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
604 if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR)
605 {
606 pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm(key, NULL);
607 }
608 else
609 {
610 if (ret < 0)
611 return gnutls_assert_val(ret);
612
613 idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
614
615 pkey->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
616 }
617
618 pkey->flags = flags;
619
620 return 0;
621}
622
623/**
624 * gnutls_privkey_import_openpgp_raw:
625 * @pkey: The private key
626 * @data: The private key data to be imported
627 * @format: The format of the private key
628 * @keyid: The key id to use (optional)
629 * @password: A password (optional)
630 *
631 * This function will import the given private key to the abstract
632 * #gnutls_privkey_t structure.
633 *
634 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
635 * negative error value.
636 *
637 * Since: 3.1.0
638 **/
639int gnutls_privkey_import_openpgp_raw (gnutls_privkey_t pkey,
640 const gnutls_datum_t * data,
641 gnutls_openpgp_crt_fmt_t format,
642 const gnutls_openpgp_keyid_t keyid,
643 const char* password)
644{
645 gnutls_openpgp_privkey_t xpriv;
646 int ret;
647
648 ret = gnutls_openpgp_privkey_init(&xpriv);
649 if (ret < 0)
650 return gnutls_assert_val(ret);
651
652 ret = gnutls_openpgp_privkey_import(xpriv, data, format, password, 0);
653 if (ret < 0)
654 {
655 gnutls_assert();
656 goto cleanup;
657 }
658
659 if(keyid)
660 {
661 ret = gnutls_openpgp_privkey_set_preferred_key_id(xpriv, keyid);
662 if (ret < 0)
663 {
664 gnutls_assert();
665 goto cleanup;
666 }
667 }
668
669 ret = gnutls_privkey_import_openpgp(pkey, xpriv, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
670 if (ret < 0)
671 {
672 gnutls_assert();
673 goto cleanup;
674 }
675
676 ret = 0;
677
678cleanup:
679 gnutls_openpgp_privkey_deinit(xpriv);
680
681 return ret;
682}
683#endif
684
685/**
686 * gnutls_privkey_sign_data:
687 * @signer: Holds the key
688 * @hash: should be a digest algorithm
689 * @flags: Zero or one of %gnutls_privkey_flags_t
690 * @data: holds the data to be signed
691 * @signature: will contain the signature allocate with gnutls_malloc()
692 *
693 * This function will sign the given data using a signature algorithm
694 * supported by the private key. Signature algorithms are always used
695 * together with a hash functions. Different hash functions may be
696 * used for the RSA algorithm, but only the SHA family for the DSA keys.
697 *
698 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
699 * the hash algorithm.
700 *
701 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
702 * negative error value.
703 *
704 * Since: 2.12.0
705 **/
706int
707gnutls_privkey_sign_data (gnutls_privkey_t signer,
708 gnutls_digest_algorithm_t hash,
709 unsigned int flags,
710 const gnutls_datum_t * data,
711 gnutls_datum_t * signature)
712{
713 int ret;
714 gnutls_datum_t digest;
715 const mac_entry_st* me = mac_to_entry(hash);
716
717 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
718 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
719
720 ret = pk_hash_data (signer->pk_algorithm, me, NULL, data, &digest);
721 if (ret < 0)
722 {
723 gnutls_assert ();
724 return ret;
725 }
726
727 ret = pk_prepare_hash (signer->pk_algorithm, me, &digest);
728 if (ret < 0)
729 {
730 gnutls_assert ();
731 goto cleanup;
732 }
733
734 ret = gnutls_privkey_sign_raw_data (signer, flags, &digest, signature);
735 _gnutls_free_datum (&digest);
736
737 if (ret < 0)
738 {
739 gnutls_assert ();
740 return ret;
741 }
742
743 return 0;
744
745cleanup:
746 _gnutls_free_datum (&digest);
747 return ret;
748}
749
750/**
751 * gnutls_privkey_sign_hash:
752 * @signer: Holds the signer's key
753 * @hash_algo: The hash algorithm used
754 * @flags: Zero or one of %gnutls_privkey_flags_t
755 * @hash_data: holds the data to be signed
756 * @signature: will contain newly allocated signature
757 *
758 * This function will sign the given hashed data using a signature algorithm
759 * supported by the private key. Signature algorithms are always used
760 * together with a hash functions. Different hash functions may be
761 * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
762 *
763 * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
764 * the hash algorithm.
765 *
766 * Note that if %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA flag is specified this function
767 * will ignore @hash_algo and perform a raw PKCS1 signature.
768 *
769 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
770 * negative error value.
771 *
772 * Since: 2.12.0
773 **/
774int
775gnutls_privkey_sign_hash (gnutls_privkey_t signer,
776 gnutls_digest_algorithm_t hash_algo,
777 unsigned int flags,
778 const gnutls_datum_t * hash_data,
779 gnutls_datum_t * signature)
780{
781 int ret;
782 gnutls_datum_t digest;
783
784 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
785 return gnutls_privkey_sign_raw_data (signer, flags, hash_data, signature);
786
787 digest.data = gnutls_malloc (hash_data->size);
788 if (digest.data == NULL)
789 {
790 gnutls_assert ();
791 return GNUTLS_E_MEMORY_ERROR;
792 }
793 digest.size = hash_data->size;
794 memcpy (digest.data, hash_data->data, digest.size);
795
796 ret = pk_prepare_hash (signer->pk_algorithm, mac_to_entry(hash_algo), &digest);
797 if (ret < 0)
798 {
799 gnutls_assert ();
800 goto cleanup;
801 }
802
803 ret = gnutls_privkey_sign_raw_data (signer, flags, &digest, signature);
804 if (ret < 0)
805 {
806 gnutls_assert ();
807 goto cleanup;
808 }
809
810 ret = 0;
811
812cleanup:
813 _gnutls_free_datum (&digest);
814 return ret;
815}
816
817/**
818 * gnutls_privkey_sign_raw_data:
819 * @key: Holds the key
820 * @flags: should be zero
821 * @data: holds the data to be signed
822 * @signature: will contain the signature allocate with gnutls_malloc()
823 *
824 * This function will sign the given data using a signature algorithm
825 * supported by the private key. Note that this is a low-level function
826 * and does not apply any preprocessing or hash on the signed data.
827 * For example on an RSA key the input @data should be of the DigestInfo
828 * PKCS #1 1.5 format. Use it only if you know what are you doing.
829 *
830 * Note this function is equivalent to using the %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA
831 * flag with gnutls_privkey_sign_hash().
832 *
833 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
834 * negative error value.
835 *
836 * Since: 3.1.10
837 **/
838int
839gnutls_privkey_sign_raw_data (gnutls_privkey_t key,
840 unsigned flags,
841 const gnutls_datum_t * data,
842 gnutls_datum_t * signature)
843{
844 switch (key->type)
845 {
846#ifdef ENABLE_OPENPGP
847 case GNUTLS_PRIVKEY_OPENPGP:
848 return gnutls_openpgp_privkey_sign_hash (key->key.openpgp,
849 data, signature);
850#endif
851#ifdef ENABLE_PKCS11
852 case GNUTLS_PRIVKEY_PKCS11:
853 return _gnutls_pkcs11_privkey_sign_hash (key->key.pkcs11,
854 data, signature);
855#endif
856 case GNUTLS_PRIVKEY_X509:
857 return _gnutls_pk_sign (key->key.x509->pk_algorithm,
858 signature, data, &key->key.x509->params);
859 case GNUTLS_PRIVKEY_EXT:
860 if (key->key.ext.sign_func == NULL)
861 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
862 return key->key.ext.sign_func(key, key->key.ext.userdata, data, signature);
863 default:
864 gnutls_assert ();
865 return GNUTLS_E_INVALID_REQUEST;
866 }
867}
868
869/**
870 * gnutls_privkey_decrypt_data:
871 * @key: Holds the key
872 * @flags: zero for now
873 * @ciphertext: holds the data to be decrypted
874 * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
875 *
876 * This function will decrypt the given data using the algorithm
877 * supported by the private key.
878 *
879 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
880 * negative error value.
881 *
882 * Since: 2.12.0
883 **/
884int
885gnutls_privkey_decrypt_data (gnutls_privkey_t key,
886 unsigned int flags,
887 const gnutls_datum_t * ciphertext,
888 gnutls_datum_t * plaintext)
889{
890 switch (key->type)
891 {
892#ifdef ENABLE_OPENPGP
893 case GNUTLS_PRIVKEY_OPENPGP:
894 return _gnutls_openpgp_privkey_decrypt_data (key->key.openpgp, flags,
895 ciphertext, plaintext);
896#endif
897 case GNUTLS_PRIVKEY_X509:
898 return _gnutls_pk_decrypt (key->pk_algorithm, plaintext, ciphertext,
899 &key->key.x509->params);
900#ifdef ENABLE_PKCS11
901 case GNUTLS_PRIVKEY_PKCS11:
902 return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11,
903 flags,
904 ciphertext, plaintext);
905#endif
906 case GNUTLS_PRIVKEY_EXT:
907 if (key->key.ext.decrypt_func == NULL)
908 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
909
910 return key->key.ext.decrypt_func(key, key->key.ext.userdata, ciphertext, plaintext);
911 default:
912 gnutls_assert ();
913 return GNUTLS_E_INVALID_REQUEST;
914 }
915}
916
917/**
918 * gnutls_privkey_import_x509_raw:
919 * @pkey: The private key
920 * @data: The private key data to be imported
921 * @format: The format of the private key
922 * @password: A password (optional)
923 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
924 *
925 * This function will import the given private key to the abstract
926 * #gnutls_privkey_t structure.
927 *
928 * The supported formats are basic unencrypted key, PKCS8, PKCS12,
929 * and the openssl format.
930 *
931 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
932 * negative error value.
933 *
934 * Since: 3.1.0
935 **/
936int gnutls_privkey_import_x509_raw (gnutls_privkey_t pkey,
937 const gnutls_datum_t * data,
938 gnutls_x509_crt_fmt_t format,
939 const char* password, unsigned int flags)
940{
941 gnutls_x509_privkey_t xpriv;
942 int ret;
943
944 ret = gnutls_x509_privkey_init(&xpriv);
945 if (ret < 0)
946 return gnutls_assert_val(ret);
947
948 ret = gnutls_x509_privkey_import2(xpriv, data, format, password, flags);
949 if (ret < 0)
950 {
951 gnutls_assert();
952 goto cleanup;
953 }
954
955 ret = gnutls_privkey_import_x509(pkey, xpriv, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
956 if (ret < 0)
957 {
958 gnutls_assert();
959 goto cleanup;
960 }
961
962 return 0;
963
964cleanup:
965 gnutls_x509_privkey_deinit(xpriv);
966
967 return ret;
968}
969
970/**
971 * gnutls_privkey_import_url:
972 * @key: A key of type #gnutls_privkey_t
973 * @url: A PKCS 11 url
974 * @flags: should be zero
975 *
976 * This function will import a PKCS11 or TPM URL as a
977 * private key. The supported URL types can be checked
978 * using gnutls_url_is_supported().
979 *
980 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
981 * negative error value.
982 *
983 * Since: 3.1.0
984 **/
985int
986gnutls_privkey_import_url (gnutls_privkey_t key, const char *url, unsigned int flags)
987{
988 if (strncmp(url, "pkcs11:", 7) == 0)
989#ifdef ENABLE_PKCS11
990 return gnutls_privkey_import_pkcs11_url(key, url);
991#else
992 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
993#endif
994
995 if (strncmp(url, "tpmkey:", 7) == 0)
996#ifdef HAVE_TROUSERS
997 return gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0);
998#else
999 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1000#endif
1001
1002 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1003}
1004
1005/**
1006 * gnutls_privkey_set_pin_function:
1007 * @key: A key of type #gnutls_privkey_t
1008 * @fn: the callback
1009 * @userdata: data associated with the callback
1010 *
1011 * This function will set a callback function to be used when
1012 * required to access the object. This function overrides any other
1013 * global PIN functions.
1014 *
1015 * Note that this function must be called right after initialization
1016 * to have effect.
1017 *
1018 * Since: 3.1.0
1019 *
1020 **/
1021void gnutls_privkey_set_pin_function (gnutls_privkey_t key,
1022 gnutls_pin_callback_t fn, void *userdata)
1023{
1024 key->pin.cb = fn;
1025 key->pin.data = userdata;
1026}
1027
1028/**
1029 * gnutls_privkey_status:
1030 * @key: Holds the key
1031 *
1032 * Checks the status of the private key token. This function
1033 * is an actual wrapper over gnutls_pkcs11_privkey_status(), and
1034 * if the private key is a PKCS #11 token it will check whether
1035 * it is inserted or not.
1036 *
1037 * Returns: this function will return non-zero if the token
1038 * holding the private key is still available (inserted), and zero otherwise.
1039 *
1040 * Since: 3.1.10
1041 *
1042 **/
1043int
1044gnutls_privkey_status (gnutls_privkey_t key)
1045{
1046 switch (key->type)
1047 {
1048#ifdef ENABLE_PKCS11
1049 case GNUTLS_PRIVKEY_PKCS11:
1050 return gnutls_pkcs11_privkey_status (key->key.pkcs11);
1051#endif
1052 default:
1053 return 1;
1054 }
1055}
1056