Import PKCS #12 keys
[gnutls.git] / lib / x509 / privkey.c
blobca47fa7b0ed4002909c47dcd5e1526aa744c20a4
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
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 3 of
11 * the License, or (at your option) any later version.
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.
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/>
23 #include <gnutls_int.h>
24 #include <gnutls_datum.h>
25 #include <gnutls_global.h>
26 #include <gnutls_errors.h>
27 #include <gnutls_rsa_export.h>
28 #include <gnutls_sig.h>
29 #include <common.h>
30 #include <gnutls_x509.h>
31 #include <x509_b64.h>
32 #include <x509_int.h>
33 #include <gnutls_pk.h>
34 #include <gnutls_mpi.h>
35 #include <gnutls_ecc.h>
37 /**
38 * gnutls_x509_privkey_init:
39 * @key: The structure to be initialized
41 * This function will initialize an private key structure.
43 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
44 * negative error value.
45 **/
46 int
47 gnutls_x509_privkey_init (gnutls_x509_privkey_t * key)
49 *key = gnutls_calloc (1, sizeof (gnutls_x509_privkey_int));
51 if (*key)
53 (*key)->key = ASN1_TYPE_EMPTY;
54 (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN;
55 return 0; /* success */
58 return GNUTLS_E_MEMORY_ERROR;
61 /**
62 * gnutls_x509_privkey_deinit:
63 * @key: The structure to be deinitialized
65 * This function will deinitialize a private key structure.
66 **/
67 void
68 gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key)
70 if (!key)
71 return;
73 gnutls_pk_params_release(&key->params);
74 asn1_delete_structure (&key->key);
75 gnutls_free (key);
78 /**
79 * gnutls_x509_privkey_cpy:
80 * @dst: The destination key, which should be initialized.
81 * @src: The source key
83 * This function will copy a private key from source to destination
84 * key. Destination has to be initialized.
86 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
87 * negative error value.
88 **/
89 int
90 gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src)
92 unsigned int i;
93 int ret;
95 if (!src || !dst)
96 return GNUTLS_E_INVALID_REQUEST;
98 for (i = 0; i < src->params.params_nr; i++)
100 dst->params.params[i] = _gnutls_mpi_copy (src->params.params[i]);
101 if (dst->params.params[i] == NULL)
102 return GNUTLS_E_MEMORY_ERROR;
105 dst->params.params_nr = src->params.params_nr;
106 dst->params.flags = src->params.flags;
108 dst->pk_algorithm = src->pk_algorithm;
110 ret = _gnutls_asn1_encode_privkey (dst->pk_algorithm, &dst->key, &dst->params);
111 if (ret < 0)
113 gnutls_assert ();
114 return ret;
117 return 0;
120 /* Converts an RSA PKCS#1 key to
121 * an internal structure (gnutls_private_key)
123 ASN1_TYPE
124 _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
125 gnutls_x509_privkey_t pkey)
127 int result;
128 ASN1_TYPE pkey_asn;
130 gnutls_pk_params_init(&pkey->params);
132 if ((result =
133 asn1_create_element (_gnutls_get_gnutls_asn (),
134 "GNUTLS.RSAPrivateKey",
135 &pkey_asn)) != ASN1_SUCCESS)
137 gnutls_assert ();
138 return NULL;
141 result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
142 if (result != ASN1_SUCCESS)
144 gnutls_assert ();
145 goto error;
148 if ((result = _gnutls_x509_read_int (pkey_asn, "modulus",
149 &pkey->params.params[0])) < 0)
151 gnutls_assert ();
152 goto error;
154 pkey->params.params_nr++;
156 if ((result =
157 _gnutls_x509_read_int (pkey_asn, "publicExponent",
158 &pkey->params.params[1])) < 0)
160 gnutls_assert ();
161 goto error;
163 pkey->params.params_nr++;
165 if ((result =
166 _gnutls_x509_read_int (pkey_asn, "privateExponent",
167 &pkey->params.params[2])) < 0)
169 gnutls_assert ();
170 goto error;
172 pkey->params.params_nr++;
174 if ((result = _gnutls_x509_read_int (pkey_asn, "prime1",
175 &pkey->params.params[3])) < 0)
177 gnutls_assert ();
178 goto error;
180 pkey->params.params_nr++;
182 if ((result = _gnutls_x509_read_int (pkey_asn, "prime2",
183 &pkey->params.params[4])) < 0)
185 gnutls_assert ();
186 goto error;
188 pkey->params.params_nr++;
190 if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient",
191 &pkey->params.params[5])) < 0)
193 gnutls_assert ();
194 goto error;
196 pkey->params.params_nr++;
198 if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1",
199 &pkey->params.params[6])) < 0)
201 gnutls_assert ();
202 goto error;
204 pkey->params.params_nr++;
206 if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2",
207 &pkey->params.params[7])) < 0)
209 gnutls_assert ();
210 goto error;
212 pkey->params.params_nr++;
214 result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params);
215 if (result < 0)
217 gnutls_assert ();
218 goto error;
221 pkey->params.params_nr = RSA_PRIVATE_PARAMS;
223 return pkey_asn;
225 error:
226 asn1_delete_structure (&pkey_asn);
227 gnutls_pk_params_release (&pkey->params);
228 return NULL;
232 /* Converts an ECC key to
233 * an internal structure (gnutls_private_key)
235 ASN1_TYPE
236 _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key,
237 gnutls_x509_privkey_t pkey)
239 int ret;
240 ASN1_TYPE pkey_asn;
241 unsigned int version;
242 char oid[MAX_OID_SIZE];
243 int oid_size;
244 gnutls_datum out;
246 gnutls_pk_params_init(&pkey->params);
248 if ((ret =
249 asn1_create_element (_gnutls_get_gnutls_asn (),
250 "GNUTLS.ECPrivateKey",
251 &pkey_asn)) != ASN1_SUCCESS)
253 gnutls_assert ();
254 return NULL;
257 ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
258 if (ret != ASN1_SUCCESS)
260 gnutls_assert ();
261 goto error;
264 ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version);
265 if (ret < 0)
267 gnutls_assert();
268 goto error;
271 if (version != 1)
273 _gnutls_debug_log("ECC private key version %u is not supported\n", version);
274 gnutls_assert();
275 goto error;
278 /* read the curve */
279 oid_size = sizeof(oid);
280 ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size);
281 if (ret != ASN1_SUCCESS)
283 gnutls_assert ();
284 goto error;
287 pkey->params.flags = _gnutls_oid_to_ecc_curve(oid);
288 if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID)
290 _gnutls_debug_log("Curve %s is not supported\n", oid);
291 gnutls_assert();
292 goto error;
295 ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params);
296 if (ret < 0)
298 gnutls_assert();
299 goto error;
302 /* read the public key */
303 ret = _gnutls_x509_read_value (pkey_asn, "publicKey", &out);
304 if (ret < 0)
306 gnutls_assert();
307 goto error;
310 ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[ECC_X],
311 &pkey->params.params[ECC_Y]);
313 _gnutls_free_datum(&out);
314 if (ret < 0)
316 gnutls_assert();
317 goto error;
319 pkey->params.params_nr += 2;
321 /* read the private key */
322 ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[ECC_K]);
323 if (ret < 0)
325 gnutls_assert();
326 goto error;
328 pkey->params.params_nr ++;
330 return pkey_asn;
332 error:
333 asn1_delete_structure (&pkey_asn);
334 gnutls_pk_params_release (&pkey->params);
335 return NULL;
340 static ASN1_TYPE
341 decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
343 int result;
344 ASN1_TYPE dsa_asn;
346 if ((result =
347 asn1_create_element (_gnutls_get_gnutls_asn (),
348 "GNUTLS.DSAPrivateKey",
349 &dsa_asn)) != ASN1_SUCCESS)
351 gnutls_assert ();
352 return NULL;
355 pkey->params.params_nr = 0;
357 result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL);
358 if (result != ASN1_SUCCESS)
360 gnutls_assert ();
361 goto error;
364 if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params.params[0])) < 0)
366 gnutls_assert ();
367 goto error;
369 pkey->params.params_nr++;
371 if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params.params[1])) < 0)
373 gnutls_assert ();
374 goto error;
376 pkey->params.params_nr++;
378 if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params.params[2])) < 0)
380 gnutls_assert ();
381 goto error;
383 pkey->params.params_nr++;
385 if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params.params[3])) < 0)
387 gnutls_assert ();
388 goto error;
390 pkey->params.params_nr++;
392 if ((result = _gnutls_x509_read_int (dsa_asn, "priv",
393 &pkey->params.params[4])) < 0)
395 gnutls_assert ();
396 goto error;
398 pkey->params.params_nr++;
400 return dsa_asn;
402 error:
403 asn1_delete_structure (&dsa_asn);
404 gnutls_pk_params_release(&pkey->params);
405 return NULL;
410 #define PEM_KEY_DSA "DSA PRIVATE KEY"
411 #define PEM_KEY_RSA "RSA PRIVATE KEY"
412 #define PEM_KEY_ECC "EC PRIVATE KEY"
415 * gnutls_x509_privkey_import:
416 * @key: The structure to store the parsed key
417 * @data: The DER or PEM encoded certificate.
418 * @format: One of DER or PEM
420 * This function will convert the given DER or PEM encoded key to the
421 * native #gnutls_x509_privkey_t format. The output will be stored in
422 * @key .
424 * If the key is PEM encoded it should have a header that contains "PRIVATE
425 * KEY". Note that this function falls back to PKCS #8 decoding without
426 * password, if the default format fails to import.
428 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
429 * negative error value.
432 gnutls_x509_privkey_import (gnutls_x509_privkey_t key,
433 const gnutls_datum_t * data,
434 gnutls_x509_crt_fmt_t format)
436 int result = 0, need_free = 0;
437 gnutls_datum_t _data;
439 if (key == NULL)
441 gnutls_assert ();
442 return GNUTLS_E_INVALID_REQUEST;
445 _data.data = data->data;
446 _data.size = data->size;
448 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
450 /* If the Certificate is in PEM format then decode it
452 if (format == GNUTLS_X509_FMT_PEM)
454 /* Try the first header */
455 result =
456 _gnutls_fbase64_decode (PEM_KEY_RSA, data->data, data->size, &_data);
458 if (result >= 0)
459 key->pk_algorithm = GNUTLS_PK_RSA;
461 if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
463 /* try for the second header */
464 result =
465 _gnutls_fbase64_decode (PEM_KEY_DSA, data->data, data->size,
466 &_data);
468 if (result >= 0)
469 key->pk_algorithm = GNUTLS_PK_DSA;
471 if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
473 /* try for the second header */
474 result =
475 _gnutls_fbase64_decode (PEM_KEY_ECC, data->data, data->size,
476 &_data);
477 if (result >= 0)
478 key->pk_algorithm = GNUTLS_PK_EC;
482 if (result < 0)
484 gnutls_assert ();
485 goto failover;
488 need_free = 1;
491 if (key->pk_algorithm == GNUTLS_PK_RSA)
493 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
494 if (key->key == NULL)
495 gnutls_assert ();
497 else if (key->pk_algorithm == GNUTLS_PK_DSA)
499 key->key = decode_dsa_key (&_data, key);
500 if (key->key == NULL)
501 gnutls_assert ();
503 else if (key->pk_algorithm == GNUTLS_PK_EC)
505 key->key = _gnutls_privkey_decode_ecc_key (&_data, key);
506 if (key->key == NULL)
507 gnutls_assert ();
509 else
511 /* Try decoding with both, and accept the one that
512 * succeeds.
514 key->pk_algorithm = GNUTLS_PK_RSA;
515 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
517 if (key->key == NULL)
519 key->pk_algorithm = GNUTLS_PK_DSA;
520 key->key = decode_dsa_key (&_data, key);
521 if (key->key == NULL)
523 key->pk_algorithm = GNUTLS_PK_EC;
524 key->key = _gnutls_privkey_decode_ecc_key (&_data, key);
525 if (key->key == NULL)
526 gnutls_assert ();
531 if (key->key == NULL)
533 gnutls_assert ();
534 result = GNUTLS_E_ASN1_DER_ERROR;
535 goto failover;
538 if (need_free)
539 _gnutls_free_datum (&_data);
541 /* The key has now been decoded.
544 return 0;
546 failover:
547 /* Try PKCS #8 */
548 if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
550 _gnutls_debug_log ("Falling back to PKCS #8 key decoding\n");
551 result = gnutls_x509_privkey_import_pkcs8 (key, data, format,
552 NULL, GNUTLS_PKCS_PLAIN);
555 if (need_free)
556 _gnutls_free_datum (&_data);
558 return result;
561 static int import_pkcs12_privkey (gnutls_x509_privkey_t key,
562 const gnutls_datum_t * data,
563 gnutls_x509_crt_fmt_t format,
564 const char* password, unsigned int flags)
566 int ret;
567 gnutls_pkcs12_t p12;
568 gnutls_x509_privkey_t newkey;
570 ret = gnutls_pkcs12_init(&p12);
571 if (ret < 0)
572 return gnutls_assert_val(ret);
574 ret = gnutls_pkcs12_import(p12, data, format, flags);
575 if (ret < 0)
577 gnutls_assert();
578 goto fail;
581 ret = gnutls_pkcs12_simple_parse (p12, password, &newkey, NULL, NULL, NULL, NULL, NULL, 0);
582 if (ret < 0)
584 gnutls_assert();
585 goto fail;
588 ret = gnutls_x509_privkey_cpy (key, newkey);
589 gnutls_x509_privkey_deinit (newkey);
590 if (ret < 0)
592 gnutls_assert();
593 goto fail;
596 ret = 0;
597 fail:
599 gnutls_pkcs12_deinit(p12);
601 return ret;
605 * gnutls_x509_privkey_import2:
606 * @key: The structure to store the parsed key
607 * @data: The DER or PEM encoded key.
608 * @format: One of DER or PEM
609 * @password: A password (optional)
610 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
612 * This function will import the given DER or PEM encoded key, to
613 * the native #gnutls_x509_privkey_t format, irrespective of the
614 * input format. The input format is auto-detected.
616 * The supported formats are basic unencrypted key, PKCS #8, PKCS #12,
617 * and the openssl format.
619 * If the provided key is encrypted but no password was given, then
620 * %GNUTLS_E_DECRYPTION_FAILED is returned.
622 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
623 * negative error value.
626 gnutls_x509_privkey_import2 (gnutls_x509_privkey_t key,
627 const gnutls_datum_t * data,
628 gnutls_x509_crt_fmt_t format,
629 const char* password, unsigned int flags)
631 int ret = 0;
633 if (password == NULL && !(flags & GNUTLS_PKCS_NULL_PASSWORD))
635 ret = gnutls_x509_privkey_import(key, data, format);
636 if (ret < 0)
638 gnutls_assert();
642 if ((password != NULL || (flags & GNUTLS_PKCS_NULL_PASSWORD)) || ret < 0)
644 ret = gnutls_x509_privkey_import_pkcs8(key, data, format, password, flags);
645 if (ret < 0)
647 ret = import_pkcs12_privkey(key, data, format, password, flags);
648 if (ret < 0 && format == GNUTLS_X509_FMT_PEM)
650 int err;
651 err = gnutls_x509_privkey_import_openssl(key, data, password);
652 if (err < 0)
654 if (err == GNUTLS_E_DECRYPTION_FAILED) ret = err;
655 gnutls_assert();
656 goto cleanup;
659 else
661 gnutls_assert();
662 goto cleanup;
667 ret = 0;
669 cleanup:
670 return ret;
675 * gnutls_x509_privkey_import_rsa_raw:
676 * @key: The structure to store the parsed key
677 * @m: holds the modulus
678 * @e: holds the public exponent
679 * @d: holds the private exponent
680 * @p: holds the first prime (p)
681 * @q: holds the second prime (q)
682 * @u: holds the coefficient
684 * This function will convert the given RSA raw parameters to the
685 * native #gnutls_x509_privkey_t format. The output will be stored in
686 * @key.
688 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
689 * negative error value.
692 gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key,
693 const gnutls_datum_t * m,
694 const gnutls_datum_t * e,
695 const gnutls_datum_t * d,
696 const gnutls_datum_t * p,
697 const gnutls_datum_t * q,
698 const gnutls_datum_t * u)
700 return gnutls_x509_privkey_import_rsa_raw2 (key, m, e, d, p, q, u, NULL,
701 NULL);
705 * gnutls_x509_privkey_import_rsa_raw2:
706 * @key: The structure to store the parsed key
707 * @m: holds the modulus
708 * @e: holds the public exponent
709 * @d: holds the private exponent
710 * @p: holds the first prime (p)
711 * @q: holds the second prime (q)
712 * @u: holds the coefficient
713 * @e1: holds e1 = d mod (p-1)
714 * @e2: holds e2 = d mod (q-1)
716 * This function will convert the given RSA raw parameters to the
717 * native #gnutls_x509_privkey_t format. The output will be stored in
718 * @key.
720 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
721 * negative error value.
724 gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
725 const gnutls_datum_t * m,
726 const gnutls_datum_t * e,
727 const gnutls_datum_t * d,
728 const gnutls_datum_t * p,
729 const gnutls_datum_t * q,
730 const gnutls_datum_t * u,
731 const gnutls_datum_t * e1,
732 const gnutls_datum_t * e2)
734 int ret;
735 size_t siz = 0;
737 if (key == NULL)
739 gnutls_assert ();
740 return GNUTLS_E_INVALID_REQUEST;
743 gnutls_pk_params_init(&key->params);
745 siz = m->size;
746 if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
748 gnutls_assert ();
749 ret = GNUTLS_E_MPI_SCAN_FAILED;
750 goto cleanup;
752 key->params.params_nr++;
754 siz = e->size;
755 if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
757 gnutls_assert ();
758 ret = GNUTLS_E_MPI_SCAN_FAILED;
759 goto cleanup;
761 key->params.params_nr++;
763 siz = d->size;
764 if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz))
766 gnutls_assert ();
767 ret = GNUTLS_E_MPI_SCAN_FAILED;
768 goto cleanup;
770 key->params.params_nr++;
772 siz = p->size;
773 if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz))
775 gnutls_assert ();
776 ret = GNUTLS_E_MPI_SCAN_FAILED;
777 goto cleanup;
779 key->params.params_nr++;
781 siz = q->size;
782 if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz))
784 gnutls_assert ();
785 ret = GNUTLS_E_MPI_SCAN_FAILED;
786 goto cleanup;
788 key->params.params_nr++;
790 siz = u->size;
791 if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz))
793 gnutls_assert ();
794 ret = GNUTLS_E_MPI_SCAN_FAILED;
795 goto cleanup;
797 key->params.params_nr++;
799 if (e1 && e2)
801 siz = e1->size;
802 if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz))
804 gnutls_assert ();
805 ret = GNUTLS_E_MPI_SCAN_FAILED;
806 goto cleanup;
808 key->params.params_nr++;
810 siz = e2->size;
811 if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz))
813 gnutls_assert ();
814 ret = GNUTLS_E_MPI_SCAN_FAILED;
815 goto cleanup;
817 key->params.params_nr++;
820 ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
821 if (ret < 0)
823 gnutls_assert ();
824 goto cleanup;
827 ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params);
828 if (ret < 0)
830 gnutls_assert ();
831 goto cleanup;
834 key->params.params_nr = RSA_PRIVATE_PARAMS;
835 key->pk_algorithm = GNUTLS_PK_RSA;
837 return 0;
839 cleanup:
840 gnutls_pk_params_release(&key->params);
841 return ret;
846 * gnutls_x509_privkey_import_dsa_raw:
847 * @key: The structure to store the parsed key
848 * @p: holds the p
849 * @q: holds the q
850 * @g: holds the g
851 * @y: holds the y
852 * @x: holds the x
854 * This function will convert the given DSA raw parameters to the
855 * native #gnutls_x509_privkey_t format. The output will be stored
856 * in @key.
858 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
859 * negative error value.
862 gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key,
863 const gnutls_datum_t * p,
864 const gnutls_datum_t * q,
865 const gnutls_datum_t * g,
866 const gnutls_datum_t * y,
867 const gnutls_datum_t * x)
869 int ret;
870 size_t siz = 0;
872 if (key == NULL)
874 gnutls_assert ();
875 return GNUTLS_E_INVALID_REQUEST;
878 siz = p->size;
879 if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
881 gnutls_assert ();
882 ret = GNUTLS_E_MPI_SCAN_FAILED;
883 goto cleanup;
886 siz = q->size;
887 if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
889 gnutls_assert ();
890 ret = GNUTLS_E_MPI_SCAN_FAILED;
891 goto cleanup;
894 siz = g->size;
895 if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
897 gnutls_assert ();
898 ret = GNUTLS_E_MPI_SCAN_FAILED;
899 goto cleanup;
902 siz = y->size;
903 if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
905 gnutls_assert ();
906 ret = GNUTLS_E_MPI_SCAN_FAILED;
907 goto cleanup;
910 siz = x->size;
911 if (_gnutls_mpi_scan_nz (&key->params.params[4], x->data, siz))
913 gnutls_assert ();
914 ret = GNUTLS_E_MPI_SCAN_FAILED;
915 goto cleanup;
918 ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &key->key, &key->params);
919 if (ret < 0)
921 gnutls_assert ();
922 goto cleanup;
925 key->params.params_nr = DSA_PRIVATE_PARAMS;
926 key->pk_algorithm = GNUTLS_PK_DSA;
928 return 0;
930 cleanup:
931 gnutls_pk_params_release(&key->params);
932 return ret;
937 * gnutls_x509_privkey_import_ecc_raw:
938 * @key: The structure to store the parsed key
939 * @curve: holds the curve
940 * @x: holds the x
941 * @y: holds the y
942 * @k: holds the k
944 * This function will convert the given elliptic curve parameters to the
945 * native #gnutls_x509_privkey_t format. The output will be stored
946 * in @key.
948 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
949 * negative error value.
951 * Since: 3.0
954 gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key,
955 gnutls_ecc_curve_t curve,
956 const gnutls_datum_t * x,
957 const gnutls_datum_t * y,
958 const gnutls_datum_t * k)
960 int ret;
962 if (key == NULL)
964 gnutls_assert ();
965 return GNUTLS_E_INVALID_REQUEST;
968 key->params.flags = curve;
970 ret = _gnutls_ecc_curve_fill_params(curve, &key->params);
971 if (ret < 0)
972 return gnutls_assert_val(ret);
974 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size))
976 gnutls_assert ();
977 ret = GNUTLS_E_MPI_SCAN_FAILED;
978 goto cleanup;
980 key->params.params_nr++;
982 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y], y->data, y->size))
984 gnutls_assert ();
985 ret = GNUTLS_E_MPI_SCAN_FAILED;
986 goto cleanup;
988 key->params.params_nr++;
990 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_K], k->data, k->size))
992 gnutls_assert ();
993 ret = GNUTLS_E_MPI_SCAN_FAILED;
994 goto cleanup;
996 key->params.params_nr++;
998 key->pk_algorithm = GNUTLS_PK_EC;
1000 return 0;
1002 cleanup:
1003 gnutls_pk_params_release(&key->params);
1004 return ret;
1010 * gnutls_x509_privkey_get_pk_algorithm:
1011 * @key: should contain a #gnutls_x509_privkey_t structure
1013 * This function will return the public key algorithm of a private
1014 * key.
1016 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1017 * success, or a negative error code on error.
1020 gnutls_x509_privkey_get_pk_algorithm (gnutls_x509_privkey_t key)
1022 if (key == NULL)
1024 gnutls_assert ();
1025 return GNUTLS_E_INVALID_REQUEST;
1028 return key->pk_algorithm;
1032 * gnutls_x509_privkey_get_pk_algorithm2:
1033 * @key: should contain a #gnutls_x509_privkey_t structure
1034 * @bits: The number of bits in the public key algorithm
1036 * This function will return the public key algorithm of a private
1037 * key.
1039 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1040 * success, or a negative error code on error.
1043 gnutls_x509_privkey_get_pk_algorithm2 (gnutls_x509_privkey_t key, unsigned int *bits)
1045 int ret;
1047 if (key == NULL)
1049 gnutls_assert ();
1050 return GNUTLS_E_INVALID_REQUEST;
1053 if (bits)
1055 ret = pubkey_to_bits(key->pk_algorithm, &key->params);
1056 if (ret < 0) ret = 0;
1057 *bits = ret;
1060 return key->pk_algorithm;
1063 static const char* set_msg(gnutls_x509_privkey_t key)
1065 if (key->pk_algorithm == GNUTLS_PK_RSA)
1066 return PEM_KEY_RSA;
1067 else if (key->pk_algorithm == GNUTLS_PK_DSA)
1068 return PEM_KEY_DSA;
1069 else if (key->pk_algorithm == GNUTLS_PK_EC)
1070 return PEM_KEY_ECC;
1071 else
1072 return "UNKNOWN";
1076 * gnutls_x509_privkey_export:
1077 * @key: Holds the key
1078 * @format: the format of output params. One of PEM or DER.
1079 * @output_data: will contain a private key PEM or DER encoded
1080 * @output_data_size: holds the size of output_data (and will be
1081 * replaced by the actual size of parameters)
1083 * This function will export the private key to a PKCS1 structure for
1084 * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
1085 * the same format with the parameters used by openssl.
1087 * If the buffer provided is not long enough to hold the output, then
1088 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER
1089 * will be returned.
1091 * If the structure is PEM encoded, it will have a header
1092 * of "BEGIN RSA PRIVATE KEY".
1094 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1095 * negative error value.
1098 gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
1099 gnutls_x509_crt_fmt_t format, void *output_data,
1100 size_t * output_data_size)
1102 const char *msg;
1104 if (key == NULL)
1106 gnutls_assert ();
1107 return GNUTLS_E_INVALID_REQUEST;
1110 msg = set_msg(key);
1112 return _gnutls_x509_export_int (key->key, format, msg,
1113 output_data, output_data_size);
1117 * gnutls_x509_privkey_export2:
1118 * @key: Holds the key
1119 * @format: the format of output params. One of PEM or DER.
1120 * @out: will contain a private key PEM or DER encoded
1122 * This function will export the private key to a PKCS1 structure for
1123 * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
1124 * the same format with the parameters used by openssl.
1126 * The output buffer is allocated using gnutls_malloc().
1128 * If the structure is PEM encoded, it will have a header
1129 * of "BEGIN RSA PRIVATE KEY".
1131 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1132 * negative error value.
1134 * Since 3.1.3
1137 gnutls_x509_privkey_export2 (gnutls_x509_privkey_t key,
1138 gnutls_x509_crt_fmt_t format,
1139 gnutls_datum_t * out)
1141 const char *msg;
1143 if (key == NULL)
1145 gnutls_assert ();
1146 return GNUTLS_E_INVALID_REQUEST;
1149 msg = set_msg(key);
1151 return _gnutls_x509_export_int2 (key->key, format, msg, out);
1155 * gnutls_x509_privkey_sec_param:
1156 * @key: a key structure
1158 * This function will return the security parameter appropriate with
1159 * this private key.
1161 * Returns: On success, a valid security parameter is returned otherwise
1162 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
1164 * Since: 2.12.0
1166 gnutls_sec_param_t
1167 gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key)
1169 int bits;
1171 bits = pubkey_to_bits(key->pk_algorithm, &key->params);
1172 if (bits <= 0)
1173 return GNUTLS_SEC_PARAM_UNKNOWN;
1175 return gnutls_pk_bits_to_sec_param(key->pk_algorithm, bits);
1179 * gnutls_x509_privkey_export_ecc_raw:
1180 * @key: a structure that holds the rsa parameters
1181 * @curve: will hold the curve
1182 * @x: will hold the x coordinate
1183 * @y: will hold the y coordinate
1184 * @k: will hold the private key
1186 * This function will export the ECC private key's parameters found
1187 * in the given structure. The new parameters will be allocated using
1188 * gnutls_malloc() and will be stored in the appropriate datum.
1190 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1191 * negative error value.
1193 * Since: 3.0
1195 int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key,
1196 gnutls_ecc_curve_t *curve,
1197 gnutls_datum_t * x, gnutls_datum_t * y,
1198 gnutls_datum_t* k)
1200 int ret;
1202 if (key == NULL)
1204 gnutls_assert ();
1205 return GNUTLS_E_INVALID_REQUEST;
1208 *curve = key->params.flags;
1210 /* X */
1211 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X], x);
1212 if (ret < 0)
1214 gnutls_assert ();
1215 return ret;
1218 /* Y */
1219 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y], y);
1220 if (ret < 0)
1222 gnutls_assert ();
1223 _gnutls_free_datum (x);
1224 return ret;
1228 /* K */
1229 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_K], k);
1230 if (ret < 0)
1232 gnutls_assert ();
1233 _gnutls_free_datum (x);
1234 _gnutls_free_datum (y);
1235 return ret;
1238 return 0;
1243 * gnutls_x509_privkey_export_rsa_raw:
1244 * @key: a structure that holds the rsa parameters
1245 * @m: will hold the modulus
1246 * @e: will hold the public exponent
1247 * @d: will hold the private exponent
1248 * @p: will hold the first prime (p)
1249 * @q: will hold the second prime (q)
1250 * @u: will hold the coefficient
1252 * This function will export the RSA private key's parameters found
1253 * in the given structure. The new parameters will be allocated using
1254 * gnutls_malloc() and will be stored in the appropriate datum.
1256 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1257 * negative error value.
1260 gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key,
1261 gnutls_datum_t * m, gnutls_datum_t * e,
1262 gnutls_datum_t * d, gnutls_datum_t * p,
1263 gnutls_datum_t * q, gnutls_datum_t * u)
1266 return gnutls_x509_privkey_export_rsa_raw2 (key, m, e, d, p, q, u, NULL,
1267 NULL);
1271 * gnutls_x509_privkey_export_rsa_raw2:
1272 * @key: a structure that holds the rsa parameters
1273 * @m: will hold the modulus
1274 * @e: will hold the public exponent
1275 * @d: will hold the private exponent
1276 * @p: will hold the first prime (p)
1277 * @q: will hold the second prime (q)
1278 * @u: will hold the coefficient
1279 * @e1: will hold e1 = d mod (p-1)
1280 * @e2: will hold e2 = d mod (q-1)
1282 * This function will export the RSA private key's parameters found
1283 * in the given structure. The new parameters will be allocated using
1284 * gnutls_malloc() and will be stored in the appropriate datum.
1286 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1287 * negative error value.
1289 * Since: 2.12.0
1292 gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
1293 gnutls_datum_t * m, gnutls_datum_t * e,
1294 gnutls_datum_t * d, gnutls_datum_t * p,
1295 gnutls_datum_t * q, gnutls_datum_t * u,
1296 gnutls_datum_t * e1, gnutls_datum_t * e2)
1298 int ret;
1299 gnutls_pk_params_st pk_params;
1301 gnutls_pk_params_init(&pk_params);
1303 if (key == NULL)
1305 gnutls_assert ();
1306 return GNUTLS_E_INVALID_REQUEST;
1309 m->data = e->data = d->data = p->data = q->data = u->data = NULL;
1310 m->size = e->size = d->size = p->size = q->size = u->size = 0;
1312 ret = _gnutls_pk_params_copy (&pk_params, &key->params);
1313 if (ret < 0)
1315 gnutls_assert ();
1316 return ret;
1319 ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
1320 if (ret < 0)
1322 gnutls_assert ();
1323 goto error;
1326 ret = _gnutls_mpi_dprint_lz (pk_params.params[0], m);
1327 if (ret < 0)
1329 gnutls_assert ();
1330 goto error;
1333 /* E */
1334 ret = _gnutls_mpi_dprint_lz (pk_params.params[1], e);
1335 if (ret < 0)
1337 gnutls_assert ();
1338 goto error;
1341 /* D */
1342 ret = _gnutls_mpi_dprint_lz (pk_params.params[2], d);
1343 if (ret < 0)
1345 gnutls_assert ();
1346 goto error;
1349 /* P */
1350 ret = _gnutls_mpi_dprint_lz (pk_params.params[3], p);
1351 if (ret < 0)
1353 gnutls_assert ();
1354 goto error;
1357 /* Q */
1358 ret = _gnutls_mpi_dprint_lz (pk_params.params[4], q);
1359 if (ret < 0)
1361 gnutls_assert ();
1362 goto error;
1365 /* U */
1366 ret = _gnutls_mpi_dprint_lz (key->params.params[5], u);
1367 if (ret < 0)
1369 gnutls_assert ();
1370 goto error;
1373 /* E1 */
1374 if (e1)
1376 ret = _gnutls_mpi_dprint_lz (key->params.params[6], e1);
1377 if (ret < 0)
1379 gnutls_assert ();
1380 goto error;
1384 /* E2 */
1385 if (e2)
1387 ret = _gnutls_mpi_dprint_lz (key->params.params[7], e2);
1388 if (ret < 0)
1390 gnutls_assert ();
1391 goto error;
1395 gnutls_pk_params_release (&pk_params);
1397 return 0;
1399 error:
1400 _gnutls_free_datum (m);
1401 _gnutls_free_datum (d);
1402 _gnutls_free_datum (e);
1403 _gnutls_free_datum (p);
1404 _gnutls_free_datum (q);
1405 gnutls_pk_params_release (&pk_params);
1407 return ret;
1411 * gnutls_x509_privkey_export_dsa_raw:
1412 * @key: a structure that holds the DSA parameters
1413 * @p: will hold the p
1414 * @q: will hold the q
1415 * @g: will hold the g
1416 * @y: will hold the y
1417 * @x: will hold the x
1419 * This function will export the DSA private key's parameters found
1420 * in the given structure. The new parameters will be allocated using
1421 * gnutls_malloc() and will be stored in the appropriate datum.
1423 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1424 * negative error value.
1427 gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
1428 gnutls_datum_t * p, gnutls_datum_t * q,
1429 gnutls_datum_t * g, gnutls_datum_t * y,
1430 gnutls_datum_t * x)
1432 int ret;
1434 if (key == NULL)
1436 gnutls_assert ();
1437 return GNUTLS_E_INVALID_REQUEST;
1440 /* P */
1441 ret = _gnutls_mpi_dprint_lz (key->params.params[0], p);
1442 if (ret < 0)
1444 gnutls_assert ();
1445 return ret;
1448 /* Q */
1449 ret = _gnutls_mpi_dprint_lz (key->params.params[1], q);
1450 if (ret < 0)
1452 gnutls_assert ();
1453 _gnutls_free_datum (p);
1454 return ret;
1458 /* G */
1459 ret = _gnutls_mpi_dprint_lz (key->params.params[2], g);
1460 if (ret < 0)
1462 gnutls_assert ();
1463 _gnutls_free_datum (p);
1464 _gnutls_free_datum (q);
1465 return ret;
1469 /* Y */
1470 ret = _gnutls_mpi_dprint_lz (key->params.params[3], y);
1471 if (ret < 0)
1473 gnutls_assert ();
1474 _gnutls_free_datum (p);
1475 _gnutls_free_datum (g);
1476 _gnutls_free_datum (q);
1477 return ret;
1480 /* X */
1481 ret = _gnutls_mpi_dprint_lz (key->params.params[4], x);
1482 if (ret < 0)
1484 gnutls_assert ();
1485 _gnutls_free_datum (y);
1486 _gnutls_free_datum (p);
1487 _gnutls_free_datum (g);
1488 _gnutls_free_datum (q);
1489 return ret;
1492 return 0;
1496 * gnutls_x509_privkey_generate:
1497 * @key: should contain a #gnutls_x509_privkey_t structure
1498 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1499 * @bits: the size of the modulus
1500 * @flags: unused for now. Must be 0.
1502 * This function will generate a random private key. Note that this
1503 * function must be called on an empty private key.
1505 * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
1507 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1508 * negative error value.
1511 gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
1512 gnutls_pk_algorithm_t algo, unsigned int bits,
1513 unsigned int flags)
1515 int ret;
1517 if (key == NULL)
1519 gnutls_assert ();
1520 return GNUTLS_E_INVALID_REQUEST;
1523 gnutls_pk_params_init(&key->params);
1525 if (algo == GNUTLS_PK_EC)
1526 bits = _gnutls_ecc_bits_to_curve(bits);
1528 ret = _gnutls_pk_generate (algo, bits, &key->params);
1529 if (ret < 0)
1531 gnutls_assert ();
1532 return ret;
1535 ret = _gnutls_asn1_encode_privkey (algo, &key->key, &key->params);
1536 if (ret < 0)
1538 gnutls_assert ();
1539 goto cleanup;
1541 key->pk_algorithm = algo;
1543 return 0;
1545 cleanup:
1546 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1547 gnutls_pk_params_release(&key->params);
1549 return ret;
1553 * gnutls_x509_privkey_verify_params:
1554 * @key: should contain a #gnutls_x509_privkey_t structure
1556 * This function will verify the private key parameters.
1558 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1559 * negative error value.
1562 gnutls_x509_privkey_verify_params (gnutls_x509_privkey_t key)
1564 int ret;
1566 ret = _gnutls_pk_verify_params (key->pk_algorithm, &key->params);
1567 if (ret < 0)
1569 gnutls_assert ();
1570 return ret;
1573 return 0;
1577 * gnutls_x509_privkey_get_key_id:
1578 * @key: Holds the key
1579 * @flags: should be 0 for now
1580 * @output_data: will contain the key ID
1581 * @output_data_size: holds the size of output_data (and will be
1582 * replaced by the actual size of parameters)
1584 * This function will return a unique ID that depends on the public key
1585 * parameters. This ID can be used in checking whether a certificate
1586 * corresponds to the given key.
1588 * If the buffer provided is not long enough to hold the output, then
1589 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1590 * be returned. The output will normally be a SHA-1 hash output,
1591 * which is 20 bytes.
1593 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1594 * negative error value.
1597 gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key,
1598 unsigned int flags,
1599 unsigned char *output_data,
1600 size_t * output_data_size)
1602 int ret;
1604 if (key == NULL)
1606 gnutls_assert ();
1607 return GNUTLS_E_INVALID_REQUEST;
1610 ret = _gnutls_get_key_id(key->pk_algorithm, &key->params, output_data, output_data_size);
1611 if (ret < 0)
1613 gnutls_assert ();
1616 return ret;
1621 * _gnutls_x509_privkey_sign_hash2:
1622 * @signer: Holds the signer's key
1623 * @hash_algo: The hash algorithm used
1624 * @hash_data: holds the data to be signed
1625 * @signature: will contain newly allocated signature
1626 * @flags: (0) for now
1628 * This function will sign the given hashed data using a signature algorithm
1629 * supported by the private key. Signature algorithms are always used
1630 * together with a hash functions. Different hash functions may be
1631 * used for the RSA algorithm, but only SHA-1,SHA-224 and SHA-256
1632 * for the DSA keys, depending on their bit size.
1634 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1635 * the hash algorithm.
1637 * The RSA algorithm is used in PKCS #1 v1.5 mode.
1639 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1640 * negative error value.
1642 static int
1643 _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer,
1644 gnutls_digest_algorithm_t hash_algo,
1645 unsigned int flags,
1646 const gnutls_datum_t * hash_data,
1647 gnutls_datum_t * signature)
1649 int ret;
1650 gnutls_datum_t digest;
1652 digest.data = gnutls_malloc (hash_data->size);
1653 if (digest.data == NULL)
1655 gnutls_assert ();
1656 return GNUTLS_E_MEMORY_ERROR;
1658 digest.size = hash_data->size;
1659 memcpy (digest.data, hash_data->data, digest.size);
1661 ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
1662 if (ret < 0)
1664 gnutls_assert ();
1665 goto cleanup;
1668 ret = _gnutls_pk_sign (signer->pk_algorithm, signature, &digest, &signer->params);
1670 if (ret < 0)
1672 gnutls_assert ();
1673 goto cleanup;
1676 ret = 0;
1678 cleanup:
1679 _gnutls_free_datum (&digest);
1680 return ret;
1684 * gnutls_x509_privkey_sign_hash:
1685 * @key: Holds the key
1686 * @hash: holds the data to be signed
1687 * @signature: will contain newly allocated signature
1689 * This function will sign the given hash using the private key. Do not
1690 * use this function directly unless you know what it is. Typical signing
1691 * requires the data to be hashed and stored in special formats
1692 * (e.g. BER Digest-Info for RSA).
1694 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1695 * negative error value.
1697 * Deprecated in: 2.12.0
1700 gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
1701 const gnutls_datum_t * hash,
1702 gnutls_datum_t * signature)
1704 int result;
1706 if (key == NULL)
1708 gnutls_assert ();
1709 return GNUTLS_E_INVALID_REQUEST;
1712 result = _gnutls_pk_sign (key->pk_algorithm, signature, hash, &key->params);
1714 if (result < 0)
1716 gnutls_assert ();
1717 return result;
1720 return 0;
1724 * gnutls_x509_privkey_sign_data:
1725 * @key: Holds the key
1726 * @digest: should be MD5 or SHA1
1727 * @flags: should be 0 for now
1728 * @data: holds the data to be signed
1729 * @signature: will contain the signature
1730 * @signature_size: holds the size of signature (and will be replaced
1731 * by the new size)
1733 * This function will sign the given data using a signature algorithm
1734 * supported by the private key. Signature algorithms are always used
1735 * together with a hash functions. Different hash functions may be
1736 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
1738 * If the buffer provided is not long enough to hold the output, then
1739 * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1740 * be returned.
1742 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1743 * the hash algorithm.
1745 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1746 * negative error value.
1748 * Deprecated: Use gnutls_privkey_sign_data().
1751 gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
1752 gnutls_digest_algorithm_t digest,
1753 unsigned int flags,
1754 const gnutls_datum_t * data,
1755 void *signature, size_t * signature_size)
1757 int result;
1758 gnutls_datum_t sig = { NULL, 0 };
1759 gnutls_datum_t hash;
1761 if (key == NULL)
1763 gnutls_assert ();
1764 return GNUTLS_E_INVALID_REQUEST;
1767 result =
1768 pk_hash_data (key->pk_algorithm, digest, &key->params, data, &hash);
1769 if (result < 0)
1771 gnutls_assert ();
1772 return result;
1775 result =
1776 _gnutls_x509_privkey_sign_hash2 (key, digest, flags, &hash, &sig);
1778 _gnutls_free_datum(&hash);
1780 if (result < 0)
1782 gnutls_assert ();
1783 return result;
1786 if (*signature_size < sig.size)
1788 *signature_size = sig.size;
1789 _gnutls_free_datum (&sig);
1790 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1793 *signature_size = sig.size;
1794 memcpy (signature, sig.data, sig.size);
1796 _gnutls_free_datum (&sig);
1798 return 0;
1803 * gnutls_x509_privkey_fix:
1804 * @key: Holds the key
1806 * This function will recalculate the secondary parameters in a key.
1807 * In RSA keys, this can be the coefficient and exponent1,2.
1809 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1810 * negative error value.
1813 gnutls_x509_privkey_fix (gnutls_x509_privkey_t key)
1815 int ret;
1817 if (key == NULL)
1819 gnutls_assert ();
1820 return GNUTLS_E_INVALID_REQUEST;
1823 asn1_delete_structure (&key->key);
1825 ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params);
1826 if (ret < 0)
1828 gnutls_assert ();
1829 return ret;
1832 return 0;