documented behavior.
[gnutls.git] / lib / x509 / privkey.c
blobdc558b6383920cc14610dc30b51b228febfc8e13
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, 2);
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 uint8_t *out;
456 /* Try the first header */
457 result =
458 _gnutls_fbase64_decode (PEM_KEY_RSA, data->data, data->size, &out);
460 if (result >= 0)
461 key->pk_algorithm = GNUTLS_PK_RSA;
463 if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
465 /* try for the second header */
466 result =
467 _gnutls_fbase64_decode (PEM_KEY_DSA, data->data, data->size,
468 &out);
470 if (result >= 0)
471 key->pk_algorithm = GNUTLS_PK_DSA;
473 if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
475 /* try for the second header */
476 result =
477 _gnutls_fbase64_decode (PEM_KEY_ECC, data->data, data->size,
478 &out);
479 if (result >= 0)
480 key->pk_algorithm = GNUTLS_PK_EC;
484 if (result < 0)
486 gnutls_assert ();
487 goto failover;
490 _data.data = out;
491 _data.size = result;
493 need_free = 1;
496 if (key->pk_algorithm == GNUTLS_PK_RSA)
498 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
499 if (key->key == NULL)
500 gnutls_assert ();
502 else if (key->pk_algorithm == GNUTLS_PK_DSA)
504 key->key = decode_dsa_key (&_data, key);
505 if (key->key == NULL)
506 gnutls_assert ();
508 else if (key->pk_algorithm == GNUTLS_PK_EC)
510 key->key = _gnutls_privkey_decode_ecc_key (&_data, key);
511 if (key->key == NULL)
512 gnutls_assert ();
514 else
516 /* Try decoding with both, and accept the one that
517 * succeeds.
519 key->pk_algorithm = GNUTLS_PK_RSA;
520 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
522 if (key->key == NULL)
524 key->pk_algorithm = GNUTLS_PK_DSA;
525 key->key = decode_dsa_key (&_data, key);
526 if (key->key == NULL)
527 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;
562 * gnutls_x509_privkey_import_rsa_raw:
563 * @key: The structure to store the parsed key
564 * @m: holds the modulus
565 * @e: holds the public exponent
566 * @d: holds the private exponent
567 * @p: holds the first prime (p)
568 * @q: holds the second prime (q)
569 * @u: holds the coefficient
571 * This function will convert the given RSA raw parameters to the
572 * native #gnutls_x509_privkey_t format. The output will be stored in
573 * @key.
575 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
576 * negative error value.
579 gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key,
580 const gnutls_datum_t * m,
581 const gnutls_datum_t * e,
582 const gnutls_datum_t * d,
583 const gnutls_datum_t * p,
584 const gnutls_datum_t * q,
585 const gnutls_datum_t * u)
587 return gnutls_x509_privkey_import_rsa_raw2 (key, m, e, d, p, q, u, NULL,
588 NULL);
592 * gnutls_x509_privkey_import_rsa_raw2:
593 * @key: The structure to store the parsed key
594 * @m: holds the modulus
595 * @e: holds the public exponent
596 * @d: holds the private exponent
597 * @p: holds the first prime (p)
598 * @q: holds the second prime (q)
599 * @u: holds the coefficient
600 * @e1: holds e1 = d mod (p-1)
601 * @e2: holds e2 = d mod (q-1)
603 * This function will convert the given RSA raw parameters to the
604 * native #gnutls_x509_privkey_t format. The output will be stored in
605 * @key.
607 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
608 * negative error value.
611 gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
612 const gnutls_datum_t * m,
613 const gnutls_datum_t * e,
614 const gnutls_datum_t * d,
615 const gnutls_datum_t * p,
616 const gnutls_datum_t * q,
617 const gnutls_datum_t * u,
618 const gnutls_datum_t * e1,
619 const gnutls_datum_t * e2)
621 int ret;
622 size_t siz = 0;
624 if (key == NULL)
626 gnutls_assert ();
627 return GNUTLS_E_INVALID_REQUEST;
630 gnutls_pk_params_init(&key->params);
632 siz = m->size;
633 if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
635 gnutls_assert ();
636 ret = GNUTLS_E_MPI_SCAN_FAILED;
637 goto cleanup;
639 key->params.params_nr++;
641 siz = e->size;
642 if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
644 gnutls_assert ();
645 ret = GNUTLS_E_MPI_SCAN_FAILED;
646 goto cleanup;
648 key->params.params_nr++;
650 siz = d->size;
651 if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz))
653 gnutls_assert ();
654 ret = GNUTLS_E_MPI_SCAN_FAILED;
655 goto cleanup;
657 key->params.params_nr++;
659 siz = p->size;
660 if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz))
662 gnutls_assert ();
663 ret = GNUTLS_E_MPI_SCAN_FAILED;
664 goto cleanup;
666 key->params.params_nr++;
668 siz = q->size;
669 if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz))
671 gnutls_assert ();
672 ret = GNUTLS_E_MPI_SCAN_FAILED;
673 goto cleanup;
675 key->params.params_nr++;
677 siz = u->size;
678 if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz))
680 gnutls_assert ();
681 ret = GNUTLS_E_MPI_SCAN_FAILED;
682 goto cleanup;
684 key->params.params_nr++;
686 if (e1 && e2)
688 siz = e1->size;
689 if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz))
691 gnutls_assert ();
692 ret = GNUTLS_E_MPI_SCAN_FAILED;
693 goto cleanup;
695 key->params.params_nr++;
697 siz = e2->size;
698 if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz))
700 gnutls_assert ();
701 ret = GNUTLS_E_MPI_SCAN_FAILED;
702 goto cleanup;
704 key->params.params_nr++;
707 ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
708 if (ret < 0)
710 gnutls_assert ();
711 goto cleanup;
714 ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params);
715 if (ret < 0)
717 gnutls_assert ();
718 goto cleanup;
721 key->params.params_nr = RSA_PRIVATE_PARAMS;
722 key->pk_algorithm = GNUTLS_PK_RSA;
724 return 0;
726 cleanup:
727 gnutls_pk_params_release(&key->params);
728 return ret;
733 * gnutls_x509_privkey_import_dsa_raw:
734 * @key: The structure to store the parsed key
735 * @p: holds the p
736 * @q: holds the q
737 * @g: holds the g
738 * @y: holds the y
739 * @x: holds the x
741 * This function will convert the given DSA raw parameters to the
742 * native #gnutls_x509_privkey_t format. The output will be stored
743 * in @key.
745 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
746 * negative error value.
749 gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key,
750 const gnutls_datum_t * p,
751 const gnutls_datum_t * q,
752 const gnutls_datum_t * g,
753 const gnutls_datum_t * y,
754 const gnutls_datum_t * x)
756 int ret;
757 size_t siz = 0;
759 if (key == NULL)
761 gnutls_assert ();
762 return GNUTLS_E_INVALID_REQUEST;
765 siz = p->size;
766 if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
768 gnutls_assert ();
769 ret = GNUTLS_E_MPI_SCAN_FAILED;
770 goto cleanup;
773 siz = q->size;
774 if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
776 gnutls_assert ();
777 ret = GNUTLS_E_MPI_SCAN_FAILED;
778 goto cleanup;
781 siz = g->size;
782 if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
784 gnutls_assert ();
785 ret = GNUTLS_E_MPI_SCAN_FAILED;
786 goto cleanup;
789 siz = y->size;
790 if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
792 gnutls_assert ();
793 ret = GNUTLS_E_MPI_SCAN_FAILED;
794 goto cleanup;
797 siz = x->size;
798 if (_gnutls_mpi_scan_nz (&key->params.params[4], x->data, siz))
800 gnutls_assert ();
801 ret = GNUTLS_E_MPI_SCAN_FAILED;
802 goto cleanup;
805 ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &key->key, &key->params);
806 if (ret < 0)
808 gnutls_assert ();
809 goto cleanup;
812 key->params.params_nr = DSA_PRIVATE_PARAMS;
813 key->pk_algorithm = GNUTLS_PK_DSA;
815 return 0;
817 cleanup:
818 gnutls_pk_params_release(&key->params);
819 return ret;
824 * gnutls_x509_privkey_import_ecc_raw:
825 * @key: The structure to store the parsed key
826 * @curve: holds the curve
827 * @x: holds the x
828 * @y: holds the y
829 * @k: holds the k
831 * This function will convert the given elliptic curve parameters to the
832 * native #gnutls_x509_privkey_t format. The output will be stored
833 * in @key.
835 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
836 * negative error value.
838 * Since: 3.0
841 gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key,
842 gnutls_ecc_curve_t curve,
843 const gnutls_datum_t * x,
844 const gnutls_datum_t * y,
845 const gnutls_datum_t * k)
847 int ret;
849 if (key == NULL)
851 gnutls_assert ();
852 return GNUTLS_E_INVALID_REQUEST;
855 key->params.flags = curve;
857 ret = _gnutls_ecc_curve_fill_params(curve, &key->params);
858 if (ret < 0)
859 return gnutls_assert_val(ret);
861 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size))
863 gnutls_assert ();
864 ret = GNUTLS_E_MPI_SCAN_FAILED;
865 goto cleanup;
867 key->params.params_nr++;
869 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y], y->data, y->size))
871 gnutls_assert ();
872 ret = GNUTLS_E_MPI_SCAN_FAILED;
873 goto cleanup;
875 key->params.params_nr++;
877 if (_gnutls_mpi_scan_nz (&key->params.params[ECC_K], k->data, k->size))
879 gnutls_assert ();
880 ret = GNUTLS_E_MPI_SCAN_FAILED;
881 goto cleanup;
883 key->params.params_nr++;
885 key->pk_algorithm = GNUTLS_PK_EC;
887 return 0;
889 cleanup:
890 gnutls_pk_params_release(&key->params);
891 return ret;
897 * gnutls_x509_privkey_get_pk_algorithm:
898 * @key: should contain a #gnutls_x509_privkey_t structure
900 * This function will return the public key algorithm of a private
901 * key.
903 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
904 * success, or a negative error code on error.
907 gnutls_x509_privkey_get_pk_algorithm (gnutls_x509_privkey_t key)
909 if (key == NULL)
911 gnutls_assert ();
912 return GNUTLS_E_INVALID_REQUEST;
915 return key->pk_algorithm;
919 * gnutls_x509_privkey_export:
920 * @key: Holds the key
921 * @format: the format of output params. One of PEM or DER.
922 * @output_data: will contain a private key PEM or DER encoded
923 * @output_data_size: holds the size of output_data (and will be
924 * replaced by the actual size of parameters)
926 * This function will export the private key to a PKCS1 structure for
927 * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
928 * the same format with the parameters used by openssl.
930 * If the buffer provided is not long enough to hold the output, then
931 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER
932 * will be returned.
934 * If the structure is PEM encoded, it will have a header
935 * of "BEGIN RSA PRIVATE KEY".
937 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
938 * negative error value.
941 gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
942 gnutls_x509_crt_fmt_t format, void *output_data,
943 size_t * output_data_size)
945 const char *msg;
947 if (key == NULL)
949 gnutls_assert ();
950 return GNUTLS_E_INVALID_REQUEST;
953 if (key->pk_algorithm == GNUTLS_PK_RSA)
954 msg = PEM_KEY_RSA;
955 else if (key->pk_algorithm == GNUTLS_PK_DSA)
956 msg = PEM_KEY_DSA;
957 else if (key->pk_algorithm == GNUTLS_PK_EC)
958 msg = PEM_KEY_ECC;
959 else
960 msg = "UNKNOWN";
962 return _gnutls_x509_export_int (key->key, format, msg,
963 output_data, output_data_size);
967 * gnutls_x509_privkey_sec_param:
968 * @key: a key structure
970 * This function will return the security parameter appropriate with
971 * this private key.
973 * Returns: On success, a valid security parameter is returned otherwise
974 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
976 * Since: 2.12.0
978 gnutls_sec_param_t
979 gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key)
981 int bits;
983 bits = pubkey_to_bits(key->pk_algorithm, &key->params);
984 if (bits <= 0)
985 return GNUTLS_SEC_PARAM_UNKNOWN;
987 return gnutls_pk_bits_to_sec_param(key->pk_algorithm, bits);
991 * gnutls_x509_privkey_export_ecc_raw:
992 * @key: a structure that holds the rsa parameters
993 * @curve: will hold the curve
994 * @x: will hold the x coordinate
995 * @y: will hold the y coordinate
996 * @k: will hold the private key
998 * This function will export the ECC private key's parameters found
999 * in the given structure. The new parameters will be allocated using
1000 * gnutls_malloc() and will be stored in the appropriate datum.
1002 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1003 * negative error value.
1005 * Since: 3.0
1007 int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key,
1008 gnutls_ecc_curve_t *curve,
1009 gnutls_datum_t * x, gnutls_datum_t * y,
1010 gnutls_datum_t* k)
1012 int ret;
1014 if (key == NULL)
1016 gnutls_assert ();
1017 return GNUTLS_E_INVALID_REQUEST;
1020 *curve = key->params.flags;
1022 /* X */
1023 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_X], x);
1024 if (ret < 0)
1026 gnutls_assert ();
1027 return ret;
1030 /* Y */
1031 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_Y], y);
1032 if (ret < 0)
1034 gnutls_assert ();
1035 _gnutls_free_datum (x);
1036 return ret;
1040 /* K */
1041 ret = _gnutls_mpi_dprint_lz (key->params.params[ECC_K], k);
1042 if (ret < 0)
1044 gnutls_assert ();
1045 _gnutls_free_datum (x);
1046 _gnutls_free_datum (y);
1047 return ret;
1050 return 0;
1055 * gnutls_x509_privkey_export_rsa_raw:
1056 * @key: a structure that holds the rsa parameters
1057 * @m: will hold the modulus
1058 * @e: will hold the public exponent
1059 * @d: will hold the private exponent
1060 * @p: will hold the first prime (p)
1061 * @q: will hold the second prime (q)
1062 * @u: will hold the coefficient
1064 * This function will export the RSA private key's parameters found
1065 * in the given structure. The new parameters will be allocated using
1066 * gnutls_malloc() and will be stored in the appropriate datum.
1068 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1069 * negative error value.
1072 gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key,
1073 gnutls_datum_t * m, gnutls_datum_t * e,
1074 gnutls_datum_t * d, gnutls_datum_t * p,
1075 gnutls_datum_t * q, gnutls_datum_t * u)
1078 return gnutls_x509_privkey_export_rsa_raw2 (key, m, e, d, p, q, u, NULL,
1079 NULL);
1083 * gnutls_x509_privkey_export_rsa_raw2:
1084 * @key: a structure that holds the rsa parameters
1085 * @m: will hold the modulus
1086 * @e: will hold the public exponent
1087 * @d: will hold the private exponent
1088 * @p: will hold the first prime (p)
1089 * @q: will hold the second prime (q)
1090 * @u: will hold the coefficient
1091 * @e1: will hold e1 = d mod (p-1)
1092 * @e2: will hold e2 = d mod (q-1)
1094 * This function will export the RSA private key's parameters found
1095 * in the given structure. The new parameters will be allocated using
1096 * gnutls_malloc() and will be stored in the appropriate datum.
1098 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1099 * negative error value.
1101 * Since: 2.12.0
1104 gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
1105 gnutls_datum_t * m, gnutls_datum_t * e,
1106 gnutls_datum_t * d, gnutls_datum_t * p,
1107 gnutls_datum_t * q, gnutls_datum_t * u,
1108 gnutls_datum_t * e1, gnutls_datum_t * e2)
1110 int ret;
1111 gnutls_pk_params_st pk_params;
1113 gnutls_pk_params_init(&pk_params);
1115 if (key == NULL)
1117 gnutls_assert ();
1118 return GNUTLS_E_INVALID_REQUEST;
1121 m->data = e->data = d->data = p->data = q->data = u->data = NULL;
1122 m->size = e->size = d->size = p->size = q->size = u->size = 0;
1124 ret = _gnutls_pk_params_copy (&pk_params, &key->params);
1125 if (ret < 0)
1127 gnutls_assert ();
1128 return ret;
1131 ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
1132 if (ret < 0)
1134 gnutls_assert ();
1135 goto error;
1138 ret = _gnutls_mpi_dprint_lz (pk_params.params[0], m);
1139 if (ret < 0)
1141 gnutls_assert ();
1142 goto error;
1145 /* E */
1146 ret = _gnutls_mpi_dprint_lz (pk_params.params[1], e);
1147 if (ret < 0)
1149 gnutls_assert ();
1150 goto error;
1153 /* D */
1154 ret = _gnutls_mpi_dprint_lz (pk_params.params[2], d);
1155 if (ret < 0)
1157 gnutls_assert ();
1158 goto error;
1161 /* P */
1162 ret = _gnutls_mpi_dprint_lz (pk_params.params[3], p);
1163 if (ret < 0)
1165 gnutls_assert ();
1166 goto error;
1169 /* Q */
1170 ret = _gnutls_mpi_dprint_lz (pk_params.params[4], q);
1171 if (ret < 0)
1173 gnutls_assert ();
1174 goto error;
1177 /* U */
1178 ret = _gnutls_mpi_dprint_lz (key->params.params[5], u);
1179 if (ret < 0)
1181 gnutls_assert ();
1182 goto error;
1185 /* E1 */
1186 if (e1)
1188 ret = _gnutls_mpi_dprint_lz (key->params.params[6], e1);
1189 if (ret < 0)
1191 gnutls_assert ();
1192 goto error;
1196 /* E2 */
1197 if (e2)
1199 ret = _gnutls_mpi_dprint_lz (key->params.params[7], e2);
1200 if (ret < 0)
1202 gnutls_assert ();
1203 goto error;
1207 gnutls_pk_params_release (&pk_params);
1209 return 0;
1211 error:
1212 _gnutls_free_datum (m);
1213 _gnutls_free_datum (d);
1214 _gnutls_free_datum (e);
1215 _gnutls_free_datum (p);
1216 _gnutls_free_datum (q);
1217 gnutls_pk_params_release (&pk_params);
1219 return ret;
1223 * gnutls_x509_privkey_export_dsa_raw:
1224 * @key: a structure that holds the DSA parameters
1225 * @p: will hold the p
1226 * @q: will hold the q
1227 * @g: will hold the g
1228 * @y: will hold the y
1229 * @x: will hold the x
1231 * This function will export the DSA private key's parameters found
1232 * in the given structure. The new parameters will be allocated using
1233 * gnutls_malloc() and will be stored in the appropriate datum.
1235 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1236 * negative error value.
1239 gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
1240 gnutls_datum_t * p, gnutls_datum_t * q,
1241 gnutls_datum_t * g, gnutls_datum_t * y,
1242 gnutls_datum_t * x)
1244 int ret;
1246 if (key == NULL)
1248 gnutls_assert ();
1249 return GNUTLS_E_INVALID_REQUEST;
1252 /* P */
1253 ret = _gnutls_mpi_dprint_lz (key->params.params[0], p);
1254 if (ret < 0)
1256 gnutls_assert ();
1257 return ret;
1260 /* Q */
1261 ret = _gnutls_mpi_dprint_lz (key->params.params[1], q);
1262 if (ret < 0)
1264 gnutls_assert ();
1265 _gnutls_free_datum (p);
1266 return ret;
1270 /* G */
1271 ret = _gnutls_mpi_dprint_lz (key->params.params[2], g);
1272 if (ret < 0)
1274 gnutls_assert ();
1275 _gnutls_free_datum (p);
1276 _gnutls_free_datum (q);
1277 return ret;
1281 /* Y */
1282 ret = _gnutls_mpi_dprint_lz (key->params.params[3], y);
1283 if (ret < 0)
1285 gnutls_assert ();
1286 _gnutls_free_datum (p);
1287 _gnutls_free_datum (g);
1288 _gnutls_free_datum (q);
1289 return ret;
1292 /* X */
1293 ret = _gnutls_mpi_dprint_lz (key->params.params[4], x);
1294 if (ret < 0)
1296 gnutls_assert ();
1297 _gnutls_free_datum (y);
1298 _gnutls_free_datum (p);
1299 _gnutls_free_datum (g);
1300 _gnutls_free_datum (q);
1301 return ret;
1304 return 0;
1308 * gnutls_x509_privkey_generate:
1309 * @key: should contain a #gnutls_x509_privkey_t structure
1310 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1311 * @bits: the size of the modulus
1312 * @flags: unused for now. Must be 0.
1314 * This function will generate a random private key. Note that this
1315 * function must be called on an empty private key.
1317 * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
1319 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1320 * negative error value.
1323 gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
1324 gnutls_pk_algorithm_t algo, unsigned int bits,
1325 unsigned int flags)
1327 int ret;
1329 if (key == NULL)
1331 gnutls_assert ();
1332 return GNUTLS_E_INVALID_REQUEST;
1335 gnutls_pk_params_init(&key->params);
1337 if (algo == GNUTLS_PK_EC)
1338 bits = _gnutls_ecc_bits_to_curve(bits);
1340 ret = _gnutls_pk_generate (algo, bits, &key->params);
1341 if (ret < 0)
1343 gnutls_assert ();
1344 return ret;
1347 ret = _gnutls_asn1_encode_privkey (algo, &key->key, &key->params);
1348 if (ret < 0)
1350 gnutls_assert ();
1351 goto cleanup;
1353 key->pk_algorithm = algo;
1355 return 0;
1357 cleanup:
1358 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1359 gnutls_pk_params_release(&key->params);
1361 return ret;
1365 * gnutls_x509_privkey_verify_params:
1366 * @key: should contain a #gnutls_x509_privkey_t structure
1368 * This function will verify the private key parameters.
1370 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1371 * negative error value.
1374 gnutls_x509_privkey_verify_params (gnutls_x509_privkey_t key)
1376 int ret;
1378 ret = _gnutls_pk_verify_params (key->pk_algorithm, &key->params);
1379 if (ret < 0)
1381 gnutls_assert ();
1382 return ret;
1385 return 0;
1389 * gnutls_x509_privkey_get_key_id:
1390 * @key: Holds the key
1391 * @flags: should be 0 for now
1392 * @output_data: will contain the key ID
1393 * @output_data_size: holds the size of output_data (and will be
1394 * replaced by the actual size of parameters)
1396 * This function will return a unique ID the depends on the public key
1397 * parameters. This ID can be used in checking whether a certificate
1398 * corresponds to the given key.
1400 * If the buffer provided is not long enough to hold the output, then
1401 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1402 * be returned. The output will normally be a SHA-1 hash output,
1403 * which is 20 bytes.
1405 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1406 * negative error value.
1409 gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key,
1410 unsigned int flags,
1411 unsigned char *output_data,
1412 size_t * output_data_size)
1414 int ret;
1416 if (key == NULL)
1418 gnutls_assert ();
1419 return GNUTLS_E_INVALID_REQUEST;
1422 ret = _gnutls_get_key_id(key->pk_algorithm, &key->params, output_data, output_data_size);
1423 if (ret < 0)
1425 gnutls_assert ();
1428 return ret;
1433 * _gnutls_x509_privkey_sign_hash2:
1434 * @signer: Holds the signer's key
1435 * @hash_algo: The hash algorithm used
1436 * @hash_data: holds the data to be signed
1437 * @signature: will contain newly allocated signature
1438 * @flags: (0) for now
1440 * This function will sign the given hashed data using a signature algorithm
1441 * supported by the private key. Signature algorithms are always used
1442 * together with a hash functions. Different hash functions may be
1443 * used for the RSA algorithm, but only SHA-1,SHA-224 and SHA-256
1444 * for the DSA keys, depending on their bit size.
1446 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1447 * the hash algorithm.
1449 * The RSA algorithm is used in PKCS #1 v1.5 mode.
1451 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1452 * negative error value.
1454 static int
1455 _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer,
1456 gnutls_digest_algorithm_t hash_algo,
1457 unsigned int flags,
1458 const gnutls_datum_t * hash_data,
1459 gnutls_datum_t * signature)
1461 int ret;
1462 gnutls_datum_t digest;
1464 digest.data = gnutls_malloc (hash_data->size);
1465 if (digest.data == NULL)
1467 gnutls_assert ();
1468 return GNUTLS_E_MEMORY_ERROR;
1470 digest.size = hash_data->size;
1471 memcpy (digest.data, hash_data->data, digest.size);
1473 ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
1474 if (ret < 0)
1476 gnutls_assert ();
1477 goto cleanup;
1480 ret = _gnutls_soft_sign (signer->pk_algorithm, &signer->params,
1481 &digest, signature);
1483 if (ret < 0)
1485 gnutls_assert ();
1486 goto cleanup;
1489 ret = 0;
1491 cleanup:
1492 _gnutls_free_datum (&digest);
1493 return ret;
1497 * gnutls_x509_privkey_sign_hash:
1498 * @key: Holds the key
1499 * @hash: holds the data to be signed
1500 * @signature: will contain newly allocated signature
1502 * This function will sign the given hash using the private key. Do not
1503 * use this function directly unless you know what it is. Typical signing
1504 * requires the data to be hashed and stored in special formats
1505 * (e.g. BER Digest-Info for RSA).
1507 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1508 * negative error value.
1510 * Deprecated in: 2.12.0
1513 gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
1514 const gnutls_datum_t * hash,
1515 gnutls_datum_t * signature)
1517 int result;
1519 if (key == NULL)
1521 gnutls_assert ();
1522 return GNUTLS_E_INVALID_REQUEST;
1525 result = _gnutls_soft_sign (key->pk_algorithm, &key->params,
1526 hash, signature);
1527 if (result < 0)
1529 gnutls_assert ();
1530 return result;
1533 return 0;
1537 * gnutls_x509_privkey_sign_data:
1538 * @key: Holds the key
1539 * @digest: should be MD5 or SHA1
1540 * @flags: should be 0 for now
1541 * @data: holds the data to be signed
1542 * @signature: will contain the signature
1543 * @signature_size: holds the size of signature (and will be replaced
1544 * by the new size)
1546 * This function will sign the given data using a signature algorithm
1547 * supported by the private key. Signature algorithms are always used
1548 * together with a hash functions. Different hash functions may be
1549 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
1551 * If the buffer provided is not long enough to hold the output, then
1552 * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1553 * be returned.
1555 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1556 * the hash algorithm.
1558 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1559 * negative error value.
1561 * Deprecated: Use gnutls_privkey_sign_data().
1564 gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
1565 gnutls_digest_algorithm_t digest,
1566 unsigned int flags,
1567 const gnutls_datum_t * data,
1568 void *signature, size_t * signature_size)
1570 int result;
1571 gnutls_datum_t sig = { NULL, 0 };
1572 gnutls_datum_t hash;
1574 if (key == NULL)
1576 gnutls_assert ();
1577 return GNUTLS_E_INVALID_REQUEST;
1580 result =
1581 pk_hash_data (key->pk_algorithm, digest, &key->params, data, &hash);
1582 if (result < 0)
1584 gnutls_assert ();
1585 return result;
1588 result =
1589 _gnutls_x509_privkey_sign_hash2 (key, digest, flags, &hash, signature);
1591 _gnutls_free_datum(&hash);
1593 if (result < 0)
1595 gnutls_assert ();
1596 return result;
1599 if (*signature_size < sig.size)
1601 *signature_size = sig.size;
1602 _gnutls_free_datum (&sig);
1603 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1606 *signature_size = sig.size;
1607 memcpy (signature, sig.data, sig.size);
1609 _gnutls_free_datum (&sig);
1611 return 0;
1616 * gnutls_x509_privkey_fix:
1617 * @key: Holds the key
1619 * This function will recalculate the secondary parameters in a key.
1620 * In RSA keys, this can be the coefficient and exponent1,2.
1622 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1623 * negative error value.
1626 gnutls_x509_privkey_fix (gnutls_x509_privkey_t key)
1628 int ret;
1630 if (key == NULL)
1632 gnutls_assert ();
1633 return GNUTLS_E_INVALID_REQUEST;
1636 asn1_delete_structure (&key->key);
1638 ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params);
1639 if (ret < 0)
1641 gnutls_assert ();
1642 return ret;
1645 return 0;