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 /* Functions on OpenPGP privkey parsing
26 #include <gnutls_int.h>
27 #include <gnutls_datum.h>
28 #include <gnutls_global.h>
29 #include <gnutls_errors.h>
30 #include <gnutls_num.h>
31 #include <openpgp_int.h>
32 #include <gnutls_openpgp.h>
33 #include <gnutls_sig.h>
34 #include <gnutls_pk.h>
37 * gnutls_openpgp_privkey_init:
38 * @key: The structure to be initialized
40 * This function will initialize an OpenPGP key structure.
42 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
45 gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t
* key
)
47 *key
= gnutls_calloc (1, sizeof (gnutls_openpgp_privkey_int
));
50 return 0; /* success */
51 return GNUTLS_E_MEMORY_ERROR
;
55 * gnutls_openpgp_privkey_deinit:
56 * @key: The structure to be initialized
58 * This function will deinitialize a key structure.
61 gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key
)
68 cdk_kbnode_release (key
->knode
);
76 * _gnutls_openpgp_privkey_cpy - This function copies a gnutls_openpgp_privkey_t structure
77 * @dest: The structure where to copy
78 * @src: The structure to be copied
80 * This function will copy an X.509 certificate structure.
82 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
83 * negative error value.
86 _gnutls_openpgp_privkey_cpy (gnutls_openpgp_privkey_t dest
, gnutls_openpgp_privkey_t src
)
93 ret
= gnutls_openpgp_privkey_export (src
, GNUTLS_OPENPGP_FMT_RAW
, NULL
, 0, NULL
, &raw_size
);
94 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
95 return gnutls_assert_val(ret
);
97 der
= gnutls_malloc (raw_size
);
99 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
101 ret
= gnutls_openpgp_privkey_export (src
, GNUTLS_OPENPGP_FMT_RAW
, NULL
, 0, der
, &raw_size
);
111 ret
= gnutls_openpgp_privkey_import (dest
, &tmp
, GNUTLS_OPENPGP_FMT_RAW
, NULL
, 0);
116 return gnutls_assert_val(ret
);
118 memcpy(dest
->preferred_keyid
, src
->preferred_keyid
, GNUTLS_OPENPGP_KEYID_SIZE
);
119 dest
->preferred_set
= src
->preferred_set
;
125 * gnutls_openpgp_privkey_sec_param:
126 * @key: a key structure
128 * This function will return the security parameter appropriate with
131 * Returns: On success, a valid security parameter is returned otherwise
132 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
137 gnutls_openpgp_privkey_sec_param (gnutls_openpgp_privkey_t key
)
139 gnutls_pk_algorithm_t algo
;
142 algo
= gnutls_openpgp_privkey_get_pk_algorithm (key
, &bits
);
143 if (algo
== GNUTLS_PK_UNKNOWN
)
146 return GNUTLS_SEC_PARAM_UNKNOWN
;
149 return gnutls_pk_bits_to_sec_param (algo
, bits
);
153 * gnutls_openpgp_privkey_import:
154 * @key: The structure to store the parsed key.
155 * @data: The RAW or BASE64 encoded key.
156 * @format: One of #gnutls_openpgp_crt_fmt_t elements.
157 * @password: not used for now
158 * @flags: should be (0)
160 * This function will convert the given RAW or Base64 encoded key to
161 * the native gnutls_openpgp_privkey_t format. The output will be
164 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
167 gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key
,
168 const gnutls_datum_t
* data
,
169 gnutls_openpgp_crt_fmt_t format
,
170 const char *password
, unsigned int flags
)
175 if (data
->data
== NULL
|| data
->size
== 0)
178 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
181 if (format
== GNUTLS_OPENPGP_FMT_RAW
)
185 rc
= cdk_kbnode_read_from_mem (&key
->knode
, armor
, data
->data
, data
->size
);
188 rc
= _gnutls_map_cdk_rc (rc
);
193 /* Test if the import was successful. */
194 pkt
= cdk_kbnode_find_packet (key
->knode
, CDK_PKT_SECRET_KEY
);
198 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
205 * gnutls_openpgp_privkey_export:
206 * @key: Holds the key.
207 * @format: One of gnutls_openpgp_crt_fmt_t elements.
208 * @password: the password that will be used to encrypt the key. (unused for now)
209 * @flags: (0) for future compatibility
210 * @output_data: will contain the key base64 encoded or raw
211 * @output_data_size: holds the size of output_data (and will be
212 * replaced by the actual size of parameters)
214 * This function will convert the given key to RAW or Base64 format.
215 * If the buffer provided is not long enough to hold the output, then
216 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
218 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
223 gnutls_openpgp_privkey_export (gnutls_openpgp_privkey_t key
,
224 gnutls_openpgp_crt_fmt_t format
,
225 const char *password
, unsigned int flags
,
226 void *output_data
, size_t * output_data_size
)
228 /* FIXME for now we do not export encrypted keys */
229 return _gnutls_openpgp_export (key
->knode
, format
, output_data
,
230 output_data_size
, 1);
234 * gnutls_openpgp_privkey_export2:
235 * @key: Holds the key.
236 * @format: One of gnutls_openpgp_crt_fmt_t elements.
237 * @password: the password that will be used to encrypt the key. (unused for now)
238 * @flags: (0) for future compatibility
239 * @out: will contain the raw or based64 encoded key
241 * This function will convert the given key to RAW or Base64 format.
242 * The output buffer is allocated using gnutls_malloc().
244 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
249 gnutls_openpgp_privkey_export2 (gnutls_openpgp_privkey_t key
,
250 gnutls_openpgp_crt_fmt_t format
,
251 const char *password
, unsigned int flags
,
254 /* FIXME for now we do not export encrypted keys */
255 return _gnutls_openpgp_export2 (key
->knode
, format
, out
, 1);
260 * gnutls_openpgp_privkey_get_pk_algorithm:
261 * @key: is an OpenPGP key
262 * @bits: if bits is non null it will hold the size of the parameters' in bits
264 * This function will return the public key algorithm of an OpenPGP
267 * If bits is non null, it should have enough size to hold the parameters
268 * size in bits. For RSA the bits returned is the modulus.
269 * For DSA the bits returned are of the public exponent.
271 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
272 * success, or a negative error code on error.
276 gnutls_pk_algorithm_t
277 gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key
,
282 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
287 return GNUTLS_PK_UNKNOWN
;
290 ret
= gnutls_openpgp_privkey_get_preferred_key_id (key
, keyid
);
295 idx
= gnutls_openpgp_privkey_get_subkey_idx (key
, keyid
);
296 if (idx
!= GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
299 gnutls_openpgp_privkey_get_subkey_pk_algorithm (key
, idx
, bits
);
304 pkt
= cdk_kbnode_find_packet (key
->knode
, CDK_PKT_SECRET_KEY
);
308 *bits
= cdk_pk_get_nbits (pkt
->pkt
.secret_key
->pk
);
309 algo
= _gnutls_openpgp_get_algo (pkt
->pkt
.secret_key
->pk
->pubkey_algo
);
316 _gnutls_openpgp_get_algo (int cdk_algo
)
320 if (is_RSA (cdk_algo
))
321 algo
= GNUTLS_PK_RSA
;
322 else if (is_DSA (cdk_algo
))
323 algo
= GNUTLS_PK_DSA
;
326 _gnutls_debug_log ("Unknown OpenPGP algorithm %d\n", cdk_algo
);
327 algo
= GNUTLS_PK_UNKNOWN
;
334 * gnutls_openpgp_privkey_get_revoked_status:
335 * @key: the structure that contains the OpenPGP private key.
337 * Get revocation status of key.
339 * Returns: true (1) if the key has been revoked, or false (0) if it
340 * has not, or a negative error code indicates an error.
345 gnutls_openpgp_privkey_get_revoked_status (gnutls_openpgp_privkey_t key
)
352 return GNUTLS_E_INVALID_REQUEST
;
355 pkt
= cdk_kbnode_find_packet (key
->knode
, CDK_PKT_SECRET_KEY
);
357 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
359 if (pkt
->pkt
.secret_key
->is_revoked
!= 0)
365 * gnutls_openpgp_privkey_get_fingerprint:
366 * @key: the raw data that contains the OpenPGP secret key.
367 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
368 * @fprlen: the integer to save the length of the fingerprint.
370 * Get the fingerprint of the OpenPGP key. Depends on the
371 * algorithm, the fingerprint can be 16 or 20 bytes.
373 * Returns: On success, 0 is returned, or an error code.
378 gnutls_openpgp_privkey_get_fingerprint (gnutls_openpgp_privkey_t key
,
379 void *fpr
, size_t * fprlen
)
382 cdk_pkt_pubkey_t pk
= NULL
;
387 return GNUTLS_E_INVALID_REQUEST
;
392 pkt
= cdk_kbnode_find_packet (key
->knode
, CDK_PKT_SECRET_KEY
);
396 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
399 pk
= pkt
->pkt
.secret_key
->pk
;
402 if (is_RSA (pk
->pubkey_algo
) && pk
->version
< 4)
405 cdk_pk_get_fingerprint (pk
, fpr
);
411 * gnutls_openpgp_privkey_get_key_id:
412 * @key: the structure that contains the OpenPGP secret key.
413 * @keyid: the buffer to save the keyid.
417 * Returns: the 64-bit keyID of the OpenPGP key.
422 gnutls_openpgp_privkey_get_key_id (gnutls_openpgp_privkey_t key
,
423 gnutls_openpgp_keyid_t keyid
)
431 return GNUTLS_E_INVALID_REQUEST
;
434 pkt
= cdk_kbnode_find_packet (key
->knode
, CDK_PKT_SECRET_KEY
);
436 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
438 cdk_sk_get_keyid (pkt
->pkt
.secret_key
, kid
);
439 _gnutls_write_uint32 (kid
[0], keyid
);
440 _gnutls_write_uint32 (kid
[1], keyid
+ 4);
446 * gnutls_openpgp_privkey_get_subkey_count:
447 * @key: is an OpenPGP key
449 * This function will return the number of subkeys present in the
450 * given OpenPGP certificate.
452 * Returns: the number of subkeys, or a negative error code on error.
457 gnutls_openpgp_privkey_get_subkey_count (gnutls_openpgp_privkey_t key
)
471 while ((p
= cdk_kbnode_walk (key
->knode
, &ctx
, 0)))
473 pkt
= cdk_kbnode_get_packet (p
);
474 if (pkt
->pkttype
== CDK_PKT_SECRET_SUBKEY
)
481 /* returns the subkey with the given index */
483 _get_secret_subkey (gnutls_openpgp_privkey_t key
, unsigned int indx
)
487 unsigned int subkeys
;
491 while ((p
= cdk_kbnode_walk (key
->knode
, &ctx
, 0)))
493 pkt
= cdk_kbnode_get_packet (p
);
494 if (pkt
->pkttype
== CDK_PKT_SECRET_SUBKEY
&& indx
== subkeys
++)
502 * gnutls_openpgp_privkey_get_subkey_revoked_status:
503 * @key: the structure that contains the OpenPGP private key.
504 * @idx: is the subkey index
506 * Get revocation status of key.
508 * Returns: true (1) if the key has been revoked, or false (0) if it
509 * has not, or a negative error code indicates an error.
514 gnutls_openpgp_privkey_get_subkey_revoked_status (gnutls_openpgp_privkey_t
515 key
, unsigned int idx
)
522 return GNUTLS_E_INVALID_REQUEST
;
525 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
526 return gnutls_openpgp_privkey_get_revoked_status(key
);
528 pkt
= _get_secret_subkey (key
, idx
);
530 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
532 if (pkt
->pkt
.secret_key
->is_revoked
!= 0)
538 * gnutls_openpgp_privkey_get_subkey_pk_algorithm:
539 * @key: is an OpenPGP key
540 * @idx: is the subkey index
541 * @bits: if bits is non null it will hold the size of the parameters' in bits
543 * This function will return the public key algorithm of a subkey of an OpenPGP
546 * If bits is non null, it should have enough size to hold the parameters
547 * size in bits. For RSA the bits returned is the modulus.
548 * For DSA the bits returned are of the public exponent.
550 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
551 * success, or a negative error code on error.
555 gnutls_pk_algorithm_t
556 gnutls_openpgp_privkey_get_subkey_pk_algorithm (gnutls_openpgp_privkey_t key
,
566 return GNUTLS_PK_UNKNOWN
;
569 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
570 return gnutls_openpgp_privkey_get_pk_algorithm(key
, bits
);
572 pkt
= _get_secret_subkey (key
, idx
);
578 *bits
= cdk_pk_get_nbits (pkt
->pkt
.secret_key
->pk
);
579 algo
= pkt
->pkt
.secret_key
->pubkey_algo
;
581 algo
= GNUTLS_PK_RSA
;
582 else if (is_DSA (algo
))
583 algo
= GNUTLS_PK_DSA
;
585 algo
= GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
592 * gnutls_openpgp_privkey_get_subkey_idx:
593 * @key: the structure that contains the OpenPGP private key.
596 * Get index of subkey.
598 * Returns: the index of the subkey or a negative error value.
603 gnutls_openpgp_privkey_get_subkey_idx (gnutls_openpgp_privkey_t key
,
604 const gnutls_openpgp_keyid_t keyid
)
608 uint8_t master_id
[GNUTLS_OPENPGP_KEYID_SIZE
];
613 return GNUTLS_E_INVALID_REQUEST
;
616 ret
= gnutls_openpgp_privkey_get_key_id (key
, master_id
);
618 return gnutls_assert_val(ret
);
619 if (memcmp(master_id
, keyid
, GNUTLS_OPENPGP_KEYID_SIZE
)==0)
620 return GNUTLS_OPENPGP_MASTER_KEYID_IDX
;
622 KEYID_IMPORT (kid
, keyid
);
623 ret
= _gnutls_openpgp_find_subkey_idx (key
->knode
, kid
, 1);
634 * gnutls_openpgp_privkey_get_subkey_creation_time:
635 * @key: the structure that contains the OpenPGP private key.
636 * @idx: the subkey index
638 * Get subkey creation time.
640 * Returns: the timestamp when the OpenPGP key was created.
645 gnutls_openpgp_privkey_get_subkey_creation_time (gnutls_openpgp_privkey_t key
,
654 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
655 pkt
= cdk_kbnode_find_packet (key
->knode
, CDK_PKT_SECRET_KEY
);
657 pkt
= _get_secret_subkey (key
, idx
);
660 timestamp
= pkt
->pkt
.secret_key
->pk
->timestamp
;
668 * gnutls_openpgp_privkey_get_subkey_expiration_time:
669 * @key: the structure that contains the OpenPGP private key.
670 * @idx: the subkey index
672 * Get subkey expiration time. A value of '0' means that the key
673 * doesn't expire at all.
675 * Returns: the time when the OpenPGP key expires.
680 gnutls_openpgp_privkey_get_subkey_expiration_time (gnutls_openpgp_privkey_t
681 key
, unsigned int idx
)
689 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
690 pkt
= cdk_kbnode_find_packet (key
->knode
, CDK_PKT_SECRET_KEY
);
692 pkt
= _get_secret_subkey (key
, idx
);
695 timestamp
= pkt
->pkt
.secret_key
->pk
->expiredate
;
703 * gnutls_openpgp_privkey_get_subkey_id:
704 * @key: the structure that contains the OpenPGP secret key.
705 * @idx: the subkey index
706 * @keyid: the buffer to save the keyid.
708 * Get the key-id for the subkey.
710 * Returns: the 64-bit keyID of the OpenPGP key.
715 gnutls_openpgp_privkey_get_subkey_id (gnutls_openpgp_privkey_t key
,
717 gnutls_openpgp_keyid_t keyid
)
725 return GNUTLS_E_INVALID_REQUEST
;
728 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
729 return gnutls_openpgp_privkey_get_key_id(key
, keyid
);
731 pkt
= _get_secret_subkey (key
, idx
);
733 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
735 cdk_sk_get_keyid (pkt
->pkt
.secret_key
, kid
);
736 _gnutls_write_uint32 (kid
[0], keyid
);
737 _gnutls_write_uint32 (kid
[1], keyid
+ 4);
743 * gnutls_openpgp_privkey_get_subkey_fingerprint:
744 * @key: the raw data that contains the OpenPGP secret key.
745 * @idx: the subkey index
746 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
747 * @fprlen: the integer to save the length of the fingerprint.
749 * Get the fingerprint of an OpenPGP subkey. Depends on the
750 * algorithm, the fingerprint can be 16 or 20 bytes.
752 * Returns: On success, 0 is returned, or an error code.
757 gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t key
,
759 void *fpr
, size_t * fprlen
)
762 cdk_pkt_pubkey_t pk
= NULL
;
767 return GNUTLS_E_INVALID_REQUEST
;
770 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
771 return gnutls_openpgp_privkey_get_fingerprint(key
, fpr
, fprlen
);
775 pkt
= _get_secret_subkey (key
, idx
);
777 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
780 pk
= pkt
->pkt
.secret_key
->pk
;
783 if (is_RSA (pk
->pubkey_algo
) && pk
->version
< 4)
786 cdk_pk_get_fingerprint (pk
, fpr
);
791 /* Extracts DSA and RSA parameters from a certificate.
794 _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey
,
795 uint32_t * keyid
/*[2] */ ,
796 gnutls_pk_params_st
* params
)
799 unsigned int i
, pk_algorithm
;
802 gnutls_pk_params_init(params
);
805 pkt
= cdk_kbnode_find_packet (pkey
->knode
, CDK_PKT_SECRET_KEY
);
807 pkt
= _gnutls_openpgp_find_key (pkey
->knode
, keyid
, 1);
812 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
816 _gnutls_openpgp_get_algo (pkt
->pkt
.secret_key
->pk
->pubkey_algo
);
818 switch (pk_algorithm
)
821 /* openpgp does not hold all parameters as in PKCS #1
823 params
->params_nr
= RSA_PRIVATE_PARAMS
- 2;
826 params
->params_nr
= DSA_PRIVATE_PARAMS
;
830 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
833 for (i
= 0; i
< params
->params_nr
; i
++)
835 result
= _gnutls_read_pgp_mpi (pkt
, 1, i
, ¶ms
->params
[i
]);
843 /* fixup will generate exp1 and exp2 that are not
846 result
= _gnutls_pk_fixup (pk_algorithm
, GNUTLS_IMPORT
, params
);
856 gnutls_pk_params_release(params
);
861 /* The internal version of export
864 _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey
, gnutls_openpgp_keyid_t keyid
,
865 gnutls_datum_t
* m
, gnutls_datum_t
* e
,
866 gnutls_datum_t
* d
, gnutls_datum_t
* p
,
867 gnutls_datum_t
* q
, gnutls_datum_t
* u
)
869 int pk_algorithm
, ret
;
872 gnutls_pk_params_st params
;
877 return GNUTLS_E_INVALID_REQUEST
;
880 KEYID_IMPORT (kid32
, keyid
);
882 pkt
= _gnutls_openpgp_find_key (pkey
->knode
, kid32
, 1);
886 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
890 _gnutls_openpgp_get_algo (pkt
->pkt
.secret_key
->pk
->pubkey_algo
);
892 if (pk_algorithm
!= GNUTLS_PK_RSA
)
895 return GNUTLS_E_INVALID_REQUEST
;
898 ret
= _gnutls_openpgp_privkey_get_mpis (pkey
, kid32
, ¶ms
);
905 ret
= _gnutls_mpi_dprint (params
.params
[0], m
);
912 ret
= _gnutls_mpi_dprint (params
.params
[1], e
);
916 _gnutls_free_datum (m
);
920 ret
= _gnutls_mpi_dprint (params
.params
[2], d
);
924 _gnutls_free_datum (m
);
925 _gnutls_free_datum (e
);
929 ret
= _gnutls_mpi_dprint (params
.params
[3], p
);
933 _gnutls_free_datum (m
);
934 _gnutls_free_datum (e
);
935 _gnutls_free_datum (d
);
939 ret
= _gnutls_mpi_dprint (params
.params
[4], q
);
943 _gnutls_free_datum (m
);
944 _gnutls_free_datum (e
);
945 _gnutls_free_datum (d
);
946 _gnutls_free_datum (p
);
950 ret
= _gnutls_mpi_dprint (params
.params
[5], u
);
954 _gnutls_free_datum (q
);
955 _gnutls_free_datum (m
);
956 _gnutls_free_datum (e
);
957 _gnutls_free_datum (d
);
958 _gnutls_free_datum (p
);
965 gnutls_pk_params_release(¶ms
);
970 _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey
, gnutls_openpgp_keyid_t keyid
,
971 gnutls_datum_t
* p
, gnutls_datum_t
* q
,
972 gnutls_datum_t
* g
, gnutls_datum_t
* y
, gnutls_datum_t
* x
)
974 int pk_algorithm
, ret
;
977 gnutls_pk_params_st params
;
982 return GNUTLS_E_INVALID_REQUEST
;
985 KEYID_IMPORT (kid32
, keyid
);
987 pkt
= _gnutls_openpgp_find_key (pkey
->knode
, kid32
, 1);
991 return GNUTLS_E_OPENPGP_GETKEY_FAILED
;
995 _gnutls_openpgp_get_algo (pkt
->pkt
.secret_key
->pk
->pubkey_algo
);
997 if (pk_algorithm
!= GNUTLS_PK_DSA
)
1000 return GNUTLS_E_INVALID_REQUEST
;
1003 ret
= _gnutls_openpgp_privkey_get_mpis (pkey
, kid32
, ¶ms
);
1011 ret
= _gnutls_mpi_dprint (params
.params
[0], p
);
1019 ret
= _gnutls_mpi_dprint (params
.params
[1], q
);
1023 _gnutls_free_datum (p
);
1029 ret
= _gnutls_mpi_dprint (params
.params
[2], g
);
1033 _gnutls_free_datum (p
);
1034 _gnutls_free_datum (q
);
1040 ret
= _gnutls_mpi_dprint (params
.params
[3], y
);
1044 _gnutls_free_datum (p
);
1045 _gnutls_free_datum (g
);
1046 _gnutls_free_datum (q
);
1050 ret
= _gnutls_mpi_dprint (params
.params
[4], x
);
1054 _gnutls_free_datum (y
);
1055 _gnutls_free_datum (p
);
1056 _gnutls_free_datum (g
);
1057 _gnutls_free_datum (q
);
1064 gnutls_pk_params_release(¶ms
);
1070 * gnutls_openpgp_privkey_export_rsa_raw:
1071 * @pkey: Holds the certificate
1072 * @m: will hold the modulus
1073 * @e: will hold the public exponent
1074 * @d: will hold the private exponent
1075 * @p: will hold the first prime (p)
1076 * @q: will hold the second prime (q)
1077 * @u: will hold the coefficient
1079 * This function will export the RSA private key's parameters found in
1080 * the given structure. The new parameters will be allocated using
1081 * gnutls_malloc() and will be stored in the appropriate datum.
1083 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1088 gnutls_openpgp_privkey_export_rsa_raw (gnutls_openpgp_privkey_t pkey
,
1089 gnutls_datum_t
* m
, gnutls_datum_t
* e
,
1090 gnutls_datum_t
* d
, gnutls_datum_t
* p
,
1091 gnutls_datum_t
* q
, gnutls_datum_t
* u
)
1093 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
1096 ret
= gnutls_openpgp_privkey_get_key_id (pkey
, keyid
);
1103 return _get_sk_rsa_raw (pkey
, keyid
, m
, e
, d
, p
, q
, u
);
1107 * gnutls_openpgp_privkey_export_dsa_raw:
1108 * @pkey: Holds the certificate
1109 * @p: will hold the p
1110 * @q: will hold the q
1111 * @g: will hold the g
1112 * @y: will hold the y
1113 * @x: will hold the x
1115 * This function will export the DSA private key's parameters found in
1116 * the given certificate. The new parameters will be allocated using
1117 * gnutls_malloc() and will be stored in the appropriate datum.
1119 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1124 gnutls_openpgp_privkey_export_dsa_raw (gnutls_openpgp_privkey_t pkey
,
1125 gnutls_datum_t
* p
, gnutls_datum_t
* q
,
1126 gnutls_datum_t
* g
, gnutls_datum_t
* y
,
1129 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
1132 ret
= gnutls_openpgp_privkey_get_key_id (pkey
, keyid
);
1139 return _get_sk_dsa_raw (pkey
, keyid
, p
, q
, g
, y
, x
);
1143 * gnutls_openpgp_privkey_export_subkey_rsa_raw:
1144 * @pkey: Holds the certificate
1145 * @idx: Is the subkey index
1146 * @m: will hold the modulus
1147 * @e: will hold the public exponent
1148 * @d: will hold the private exponent
1149 * @p: will hold the first prime (p)
1150 * @q: will hold the second prime (q)
1151 * @u: will hold the coefficient
1153 * This function will export the RSA private key's parameters found in
1154 * the given structure. The new parameters will be allocated using
1155 * gnutls_malloc() and will be stored in the appropriate datum.
1157 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1162 gnutls_openpgp_privkey_export_subkey_rsa_raw (gnutls_openpgp_privkey_t pkey
,
1171 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
1174 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
1175 ret
= gnutls_openpgp_privkey_get_key_id (pkey
, keyid
);
1177 ret
= gnutls_openpgp_privkey_get_subkey_id (pkey
, idx
, keyid
);
1184 return _get_sk_rsa_raw (pkey
, keyid
, m
, e
, d
, p
, q
, u
);
1188 * gnutls_openpgp_privkey_export_subkey_dsa_raw:
1189 * @pkey: Holds the certificate
1190 * @idx: Is the subkey index
1191 * @p: will hold the p
1192 * @q: will hold the q
1193 * @g: will hold the g
1194 * @y: will hold the y
1195 * @x: will hold the x
1197 * This function will export the DSA private key's parameters found
1198 * in the given certificate. The new parameters will be allocated
1199 * using gnutls_malloc() and will be stored in the appropriate datum.
1201 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1206 gnutls_openpgp_privkey_export_subkey_dsa_raw (gnutls_openpgp_privkey_t pkey
,
1214 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
1217 if (idx
== GNUTLS_OPENPGP_MASTER_KEYID_IDX
)
1218 ret
= gnutls_openpgp_privkey_get_key_id (pkey
, keyid
);
1220 ret
= gnutls_openpgp_privkey_get_subkey_id (pkey
, idx
, keyid
);
1228 return _get_sk_dsa_raw (pkey
, keyid
, p
, q
, g
, y
, x
);
1232 * gnutls_openpgp_privkey_get_preferred_key_id:
1233 * @key: the structure that contains the OpenPGP public key.
1234 * @keyid: the struct to save the keyid.
1236 * Get the preferred key-id for the key.
1238 * Returns: the 64-bit preferred keyID of the OpenPGP key, or if it
1239 * hasn't been set it returns %GNUTLS_E_INVALID_REQUEST.
1242 gnutls_openpgp_privkey_get_preferred_key_id (gnutls_openpgp_privkey_t key
,
1243 gnutls_openpgp_keyid_t keyid
)
1245 if (!key
->preferred_set
)
1246 return gnutls_assert_val(GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR
);
1251 return GNUTLS_E_INVALID_REQUEST
;
1254 memcpy (keyid
, key
->preferred_keyid
, GNUTLS_OPENPGP_KEYID_SIZE
);
1260 * gnutls_openpgp_privkey_set_preferred_key_id:
1261 * @key: the structure that contains the OpenPGP public key.
1262 * @keyid: the selected keyid
1264 * This allows setting a preferred key id for the given certificate.
1265 * This key will be used by functions that involve key handling.
1267 * If the provided @keyid is %NULL then the master key is
1270 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1271 * otherwise a negative error code is returned.
1274 gnutls_openpgp_privkey_set_preferred_key_id (gnutls_openpgp_privkey_t key
,
1275 const gnutls_openpgp_keyid_t
1283 return GNUTLS_E_INVALID_REQUEST
;
1286 if (keyid
== NULL
) /* set the master as preferred */
1288 uint8_t tmp
[GNUTLS_OPENPGP_KEYID_SIZE
];
1290 ret
= gnutls_openpgp_privkey_get_key_id (key
, tmp
);
1292 return gnutls_assert_val(ret
);
1294 key
->preferred_set
= 1;
1295 memcpy (key
->preferred_keyid
, tmp
, GNUTLS_OPENPGP_KEYID_SIZE
);
1300 /* check if the id is valid */
1301 ret
= gnutls_openpgp_privkey_get_subkey_idx (key
, keyid
);
1304 _gnutls_debug_log ("the requested subkey does not exist\n");
1309 key
->preferred_set
= 1;
1310 memcpy (key
->preferred_keyid
, keyid
, GNUTLS_OPENPGP_KEYID_SIZE
);
1316 * gnutls_openpgp_privkey_sign_hash:
1317 * @key: Holds the key
1318 * @hash: holds the data to be signed
1319 * @signature: will contain newly allocated signature
1321 * This function will sign the given hash using the private key. You
1322 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
1323 * calling this function to set the subkey to use.
1325 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1326 * negative error value.
1328 * Deprecated: Use gnutls_privkey_sign_hash() instead.
1331 gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key
,
1332 const gnutls_datum_t
* hash
,
1333 gnutls_datum_t
* signature
)
1336 gnutls_pk_params_st params
;
1338 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
1343 return GNUTLS_E_INVALID_REQUEST
;
1346 result
= gnutls_openpgp_privkey_get_preferred_key_id (key
, keyid
);
1352 KEYID_IMPORT (kid
, keyid
);
1354 idx
= gnutls_openpgp_privkey_get_subkey_idx (key
, keyid
);
1356 gnutls_openpgp_privkey_get_subkey_pk_algorithm (key
, idx
, NULL
);
1358 _gnutls_openpgp_privkey_get_mpis (key
, kid
, ¶ms
);
1362 pk_algorithm
= gnutls_openpgp_privkey_get_pk_algorithm (key
, NULL
);
1363 result
= _gnutls_openpgp_privkey_get_mpis (key
, NULL
, ¶ms
);
1374 _gnutls_pk_sign (pk_algorithm
, signature
, hash
, ¶ms
);
1376 gnutls_pk_params_release(¶ms
);
1388 * _gnutls_openpgp_privkey_decrypt_data:
1389 * @key: Holds the key
1390 * @flags: (0) for now
1391 * @ciphertext: holds the data to be decrypted
1392 * @plaintext: will contain newly allocated plaintext
1394 * This function will sign the given hash using the private key. You
1395 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
1396 * calling this function to set the subkey to use.
1398 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1399 * negative error value.
1402 _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key
,
1404 const gnutls_datum_t
* ciphertext
,
1405 gnutls_datum_t
* plaintext
)
1408 gnutls_pk_params_st params
;
1410 uint8_t keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
1415 return GNUTLS_E_INVALID_REQUEST
;
1418 result
= gnutls_openpgp_privkey_get_preferred_key_id (key
, keyid
);
1423 KEYID_IMPORT (kid
, keyid
);
1424 result
= _gnutls_openpgp_privkey_get_mpis (key
, kid
, ¶ms
);
1426 i
= gnutls_openpgp_privkey_get_subkey_idx (key
, keyid
);
1428 pk_algorithm
= gnutls_openpgp_privkey_get_subkey_pk_algorithm (key
, i
, NULL
);
1432 pk_algorithm
= gnutls_openpgp_privkey_get_pk_algorithm (key
, NULL
);
1434 result
= _gnutls_openpgp_privkey_get_mpis (key
, NULL
, ¶ms
);
1444 result
= _gnutls_pk_decrypt (pk_algorithm
, plaintext
, ciphertext
, ¶ms
);
1446 gnutls_pk_params_release(¶ms
);
1449 return gnutls_assert_val(result
);