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_value (pkey_asn
, "publicKey", &out
);
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
);
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
)
568 gnutls_x509_privkey_t newkey
;
570 ret
= gnutls_pkcs12_init(&p12
);
572 return gnutls_assert_val(ret
);
574 ret
= gnutls_pkcs12_import(p12
, data
, format
, flags
);
581 ret
= gnutls_pkcs12_simple_parse (p12
, password
, &newkey
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
588 ret
= gnutls_x509_privkey_cpy (key
, newkey
);
589 gnutls_x509_privkey_deinit (newkey
);
599 gnutls_pkcs12_deinit(p12
);
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
)
633 if (password
== NULL
&& !(flags
& GNUTLS_PKCS_NULL_PASSWORD
))
635 ret
= gnutls_x509_privkey_import(key
, data
, format
);
642 if ((password
!= NULL
|| (flags
& GNUTLS_PKCS_NULL_PASSWORD
)) || ret
< 0)
644 ret
= gnutls_x509_privkey_import_pkcs8(key
, data
, format
, password
, flags
);
647 ret
= import_pkcs12_privkey(key
, data
, format
, password
, flags
);
648 if (ret
< 0 && format
== GNUTLS_X509_FMT_PEM
)
651 err
= gnutls_x509_privkey_import_openssl(key
, data
, password
);
654 if (err
== GNUTLS_E_DECRYPTION_FAILED
) ret
= err
;
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
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
,
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
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
)
740 return GNUTLS_E_INVALID_REQUEST
;
743 gnutls_pk_params_init(&key
->params
);
746 if (_gnutls_mpi_scan_nz (&key
->params
.params
[0], m
->data
, siz
))
749 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
752 key
->params
.params_nr
++;
755 if (_gnutls_mpi_scan_nz (&key
->params
.params
[1], e
->data
, siz
))
758 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
761 key
->params
.params_nr
++;
764 if (_gnutls_mpi_scan_nz (&key
->params
.params
[2], d
->data
, siz
))
767 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
770 key
->params
.params_nr
++;
773 if (_gnutls_mpi_scan_nz (&key
->params
.params
[3], p
->data
, siz
))
776 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
779 key
->params
.params_nr
++;
782 if (_gnutls_mpi_scan_nz (&key
->params
.params
[4], q
->data
, siz
))
785 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
788 key
->params
.params_nr
++;
791 if (_gnutls_mpi_scan_nz (&key
->params
.params
[5], u
->data
, siz
))
794 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
797 key
->params
.params_nr
++;
802 if (_gnutls_mpi_scan_nz (&key
->params
.params
[6], e1
->data
, siz
))
805 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
808 key
->params
.params_nr
++;
811 if (_gnutls_mpi_scan_nz (&key
->params
.params
[7], e2
->data
, siz
))
814 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
817 key
->params
.params_nr
++;
820 ret
= _gnutls_pk_fixup (GNUTLS_PK_RSA
, GNUTLS_IMPORT
, &key
->params
);
827 ret
= _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA
, &key
->key
, &key
->params
);
834 key
->params
.params_nr
= RSA_PRIVATE_PARAMS
;
835 key
->pk_algorithm
= GNUTLS_PK_RSA
;
840 gnutls_pk_params_release(&key
->params
);
846 * gnutls_x509_privkey_import_dsa_raw:
847 * @key: The structure to store the parsed key
854 * This function will convert the given DSA raw parameters to the
855 * native #gnutls_x509_privkey_t format. The output will be stored
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
)
875 return GNUTLS_E_INVALID_REQUEST
;
879 if (_gnutls_mpi_scan_nz (&key
->params
.params
[0], p
->data
, siz
))
882 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
887 if (_gnutls_mpi_scan_nz (&key
->params
.params
[1], q
->data
, siz
))
890 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
895 if (_gnutls_mpi_scan_nz (&key
->params
.params
[2], g
->data
, siz
))
898 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
903 if (_gnutls_mpi_scan_nz (&key
->params
.params
[3], y
->data
, siz
))
906 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
911 if (_gnutls_mpi_scan_nz (&key
->params
.params
[4], x
->data
, siz
))
914 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
918 ret
= _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA
, &key
->key
, &key
->params
);
925 key
->params
.params_nr
= DSA_PRIVATE_PARAMS
;
926 key
->pk_algorithm
= GNUTLS_PK_DSA
;
931 gnutls_pk_params_release(&key
->params
);
937 * gnutls_x509_privkey_import_ecc_raw:
938 * @key: The structure to store the parsed key
939 * @curve: holds the curve
944 * This function will convert the given elliptic curve parameters to the
945 * native #gnutls_x509_privkey_t format. The output will be stored
948 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
949 * negative error value.
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
)
965 return GNUTLS_E_INVALID_REQUEST
;
968 key
->params
.flags
= curve
;
970 ret
= _gnutls_ecc_curve_fill_params(curve
, &key
->params
);
972 return gnutls_assert_val(ret
);
974 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_X
], x
->data
, x
->size
))
977 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
980 key
->params
.params_nr
++;
982 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_Y
], y
->data
, y
->size
))
985 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
988 key
->params
.params_nr
++;
990 if (_gnutls_mpi_scan_nz (&key
->params
.params
[ECC_K
], k
->data
, k
->size
))
993 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
996 key
->params
.params_nr
++;
998 key
->pk_algorithm
= GNUTLS_PK_EC
;
1003 gnutls_pk_params_release(&key
->params
);
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
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
)
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
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
)
1050 return GNUTLS_E_INVALID_REQUEST
;
1055 ret
= pubkey_to_bits(key
->pk_algorithm
, &key
->params
);
1056 if (ret
< 0) ret
= 0;
1060 return key
->pk_algorithm
;
1063 static const char* set_msg(gnutls_x509_privkey_t key
)
1065 if (key
->pk_algorithm
== GNUTLS_PK_RSA
)
1067 else if (key
->pk_algorithm
== GNUTLS_PK_DSA
)
1069 else if (key
->pk_algorithm
== GNUTLS_PK_EC
)
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
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
)
1107 return GNUTLS_E_INVALID_REQUEST
;
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.
1137 gnutls_x509_privkey_export2 (gnutls_x509_privkey_t key
,
1138 gnutls_x509_crt_fmt_t format
,
1139 gnutls_datum_t
* out
)
1146 return GNUTLS_E_INVALID_REQUEST
;
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
1161 * Returns: On success, a valid security parameter is returned otherwise
1162 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
1167 gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key
)
1171 bits
= pubkey_to_bits(key
->pk_algorithm
, &key
->params
);
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.
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
,
1205 return GNUTLS_E_INVALID_REQUEST
;
1208 *curve
= key
->params
.flags
;
1211 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_X
], x
);
1219 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_Y
], y
);
1223 _gnutls_free_datum (x
);
1229 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[ECC_K
], k
);
1233 _gnutls_free_datum (x
);
1234 _gnutls_free_datum (y
);
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
,
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.
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
)
1299 gnutls_pk_params_st pk_params
;
1301 gnutls_pk_params_init(&pk_params
);
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
);
1319 ret
= _gnutls_pk_fixup (GNUTLS_PK_RSA
, GNUTLS_EXPORT
, &pk_params
);
1326 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[0], m
);
1334 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[1], e
);
1342 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[2], d
);
1350 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[3], p
);
1358 ret
= _gnutls_mpi_dprint_lz (pk_params
.params
[4], q
);
1366 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[5], u
);
1376 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[6], e1
);
1387 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[7], e2
);
1395 gnutls_pk_params_release (&pk_params
);
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
);
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
,
1437 return GNUTLS_E_INVALID_REQUEST
;
1441 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[0], p
);
1449 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[1], q
);
1453 _gnutls_free_datum (p
);
1459 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[2], g
);
1463 _gnutls_free_datum (p
);
1464 _gnutls_free_datum (q
);
1470 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[3], y
);
1474 _gnutls_free_datum (p
);
1475 _gnutls_free_datum (g
);
1476 _gnutls_free_datum (q
);
1481 ret
= _gnutls_mpi_dprint_lz (key
->params
.params
[4], x
);
1485 _gnutls_free_datum (y
);
1486 _gnutls_free_datum (p
);
1487 _gnutls_free_datum (g
);
1488 _gnutls_free_datum (q
);
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
,
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
);
1535 ret
= _gnutls_asn1_encode_privkey (algo
, &key
->key
, &key
->params
);
1541 key
->pk_algorithm
= algo
;
1546 key
->pk_algorithm
= GNUTLS_PK_UNKNOWN
;
1547 gnutls_pk_params_release(&key
->params
);
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
)
1566 ret
= _gnutls_pk_verify_params (key
->pk_algorithm
, &key
->params
);
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
,
1599 unsigned char *output_data
,
1600 size_t * output_data_size
)
1607 return GNUTLS_E_INVALID_REQUEST
;
1610 ret
= _gnutls_get_key_id(key
->pk_algorithm
, &key
->params
, output_data
, output_data_size
);
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.
1643 _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer
,
1644 gnutls_digest_algorithm_t hash_algo
,
1646 const gnutls_datum_t
* hash_data
,
1647 gnutls_datum_t
* signature
)
1650 gnutls_datum_t digest
;
1652 digest
.data
= gnutls_malloc (hash_data
->size
);
1653 if (digest
.data
== NULL
)
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
);
1668 ret
= _gnutls_pk_sign (signer
->pk_algorithm
, signature
, &digest
, &signer
->params
);
1679 _gnutls_free_datum (&digest
);
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
)
1709 return GNUTLS_E_INVALID_REQUEST
;
1712 result
= _gnutls_pk_sign (key
->pk_algorithm
, signature
, hash
, &key
->params
);
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
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
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
,
1754 const gnutls_datum_t
* data
,
1755 void *signature
, size_t * signature_size
)
1758 gnutls_datum_t sig
= { NULL
, 0 };
1759 gnutls_datum_t hash
;
1764 return GNUTLS_E_INVALID_REQUEST
;
1768 pk_hash_data (key
->pk_algorithm
, digest
, &key
->params
, data
, &hash
);
1776 _gnutls_x509_privkey_sign_hash2 (key
, digest
, flags
, &hash
, &sig
);
1778 _gnutls_free_datum(&hash
);
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
);
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
)
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
);