2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 * Free Software Foundation, Inc.
5 * Author: Timo Schulz, 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 key parsing
29 #include <gnutls_int.h>
30 #include <gnutls_datum.h>
31 #include <gnutls_global.h>
32 #include <gnutls_errors.h>
33 #include <openpgp_int.h>
34 #include <gnutls_str.h>
35 #include <gnutls_num.h>
36 #include <x509/common.h>
39 * gnutls_openpgp_crt_init:
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.
47 gnutls_openpgp_crt_init (gnutls_openpgp_crt_t * key)
49 *key = gnutls_calloc (1, sizeof (gnutls_openpgp_crt_int));
52 return 0; /* success */
53 return GNUTLS_E_MEMORY_ERROR;
57 * gnutls_openpgp_crt_deinit:
58 * @key: The structure to be initialized
60 * This function will deinitialize a key structure.
63 gnutls_openpgp_crt_deinit (gnutls_openpgp_crt_t key)
70 cdk_kbnode_release (key->knode);
78 * gnutls_openpgp_crt_import:
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.
83 * This function will convert the given RAW or Base64 encoded key to
84 * the native #gnutls_openpgp_crt_t format. The output will be stored
87 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
90 gnutls_openpgp_crt_import (gnutls_openpgp_crt_t key,
91 const gnutls_datum_t * data,
92 gnutls_openpgp_crt_fmt_t format)
98 if (data->data == NULL || data->size == 0)
101 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
104 if (format == GNUTLS_OPENPGP_FMT_RAW)
106 rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
109 rc = _gnutls_map_cdk_rc (rc);
116 rc = cdk_stream_tmp_from_mem (data->data, data->size, &inp);
119 rc = _gnutls_map_cdk_rc (rc);
123 if (cdk_armor_filter_use (inp))
124 rc = cdk_stream_set_armor_flag (inp, 0);
126 rc = cdk_keydb_get_keyblock (inp, &key->knode);
127 cdk_stream_close (inp);
130 if (rc == CDK_Inv_Packet)
131 rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
133 rc = _gnutls_map_cdk_rc (rc);
139 /* Test if the import was successful. */
140 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
144 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
150 /* internal version of export
153 _gnutls_openpgp_export (cdk_kbnode_t node,
154 gnutls_openpgp_crt_fmt_t format,
156 size_t * output_data_size, int private)
158 size_t input_data_size = *output_data_size;
162 rc = cdk_kbnode_write_to_mem (node, output_data, output_data_size);
165 rc = _gnutls_map_cdk_rc (rc);
170 /* If the caller uses output_data == NULL then return what he expects.
175 return GNUTLS_E_SHORT_MEMORY_BUFFER;
178 if (format == GNUTLS_OPENPGP_FMT_BASE64)
180 unsigned char *in = gnutls_calloc (1, *output_data_size);
181 memcpy (in, output_data, *output_data_size);
183 /* Calculate the size of the encoded data and check if the provided
184 buffer is large enough. */
185 rc = cdk_armor_encode_buffer (in, *output_data_size,
187 private ? CDK_ARMOR_SECKEY :
189 if (rc || calc_size > input_data_size)
192 *output_data_size = calc_size;
194 return GNUTLS_E_SHORT_MEMORY_BUFFER;
197 rc = cdk_armor_encode_buffer (in, *output_data_size,
198 output_data, input_data_size, &calc_size,
199 private ? CDK_ARMOR_SECKEY :
202 *output_data_size = calc_size;
206 rc = _gnutls_map_cdk_rc (rc);
217 * gnutls_openpgp_crt_export:
218 * @key: Holds the key.
219 * @format: One of gnutls_openpgp_crt_fmt_t elements.
220 * @output_data: will contain the key base64 encoded or raw
221 * @output_data_size: holds the size of output_data (and will
222 * be replaced by the actual size of parameters)
224 * This function will convert the given key to RAW or Base64 format.
225 * If the buffer provided is not long enough to hold the output, then
226 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
228 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
231 gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key,
232 gnutls_openpgp_crt_fmt_t format,
233 void *output_data, size_t * output_data_size)
235 return _gnutls_openpgp_export (key->knode, format, output_data,
236 output_data_size, 0);
240 * gnutls_openpgp_crt_get_fingerprint:
241 * @key: the raw data that contains the OpenPGP public key.
242 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
243 * @fprlen: the integer to save the length of the fingerprint.
245 * Get key fingerprint. Depending on the algorithm, the fingerprint
246 * can be 16 or 20 bytes.
248 * Returns: On success, 0 is returned. Otherwise, an error code.
251 gnutls_openpgp_crt_get_fingerprint (gnutls_openpgp_crt_t key,
252 void *fpr, size_t * fprlen)
255 cdk_pkt_pubkey_t pk = NULL;
260 return GNUTLS_E_INVALID_REQUEST;
265 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
267 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
269 pk = pkt->pkt.public_key;
272 /* FIXME: Check if the draft allows old PGP keys. */
273 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
275 cdk_pk_get_fingerprint (pk, fpr);
281 _gnutls_openpgp_count_key_names (gnutls_openpgp_crt_t key)
295 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
297 pkt = cdk_kbnode_get_packet (p);
298 if (pkt->pkttype == CDK_PKT_USER_ID)
307 * gnutls_openpgp_crt_get_name:
308 * @key: the structure that contains the OpenPGP public key.
309 * @idx: the index of the ID to extract
310 * @buf: a pointer to a structure to hold the name, may be %NULL
311 * to only get the @sizeof_buf.
312 * @sizeof_buf: holds the maximum size of @buf, on return hold the
313 * actual/required size of @buf.
315 * Extracts the userID from the parsed OpenPGP key.
317 * Returns: %GNUTLS_E_SUCCESS on success, and if the index of the ID
318 * does not exist %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, or an
322 gnutls_openpgp_crt_get_name (gnutls_openpgp_crt_t key,
323 int idx, char *buf, size_t * sizeof_buf)
325 cdk_kbnode_t ctx = NULL, p;
326 cdk_packet_t pkt = NULL;
327 cdk_pkt_userid_t uid = NULL;
333 return GNUTLS_E_INVALID_REQUEST;
336 if (idx < 0 || idx >= _gnutls_openpgp_count_key_names (key))
337 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
340 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
342 pkt = cdk_kbnode_get_packet (p);
343 if (pkt->pkttype == CDK_PKT_USER_ID)
354 return GNUTLS_E_INTERNAL_ERROR;
357 uid = pkt->pkt.user_id;
358 if (uid->len >= *sizeof_buf)
361 *sizeof_buf = uid->len + 1;
362 return GNUTLS_E_SHORT_MEMORY_BUFFER;
367 memcpy (buf, uid->name, uid->len);
368 buf[uid->len] = '\0'; /* make sure it's a string */
370 *sizeof_buf = uid->len + 1;
373 return GNUTLS_E_OPENPGP_UID_REVOKED;
379 * gnutls_openpgp_crt_get_pk_algorithm:
380 * @key: is an OpenPGP key
381 * @bits: if bits is non null it will hold the size of the parameters' in bits
383 * This function will return the public key algorithm of an OpenPGP
386 * If bits is non null, it should have enough size to hold the parameters
387 * size in bits. For RSA the bits returned is the modulus.
388 * For DSA the bits returned are of the public exponent.
390 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
391 * success, or GNUTLS_PK_UNKNOWN on error.
393 gnutls_pk_algorithm_t
394 gnutls_openpgp_crt_get_pk_algorithm (gnutls_openpgp_crt_t key,
403 return GNUTLS_PK_UNKNOWN;
407 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
411 *bits = cdk_pk_get_nbits (pkt->pkt.public_key);
412 algo = _gnutls_openpgp_get_algo (pkt->pkt.public_key->pubkey_algo);
420 * gnutls_openpgp_crt_get_version:
421 * @key: the structure that contains the OpenPGP public key.
423 * Extract the version of the OpenPGP key.
425 * Returns: the version number is returned, or a negative value on errors.
428 gnutls_openpgp_crt_get_version (gnutls_openpgp_crt_t key)
436 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
438 version = pkt->pkt.public_key->version;
447 * gnutls_openpgp_crt_get_creation_time:
448 * @key: the structure that contains the OpenPGP public key.
450 * Get key creation time.
452 * Returns: the timestamp when the OpenPGP key was created.
455 gnutls_openpgp_crt_get_creation_time (gnutls_openpgp_crt_t key)
463 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
465 timestamp = pkt->pkt.public_key->timestamp;
474 * gnutls_openpgp_crt_get_expiration_time:
475 * @key: the structure that contains the OpenPGP public key.
477 * Get key expiration time. A value of '0' means that the key doesn't
480 * Returns: the time when the OpenPGP key expires.
483 gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key)
491 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
493 expiredate = pkt->pkt.public_key->expiredate;
501 * gnutls_openpgp_crt_get_key_id:
502 * @key: the structure that contains the OpenPGP public key.
503 * @keyid: the buffer to save the keyid.
507 * Returns: the 64-bit keyID of the OpenPGP key.
512 gnutls_openpgp_crt_get_key_id (gnutls_openpgp_crt_t key,
513 gnutls_openpgp_keyid_t keyid)
521 return GNUTLS_E_INVALID_REQUEST;
524 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
526 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
528 cdk_pk_get_keyid (pkt->pkt.public_key, kid);
529 _gnutls_write_uint32 (kid[0], keyid);
530 _gnutls_write_uint32 (kid[1], keyid + 4);
536 * gnutls_openpgp_crt_get_revoked_status:
537 * @key: the structure that contains the OpenPGP public key.
539 * Get revocation status of key.
541 * Returns: true (1) if the key has been revoked, or false (0) if it
547 gnutls_openpgp_crt_get_revoked_status (gnutls_openpgp_crt_t key)
554 return GNUTLS_E_INVALID_REQUEST;
557 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
559 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
561 if (pkt->pkt.public_key->is_revoked != 0)
567 * gnutls_openpgp_crt_check_hostname:
568 * @key: should contain a #gnutls_openpgp_crt_t structure
569 * @hostname: A null terminated string that contains a DNS name
571 * This function will check if the given key's owner matches the
572 * given hostname. This is a basic implementation of the matching
573 * described in RFC2818 (HTTPS), which takes into account wildcards.
575 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
578 gnutls_openpgp_crt_check_hostname (gnutls_openpgp_crt_t key,
579 const char *hostname)
581 char dnsname[MAX_CN];
586 /* Check through all included names. */
587 for (i = 0; !(ret < 0); i++)
589 dnsnamesize = sizeof (dnsname);
590 ret = gnutls_openpgp_crt_get_name (key, i, dnsname, &dnsnamesize);
594 /* Length returned by gnutls_openpgp_crt_get_name includes
595 the terminating zero. */
598 if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname, 0))
603 /* not found a matching name */
608 _gnutls_get_pgp_key_usage (unsigned int cdk_usage)
610 unsigned int usage = 0;
612 if (cdk_usage & CDK_KEY_USG_CERT_SIGN)
613 usage |= GNUTLS_KEY_KEY_CERT_SIGN;
614 if (cdk_usage & CDK_KEY_USG_DATA_SIGN)
615 usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
616 if (cdk_usage & CDK_KEY_USG_COMM_ENCR)
617 usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
618 if (cdk_usage & CDK_KEY_USG_STORAGE_ENCR)
619 usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
620 if (cdk_usage & CDK_KEY_USG_AUTH)
621 usage |= GNUTLS_KEY_KEY_AGREEMENT;
627 * gnutls_openpgp_crt_get_key_usage:
628 * @key: should contain a gnutls_openpgp_crt_t structure
629 * @key_usage: where the key usage bits will be stored
631 * This function will return certificate's key usage, by checking the
632 * key algorithm. The key usage value will ORed values of the:
633 * %GNUTLS_KEY_DIGITAL_SIGNATURE, %GNUTLS_KEY_KEY_ENCIPHERMENT.
635 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
638 gnutls_openpgp_crt_get_key_usage (gnutls_openpgp_crt_t key,
639 unsigned int *key_usage)
646 return GNUTLS_E_INVALID_REQUEST;
649 pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
651 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
653 *key_usage = _gnutls_get_pgp_key_usage (pkt->pkt.public_key->pubkey_usage);
659 * gnutls_openpgp_crt_get_subkey_count:
660 * @key: is an OpenPGP key
662 * This function will return the number of subkeys present in the
663 * given OpenPGP certificate.
665 * Returns: the number of subkeys, or a negative value on error.
670 gnutls_openpgp_crt_get_subkey_count (gnutls_openpgp_crt_t key)
684 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
686 pkt = cdk_kbnode_get_packet (p);
687 if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
694 /* returns the subkey with the given index */
696 _get_public_subkey (gnutls_openpgp_crt_t key, unsigned int indx)
700 unsigned int subkeys;
710 while ((p = cdk_kbnode_walk (key->knode, &ctx, 0)))
712 pkt = cdk_kbnode_get_packet (p);
713 if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY && indx == subkeys++)
720 /* returns the key with the given keyid. It can be either key or subkey.
721 * depending on what requested:
722 * pkt->pkt.secret_key;
723 * pkt->pkt.public_key;
726 _gnutls_openpgp_find_key (cdk_kbnode_t knode, uint32_t keyid[2],
731 uint32_t local_keyid[2];
734 while ((p = cdk_kbnode_walk (knode, &ctx, 0)))
736 pkt = cdk_kbnode_get_packet (p);
739 && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY
740 || pkt->pkttype == CDK_PKT_PUBLIC_KEY)) || (priv != 0
742 CDK_PKT_SECRET_SUBKEY
745 CDK_PKT_SECRET_KEY)))
748 cdk_pk_get_keyid (pkt->pkt.public_key, local_keyid);
750 cdk_pk_get_keyid (pkt->pkt.secret_key->pk, local_keyid);
752 if (local_keyid[0] == keyid[0] && local_keyid[1] == keyid[1])
763 /* returns the key with the given keyid
764 * depending on what requested:
765 * pkt->pkt.secret_key;
766 * pkt->pkt.public_key;
769 _gnutls_openpgp_find_subkey_idx (cdk_kbnode_t knode, uint32_t keyid[2],
775 uint32_t local_keyid[2];
777 _gnutls_hard_log ("Looking keyid: %x.%x\n", keyid[0], keyid[1]);
780 while ((p = cdk_kbnode_walk (knode, &ctx, 0)))
782 pkt = cdk_kbnode_get_packet (p);
784 if ((priv == 0 && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)) ||
785 (priv != 0 && (pkt->pkttype == CDK_PKT_SECRET_SUBKEY)))
788 cdk_pk_get_keyid (pkt->pkt.public_key, local_keyid);
790 cdk_pk_get_keyid (pkt->pkt.secret_key->pk, local_keyid);
792 _gnutls_hard_log ("Found keyid: %x.%x\n", local_keyid[0],
794 if (local_keyid[0] == keyid[0] && local_keyid[1] == keyid[1])
803 return GNUTLS_E_OPENPGP_SUBKEY_ERROR;
807 * gnutls_openpgp_crt_get_subkey_revoked_status:
808 * @key: the structure that contains the OpenPGP public key.
809 * @idx: is the subkey index
811 * Get subkey revocation status. A negative value indicates an error.
813 * Returns: true (1) if the key has been revoked, or false (0) if it
819 gnutls_openpgp_crt_get_subkey_revoked_status (gnutls_openpgp_crt_t key,
827 return GNUTLS_E_INVALID_REQUEST;
830 pkt = _get_public_subkey (key, idx);
832 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
834 if (pkt->pkt.public_key->is_revoked != 0)
840 * gnutls_openpgp_crt_get_subkey_pk_algorithm:
841 * @key: is an OpenPGP key
842 * @idx: is the subkey index
843 * @bits: if bits is non null it will hold the size of the parameters' in bits
845 * This function will return the public key algorithm of a subkey of an OpenPGP
848 * If bits is non null, it should have enough size to hold the
849 * parameters size in bits. For RSA the bits returned is the modulus.
850 * For DSA the bits returned are of the public exponent.
852 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
853 * success, or GNUTLS_PK_UNKNOWN on error.
857 gnutls_pk_algorithm_t
858 gnutls_openpgp_crt_get_subkey_pk_algorithm (gnutls_openpgp_crt_t key,
868 return GNUTLS_PK_UNKNOWN;
871 pkt = _get_public_subkey (key, idx);
877 *bits = cdk_pk_get_nbits (pkt->pkt.public_key);
878 algo = _gnutls_openpgp_get_algo (pkt->pkt.public_key->pubkey_algo);
885 * gnutls_openpgp_crt_get_subkey_creation_time:
886 * @key: the structure that contains the OpenPGP public key.
887 * @idx: the subkey index
889 * Get subkey creation time.
891 * Returns: the timestamp when the OpenPGP sub-key was created.
896 gnutls_openpgp_crt_get_subkey_creation_time (gnutls_openpgp_crt_t key,
905 pkt = _get_public_subkey (key, idx);
907 timestamp = pkt->pkt.public_key->timestamp;
916 * gnutls_openpgp_crt_get_subkey_expiration_time:
917 * @key: the structure that contains the OpenPGP public key.
918 * @idx: the subkey index
920 * Get subkey expiration time. A value of '0' means that the key
921 * doesn't expire at all.
923 * Returns: the time when the OpenPGP key expires.
928 gnutls_openpgp_crt_get_subkey_expiration_time (gnutls_openpgp_crt_t key,
937 pkt = _get_public_subkey (key, idx);
939 expiredate = pkt->pkt.public_key->expiredate;
947 * gnutls_openpgp_crt_get_subkey_id:
948 * @key: the structure that contains the OpenPGP public key.
949 * @idx: the subkey index
950 * @keyid: the buffer to save the keyid.
952 * Get the subkey's key-id.
954 * Returns: the 64-bit keyID of the OpenPGP key.
957 gnutls_openpgp_crt_get_subkey_id (gnutls_openpgp_crt_t key,
959 gnutls_openpgp_keyid_t keyid)
967 return GNUTLS_E_INVALID_REQUEST;
970 pkt = _get_public_subkey (key, idx);
972 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
974 cdk_pk_get_keyid (pkt->pkt.public_key, kid);
975 _gnutls_write_uint32 (kid[0], keyid);
976 _gnutls_write_uint32 (kid[1], keyid + 4);
982 * gnutls_openpgp_crt_get_subkey_fingerprint:
983 * @key: the raw data that contains the OpenPGP public key.
984 * @idx: the subkey index
985 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
986 * @fprlen: the integer to save the length of the fingerprint.
988 * Get key fingerprint of a subkey. Depending on the algorithm, the
989 * fingerprint can be 16 or 20 bytes.
991 * Returns: On success, 0 is returned. Otherwise, an error code.
996 gnutls_openpgp_crt_get_subkey_fingerprint (gnutls_openpgp_crt_t key,
998 void *fpr, size_t * fprlen)
1001 cdk_pkt_pubkey_t pk = NULL;
1003 if (!fpr || !fprlen)
1006 return GNUTLS_E_INVALID_REQUEST;
1011 pkt = _get_public_subkey (key, idx);
1013 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
1015 pk = pkt->pkt.public_key;
1018 /* FIXME: Check if the draft allows old PGP keys. */
1019 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
1021 cdk_pk_get_fingerprint (pk, fpr);
1027 * gnutls_openpgp_crt_get_subkey_idx:
1028 * @key: the structure that contains the OpenPGP public key.
1029 * @keyid: the keyid.
1031 * Get subkey's index.
1033 * Returns: the index of the subkey or a negative error value.
1038 gnutls_openpgp_crt_get_subkey_idx (gnutls_openpgp_crt_t key,
1039 const gnutls_openpgp_keyid_t keyid)
1047 return GNUTLS_E_INVALID_REQUEST;
1050 KEYID_IMPORT (kid, keyid);
1051 ret = _gnutls_openpgp_find_subkey_idx (key->knode, kid, 0);
1062 * gnutls_openpgp_crt_get_subkey_usage:
1063 * @key: should contain a gnutls_openpgp_crt_t structure
1064 * @idx: the subkey index
1065 * @key_usage: where the key usage bits will be stored
1067 * This function will return certificate's key usage, by checking the
1068 * key algorithm. The key usage value will ORed values of
1069 * %GNUTLS_KEY_DIGITAL_SIGNATURE or %GNUTLS_KEY_KEY_ENCIPHERMENT.
1071 * A negative value may be returned in case of parsing error.
1073 * Returns: key usage value.
1078 gnutls_openpgp_crt_get_subkey_usage (gnutls_openpgp_crt_t key,
1080 unsigned int *key_usage)
1087 return GNUTLS_E_INVALID_REQUEST;
1090 pkt = _get_public_subkey (key, idx);
1092 return GNUTLS_E_OPENPGP_SUBKEY_ERROR;
1094 *key_usage = _gnutls_get_pgp_key_usage (pkt->pkt.public_key->pubkey_usage);
1100 _gnutls_read_pgp_mpi (cdk_packet_t pkt, unsigned int priv, size_t idx,
1103 size_t buf_size = 512;
1104 opaque *buf = gnutls_malloc (buf_size);
1106 unsigned int max_pub_params = 0;
1109 max_pub_params = cdk_pk_get_npkey (pkt->pkt.secret_key->pk->pubkey_algo);
1114 return GNUTLS_E_MEMORY_ERROR;
1117 /* FIXME: Note that opencdk doesn't like the buf to be NULL.
1121 cdk_pk_get_mpi (pkt->pkt.public_key, idx, buf, buf_size, &buf_size,
1125 if (idx < max_pub_params)
1127 cdk_pk_get_mpi (pkt->pkt.secret_key->pk, idx, buf, buf_size,
1132 cdk_sk_get_mpi (pkt->pkt.secret_key, idx - max_pub_params, buf,
1133 buf_size, &buf_size, NULL);
1137 if (err == CDK_Too_Short)
1139 buf = gnutls_realloc_fast (buf, buf_size);
1143 return GNUTLS_E_MEMORY_ERROR;
1148 cdk_pk_get_mpi (pkt->pkt.public_key, idx, buf, buf_size, &buf_size,
1152 if (idx < max_pub_params)
1154 cdk_pk_get_mpi (pkt->pkt.secret_key->pk, idx, buf, buf_size,
1159 cdk_sk_get_mpi (pkt->pkt.secret_key, idx - max_pub_params,
1160 buf, buf_size, &buf_size, NULL);
1165 if (err != CDK_Success)
1169 return _gnutls_map_cdk_rc (err);
1172 err = _gnutls_mpi_scan (m, buf, buf_size);
1185 /* Extracts DSA and RSA parameters from a certificate.
1188 _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert,
1189 uint32_t * keyid /* [2] */ ,
1190 bigint_t * params, int *params_size)
1193 int pk_algorithm, local_params;
1197 pkt = cdk_kbnode_find_packet (cert->knode, CDK_PKT_PUBLIC_KEY);
1199 pkt = _gnutls_openpgp_find_key (cert->knode, keyid, 0);
1204 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
1207 pk_algorithm = _gnutls_openpgp_get_algo (pkt->pkt.public_key->pubkey_algo);
1209 switch (pk_algorithm)
1212 local_params = RSA_PUBLIC_PARAMS;
1215 local_params = DSA_PUBLIC_PARAMS;
1219 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1222 if (*params_size < local_params)
1225 return GNUTLS_E_INTERNAL_ERROR;
1228 *params_size = local_params;
1230 for (i = 0; i < local_params; i++)
1232 result = _gnutls_read_pgp_mpi (pkt, 0, i, ¶ms[i]);
1245 for (j = 0; j < i; j++)
1246 _gnutls_mpi_release (¶ms[j]);
1252 /* The internal version of export
1255 _get_pk_rsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
1256 gnutls_datum_t * m, gnutls_datum_t * e)
1258 int pk_algorithm, ret, i;
1261 bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
1262 int params_size = MAX_PUBLIC_PARAMS_SIZE;
1267 return GNUTLS_E_INVALID_REQUEST;
1270 KEYID_IMPORT (kid32, keyid);
1272 pkt = _gnutls_openpgp_find_key (crt->knode, kid32, 0);
1276 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
1279 pk_algorithm = _gnutls_openpgp_get_algo (pkt->pkt.public_key->pubkey_algo);
1281 if (pk_algorithm != GNUTLS_PK_RSA)
1284 return GNUTLS_E_INVALID_REQUEST;
1287 ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, ¶ms_size);
1294 ret = _gnutls_mpi_dprint (params[0], m);
1301 ret = _gnutls_mpi_dprint (params[1], e);
1305 _gnutls_free_datum (m);
1312 for (i = 0; i < params_size; i++)
1314 _gnutls_mpi_release (¶ms[i]);
1320 _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid,
1321 gnutls_datum_t * p, gnutls_datum_t * q,
1322 gnutls_datum_t * g, gnutls_datum_t * y)
1324 int pk_algorithm, ret, i;
1327 bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
1328 int params_size = MAX_PUBLIC_PARAMS_SIZE;
1333 return GNUTLS_E_INVALID_REQUEST;
1336 KEYID_IMPORT (kid32, keyid);
1338 pkt = _gnutls_openpgp_find_key (crt->knode, kid32, 0);
1342 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
1345 pk_algorithm = _gnutls_openpgp_get_algo (pkt->pkt.public_key->pubkey_algo);
1347 if (pk_algorithm != GNUTLS_PK_DSA)
1350 return GNUTLS_E_INVALID_REQUEST;
1353 ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, ¶ms_size);
1361 ret = _gnutls_mpi_dprint (params[0], p);
1369 ret = _gnutls_mpi_dprint (params[1], q);
1373 _gnutls_free_datum (p);
1379 ret = _gnutls_mpi_dprint (params[2], g);
1383 _gnutls_free_datum (p);
1384 _gnutls_free_datum (q);
1390 ret = _gnutls_mpi_dprint (params[3], y);
1394 _gnutls_free_datum (p);
1395 _gnutls_free_datum (g);
1396 _gnutls_free_datum (q);
1403 for (i = 0; i < params_size; i++)
1405 _gnutls_mpi_release (¶ms[i]);
1412 * gnutls_openpgp_crt_get_pk_rsa_raw:
1413 * @crt: Holds the certificate
1414 * @m: will hold the modulus
1415 * @e: will hold the public exponent
1417 * This function will export the RSA public key's parameters found in
1418 * the given structure. The new parameters will be allocated using
1419 * gnutls_malloc() and will be stored in the appropriate datum.
1421 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1426 gnutls_openpgp_crt_get_pk_rsa_raw (gnutls_openpgp_crt_t crt,
1427 gnutls_datum_t * m, gnutls_datum_t * e)
1429 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1432 ret = gnutls_openpgp_crt_get_key_id (crt, keyid);
1439 return _get_pk_rsa_raw (crt, keyid, m, e);
1443 * gnutls_openpgp_crt_get_pk_dsa_raw:
1444 * @crt: Holds the certificate
1445 * @p: will hold the p
1446 * @q: will hold the q
1447 * @g: will hold the g
1448 * @y: will hold the y
1450 * This function will export the DSA public key's parameters found in
1451 * the given certificate. The new parameters will be allocated using
1452 * gnutls_malloc() and will be stored in the appropriate datum.
1454 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1459 gnutls_openpgp_crt_get_pk_dsa_raw (gnutls_openpgp_crt_t crt,
1460 gnutls_datum_t * p, gnutls_datum_t * q,
1461 gnutls_datum_t * g, gnutls_datum_t * y)
1463 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1466 ret = gnutls_openpgp_crt_get_key_id (crt, keyid);
1473 return _get_pk_dsa_raw (crt, keyid, p, q, g, y);
1477 * gnutls_openpgp_crt_get_subkey_pk_rsa_raw:
1478 * @crt: Holds the certificate
1479 * @idx: Is the subkey index
1480 * @m: will hold the modulus
1481 * @e: will hold the public exponent
1483 * This function will export the RSA public key's parameters found in
1484 * the given structure. The new parameters will be allocated using
1485 * gnutls_malloc() and will be stored in the appropriate datum.
1487 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1492 gnutls_openpgp_crt_get_subkey_pk_rsa_raw (gnutls_openpgp_crt_t crt,
1497 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1500 ret = gnutls_openpgp_crt_get_subkey_id (crt, idx, keyid);
1507 return _get_pk_rsa_raw (crt, keyid, m, e);
1511 * gnutls_openpgp_crt_get_subkey_pk_dsa_raw:
1512 * @crt: Holds the certificate
1513 * @idx: Is the subkey index
1514 * @p: will hold the p
1515 * @q: will hold the q
1516 * @g: will hold the g
1517 * @y: will hold the y
1519 * This function will export the DSA public key's parameters found in
1520 * the given certificate. The new parameters will be allocated using
1521 * gnutls_malloc() and will be stored in the appropriate datum.
1523 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
1528 gnutls_openpgp_crt_get_subkey_pk_dsa_raw (gnutls_openpgp_crt_t crt,
1535 uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
1538 ret = gnutls_openpgp_crt_get_subkey_id (crt, idx, keyid);
1545 return _get_pk_dsa_raw (crt, keyid, p, q, g, y);
1549 * gnutls_openpgp_crt_get_preferred_key_id:
1550 * @key: the structure that contains the OpenPGP public key.
1551 * @keyid: the struct to save the keyid.
1553 * Get preferred key id. If it hasn't been set it returns
1554 * %GNUTLS_E_INVALID_REQUEST.
1556 * Returns: the 64-bit preferred keyID of the OpenPGP key.
1559 gnutls_openpgp_crt_get_preferred_key_id (gnutls_openpgp_crt_t key,
1560 gnutls_openpgp_keyid_t keyid)
1562 if (!key->preferred_set)
1563 return gnutls_assert_val(GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR);
1568 return GNUTLS_E_INVALID_REQUEST;
1571 memcpy (keyid, key->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE);
1577 * gnutls_openpgp_crt_set_preferred_key_id:
1578 * @key: the structure that contains the OpenPGP public key.
1579 * @keyid: the selected keyid
1581 * This allows setting a preferred key id for the given certificate.
1582 * This key will be used by functions that involve key handling.
1584 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
1585 * otherwise an error code is returned.
1588 gnutls_openpgp_crt_set_preferred_key_id (gnutls_openpgp_crt_t key,
1589 const gnutls_openpgp_keyid_t keyid)
1596 return GNUTLS_E_INVALID_REQUEST;
1599 /* check if the id is valid */
1600 ret = gnutls_openpgp_crt_get_subkey_idx (key, keyid);
1603 _gnutls_x509_log ("the requested subkey does not exist\n");
1608 key->preferred_set = 1;
1609 memcpy (key->preferred_keyid, keyid, GNUTLS_OPENPGP_KEYID_SIZE);
1615 * gnutls_openpgp_crt_get_auth_subkey:
1616 * @crt: the structure that contains the OpenPGP public key.
1617 * @keyid: the struct to save the keyid.
1618 * @flag: Non zero indicates that a valid subkey is always returned.
1620 * Returns the 64-bit keyID of the first valid OpenPGP subkey marked
1621 * for authentication. If flag is non zero and no authentication
1622 * subkey exists, then a valid subkey will be returned even if it is
1623 * not marked for authentication.
1624 * Returns the 64-bit keyID of the first valid OpenPGP subkey marked
1625 * for authentication. If flag is non zero and no authentication
1626 * subkey exists, then a valid subkey will be returned even if it is
1627 * not marked for authentication.
1629 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1632 gnutls_openpgp_crt_get_auth_subkey (gnutls_openpgp_crt_t crt,
1633 gnutls_openpgp_keyid_t keyid,
1636 int ret, subkeys, i;
1638 unsigned int keyid_init = 0;
1640 subkeys = gnutls_openpgp_crt_get_subkey_count (crt);
1644 return GNUTLS_E_OPENPGP_SUBKEY_ERROR;
1647 /* Try to find a subkey with the authentication flag set.
1648 * if none exists use the last one found
1650 for (i = 0; i < subkeys; i++)
1652 ret = gnutls_openpgp_crt_get_subkey_pk_algorithm(crt, i, NULL);
1653 if (ret == GNUTLS_PK_UNKNOWN)
1656 ret = gnutls_openpgp_crt_get_subkey_revoked_status (crt, i);
1657 if (ret != 0) /* it is revoked. ignore it */
1660 if (keyid_init == 0)
1661 { /* keep the first valid subkey */
1662 ret = gnutls_openpgp_crt_get_subkey_id (crt, i, keyid);
1672 ret = gnutls_openpgp_crt_get_subkey_usage (crt, i, &usage);
1679 if (usage & GNUTLS_KEY_KEY_AGREEMENT)
1681 ret = gnutls_openpgp_crt_get_subkey_id (crt, i, keyid);
1691 if (flag && keyid_init)
1694 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;