Update copyright years.
[gnutls.git] / lib / openpgp / privkey.c
blob6b8cdcaf8f62e13a7d9e6942ac05acb61f7fd6f9
1 /*
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 library 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
22 * 02110-1301, USA
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>
38 /**
39 * gnutls_openpgp_privkey_init - initializes a #gnutls_openpgp_privkey_t structure
40 * @key: The structure to be initialized
42 * This function will initialize an OpenPGP key structure.
44 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
45 **/
46 int
47 gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key)
49 *key = gnutls_calloc (1, sizeof (gnutls_openpgp_privkey_int));
51 if (*key)
52 return 0; /* success */
53 return GNUTLS_E_MEMORY_ERROR;
56 /**
57 * gnutls_openpgp_privkey_deinit - deinitializes memory used by a #gnutls_openpgp_privkey_t structure
58 * @key: The structure to be initialized
60 * This function will deinitialize a key structure.
61 **/
62 void
63 gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key)
65 if (!key)
66 return;
68 if (key->knode)
70 cdk_kbnode_release (key->knode);
71 key->knode = NULL;
74 gnutls_free (key);
77 /**
78 * gnutls_openpgp_privkey_import - import a RAW or BASE64 encoded key
79 * @key: The structure to store the parsed key.
80 * @data: The RAW or BASE64 encoded key.
81 * @format: One of #gnutls_openpgp_crt_fmt_t elements.
82 * @password: not used for now
83 * @flags: should be zero
85 * This function will convert the given RAW or Base64 encoded key to
86 * the native gnutls_openpgp_privkey_t format. The output will be
87 * stored in 'key'.
89 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
90 **/
91 int
92 gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
93 const gnutls_datum_t * data,
94 gnutls_openpgp_crt_fmt_t format,
95 const char *password, unsigned int flags)
97 cdk_stream_t inp;
98 cdk_packet_t pkt;
99 int rc;
101 if (data->data == NULL || data->size == 0)
103 gnutls_assert ();
104 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
107 if (format == GNUTLS_OPENPGP_FMT_RAW)
109 rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
110 if (rc != 0)
112 rc = _gnutls_map_cdk_rc (rc);
113 gnutls_assert ();
114 return rc;
117 else
119 rc = cdk_stream_tmp_from_mem (data->data, data->size, &inp);
120 if (rc != 0)
122 rc = _gnutls_map_cdk_rc (rc);
123 gnutls_assert ();
124 return rc;
127 if (cdk_armor_filter_use (inp))
129 rc = cdk_stream_set_armor_flag (inp, 0);
130 if (rc != 0)
132 rc = _gnutls_map_cdk_rc (rc);
133 cdk_stream_close (inp);
134 gnutls_assert ();
135 return rc;
139 rc = cdk_keydb_get_keyblock (inp, &key->knode);
140 cdk_stream_close (inp);
142 if (rc != 0)
144 rc = _gnutls_map_cdk_rc (rc);
145 gnutls_assert ();
146 return rc;
150 /* Test if the import was successful. */
151 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
152 if (pkt == NULL)
154 gnutls_assert ();
155 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
158 return 0;
162 * gnutls_openpgp_privkey_export - export a RAW or BASE64 encoded key
163 * @key: Holds the key.
164 * @format: One of gnutls_openpgp_crt_fmt_t elements.
165 * @password: the password that will be used to encrypt the key. (unused for now)
166 * @flags: zero for future compatibility
167 * @output_data: will contain the key base64 encoded or raw
168 * @output_data_size: holds the size of output_data (and will be
169 * replaced by the actual size of parameters)
171 * This function will convert the given key to RAW or Base64 format.
172 * If the buffer provided is not long enough to hold the output, then
173 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
175 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
177 * Since: 2.4.0
180 gnutls_openpgp_privkey_export (gnutls_openpgp_privkey_t key,
181 gnutls_openpgp_crt_fmt_t format,
182 const char *password, unsigned int flags,
183 void *output_data, size_t * output_data_size)
185 /* FIXME for now we do not export encrypted keys */
186 return _gnutls_openpgp_export (key->knode, format, output_data,
187 output_data_size, 1);
192 * gnutls_openpgp_privkey_get_pk_algorithm - return the key's PublicKey algorithm
193 * @key: is an OpenPGP key
194 * @bits: if bits is non null it will hold the size of the parameters' in bits
196 * This function will return the public key algorithm of an OpenPGP
197 * certificate.
199 * If bits is non null, it should have enough size to hold the parameters
200 * size in bits. For RSA the bits returned is the modulus.
201 * For DSA the bits returned are of the public exponent.
203 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
204 * success, or a negative value on error.
206 * Since: 2.4.0
208 gnutls_pk_algorithm_t
209 gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
210 unsigned int *bits)
212 cdk_packet_t pkt;
213 int algo;
215 if (!key)
217 gnutls_assert ();
218 return GNUTLS_PK_UNKNOWN;
221 algo = 0;
222 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
223 if (pkt)
225 if (bits)
226 *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
227 algo = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
230 return algo;
234 _gnutls_openpgp_get_algo (int cdk_algo)
236 int algo;
238 if (is_RSA (cdk_algo))
239 algo = GNUTLS_PK_RSA;
240 else if (is_DSA (cdk_algo))
241 algo = GNUTLS_PK_DSA;
242 else
244 _gnutls_x509_log ("Unknown OpenPGP algorithm %d\n", cdk_algo);
245 algo = GNUTLS_PK_UNKNOWN;
248 return algo;
252 * gnutls_openpgp_privkey_get_revoked_ status - Get the revoked status of the key
253 * @key: the structure that contains the OpenPGP private key.
255 * Get revocation status of key.
257 * Returns: true (1) if the key has been revoked, or false (0) if it
258 * has not, or a negative value indicates an error.
260 * Since: 2.4.0
263 gnutls_openpgp_privkey_get_revoked_status (gnutls_openpgp_privkey_t key)
265 cdk_packet_t pkt;
267 if (!key)
269 gnutls_assert ();
270 return GNUTLS_E_INVALID_REQUEST;
273 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
274 if (!pkt)
275 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
277 if (pkt->pkt.secret_key->is_revoked != 0)
278 return 1;
279 return 0;
283 * gnutls_openpgp_privkey_get_fingerprint - Gets the fingerprint
284 * @key: the raw data that contains the OpenPGP secret key.
285 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
286 * @fprlen: the integer to save the length of the fingerprint.
288 * Get the fingerprint of the OpenPGP key. Depends on the
289 * algorithm, the fingerprint can be 16 or 20 bytes.
291 * Returns: On success, 0 is returned, or an error code.
293 * Since: 2.4.0
296 gnutls_openpgp_privkey_get_fingerprint (gnutls_openpgp_privkey_t key,
297 void *fpr, size_t * fprlen)
299 cdk_packet_t pkt;
300 cdk_pkt_pubkey_t pk = NULL;
302 if (!fpr || !fprlen)
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_REQUEST;
308 *fprlen = 0;
310 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
311 if (!pkt)
313 gnutls_assert ();
314 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
317 pk = pkt->pkt.secret_key->pk;
318 *fprlen = 20;
320 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
321 *fprlen = 16;
323 cdk_pk_get_fingerprint (pk, fpr);
325 return 0;
329 * gnutls_openpgp_privkey_get_key_id - Gets the keyID
330 * @key: the structure that contains the OpenPGP secret key.
331 * @keyid: the buffer to save the keyid.
333 * Get key-id.
335 * Returns: the 64-bit keyID of the OpenPGP key.
337 * Since: 2.4.0
340 gnutls_openpgp_privkey_get_key_id (gnutls_openpgp_privkey_t key,
341 gnutls_openpgp_keyid_t keyid)
343 cdk_packet_t pkt;
344 uint32_t kid[2];
346 if (!key || !keyid)
348 gnutls_assert ();
349 return GNUTLS_E_INVALID_REQUEST;
352 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
353 if (!pkt)
354 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
356 cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
357 _gnutls_write_uint32 (kid[0], keyid);
358 _gnutls_write_uint32 (kid[1], keyid + 4);
360 return 0;
365 * gnutls_openpgp_privkey_get_subkey_count - return the number of subkeys
366 * @key: is an OpenPGP key
368 * This function will return the number of subkeys present in the
369 * given OpenPGP certificate.
371 * Returns: the number of subkeys, or a negative value on error.
373 * Since: 2.4.0
376 gnutls_openpgp_privkey_get_subkey_count (gnutls_openpgp_privkey_t key)
378 cdk_kbnode_t p, ctx;
379 cdk_packet_t pkt;
380 int subkeys;
382 if (key == NULL)
384 gnutls_assert ();
385 return 0;
388 ctx = NULL;
389 subkeys = 0;
390 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
392 pkt = cdk_kbnode_get_packet (p);
393 if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
394 subkeys++;
397 return subkeys;
400 /* returns the subkey with the given index */
401 static cdk_packet_t
402 _get_secret_subkey (gnutls_openpgp_privkey_t key, unsigned int indx)
404 cdk_kbnode_t p, ctx;
405 cdk_packet_t pkt;
406 unsigned int subkeys;
408 ctx = NULL;
409 subkeys = 0;
410 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
412 pkt = cdk_kbnode_get_packet (p);
413 if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY && indx == subkeys++)
414 return pkt;
417 return NULL;
421 * gnutls_openpgp_privkey_get_subkey_revoked_ status - Get the revoked status of the key
422 * @key: the structure that contains the OpenPGP private key.
423 * @idx: is the subkey index
425 * Get revocation status of key.
427 * Returns: true (1) if the key has been revoked, or false (0) if it
428 * has not, or a negative value indicates an error.
430 * Since: 2.4.0
433 gnutls_openpgp_privkey_get_subkey_revoked_status (gnutls_openpgp_privkey_t
434 key, unsigned int idx)
436 cdk_packet_t pkt;
438 if (!key)
440 gnutls_assert ();
441 return GNUTLS_E_INVALID_REQUEST;
444 pkt = _get_secret_subkey (key, idx);
445 if (!pkt)
446 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
448 if (pkt->pkt.secret_key->is_revoked != 0)
449 return 1;
450 return 0;
454 * gnutls_openpgp_privkey_get_subkey_pk_algorithm - return the subkey's PublicKey algorithm
455 * @key: is an OpenPGP key
456 * @idx: is the subkey index
457 * @bits: if bits is non null it will hold the size of the parameters' in bits
459 * This function will return the public key algorithm of a subkey of an OpenPGP
460 * certificate.
462 * If bits is non null, it should have enough size to hold the parameters
463 * size in bits. For RSA the bits returned is the modulus.
464 * For DSA the bits returned are of the public exponent.
466 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
467 * success, or a negative value on error.
469 * Since: 2.4.0
471 gnutls_pk_algorithm_t
472 gnutls_openpgp_privkey_get_subkey_pk_algorithm (gnutls_openpgp_privkey_t key,
473 unsigned int idx,
474 unsigned int *bits)
476 cdk_packet_t pkt;
477 int algo;
479 if (!key)
481 gnutls_assert ();
482 return GNUTLS_PK_UNKNOWN;
485 pkt = _get_secret_subkey (key, idx);
487 algo = 0;
488 if (pkt)
490 if (bits)
491 *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
492 algo = pkt->pkt.secret_key->pubkey_algo;
493 if (is_RSA (algo))
494 algo = GNUTLS_PK_RSA;
495 else if (is_DSA (algo))
496 algo = GNUTLS_PK_DSA;
497 else
498 algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
501 return algo;
505 * gnutls_openpgp_privkey_get_subkey_idx - Returns the subkey's index
506 * @key: the structure that contains the OpenPGP private key.
507 * @keyid: the keyid.
509 * Get index of subkey.
511 * Returns: the index of the subkey or a negative error value.
513 * Since: 2.4.0
516 gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key,
517 const gnutls_openpgp_keyid_t keyid)
519 int ret;
520 uint32_t kid[2];
522 if (!key)
524 gnutls_assert ();
525 return GNUTLS_E_INVALID_REQUEST;
528 KEYID_IMPORT (kid, keyid);
529 ret = _gnutls_openpgp_find_subkey_idx (key->knode, kid, 1);
531 if (ret < 0)
533 gnutls_assert ();
536 return ret;
540 * gnutls_openpgp_privkey_get_subkey_creation_time - Extract the timestamp
541 * @key: the structure that contains the OpenPGP private key.
542 * @idx: the subkey index
544 * Get subkey creation time.
546 * Returns: the timestamp when the OpenPGP key was created.
548 * Since: 2.4.0
550 time_t
551 gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key,
552 unsigned int idx)
554 cdk_packet_t pkt;
555 time_t timestamp;
557 if (!key)
558 return (time_t) - 1;
560 pkt = _get_secret_subkey (key, idx);
561 if (pkt)
562 timestamp = pkt->pkt.secret_key->pk->timestamp;
563 else
564 timestamp = 0;
566 return timestamp;
570 * gnutls_openpgp_privkey_get_subkey_expiration_time - Extract the expire date
571 * @key: the structure that contains the OpenPGP private key.
572 * @idx: the subkey index
574 * Get subkey expiration time. A value of '0' means that the key
575 * doesn't expire at all.
577 * Returns: the time when the OpenPGP key expires.
579 * Since: 2.4.0
581 time_t
582 gnutls_openpgp_privkey_get_subkey_expiration_time (gnutls_openpgp_privkey_t
583 key, unsigned int idx)
585 cdk_packet_t pkt;
586 time_t expiredate;
588 if (!key)
589 return (time_t) - 1;
591 pkt = _get_secret_subkey (key, idx);
592 if (pkt)
593 expiredate = pkt->pkt.secret_key->expiredate;
594 else
595 expiredate = 0;
597 return expiredate;
601 * gnutls_openpgp_privkey_get_subkey_id - Gets the keyID
602 * @key: the structure that contains the OpenPGP secret key.
603 * @idx: the subkey index
604 * @keyid: the buffer to save the keyid.
606 * Get the key-id for the subkey.
608 * Returns: the 64-bit keyID of the OpenPGP key.
610 * Since: 2.4.0
613 gnutls_openpgp_privkey_get_subkey_id (gnutls_openpgp_privkey_t key,
614 unsigned int idx,
615 gnutls_openpgp_keyid_t keyid)
617 cdk_packet_t pkt;
618 uint32_t kid[2];
620 if (!key || !keyid)
622 gnutls_assert ();
623 return GNUTLS_E_INVALID_REQUEST;
626 pkt = _get_secret_subkey (key, idx);
627 if (!pkt)
628 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
630 cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
631 _gnutls_write_uint32 (kid[0], keyid);
632 _gnutls_write_uint32 (kid[1], keyid + 4);
634 return 0;
638 * gnutls_openpgp_privkey_get_subkey_fingerprint - Gets the fingerprint of a subkey
639 * @key: the raw data that contains the OpenPGP secret key.
640 * @idx: the subkey index
641 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
642 * @fprlen: the integer to save the length of the fingerprint.
644 * Get the fingerprint of an OpenPGP subkey. Depends on the
645 * algorithm, the fingerprint can be 16 or 20 bytes.
647 * Returns: On success, 0 is returned, or an error code.
649 * Since: 2.4.0
652 gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t key,
653 unsigned int idx,
654 void *fpr, size_t * fprlen)
656 cdk_packet_t pkt;
657 cdk_pkt_pubkey_t pk = NULL;
659 if (!fpr || !fprlen)
661 gnutls_assert ();
662 return GNUTLS_E_INVALID_REQUEST;
665 *fprlen = 0;
667 pkt = _get_secret_subkey (key, idx);
668 if (!pkt)
669 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
672 pk = pkt->pkt.secret_key->pk;
673 *fprlen = 20;
675 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
676 *fprlen = 16;
678 cdk_pk_get_fingerprint (pk, fpr);
680 return 0;
683 /* Extracts DSA and RSA parameters from a certificate.
686 _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey,
687 uint32_t * keyid /*[2] */ ,
688 bigint_t * params, int *params_size)
690 int result, i;
691 int pk_algorithm, local_params;
692 cdk_packet_t pkt;
694 if (keyid == NULL)
695 pkt = cdk_kbnode_find_packet (pkey->knode, CDK_PKT_SECRET_KEY);
696 else
697 pkt = _gnutls_openpgp_find_key (pkey->knode, keyid, 1);
699 if (pkt == NULL)
701 gnutls_assert ();
702 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
705 pk_algorithm =
706 _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
708 switch (pk_algorithm)
710 case GNUTLS_PK_RSA:
711 local_params = RSA_PRIVATE_PARAMS;
712 break;
713 case GNUTLS_PK_DSA:
714 local_params = DSA_PRIVATE_PARAMS;
715 break;
716 default:
717 gnutls_assert ();
718 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
721 if (*params_size < local_params)
723 gnutls_assert ();
724 return GNUTLS_E_INTERNAL_ERROR;
727 *params_size = local_params;
730 for (i = 0; i < local_params; i++)
732 result = _gnutls_read_pgp_mpi (pkt, 1, i, &params[i]);
733 if (result < 0)
735 gnutls_assert ();
736 goto error;
740 return 0;
742 error:
744 int j;
745 for (j = 0; j < i; j++)
746 _gnutls_mpi_release (&params[j]);
749 return result;
752 /* The internal version of export
754 static int
755 _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
756 gnutls_datum_t * m, gnutls_datum_t * e,
757 gnutls_datum_t * d, gnutls_datum_t * p,
758 gnutls_datum_t * q, gnutls_datum_t * u)
760 int pk_algorithm, ret, i;
761 cdk_packet_t pkt;
762 uint32_t kid32[2];
763 bigint_t params[MAX_PRIV_PARAMS_SIZE];
764 int params_size = MAX_PRIV_PARAMS_SIZE;
766 if (pkey == NULL)
768 gnutls_assert ();
769 return GNUTLS_E_INVALID_REQUEST;
772 KEYID_IMPORT (kid32, keyid);
774 pkt = _gnutls_openpgp_find_key (pkey->knode, kid32, 1);
775 if (pkt == NULL)
777 gnutls_assert ();
778 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
781 pk_algorithm =
782 _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
784 if (pk_algorithm != GNUTLS_PK_RSA)
786 gnutls_assert ();
787 return GNUTLS_E_INVALID_REQUEST;
790 ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, &params_size);
791 if (ret < 0)
793 gnutls_assert ();
794 return ret;
797 ret = _gnutls_mpi_dprint (params[0], m);
798 if (ret < 0)
800 gnutls_assert ();
801 goto cleanup;
804 ret = _gnutls_mpi_dprint (params[1], e);
805 if (ret < 0)
807 gnutls_assert ();
808 _gnutls_free_datum (m);
809 goto cleanup;
812 ret = _gnutls_mpi_dprint (params[2], d);
813 if (ret < 0)
815 gnutls_assert ();
816 _gnutls_free_datum (m);
817 _gnutls_free_datum (e);
818 goto cleanup;
821 ret = _gnutls_mpi_dprint (params[3], p);
822 if (ret < 0)
824 gnutls_assert ();
825 _gnutls_free_datum (m);
826 _gnutls_free_datum (e);
827 _gnutls_free_datum (d);
828 goto cleanup;
831 ret = _gnutls_mpi_dprint (params[4], q);
832 if (ret < 0)
834 gnutls_assert ();
835 _gnutls_free_datum (m);
836 _gnutls_free_datum (e);
837 _gnutls_free_datum (d);
838 _gnutls_free_datum (p);
839 goto cleanup;
842 ret = _gnutls_mpi_dprint (params[5], u);
843 if (ret < 0)
845 gnutls_assert ();
846 _gnutls_free_datum (q);
847 _gnutls_free_datum (m);
848 _gnutls_free_datum (e);
849 _gnutls_free_datum (d);
850 _gnutls_free_datum (p);
851 goto cleanup;
854 ret = 0;
856 cleanup:
857 for (i = 0; i < params_size; i++)
859 _gnutls_mpi_release (&params[i]);
861 return ret;
864 static int
865 _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid,
866 gnutls_datum_t * p, gnutls_datum_t * q,
867 gnutls_datum_t * g, gnutls_datum_t * y, gnutls_datum_t * x)
869 int pk_algorithm, ret, i;
870 cdk_packet_t pkt;
871 uint32_t kid32[2];
872 bigint_t params[MAX_PRIV_PARAMS_SIZE];
873 int params_size = MAX_PRIV_PARAMS_SIZE;
875 if (pkey == NULL)
877 gnutls_assert ();
878 return GNUTLS_E_INVALID_REQUEST;
881 KEYID_IMPORT (kid32, keyid);
883 pkt = _gnutls_openpgp_find_key (pkey->knode, kid32, 1);
884 if (pkt == NULL)
886 gnutls_assert ();
887 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
890 pk_algorithm =
891 _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
893 if (pk_algorithm != GNUTLS_PK_DSA)
895 gnutls_assert ();
896 return GNUTLS_E_INVALID_REQUEST;
899 ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, &params_size);
900 if (ret < 0)
902 gnutls_assert ();
903 return ret;
906 /* P */
907 ret = _gnutls_mpi_dprint (params[0], p);
908 if (ret < 0)
910 gnutls_assert ();
911 goto cleanup;
914 /* Q */
915 ret = _gnutls_mpi_dprint (params[1], q);
916 if (ret < 0)
918 gnutls_assert ();
919 _gnutls_free_datum (p);
920 goto cleanup;
924 /* G */
925 ret = _gnutls_mpi_dprint (params[2], g);
926 if (ret < 0)
928 gnutls_assert ();
929 _gnutls_free_datum (p);
930 _gnutls_free_datum (q);
931 goto cleanup;
935 /* Y */
936 ret = _gnutls_mpi_dprint (params[3], y);
937 if (ret < 0)
939 gnutls_assert ();
940 _gnutls_free_datum (p);
941 _gnutls_free_datum (g);
942 _gnutls_free_datum (q);
943 goto cleanup;
946 ret = _gnutls_mpi_dprint (params[4], x);
947 if (ret < 0)
949 gnutls_assert ();
950 _gnutls_free_datum (y);
951 _gnutls_free_datum (p);
952 _gnutls_free_datum (g);
953 _gnutls_free_datum (q);
954 goto cleanup;
957 ret = 0;
959 cleanup:
960 for (i = 0; i < params_size; i++)
962 _gnutls_mpi_release (&params[i]);
964 return ret;
969 * gnutls_openpgp_privkey_export_rsa_raw - This function will export the RSA private key
970 * @pkey: Holds the certificate
971 * @m: will hold the modulus
972 * @e: will hold the public exponent
973 * @d: will hold the private exponent
974 * @p: will hold the first prime (p)
975 * @q: will hold the second prime (q)
976 * @u: will hold the coefficient
978 * This function will export the RSA private key's parameters found in
979 * the given structure. The new parameters will be allocated using
980 * gnutls_malloc() and will be stored in the appropriate datum.
982 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
984 * Since: 2.4.0
987 gnutls_openpgp_privkey_export_rsa_raw (gnutls_openpgp_privkey_t pkey,
988 gnutls_datum_t * m, gnutls_datum_t * e,
989 gnutls_datum_t * d, gnutls_datum_t * p,
990 gnutls_datum_t * q, gnutls_datum_t * u)
992 gnutls_openpgp_keyid_t keyid;
993 int ret;
995 ret = gnutls_openpgp_privkey_get_key_id (pkey, keyid);
996 if (ret < 0)
998 gnutls_assert ();
999 return ret;
1002 return _get_sk_rsa_raw (pkey, keyid, m, e, d, p, q, u);
1006 * gnutls_openpgp_privkey_export_dsa_raw - This function will export the DSA private key
1007 * @pkey: Holds the certificate
1008 * @p: will hold the p
1009 * @q: will hold the q
1010 * @g: will hold the g
1011 * @y: will hold the y
1012 * @x: will hold the x
1014 * This function will export the DSA private key's parameters found in
1015 * the given certificate. The new parameters will be allocated using
1016 * gnutls_malloc() and will be stored in the appropriate datum.
1018 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1020 * Since: 2.4.0
1023 gnutls_openpgp_privkey_export_dsa_raw (gnutls_openpgp_privkey_t pkey,
1024 gnutls_datum_t * p, gnutls_datum_t * q,
1025 gnutls_datum_t * g, gnutls_datum_t * y,
1026 gnutls_datum_t * x)
1028 gnutls_openpgp_keyid_t keyid;
1029 int ret;
1031 ret = gnutls_openpgp_privkey_get_key_id (pkey, keyid);
1032 if (ret < 0)
1034 gnutls_assert ();
1035 return ret;
1038 return _get_sk_dsa_raw (pkey, keyid, p, q, g, y, x);
1042 * gnutls_openpgp_privkey_export_subkey_rsa_raw - export the RSA private key
1043 * @pkey: Holds the certificate
1044 * @idx: Is the subkey index
1045 * @m: will hold the modulus
1046 * @e: will hold the public exponent
1047 * @d: will hold the private exponent
1048 * @p: will hold the first prime (p)
1049 * @q: will hold the second prime (q)
1050 * @u: will hold the coefficient
1052 * This function will export the RSA private key's parameters found in
1053 * the given structure. The new parameters will be allocated using
1054 * gnutls_malloc() and will be stored in the appropriate datum.
1056 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1058 * Since: 2.4.0
1061 gnutls_openpgp_privkey_export_subkey_rsa_raw (gnutls_openpgp_privkey_t pkey,
1062 unsigned int idx,
1063 gnutls_datum_t * m,
1064 gnutls_datum_t * e,
1065 gnutls_datum_t * d,
1066 gnutls_datum_t * p,
1067 gnutls_datum_t * q,
1068 gnutls_datum_t * u)
1070 gnutls_openpgp_keyid_t keyid;
1071 int ret;
1073 ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
1074 if (ret < 0)
1076 gnutls_assert ();
1077 return ret;
1080 return _get_sk_rsa_raw (pkey, keyid, m, e, d, p, q, u);
1084 * gnutls_openpgp_privkey_export_subkey_dsa_raw - export the DSA private key
1085 * @pkey: Holds the certificate
1086 * @idx: Is the subkey index
1087 * @p: will hold the p
1088 * @q: will hold the q
1089 * @g: will hold the g
1090 * @y: will hold the y
1091 * @x: will hold the x
1093 * This function will export the DSA private key's parameters found
1094 * in the given certificate. The new parameters will be allocated
1095 * using gnutls_malloc() and will be stored in the appropriate datum.
1097 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1099 * Since: 2.4.0
1102 gnutls_openpgp_privkey_export_subkey_dsa_raw (gnutls_openpgp_privkey_t pkey,
1103 unsigned int idx,
1104 gnutls_datum_t * p,
1105 gnutls_datum_t * q,
1106 gnutls_datum_t * g,
1107 gnutls_datum_t * y,
1108 gnutls_datum_t * x)
1110 gnutls_openpgp_keyid_t keyid;
1111 int ret;
1113 ret = gnutls_openpgp_privkey_get_subkey_id (pkey, idx, keyid);
1114 if (ret < 0)
1116 gnutls_assert ();
1117 return ret;
1120 return _get_sk_dsa_raw (pkey, keyid, p, q, g, y, x);
1124 * gnutls_openpgp_privkey_get_preferred_key_id - Gets the preferred keyID
1125 * @key: the structure that contains the OpenPGP public key.
1126 * @keyid: the struct to save the keyid.
1128 * Get the preferred key-id for the key.
1130 * Returns: the 64-bit preferred keyID of the OpenPGP key, or if it
1131 * hasn't been set it returns %GNUTLS_E_INVALID_REQUEST.
1134 gnutls_openpgp_privkey_get_preferred_key_id (gnutls_openpgp_privkey_t key,
1135 gnutls_openpgp_keyid_t keyid)
1137 if (!key || !keyid || !key->preferred_set)
1139 gnutls_assert ();
1140 return GNUTLS_E_INVALID_REQUEST;
1143 memcpy (keyid, key->preferred_keyid, sizeof (gnutls_openpgp_keyid_t));
1145 return 0;
1149 * gnutls_openpgp_privkey_set_preferred_key_id - Set the preferred keyID
1150 * @key: the structure that contains the OpenPGP public key.
1151 * @keyid: the selected keyid
1153 * This allows setting a preferred key id for the given certificate.
1154 * This key will be used by functions that involve key handling.
1156 * Returns: On success, 0 is returned, or an error code.
1159 gnutls_openpgp_privkey_set_preferred_key_id (gnutls_openpgp_privkey_t key,
1160 const gnutls_openpgp_keyid_t
1161 keyid)
1163 int ret;
1165 if (!key)
1167 gnutls_assert ();
1168 return GNUTLS_E_INVALID_REQUEST;
1171 /* check if the id is valid */
1172 ret = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
1173 if (ret < 0)
1175 _gnutls_x509_log ("the requested subkey does not exist\n");
1176 gnutls_assert ();
1177 return ret;
1180 key->preferred_set = 1;
1181 memcpy (key->preferred_keyid, keyid, sizeof (gnutls_openpgp_keyid_t));
1183 return 0;