2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 /* Functions on OpenPGP privkey parsing
29 #include <gnutls_int.h>
30 #include <gnutls_datum.h>
31 #include <gnutls_global.h>
32 #include <gnutls_errors.h>
33 #include <gnutls_num.h>
34 #include <openpgp_int.h>
35 #include <gnutls_openpgp.h>
36 #include <gnutls_cert.h>
37 #include <gnutls_sig.h>
40 * gnutls_openpgp_privkey_init:
41 * @key: The structure to be initialized
43 * This function will initialize an OpenPGP key structure.
45 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
48 gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key)
50 *key = gnutls_calloc (1, sizeof (gnutls_openpgp_privkey_int));
53 return 0; /* success */
54 return GNUTLS_E_MEMORY_ERROR;
58 * gnutls_openpgp_privkey_deinit:
59 * @key: The structure to be initialized
61 * This function will deinitialize a key structure.
64 gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key)
71 cdk_kbnode_release (key->knode);
79 * _gnutls_openpgp_privkey_cpy - This function copies a gnutls_openpgp_privkey_t structure
80 * @dest: The structure where to copy
81 * @src: The structure to be copied
83 * This function will copy an X.509 certificate structure.
85 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
86 * negative error value.
89 _gnutls_openpgp_privkey_cpy (gnutls_openpgp_privkey_t dest, gnutls_openpgp_privkey_t src)
96 ret = gnutls_openpgp_privkey_export (src, GNUTLS_OPENPGP_FMT_RAW, NULL, 0, NULL, &der_size);
97 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
98 return gnutls_assert_val(ret);
100 der = gnutls_malloc (der_size);
102 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
104 ret = gnutls_openpgp_privkey_export (src, GNUTLS_OPENPGP_FMT_RAW, NULL, 0, der, &der_size);
114 ret = gnutls_openpgp_privkey_import (dest, &tmp, GNUTLS_OPENPGP_FMT_RAW, NULL, 0);
119 return gnutls_assert_val(ret);
121 memcpy(dest->preferred_keyid, src->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE);
122 dest->preferred_set = src->preferred_set;
128 * gnutls_openpgp_privkey_sec_param:
129 * @key: a key structure
131 * This function will return the security parameter appropriate with
134 * Returns: On success, a valid security parameter is returned otherwise
135 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
138 gnutls_openpgp_privkey_sec_param (gnutls_openpgp_privkey_t key)
140 gnutls_pk_algorithm_t algo;
143 algo = gnutls_openpgp_privkey_get_pk_algorithm (key, &bits);
144 if (algo == GNUTLS_PK_UNKNOWN)
147 return GNUTLS_SEC_PARAM_UNKNOWN;
150 return gnutls_pk_bits_to_sec_param (algo, bits);
154 * gnutls_openpgp_privkey_import:
155 * @key: The structure to store the parsed key.
156 * @data: The RAW or BASE64 encoded key.
157 * @format: One of #gnutls_openpgp_crt_fmt_t elements.
158 * @password: not used for now
159 * @flags: should be zero
161 * This function will convert the given RAW or Base64 encoded key to
162 * the native gnutls_openpgp_privkey_t format. The output will be
165 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
168 gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
169 const gnutls_datum_t * data,
170 gnutls_openpgp_crt_fmt_t format,
171 const char *password, unsigned int flags)
177 if (data->data == NULL || data->size == 0)
180 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
183 if (format == GNUTLS_OPENPGP_FMT_RAW)
185 rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
188 rc = _gnutls_map_cdk_rc (rc);
195 rc = cdk_stream_tmp_from_mem (data->data, data->size, &inp);
198 rc = _gnutls_map_cdk_rc (rc);
203 if (cdk_armor_filter_use (inp))
205 rc = cdk_stream_set_armor_flag (inp, 0);
208 rc = _gnutls_map_cdk_rc (rc);
209 cdk_stream_close (inp);
215 rc = cdk_keydb_get_keyblock (inp, &key->knode);
216 cdk_stream_close (inp);
220 rc = _gnutls_map_cdk_rc (rc);
226 /* Test if the import was successful. */
227 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
231 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
238 * gnutls_openpgp_privkey_export:
239 * @key: Holds the key.
240 * @format: One of gnutls_openpgp_crt_fmt_t elements.
241 * @password: the password that will be used to encrypt the key. (unused for now)
242 * @flags: zero for future compatibility
243 * @output_data: will contain the key base64 encoded or raw
244 * @output_data_size: holds the size of output_data (and will be
245 * replaced by the actual size of parameters)
247 * This function will convert the given key to RAW or Base64 format.
248 * If the buffer provided is not long enough to hold the output, then
249 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
251 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
256 gnutls_openpgp_privkey_export (gnutls_openpgp_privkey_t key,
257 gnutls_openpgp_crt_fmt_t format,
258 const char *password, unsigned int flags,
259 void *output_data, size_t * output_data_size)
261 /* FIXME for now we do not export encrypted keys */
262 return _gnutls_openpgp_export (key->knode, format, output_data,
263 output_data_size, 1);
268 * gnutls_openpgp_privkey_get_pk_algorithm:
269 * @key: is an OpenPGP key
270 * @bits: if bits is non null it will hold the size of the parameters' in bits
272 * This function will return the public key algorithm of an OpenPGP
275 * If bits is non null, it should have enough size to hold the parameters
276 * size in bits. For RSA the bits returned is the modulus.
277 * For DSA the bits returned are of the public exponent.
279 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
280 * success, or a negative value on error.
284 gnutls_pk_algorithm_t
285 gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
294 return GNUTLS_PK_UNKNOWN;
298 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
302 *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
303 algo = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
310 _gnutls_openpgp_get_algo (int cdk_algo)
314 if (is_RSA (cdk_algo))
315 algo = GNUTLS_PK_RSA;
316 else if (is_DSA (cdk_algo))
317 algo = GNUTLS_PK_DSA;
320 _gnutls_x509_log ("Unknown OpenPGP algorithm %d\n", cdk_algo);
321 algo = GNUTLS_PK_UNKNOWN;
328 * gnutls_openpgp_privkey_get_revoked_status:
329 * @key: the structure that contains the OpenPGP private key.
331 * Get revocation status of key.
333 * Returns: true (1) if the key has been revoked, or false (0) if it
334 * has not, or a negative value indicates an error.
339 gnutls_openpgp_privkey_get_revoked_status (gnutls_openpgp_privkey_t key)
346 return GNUTLS_E_INVALID_REQUEST;
349 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
351 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
353 if (pkt->pkt.secret_key->is_revoked != 0)
359 * gnutls_openpgp_privkey_get_fingerprint:
360 * @key: the raw data that contains the OpenPGP secret key.
361 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
362 * @fprlen: the integer to save the length of the fingerprint.
364 * Get the fingerprint of the OpenPGP key. Depends on the
365 * algorithm, the fingerprint can be 16 or 20 bytes.
367 * Returns: On success, 0 is returned, or an error code.
372 gnutls_openpgp_privkey_get_fingerprint (gnutls_openpgp_privkey_t key,
373 void *fpr, size_t * fprlen)
376 cdk_pkt_pubkey_t pk = NULL;
381 return GNUTLS_E_INVALID_REQUEST;
386 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
390 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
393 pk = pkt->pkt.secret_key->pk;
396 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
399 cdk_pk_get_fingerprint (pk, fpr);
405 * gnutls_openpgp_privkey_get_key_id:
406 * @key: the structure that contains the OpenPGP secret key.
407 * @keyid: the buffer to save the keyid.
411 * Returns: the 64-bit keyID of the OpenPGP key.
416 gnutls_openpgp_privkey_get_key_id (gnutls_openpgp_privkey_t key,
417 gnutls_openpgp_keyid_t keyid)
425 return GNUTLS_E_INVALID_REQUEST;
428 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
430 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
432 cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
433 _gnutls_write_uint32 (kid[0], keyid);
434 _gnutls_write_uint32 (kid[1], keyid + 4);
441 * gnutls_openpgp_privkey_get_subkey_count:
442 * @key: is an OpenPGP key
444 * This function will return the number of subkeys present in the
445 * given OpenPGP certificate.
447 * Returns: the number of subkeys, or a negative value on error.
452 gnutls_openpgp_privkey_get_subkey_count (gnutls_openpgp_privkey_t key)
466 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
468 pkt = cdk_kbnode_get_packet (p);
469 if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
476 /* returns the subkey with the given index */
478 _get_secret_subkey (gnutls_openpgp_privkey_t key, unsigned int indx)
482 unsigned int subkeys;
486 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
488 pkt = cdk_kbnode_get_packet (p);
489 if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY && indx == subkeys++)
497 * gnutls_openpgp_privkey_get_subkey_revoked_status:
498 * @key: the structure that contains the OpenPGP private key.
499 * @idx: is the subkey index
501 * Get revocation status of key.
503 * Returns: true (1) if the key has been revoked, or false (0) if it
504 * has not, or a negative value indicates an error.
509 gnutls_openpgp_privkey_get_subkey_revoked_status (gnutls_openpgp_privkey_t
510 key, unsigned int idx)
517 return GNUTLS_E_INVALID_REQUEST;
520 pkt = _get_secret_subkey (key, idx);
522 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
524 if (pkt->pkt.secret_key->is_revoked != 0)
530 * gnutls_openpgp_privkey_get_subkey_pk_algorithm:
531 * @key: is an OpenPGP key
532 * @idx: is the subkey index
533 * @bits: if bits is non null it will hold the size of the parameters' in bits
535 * This function will return the public key algorithm of a subkey of an OpenPGP
538 * If bits is non null, it should have enough size to hold the parameters
539 * size in bits. For RSA the bits returned is the modulus.
540 * For DSA the bits returned are of the public exponent.
542 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
543 * success, or a negative value on error.
547 gnutls_pk_algorithm_t
548 gnutls_openpgp_privkey_get_subkey_pk_algorithm (gnutls_openpgp_privkey_t key,
558 return GNUTLS_PK_UNKNOWN;
561 pkt = _get_secret_subkey (key, idx);
567 *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
568 algo = pkt->pkt.secret_key->pubkey_algo;
570 algo = GNUTLS_PK_RSA;
571 else if (is_DSA (algo))
572 algo = GNUTLS_PK_DSA;
574 algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
581 * gnutls_openpgp_privkey_get_subkey_idx:
582 * @key: the structure that contains the OpenPGP private key.
585 * Get index of subkey.
587 * Returns: the index of the subkey or a negative error value.
592 gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key,
593 const gnutls_openpgp_keyid_t keyid)
601 return GNUTLS_E_INVALID_REQUEST;
604 KEYID_IMPORT (kid, keyid);
605 ret = _gnutls_openpgp_find_subkey_idx (key->knode, kid, 1);
616 * gnutls_openpgp_privkey_get_subkey_creation_time:
617 * @key: the structure that contains the OpenPGP private key.
618 * @idx: the subkey index
620 * Get subkey creation time.
622 * Returns: the timestamp when the OpenPGP key was created.
627 gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key,
636 pkt = _get_secret_subkey (key, idx);
638 timestamp = pkt->pkt.secret_key->pk->timestamp;
646 * gnutls_openpgp_privkey_get_subkey_expiration_time:
647 * @key: the structure that contains the OpenPGP private key.
648 * @idx: the subkey index
650 * Get subkey expiration time. A value of '0' means that the key
651 * doesn't expire at all.
653 * Returns: the time when the OpenPGP key expires.
658 gnutls_openpgp_privkey_get_subkey_expiration_time (gnutls_openpgp_privkey_t
659 key, unsigned int idx)
667 pkt = _get_secret_subkey (key, idx);
669 expiredate = pkt->pkt.secret_key->expiredate;
677 * gnutls_openpgp_privkey_get_subkey_id:
678 * @key: the structure that contains the OpenPGP secret key.
679 * @idx: the subkey index
680 * @keyid: the buffer to save the keyid.
682 * Get the key-id for the subkey.
684 * Returns: the 64-bit keyID of the OpenPGP key.
689 gnutls_openpgp_privkey_get_subkey_id (gnutls_openpgp_privkey_t key,
691 gnutls_openpgp_keyid_t keyid)
699 return GNUTLS_E_INVALID_REQUEST;
702 pkt = _get_secret_subkey (key, idx);
704 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
706 cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
707 _gnutls_write_uint32 (kid[0], keyid);
708 _gnutls_write_uint32 (kid[1], keyid + 4);
714 * gnutls_openpgp_privkey_get_subkey_fingerprint:
715 * @key: the raw data that contains the OpenPGP secret key.
716 * @idx: the subkey index
717 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
718 * @fprlen: the integer to save the length of the fingerprint.
720 * Get the fingerprint of an OpenPGP subkey. Depends on the
721 * algorithm, the fingerprint can be 16 or 20 bytes.
723 * Returns: On success, 0 is returned, or an error code.
728 gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t key,
730 void *fpr, size_t * fprlen)
733 cdk_pkt_pubkey_t pk = NULL;
738 return GNUTLS_E_INVALID_REQUEST;
743 pkt = _get_secret_subkey (key, idx);
745 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
748 pk = pkt->pkt.secret_key->pk;
751 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
754 cdk_pk_get_fingerprint (pk, fpr);
759 /* Extracts DSA and RSA parameters from a certificate.
762 _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
763 uint32_t * keyid /*[2] */ ,
764 bigint_t * params, int *params_size)
768 gnutls_pk_params_st pk_params;
771 memset (&pk_params, 0, sizeof (pk_params));
774 pkt = cdk_kbnode_find_packet (pkey->knode, CDK_PKT_SECRET_KEY);
776 pkt = _gnutls_openpgp_find_key (pkey->knode, keyid, 1);
781 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
785 _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
787 switch (pk_algorithm)
790 /* openpgp does not hold all parameters as in PKCS #1
792 pk_params.params_nr = RSA_PRIVATE_PARAMS - 2;
795 pk_params.params_nr = DSA_PRIVATE_PARAMS;
799 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
802 for (i = 0; i < pk_params.params_nr; i++)
804 result = _gnutls_read_pgp_mpi (pkt, 1, i, &pk_params.params[i]);
812 /* fixup will generate exp1 and exp2 that are not
815 result = _gnutls_pk_fixup (pk_algorithm, GNUTLS_IMPORT, &pk_params);
822 if (*params_size < pk_params.params_nr)
825 return GNUTLS_E_INTERNAL_ERROR;
828 *params_size = pk_params.params_nr;
829 for (i = 0; i < pk_params.params_nr; i++)
830 params[i] = pk_params.params[i];
837 for (j = 0; j < i; j++)
838 _gnutls_mpi_release (&pk_params.params[j]);
844 /* The internal version of export
847 _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
848 gnutls_datum_t * m, gnutls_datum_t * e,
849 gnutls_datum_t * d, gnutls_datum_t * p,
850 gnutls_datum_t * q, gnutls_datum_t * u)
852 int pk_algorithm, ret, i;
855 bigint_t params[MAX_PRIV_PARAMS_SIZE];
856 int params_size = MAX_PRIV_PARAMS_SIZE;
861 return GNUTLS_E_INVALID_REQUEST;
864 KEYID_IMPORT (kid32, keyid);
866 pkt = _gnutls_openpgp_find_key (pkey->knode, kid32, 1);
870 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
874 _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
876 if (pk_algorithm != GNUTLS_PK_RSA)
879 return GNUTLS_E_INVALID_REQUEST;
882 ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, ¶ms_size);
889 ret = _gnutls_mpi_dprint (params[0], m);
896 ret = _gnutls_mpi_dprint (params[1], e);
900 _gnutls_free_datum (m);
904 ret = _gnutls_mpi_dprint (params[2], d);
908 _gnutls_free_datum (m);
909 _gnutls_free_datum (e);
913 ret = _gnutls_mpi_dprint (params[3], p);
917 _gnutls_free_datum (m);
918 _gnutls_free_datum (e);
919 _gnutls_free_datum (d);
923 ret = _gnutls_mpi_dprint (params[4], q);
927 _gnutls_free_datum (m);
928 _gnutls_free_datum (e);
929 _gnutls_free_datum (d);
930 _gnutls_free_datum (p);
934 ret = _gnutls_mpi_dprint (params[5], u);
938 _gnutls_free_datum (q);
939 _gnutls_free_datum (m);
940 _gnutls_free_datum (e);
941 _gnutls_free_datum (d);
942 _gnutls_free_datum (p);
949 for (i = 0; i < params_size; i++)
951 _gnutls_mpi_release (¶ms[i]);
957 _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
958 gnutls_datum_t * p, gnutls_datum_t * q,
959 gnutls_datum_t * g, gnutls_datum_t * y, gnutls_datum_t * x)
961 int pk_algorithm, ret, i;
964 bigint_t params[MAX_PRIV_PARAMS_SIZE];
965 int params_size = MAX_PRIV_PARAMS_SIZE;
970 return GNUTLS_E_INVALID_REQUEST;
973 KEYID_IMPORT (kid32, keyid);
975 pkt = _gnutls_openpgp_find_key (pkey->knode, kid32, 1);
979 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
983 _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
985 if (pk_algorithm != GNUTLS_PK_DSA)
988 return GNUTLS_E_INVALID_REQUEST;
991 ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, ¶ms_size);
999 ret = _gnutls_mpi_dprint (params[0], p);
1007 ret = _gnutls_mpi_dprint (params[1], q);
1011 _gnutls_free_datum (p);
1017 ret = _gnutls_mpi_dprint (params[2], g);
1021 _gnutls_free_datum (p);
1022 _gnutls_free_datum (q);
1028 ret = _gnutls_mpi_dprint (params[3], y);
1032 _gnutls_free_datum (p);
1033 _gnutls_free_datum (g);
1034 _gnutls_free_datum (q);
1038 ret = _gnutls_mpi_dprint (params[4], x);
1042 _gnutls_free_datum (y);
1043 _gnutls_free_datum (p);
1044 _gnutls_free_datum (g);
1045 _gnutls_free_datum (q);
1052 for (i = 0; i < params_size; i++)
1054 _gnutls_mpi_release (¶ms[i]);
1061 * gnutls_openpgp_privkey_export_rsa_raw:
1062 * @pkey: Holds the certificate
1063 * @m: will hold the modulus
1064 * @e: will hold the public exponent
1065 * @d: will hold the private exponent
1066 * @p: will hold the first prime (p)
1067 * @q: will hold the second prime (q)
1068 * @u: will hold the coefficient
1070 * This function will export the RSA private key's parameters found in
1071 * the given structure. The new parameters will be allocated using
1072 * gnutls_malloc() and will be stored in the appropriate datum.
1074 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1079 gnutls_openpgp_privkey_export_rsa_raw (gnutls_openpgp_privkey_t pkey,
1080 gnutls_datum_t * m, gnutls_datum_t * e,
1081 gnutls_datum_t * d, gnutls_datum_t * p,
1082 gnutls_datum_t * q, gnutls_datum_t * u)
1084 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1087 ret = gnutls_openpgp_privkey_get_key_id (pkey, keyid);
1094 return _get_sk_rsa_raw (pkey, keyid, m, e, d, p, q, u);
1098 * gnutls_openpgp_privkey_export_dsa_raw:
1099 * @pkey: Holds the certificate
1100 * @p: will hold the p
1101 * @q: will hold the q
1102 * @g: will hold the g
1103 * @y: will hold the y
1104 * @x: will hold the x
1106 * This function will export the DSA private key's parameters found in
1107 * the given certificate. The new parameters will be allocated using
1108 * gnutls_malloc() and will be stored in the appropriate datum.
1110 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1115 gnutls_openpgp_privkey_export_dsa_raw (gnutls_openpgp_privkey_t pkey,
1116 gnutls_datum_t * p, gnutls_datum_t * q,
1117 gnutls_datum_t * g, gnutls_datum_t * y,
1120 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1123 ret = gnutls_openpgp_privkey_get_key_id (pkey, keyid);
1130 return _get_sk_dsa_raw (pkey, keyid, p, q, g, y, x);
1134 * gnutls_openpgp_privkey_export_subkey_rsa_raw:
1135 * @pkey: Holds the certificate
1136 * @idx: Is the subkey index
1137 * @m: will hold the modulus
1138 * @e: will hold the public exponent
1139 * @d: will hold the private exponent
1140 * @p: will hold the first prime (p)
1141 * @q: will hold the second prime (q)
1142 * @u: will hold the coefficient
1144 * This function will export the RSA private key's parameters found in
1145 * the given structure. The new parameters will be allocated using
1146 * gnutls_malloc() and will be stored in the appropriate datum.
1148 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1153 gnutls_openpgp_privkey_export_subkey_rsa_raw (gnutls_openpgp_privkey_t pkey,
1162 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1165 ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
1172 return _get_sk_rsa_raw (pkey, keyid, m, e, d, p, q, u);
1176 * gnutls_openpgp_privkey_export_subkey_dsa_raw:
1177 * @pkey: Holds the certificate
1178 * @idx: Is the subkey index
1179 * @p: will hold the p
1180 * @q: will hold the q
1181 * @g: will hold the g
1182 * @y: will hold the y
1183 * @x: will hold the x
1185 * This function will export the DSA private key's parameters found
1186 * in the given certificate. The new parameters will be allocated
1187 * using gnutls_malloc() and will be stored in the appropriate datum.
1189 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1194 gnutls_openpgp_privkey_export_subkey_dsa_raw (gnutls_openpgp_privkey_t pkey,
1202 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1205 ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
1212 return _get_sk_dsa_raw (pkey, keyid, p, q, g, y, x);
1216 * gnutls_openpgp_privkey_get_preferred_key_id:
1217 * @key: the structure that contains the OpenPGP public key.
1218 * @keyid: the struct to save the keyid.
1220 * Get the preferred key-id for the key.
1222 * Returns: the 64-bit preferred keyID of the OpenPGP key, or if it
1223 * hasn't been set it returns %GNUTLS_E_INVALID_REQUEST.
1226 gnutls_openpgp_privkey_get_preferred_key_id (gnutls_openpgp_privkey_t key,
1227 gnutls_openpgp_keyid_t keyid)
1229 if (!key->preferred_set)
1230 return gnutls_assert_val(GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR);
1235 return GNUTLS_E_INVALID_REQUEST;
1238 memcpy (keyid, key->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE);
1244 * gnutls_openpgp_privkey_set_preferred_key_id:
1245 * @key: the structure that contains the OpenPGP public key.
1246 * @keyid: the selected keyid
1248 * This allows setting a preferred key id for the given certificate.
1249 * This key will be used by functions that involve key handling.
1251 * Returns: On success, 0 is returned, or an error code.
1254 gnutls_openpgp_privkey_set_preferred_key_id (gnutls_openpgp_privkey_t key,
1255 const gnutls_openpgp_keyid_t
1263 return GNUTLS_E_INVALID_REQUEST;
1266 /* check if the id is valid */
1267 ret = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
1270 _gnutls_x509_log ("the requested subkey does not exist\n");
1275 key->preferred_set = 1;
1276 memcpy (key->preferred_keyid, keyid, GNUTLS_OPENPGP_KEYID_SIZE);
1282 * gnutls_openpgp_privkey_sign_hash:
1283 * @key: Holds the key
1284 * @hash: holds the data to be signed
1285 * @signature: will contain newly allocated signature
1287 * This function will sign the given hash using the private key. You
1288 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
1289 * calling this function to set the subkey to use.
1291 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1292 * negative error value.
1294 * Deprecated: Use gnutls_privkey_sign_hash() instead.
1297 gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
1298 const gnutls_datum_t * hash,
1299 gnutls_datum_t * signature)
1302 bigint_t params[MAX_PRIV_PARAMS_SIZE];
1303 int params_size = MAX_PRIV_PARAMS_SIZE;
1305 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1310 return GNUTLS_E_INVALID_REQUEST;
1313 result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
1319 KEYID_IMPORT (kid, keyid);
1321 idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
1323 gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
1325 _gnutls_openpgp_privkey_get_mpis (key, kid, params, ¶ms_size);
1329 pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1330 result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
1331 params, ¶ms_size);
1342 _gnutls_soft_sign (pk_algorithm, params, params_size, hash, signature);
1344 for (i = 0; i < params_size; i++)
1345 _gnutls_mpi_release (¶ms[i]);
1357 * _gnutls_openpgp_privkey_decrypt_data:
1358 * @key: Holds the key
1359 * @flags: zero for now
1360 * @ciphertext: holds the data to be decrypted
1361 * @plaintext: will contain newly allocated plaintext
1363 * This function will sign the given hash using the private key. You
1364 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
1365 * calling this function to set the subkey to use.
1367 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1368 * negative error value.
1371 _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
1373 const gnutls_datum_t * ciphertext,
1374 gnutls_datum_t * plaintext)
1377 bigint_t params[MAX_PRIV_PARAMS_SIZE];
1378 int params_size = MAX_PRIV_PARAMS_SIZE;
1380 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1385 return GNUTLS_E_INVALID_REQUEST;
1388 result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
1393 KEYID_IMPORT (kid, keyid);
1394 result = _gnutls_openpgp_privkey_get_mpis (key, kid,
1395 params, ¶ms_size);
1397 i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
1399 pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
1403 pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
1405 result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
1406 params, ¶ms_size);
1416 if (pk_algorithm != GNUTLS_PK_RSA)
1419 return GNUTLS_E_INVALID_REQUEST;
1423 _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, params, params_size, 2);
1425 for (i = 0; i < params_size; i++)
1426 _gnutls_mpi_release (¶ms[i]);