corrected copyright notices
[gnutls.git] / lib / openpgp / extras.c
blob4a4c8a0d490857ba07f262ba49a4f9c927d3f75f
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos, Timo Schulz
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 keyring parsing
26 #include <gnutls_int.h>
27 #include <gnutls_datum.h>
28 #include <gnutls_global.h>
29 #include <gnutls_errors.h>
30 #include <openpgp_int.h>
31 #include <gnutls_openpgp.h>
32 #include <gnutls_num.h>
34 /* Keyring stuff.
37 /**
38 * gnutls_openpgp_keyring_init:
39 * @keyring: The structure to be initialized
41 * This function will initialize an keyring structure.
43 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
44 **/
45 int
46 gnutls_openpgp_keyring_init (gnutls_openpgp_keyring_t * keyring)
48 *keyring = gnutls_calloc (1, sizeof (gnutls_openpgp_keyring_int));
50 if (*keyring)
51 return 0; /* success */
52 return GNUTLS_E_MEMORY_ERROR;
56 /**
57 * gnutls_openpgp_keyring_deinit:
58 * @keyring: The structure to be initialized
60 * This function will deinitialize a keyring structure.
61 **/
62 void
63 gnutls_openpgp_keyring_deinit (gnutls_openpgp_keyring_t keyring)
65 if (!keyring)
66 return;
68 if (keyring->db)
70 cdk_keydb_free (keyring->db);
71 keyring->db = NULL;
74 gnutls_free (keyring);
77 /**
78 * gnutls_openpgp_keyring_check_id:
79 * @ring: holds the keyring to check against
80 * @keyid: will hold the keyid to check for.
81 * @flags: unused (should be 0)
83 * Check if a given key ID exists in the keyring.
85 * Returns: %GNUTLS_E_SUCCESS on success (if keyid exists) and a
86 * negative error code on failure.
87 **/
88 int
89 gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring,
90 const gnutls_openpgp_keyid_t keyid,
91 unsigned int flags)
93 cdk_pkt_pubkey_t pk;
94 uint32_t id[2];
96 id[0] = _gnutls_read_uint32 (keyid);
97 id[1] = _gnutls_read_uint32 (&keyid[4]);
99 if (!cdk_keydb_get_pk (ring->db, id, &pk))
101 cdk_pk_release (pk);
102 return 0;
105 _gnutls_debug_log ("PGP: key not found %08lX\n", (unsigned long) id[1]);
106 return GNUTLS_E_NO_CERTIFICATE_FOUND;
110 * gnutls_openpgp_keyring_import:
111 * @keyring: The structure to store the parsed key.
112 * @data: The RAW or BASE64 encoded keyring.
113 * @format: One of #gnutls_openpgp_keyring_fmt elements.
115 * This function will convert the given RAW or Base64 encoded keyring
116 * to the native #gnutls_openpgp_keyring_t format. The output will be
117 * stored in 'keyring'.
119 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
122 gnutls_openpgp_keyring_import (gnutls_openpgp_keyring_t keyring,
123 const gnutls_datum_t * data,
124 gnutls_openpgp_crt_fmt_t format)
126 cdk_error_t err;
127 cdk_stream_t input = NULL;
128 size_t raw_len = 0;
129 uint8_t *raw_data = NULL;
131 if (data->data == NULL || data->size == 0)
133 gnutls_assert ();
134 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
137 _gnutls_debug_log ("PGP: keyring import format '%s'\n",
138 format == GNUTLS_OPENPGP_FMT_RAW ? "raw" : "base64");
140 /* Create a new stream from the given data, decode it, and import
141 * the raw database. This to avoid using opencdk streams which are
142 * not thread safe.
144 if (format == GNUTLS_OPENPGP_FMT_BASE64)
146 size_t written = 0;
148 err = cdk_stream_tmp_from_mem (data->data, data->size, &input);
149 if (err == 0)
150 err = cdk_stream_set_armor_flag (input, 0);
151 if (err)
153 gnutls_assert ();
154 err = _gnutls_map_cdk_rc (err);
155 goto error;
158 raw_len = cdk_stream_get_length (input);
159 if (raw_len == 0)
161 gnutls_assert ();
162 err = GNUTLS_E_BASE64_DECODING_ERROR;
163 goto error;
166 raw_data = gnutls_malloc (raw_len);
167 if (raw_data == NULL)
169 gnutls_assert ();
170 err = GNUTLS_E_MEMORY_ERROR;
171 goto error;
176 err =
177 cdk_stream_read (input, raw_data + written, raw_len - written);
179 if (err > 0)
180 written += err;
182 while (written < raw_len && err != EOF && err > 0);
184 raw_len = written;
186 else
187 { /* RAW */
188 raw_len = data->size;
189 raw_data = data->data;
192 err = cdk_keydb_new_from_mem (&keyring->db, 0, 0, raw_data, raw_len);
193 if (err)
194 gnutls_assert ();
196 return _gnutls_map_cdk_rc (err);
198 error:
199 gnutls_free (raw_data);
200 cdk_stream_close (input);
202 return err;
205 #define knode_is_pkey(node) \
206 cdk_kbnode_find_packet (node, CDK_PKT_PUBLIC_KEY)!=NULL
209 * gnutls_openpgp_keyring_get_crt_count:
210 * @ring: is an OpenPGP key ring
212 * This function will return the number of OpenPGP certificates
213 * present in the given keyring.
215 * Returns: the number of subkeys, or a negative error code on error.
218 gnutls_openpgp_keyring_get_crt_count (gnutls_openpgp_keyring_t ring)
220 cdk_kbnode_t knode;
221 cdk_error_t err;
222 cdk_keydb_search_t st;
223 int ret = 0;
225 err = cdk_keydb_search_start (&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
226 if (err != CDK_Success)
228 gnutls_assert ();
229 return _gnutls_map_cdk_rc (err);
234 err = cdk_keydb_search (st, ring->db, &knode);
235 if (err != CDK_Error_No_Key && err != CDK_Success)
237 gnutls_assert ();
238 cdk_keydb_search_release (st);
239 return _gnutls_map_cdk_rc (err);
242 if (knode_is_pkey (knode))
243 ret++;
245 cdk_kbnode_release (knode);
248 while (err != CDK_Error_No_Key);
250 cdk_keydb_search_release (st);
251 return ret;
255 * gnutls_openpgp_keyring_get_crt:
256 * @ring: Holds the keyring.
257 * @idx: the index of the certificate to export
258 * @cert: An uninitialized #gnutls_openpgp_crt_t structure
260 * This function will extract an OpenPGP certificate from the given
261 * keyring. If the index given is out of range
262 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. The
263 * returned structure needs to be deinited.
265 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
268 gnutls_openpgp_keyring_get_crt (gnutls_openpgp_keyring_t ring,
269 unsigned int idx, gnutls_openpgp_crt_t * cert)
271 cdk_kbnode_t knode;
272 cdk_error_t err;
273 int ret = 0;
274 unsigned int count = 0;
275 cdk_keydb_search_t st;
277 err = cdk_keydb_search_start (&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
278 if (err != CDK_Success)
280 gnutls_assert ();
281 return _gnutls_map_cdk_rc (err);
286 err = cdk_keydb_search (st, ring->db, &knode);
287 if (err != CDK_EOF && err != CDK_Success)
289 gnutls_assert ();
290 cdk_keydb_search_release (st);
291 return _gnutls_map_cdk_rc (err);
294 if (idx == count && err == CDK_Success)
296 ret = gnutls_openpgp_crt_init (cert);
297 if (ret == 0)
298 (*cert)->knode = knode;
299 cdk_keydb_search_release (st);
300 return ret;
303 if (knode_is_pkey (knode))
304 count++;
306 cdk_kbnode_release (knode);
309 while (err != CDK_EOF);
311 cdk_keydb_search_release (st);
312 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;