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>
30 #include <gnutls_x509.h>
33 #include <gnutls_pk.h>
34 #include <gnutls_mpi.h>
35 #include <gnutls_ecc.h>
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.
47 gnutls_x509_privkey_init (gnutls_x509_privkey_t
* key
)
49 *key
= gnutls_calloc (1, sizeof (gnutls_x509_privkey_int
));
53 (*key
)->key
= ASN1_TYPE_EMPTY
;
54 (*key
)->pk_algorithm
= GNUTLS_PK_UNKNOWN
;
55 return 0; /* success */
58 return GNUTLS_E_MEMORY_ERROR
;
62 * gnutls_x509_privkey_deinit:
63 * @key: The structure to be deinitialized
65 * This function will deinitialize a private key structure.
68 gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key
)
73 gnutls_pk_params_release(&key
->params
);
74 asn1_delete_structure (&key
->key
);
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.
90 gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst
, gnutls_x509_privkey_t src
)
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
);
120 /* Converts an RSA PKCS#1 key to
121 * an internal structure (gnutls_private_key)
124 _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t
* raw_key
,
125 gnutls_x509_privkey_t pkey
)
130 gnutls_pk_params_init(&pkey
->params
);
133 asn1_create_element (_gnutls_get_gnutls_asn (),
134 "GNUTLS.RSAPrivateKey",
135 &pkey_asn
)) != ASN1_SUCCESS
)
141 result
= asn1_der_decoding (&pkey_asn
, raw_key
->data
, raw_key
->size
, NULL
);
142 if (result
!= ASN1_SUCCESS
)
148 if ((result
= _gnutls_x509_read_int (pkey_asn
, "modulus",
149 &pkey
->params
.params
[0])) < 0)
154 pkey
->params
.params_nr
++;
157 _gnutls_x509_read_int (pkey_asn
, "publicExponent",
158 &pkey
->params
.params
[1])) < 0)
163 pkey
->params
.params_nr
++;
166 _gnutls_x509_read_int (pkey_asn
, "privateExponent",
167 &pkey
->params
.params
[2])) < 0)
172 pkey
->params
.params_nr
++;
174 if ((result
= _gnutls_x509_read_int (pkey_asn
, "prime1",
175 &pkey
->params
.params
[3])) < 0)
180 pkey
->params
.params_nr
++;
182 if ((result
= _gnutls_x509_read_int (pkey_asn
, "prime2",
183 &pkey
->params
.params
[4])) < 0)
188 pkey
->params
.params_nr
++;
190 if ((result
= _gnutls_x509_read_int (pkey_asn
, "coefficient",
191 &pkey
->params
.params
[5])) < 0)
196 pkey
->params
.params_nr
++;
198 if ((result
= _gnutls_x509_read_int (pkey_asn
, "exponent1",
199 &pkey
->params
.params
[6])) < 0)
204 pkey
->params
.params_nr
++;
206 if ((result
= _gnutls_x509_read_int (pkey_asn
, "exponent2",
207 &pkey
->params
.params
[7])) < 0)
212 pkey
->params
.params_nr
++;
214 result
= _gnutls_pk_fixup (GNUTLS_PK_RSA
, GNUTLS_IMPORT
, &pkey
->params
);
221 pkey
->params
.params_nr
= RSA_PRIVATE_PARAMS
;
226 asn1_delete_structure (&pkey_asn
);
227 gnutls_pk_params_release (&pkey
->params
);
232 /* Converts an ECC key to
233 * an internal structure (gnutls_private_key)
236 _gnutls_privkey_decode_ecc_key (const gnutls_datum_t
* raw_key
,
237 gnutls_x509_privkey_t pkey
)
241 unsigned int version
;
242 char oid
[MAX_OID_SIZE
];
246 gnutls_pk_params_init(&pkey
->params
);
249 asn1_create_element (_gnutls_get_gnutls_asn (),
250 "GNUTLS.ECPrivateKey",
251 &pkey_asn
)) != ASN1_SUCCESS
)
257 ret
= asn1_der_decoding (&pkey_asn
, raw_key
->data
, raw_key
->size
, NULL
);
258 if (ret
!= ASN1_SUCCESS
)
264 ret
= _gnutls_x509_read_uint (pkey_asn
, "Version", &version
);
273 _gnutls_debug_log("ECC private key version %u is not supported\n", version
);
279 oid_size
= sizeof(oid
);
280 ret
= asn1_read_value(pkey_asn
, "parameters.namedCurve", oid
, &oid_size
);
281 if (ret
!= ASN1_SUCCESS
)
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
);
295 ret
= _gnutls_ecc_curve_fill_params(pkey
->params
.flags
, &pkey
->params
);
302 /* read the public key */
303 ret
= _gnutls_x509_read_string(pkey_asn
, "publicKey", &out
, RV_BIT_STRING
);
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
);
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
]);
328 pkey
->params
.params_nr
++;
333 asn1_delete_structure (&pkey_asn
);
334 gnutls_pk_params_release (&pkey
->params
);
341 decode_dsa_key (const gnutls_datum_t
* raw_key
, gnutls_x509_privkey_t pkey
)
347 asn1_create_element (_gnutls_get_gnutls_asn (),
348 "GNUTLS.DSAPrivateKey",
349 &dsa_asn
)) != ASN1_SUCCESS
)
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
)
364 if ((result
= _gnutls_x509_read_int (dsa_asn
, "p", &pkey
->params
.params
[0])) < 0)
369 pkey
->params
.params_nr
++;
371 if ((result
= _gnutls_x509_read_int (dsa_asn
, "q", &pkey
->params
.params
[1])) < 0)
376 pkey
->params
.params_nr
++;
378 if ((result
= _gnutls_x509_read_int (dsa_asn
, "g", &pkey
->params
.params
[2])) < 0)
383 pkey
->params
.params_nr
++;
385 if ((result
= _gnutls_x509_read_int (dsa_asn
, "Y", &pkey
->params
.params
[3])) < 0)
390 pkey
->params
.params_nr
++;
392 if ((result
= _gnutls_x509_read_int (dsa_asn
, "priv",
393 &pkey
->params
.params
[4])) < 0)
398 pkey
->params
.params_nr
++;
403 asn1_delete_structure (&dsa_asn
);
404 gnutls_pk_params_release(&pkey
->params
);
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
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
;
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 */
456 _gnutls_fbase64_decode (PEM_KEY_RSA
, data
->data
, data
->size
, &_data
);
459 key
->pk_algorithm
= GNUTLS_PK_RSA
;
461 if (result
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
463 /* try for the second header */
465 _gnutls_fbase64_decode (PEM_KEY_DSA
, data
->data
, data
->size
,
469 key
->pk_algorithm
= GNUTLS_PK_DSA
;
471 if (result
== GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR
)
473 /* try for the second header */
475 _gnutls_fbase64_decode (PEM_KEY_ECC
, data
->data
, data
->size
,
478 key
->pk_algorithm
= GNUTLS_PK_EC
;
491 if (key
->pk_algorithm
== GNUTLS_PK_RSA
)
493 key
->key
= _gnutls_privkey_decode_pkcs1_rsa_key (&_data
, key
);
494 if (key
->key
== NULL
)
497 else if (key
->pk_algorithm
== GNUTLS_PK_DSA
)
499 key
->key
= decode_dsa_key (&_data
, key
);
500 if (key
->key
== NULL
)
503 else if (key
->pk_algorithm
== GNUTLS_PK_EC
)
505 key
->key
= _gnutls_privkey_decode_ecc_key (&_data
, key
);
506 if (key
->key
== NULL
)
511 /* Try decoding with both, and accept the one that
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
)
531 if (key
->key
== NULL
)
534 result
= GNUTLS_E_ASN1_DER_ERROR
;
539 _gnutls_free_datum (&_data
);
541 /* The key has now been decoded.
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
);
556 _gnutls_free_datum (&_data
);
562 * gnutls_x509_privkey_import2:
563 * @key: The structure to store the parsed key
564 * @data: The DER or PEM encoded key.
565 * @format: One of DER or PEM
566 * @password: A password (optional)
567 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
569 * This function will import the given DER or PEM encoded key, to
570 * the native #gnutls_x509_privkey_t format, irrespective of the
571 * input format. The input format is auto-detected.
573 * The supported formats are typical X.509, PKCS #8 and the openssl
576 * If the provided key is encrypted but no password was given, then
577 * %GNUTLS_E_DECRYPTION_FAILED is returned.
579 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
580 * negative error value.
583 gnutls_x509_privkey_import2 (gnutls_x509_privkey_t key
,
584 const gnutls_datum_t
* data
,
585 gnutls_x509_crt_fmt_t format
,
586 const char* password
, unsigned int flags
)
590 if (password
== NULL
&& !(flags
& GNUTLS_PKCS_NULL_PASSWORD
))
592 ret
= gnutls_x509_privkey_import(key
, data
, format
);
599 if ((password
!= NULL
|| (flags
& GNUTLS_PKCS_NULL_PASSWORD
)) || ret
< 0)
601 ret
= gnutls_x509_privkey_import_pkcs8(key
, data
, format
, password
, flags
);
604 if (format
== GNUTLS_X509_FMT_PEM
)
607 err
= gnutls_x509_privkey_import_openssl(key
, data
, password
);
610 if (err
== GNUTLS_E_DECRYPTION_FAILED
) ret
= err
;
631 * gnutls_x509_privkey_import_rsa_raw:
632 * @key: The structure to store the parsed key
633 * @m: holds the modulus
634 * @e: holds the public exponent
635 * @d: holds the private exponent
636 * @p: holds the first prime (p)
637 * @q: holds the second prime (q)
638 * @u: holds the coefficient
640 * This function will convert the given RSA raw parameters to the
641 * native #gnutls_x509_privkey_t format. The output will be stored in
644 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
645 * negative error value.
648 gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key
,
649 const gnutls_datum_t
* m
,
650 const gnutls_datum_t
* e
,
651 const gnutls_datum_t
* d
,
652 const gnutls_datum_t
* p
,
653 const gnutls_datum_t
* q
,
654 const gnutls_datum_t
* u
)
656 return gnutls_x509_privkey_import_rsa_raw2 (key
, m
, e
, d
, p
, q
, u
, NULL
,
661 * gnutls_x509_privkey_import_rsa_raw2:
662 * @key: The structure to store the parsed key
663 * @m: holds the modulus
664 * @e: holds the public exponent
665 * @d: holds the private exponent
666 * @p: holds the first prime (p)
667 * @q: holds the second prime (q)
668 * @u: holds the coefficient
669 * @e1: holds e1 = d mod (p-1)
670 * @e2: holds e2 = d mod (q-1)
672 * This function will convert the given RSA raw parameters to the
673 * native #gnutls_x509_privkey_t format. The output will be stored in
676 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
677 * negative error value.
680 gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key
,
681 const gnutls_datum_t
* m
,
682 const gnutls_datum_t
* e
,
683 const gnutls_datum_t
* d
,
684 const gnutls_datum_t
* p
,
685 const gnutls_datum_t
* q
,
686 const gnutls_datum_t
* u
,
687 const gnutls_datum_t
* e1
,
688 const gnutls_datum_t
* e2
)
696 return GNUTLS_E_INVALID_REQUEST
;
699 gnutls_pk_params_init(&key
->params
);
702 if (_gnutls_mpi_scan_nz (&key
->params
.params
[0], m
->data
, siz
))
705 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
708 key
->params
.params_nr
++;
711 if (_gnutls_mpi_scan_nz (&key
->params
.params
[1], e
->data
, siz
))
714 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
717 key
->params
.params_nr
++;
720 if (_gnutls_mpi_scan_nz (&key
->params
.params
[2], d
->data
, siz
))
723 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
726 key
->params
.params_nr
++;
729 if (_gnutls_mpi_scan_nz (&key
->params
.params
[3], p
->data
, siz
))
732 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
735 key
->params
.params_nr
++;
738 if (_gnutls_mpi_scan_nz (&key
->params
.params
[4], q
->data
, siz
))
741 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
744 key
->params
.params_nr
++;
747 if (_gnutls_mpi_scan_nz (&key
->params
.params
[5], u
->data
, siz
))
750 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
753 key
->params
.params_nr
++;
758 if (_gnutls_mpi_scan_nz (&key
->params
.params
[6], e1
->data
, siz
))
761 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
764 key
->params
.params_nr
++;
767 if (_gnutls_mpi_scan_nz (&key
->params
.params
[7], e2
->data
, siz
))
770 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
773 key
->params
.params_nr
++;
776 ret
= _gnutls_pk_fixup (GNUTLS_PK_RSA
, GNUTLS_IMPORT
, &key
->params
);
783 ret
= _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA
, &key
->key
, &key
->params
);
790 key
->params
.params_nr
= RSA_PRIVATE_PARAMS
;
791 key
->pk_algorithm
= GNUTLS_PK_RSA
;
796 gnutls_pk_params_release(&key
->params
);
802 * gnutls_x509_privkey_import_dsa_raw:
803 * @key: The structure to store the parsed key
810 * This function will convert the given DSA raw parameters to the
811 * native #gnutls_x509_privkey_t format. The output will be stored
814 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
815 * negative error value.
818 gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key
,
819 const gnutls_datum_t
* p
,
820 const gnutls_datum_t
* q
,
821 const gnutls_datum_t
* g
,
822 const gnutls_datum_t
* y
,
823 const gnutls_datum_t
* x
)
831 return GNUTLS_E_INVALID_REQUEST
;
835 if (_gnutls_mpi_scan_nz (&key
->params
.params
[0], p
->data
, siz
))
838 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
843 if (_gnutls_mpi_scan_nz (&key
->params
.params
[1], q
->data
, siz
))
846 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
851 if (_gnutls_mpi_scan_nz (&key
->params
.params
[2], g
->data
, siz
))
854 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
859 if (_gnutls_mpi_scan_nz (&key
->params
.params
[3], y
->data
, siz
))
862 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
867 if (_gnutls_mpi_scan_nz (&key
->params
.params
[4], x
->data
, siz
))
870 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
874 ret
= _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA
, &key
->key
, &key
->params
);
881 key
->params
.params_nr
= DSA_PRIVATE_PARAMS
;
882 key
->pk_algorithm
= GNUTLS_PK_DSA
;
887 gnutls_pk_params_release(&key
->params
);
893 * gnutls_x509_privkey_import_ecc_raw:
894 * @key: The structure to store the parsed key
895 * @curve: holds the curve
900 * This function will convert the given elliptic curve parameters to the
901 * native #gnutls_x509_privkey_t format. The output will be stored
904 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
905 * negative error value.
910 gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key
,
911 gnutls_ecc_curve_t curve
,
912 const gnutls_datum_t
* x
,
913 const gnutls_datum_t
* y
,
914 const gnutls_datum_t
* k
)
921 return GNUTLS_E_INVALID_REQUEST
;
924 key
->params
.flags
= curve
;
926 ret
= _gnutls_ecc_curve_fill_params(curve
, &key
->params
);
928 return gnutls_assert_val(ret
);
930 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_X
], x
->data
, x
->size
))
933 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
936 key
->params
.params_nr
++;
938 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_Y
], y
->data
, y
->size
))
941 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
944 key
->params
.params_nr
++;
946 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_K
], k
->data
, k
->size
))
949 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
952 key
->params
.params_nr
++;
954 key
->pk_algorithm
= GNUTLS_PK_EC
;
959 gnutls_pk_params_release(&key
->params
);
966 * gnutls_x509_privkey_get_pk_algorithm:
967 * @key: should contain a #gnutls_x509_privkey_t structure
969 * This function will return the public key algorithm of a private
972 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
973 * success, or a negative error code on error.
976 gnutls_x509_privkey_get_pk_algorithm (gnutls_x509_privkey_t key
)
981 return GNUTLS_E_INVALID_REQUEST
;
984 return key
->pk_algorithm
;
988 * gnutls_x509_privkey_get_pk_algorithm2:
989 * @key: should contain a #gnutls_x509_privkey_t structure
990 * @bits: The number of bits in the public key algorithm
992 * This function will return the public key algorithm of a private
995 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
996 * success, or a negative error code on error.
999 gnutls_x509_privkey_get_pk_algorithm2 (gnutls_x509_privkey_t key
, unsigned int *bits
)
1006 return GNUTLS_E_INVALID_REQUEST
;
1011 ret
= pubkey_to_bits(key
->pk_algorithm
, &key
->params
);
1012 if (ret
< 0) ret
= 0;
1016 return key
->pk_algorithm
;
1019 static const char* set_msg(gnutls_x509_privkey_t key
)
1021 if (key
->pk_algorithm
== GNUTLS_PK_RSA
)
1023 else if (key
->pk_algorithm
== GNUTLS_PK_DSA
)
1025 else if (key
->pk_algorithm
== GNUTLS_PK_EC
)
1032 * gnutls_x509_privkey_export:
1033 * @key: Holds the key
1034 * @format: the format of output params. One of PEM or DER.
1035 * @output_data: will contain a private key PEM or DER encoded
1036 * @output_data_size: holds the size of output_data (and will be
1037 * replaced by the actual size of parameters)
1039 * This function will export the private key to a PKCS1 structure for
1040 * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
1041 * the same format with the parameters used by openssl.
1043 * If the buffer provided is not long enough to hold the output, then
1044 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER
1047 * If the structure is PEM encoded, it will have a header
1048 * of "BEGIN RSA PRIVATE KEY".
1050 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1051 * negative error value.
1054 gnutls_x509_privkey_export (gnutls_x509_privkey_t key
,
1055 gnutls_x509_crt_fmt_t format
, void *output_data
,
1056 size_t * output_data_size
)
1063 return GNUTLS_E_INVALID_REQUEST
;
1068 return _gnutls_x509_export_int (key
->key
, format
, msg
,
1069 output_data
, output_data_size
);
1073 * gnutls_x509_privkey_export2:
1074 * @key: Holds the key
1075 * @format: the format of output params. One of PEM or DER.
1076 * @out: will contain a private key PEM or DER encoded
1078 * This function will export the private key to a PKCS1 structure for
1079 * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
1080 * the same format with the parameters used by openssl.
1082 * The output buffer is allocated using gnutls_malloc().
1084 * If the structure is PEM encoded, it will have a header
1085 * of "BEGIN RSA PRIVATE KEY".
1087 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1088 * negative error value.
1093 gnutls_x509_privkey_export2 (gnutls_x509_privkey_t key
,
1094 gnutls_x509_crt_fmt_t format
,
1095 gnutls_datum_t
* out
)
1102 return GNUTLS_E_INVALID_REQUEST
;
1107 return _gnutls_x509_export_int2 (key
->key
, format
, msg
, out
);
1111 * gnutls_x509_privkey_sec_param:
1112 * @key: a key structure
1114 * This function will return the security parameter appropriate with
1117 * Returns: On success, a valid security parameter is returned otherwise
1118 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
1123 gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key
)
1127 bits
= pubkey_to_bits(key
->pk_algorithm
, &key
->params
);
1129 return GNUTLS_SEC_PARAM_UNKNOWN
;
1131 return gnutls_pk_bits_to_sec_param(key
->pk_algorithm
, bits
);
1135 * gnutls_x509_privkey_export_ecc_raw:
1136 * @key: a structure that holds the rsa parameters
1137 * @curve: will hold the curve
1138 * @x: will hold the x coordinate
1139 * @y: will hold the y coordinate
1140 * @k: will hold the private key
1142 * This function will export the ECC private key's parameters found
1143 * in the given structure. The new parameters will be allocated using
1144 * gnutls_malloc() and will be stored in the appropriate datum.
1146 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1147 * negative error value.
1151 int gnutls_x509_privkey_export_ecc_raw (gnutls_x509_privkey_t key
,
1152 gnutls_ecc_curve_t
*curve
,
1153 gnutls_datum_t
* x
, gnutls_datum_t
* y
,
1161 return GNUTLS_E_INVALID_REQUEST
;
1164 *curve
= key
->params
.flags
;
1167 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_X
], x
);
1175 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_Y
], y
);
1179 _gnutls_free_datum (x
);
1185 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_K
], k
);
1189 _gnutls_free_datum (x
);
1190 _gnutls_free_datum (y
);
1199 * gnutls_x509_privkey_export_rsa_raw:
1200 * @key: a structure that holds the rsa parameters
1201 * @m: will hold the modulus
1202 * @e: will hold the public exponent
1203 * @d: will hold the private exponent
1204 * @p: will hold the first prime (p)
1205 * @q: will hold the second prime (q)
1206 * @u: will hold the coefficient
1208 * This function will export the RSA private key's parameters found
1209 * in the given structure. The new parameters will be allocated using
1210 * gnutls_malloc() and will be stored in the appropriate datum.
1212 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1213 * negative error value.
1216 gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key
,
1217 gnutls_datum_t
* m
, gnutls_datum_t
* e
,
1218 gnutls_datum_t
* d
, gnutls_datum_t
* p
,
1219 gnutls_datum_t
* q
, gnutls_datum_t
* u
)
1222 return gnutls_x509_privkey_export_rsa_raw2 (key
, m
, e
, d
, p
, q
, u
, NULL
,
1227 * gnutls_x509_privkey_export_rsa_raw2:
1228 * @key: a structure that holds the rsa parameters
1229 * @m: will hold the modulus
1230 * @e: will hold the public exponent
1231 * @d: will hold the private exponent
1232 * @p: will hold the first prime (p)
1233 * @q: will hold the second prime (q)
1234 * @u: will hold the coefficient
1235 * @e1: will hold e1 = d mod (p-1)
1236 * @e2: will hold e2 = d mod (q-1)
1238 * This function will export the RSA private key's parameters found
1239 * in the given structure. The new parameters will be allocated using
1240 * gnutls_malloc() and will be stored in the appropriate datum.
1242 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1243 * negative error value.
1248 gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key
,
1249 gnutls_datum_t
* m
, gnutls_datum_t
* e
,
1250 gnutls_datum_t
* d
, gnutls_datum_t
* p
,
1251 gnutls_datum_t
* q
, gnutls_datum_t
* u
,
1252 gnutls_datum_t
* e1
, gnutls_datum_t
* e2
)
1255 gnutls_pk_params_st pk_params
;
1257 gnutls_pk_params_init(&pk_params
);
1262 return GNUTLS_E_INVALID_REQUEST
;
1265 m
->data
= e
->data
= d
->data
= p
->data
= q
->data
= u
->data
= NULL
;
1266 m
->size
= e
->size
= d
->size
= p
->size
= q
->size
= u
->size
= 0;
1268 ret
= _gnutls_pk_params_copy (&pk_params
, &key
->params
);
1275 ret
= _gnutls_pk_fixup (GNUTLS_PK_RSA
, GNUTLS_EXPORT
, &pk_params
);
1282 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[0], m
);
1290 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[1], e
);
1298 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[2], d
);
1306 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[3], p
);
1314 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[4], q
);
1322 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[5], u
);
1332 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[6], e1
);
1343 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[7], e2
);
1351 gnutls_pk_params_release (&pk_params
);
1356 _gnutls_free_datum (m
);
1357 _gnutls_free_datum (d
);
1358 _gnutls_free_datum (e
);
1359 _gnutls_free_datum (p
);
1360 _gnutls_free_datum (q
);
1361 gnutls_pk_params_release (&pk_params
);
1367 * gnutls_x509_privkey_export_dsa_raw:
1368 * @key: a structure that holds the DSA parameters
1369 * @p: will hold the p
1370 * @q: will hold the q
1371 * @g: will hold the g
1372 * @y: will hold the y
1373 * @x: will hold the x
1375 * This function will export the DSA private key's parameters found
1376 * in the given structure. The new parameters will be allocated using
1377 * gnutls_malloc() and will be stored in the appropriate datum.
1379 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1380 * negative error value.
1383 gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key
,
1384 gnutls_datum_t
* p
, gnutls_datum_t
* q
,
1385 gnutls_datum_t
* g
, gnutls_datum_t
* y
,
1393 return GNUTLS_E_INVALID_REQUEST
;
1397 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[0], p
);
1405 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[1], q
);
1409 _gnutls_free_datum (p
);
1415 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[2], g
);
1419 _gnutls_free_datum (p
);
1420 _gnutls_free_datum (q
);
1426 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[3], y
);
1430 _gnutls_free_datum (p
);
1431 _gnutls_free_datum (g
);
1432 _gnutls_free_datum (q
);
1437 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[4], x
);
1441 _gnutls_free_datum (y
);
1442 _gnutls_free_datum (p
);
1443 _gnutls_free_datum (g
);
1444 _gnutls_free_datum (q
);
1452 * gnutls_x509_privkey_generate:
1453 * @key: should contain a #gnutls_x509_privkey_t structure
1454 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1455 * @bits: the size of the modulus
1456 * @flags: unused for now. Must be 0.
1458 * This function will generate a random private key. Note that this
1459 * function must be called on an empty private key.
1461 * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
1463 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1464 * negative error value.
1467 gnutls_x509_privkey_generate (gnutls_x509_privkey_t key
,
1468 gnutls_pk_algorithm_t algo
, unsigned int bits
,
1476 return GNUTLS_E_INVALID_REQUEST
;
1479 gnutls_pk_params_init(&key
->params
);
1481 if (algo
== GNUTLS_PK_EC
)
1482 bits
= _gnutls_ecc_bits_to_curve(bits
);
1484 ret
= _gnutls_pk_generate (algo
, bits
, &key
->params
);
1491 ret
= _gnutls_asn1_encode_privkey (algo
, &key
->key
, &key
->params
);
1497 key
->pk_algorithm
= algo
;
1502 key
->pk_algorithm
= GNUTLS_PK_UNKNOWN
;
1503 gnutls_pk_params_release(&key
->params
);
1509 * gnutls_x509_privkey_verify_params:
1510 * @key: should contain a #gnutls_x509_privkey_t structure
1512 * This function will verify the private key parameters.
1514 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1515 * negative error value.
1518 gnutls_x509_privkey_verify_params (gnutls_x509_privkey_t key
)
1522 ret
= _gnutls_pk_verify_params (key
->pk_algorithm
, &key
->params
);
1533 * gnutls_x509_privkey_get_key_id:
1534 * @key: Holds the key
1535 * @flags: should be 0 for now
1536 * @output_data: will contain the key ID
1537 * @output_data_size: holds the size of output_data (and will be
1538 * replaced by the actual size of parameters)
1540 * This function will return a unique ID that depends on the public key
1541 * parameters. This ID can be used in checking whether a certificate
1542 * corresponds to the given key.
1544 * If the buffer provided is not long enough to hold the output, then
1545 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1546 * be returned. The output will normally be a SHA-1 hash output,
1547 * which is 20 bytes.
1549 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1550 * negative error value.
1553 gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key
,
1555 unsigned char *output_data
,
1556 size_t * output_data_size
)
1563 return GNUTLS_E_INVALID_REQUEST
;
1566 ret
= _gnutls_get_key_id(key
->pk_algorithm
, &key
->params
, output_data
, output_data_size
);
1577 * _gnutls_x509_privkey_sign_hash2:
1578 * @signer: Holds the signer's key
1579 * @hash_algo: The hash algorithm used
1580 * @hash_data: holds the data to be signed
1581 * @signature: will contain newly allocated signature
1582 * @flags: (0) for now
1584 * This function will sign the given hashed data using a signature algorithm
1585 * supported by the private key. Signature algorithms are always used
1586 * together with a hash functions. Different hash functions may be
1587 * used for the RSA algorithm, but only SHA-1,SHA-224 and SHA-256
1588 * for the DSA keys, depending on their bit size.
1590 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1591 * the hash algorithm.
1593 * The RSA algorithm is used in PKCS #1 v1.5 mode.
1595 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1596 * negative error value.
1599 _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer
,
1600 gnutls_digest_algorithm_t hash_algo
,
1602 const gnutls_datum_t
* hash_data
,
1603 gnutls_datum_t
* signature
)
1606 gnutls_datum_t digest
;
1608 digest
.data
= gnutls_malloc (hash_data
->size
);
1609 if (digest
.data
== NULL
)
1612 return GNUTLS_E_MEMORY_ERROR
;
1614 digest
.size
= hash_data
->size
;
1615 memcpy (digest
.data
, hash_data
->data
, digest
.size
);
1617 ret
= pk_prepare_hash (signer
->pk_algorithm
, hash_algo
, &digest
);
1624 ret
= _gnutls_pk_sign (signer
->pk_algorithm
, signature
, &digest
, &signer
->params
);
1635 _gnutls_free_datum (&digest
);
1640 * gnutls_x509_privkey_sign_hash:
1641 * @key: Holds the key
1642 * @hash: holds the data to be signed
1643 * @signature: will contain newly allocated signature
1645 * This function will sign the given hash using the private key. Do not
1646 * use this function directly unless you know what it is. Typical signing
1647 * requires the data to be hashed and stored in special formats
1648 * (e.g. BER Digest-Info for RSA).
1650 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1651 * negative error value.
1653 * Deprecated in: 2.12.0
1656 gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key
,
1657 const gnutls_datum_t
* hash
,
1658 gnutls_datum_t
* signature
)
1665 return GNUTLS_E_INVALID_REQUEST
;
1668 result
= _gnutls_pk_sign (key
->pk_algorithm
, signature
, hash
, &key
->params
);
1680 * gnutls_x509_privkey_sign_data:
1681 * @key: Holds the key
1682 * @digest: should be MD5 or SHA1
1683 * @flags: should be 0 for now
1684 * @data: holds the data to be signed
1685 * @signature: will contain the signature
1686 * @signature_size: holds the size of signature (and will be replaced
1689 * This function will sign the given data using a signature algorithm
1690 * supported by the private key. Signature algorithms are always used
1691 * together with a hash functions. Different hash functions may be
1692 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
1694 * If the buffer provided is not long enough to hold the output, then
1695 * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
1698 * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
1699 * the hash algorithm.
1701 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1702 * negative error value.
1704 * Deprecated: Use gnutls_privkey_sign_data().
1707 gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key
,
1708 gnutls_digest_algorithm_t digest
,
1710 const gnutls_datum_t
* data
,
1711 void *signature
, size_t * signature_size
)
1714 gnutls_datum_t sig
= { NULL
, 0 };
1715 gnutls_datum_t hash
;
1720 return GNUTLS_E_INVALID_REQUEST
;
1724 pk_hash_data (key
->pk_algorithm
, digest
, &key
->params
, data
, &hash
);
1732 _gnutls_x509_privkey_sign_hash2 (key
, digest
, flags
, &hash
, &sig
);
1734 _gnutls_free_datum(&hash
);
1742 if (*signature_size
< sig
.size
)
1744 *signature_size
= sig
.size
;
1745 _gnutls_free_datum (&sig
);
1746 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
1749 *signature_size
= sig
.size
;
1750 memcpy (signature
, sig
.data
, sig
.size
);
1752 _gnutls_free_datum (&sig
);
1759 * gnutls_x509_privkey_fix:
1760 * @key: Holds the key
1762 * This function will recalculate the secondary parameters in a key.
1763 * In RSA keys, this can be the coefficient and exponent1,2.
1765 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1766 * negative error value.
1769 gnutls_x509_privkey_fix (gnutls_x509_privkey_t key
)
1776 return GNUTLS_E_INVALID_REQUEST
;
1779 asn1_delete_structure (&key
->key
);
1781 ret
= _gnutls_asn1_encode_privkey (key
->pk_algorithm
, &key
->key
, &key
->params
);