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>
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.
46 gnutls_openpgp_keyring_init (gnutls_openpgp_keyring_t
* keyring
)
48 *keyring
= gnutls_calloc (1, sizeof (gnutls_openpgp_keyring_int
));
51 return 0; /* success */
52 return GNUTLS_E_MEMORY_ERROR
;
57 * gnutls_openpgp_keyring_deinit:
58 * @keyring: The structure to be initialized
60 * This function will deinitialize a keyring structure.
63 gnutls_openpgp_keyring_deinit (gnutls_openpgp_keyring_t keyring
)
70 cdk_keydb_free (keyring
->db
);
74 gnutls_free (keyring
);
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.
89 gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring
,
90 const gnutls_openpgp_keyid_t keyid
,
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
))
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
)
127 cdk_stream_t input
= NULL
;
129 uint8_t *raw_data
= NULL
;
131 if (data
->data
== NULL
|| data
->size
== 0)
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
144 if (format
== GNUTLS_OPENPGP_FMT_BASE64
)
148 err
= cdk_stream_tmp_from_mem (data
->data
, data
->size
, &input
);
150 err
= cdk_stream_set_armor_flag (input
, 0);
154 err
= _gnutls_map_cdk_rc (err
);
158 raw_len
= cdk_stream_get_length (input
);
162 err
= GNUTLS_E_BASE64_DECODING_ERROR
;
166 raw_data
= gnutls_malloc (raw_len
);
167 if (raw_data
== NULL
)
170 err
= GNUTLS_E_MEMORY_ERROR
;
177 cdk_stream_read (input
, raw_data
+ written
, raw_len
- written
);
182 while (written
< raw_len
&& err
!= EOF
&& err
> 0);
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
);
196 return _gnutls_map_cdk_rc (err
);
199 gnutls_free (raw_data
);
200 cdk_stream_close (input
);
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
)
222 cdk_keydb_search_t st
;
225 err
= cdk_keydb_search_start (&st
, ring
->db
, CDK_DBSEARCH_NEXT
, NULL
);
226 if (err
!= CDK_Success
)
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
)
238 cdk_keydb_search_release (st
);
239 return _gnutls_map_cdk_rc (err
);
242 if (knode_is_pkey (knode
))
245 cdk_kbnode_release (knode
);
248 while (err
!= CDK_Error_No_Key
);
250 cdk_keydb_search_release (st
);
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
)
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
)
281 return _gnutls_map_cdk_rc (err
);
286 err
= cdk_keydb_search (st
, ring
->db
, &knode
);
287 if (err
!= CDK_EOF
&& err
!= CDK_Success
)
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
);
298 (*cert
)->knode
= knode
;
299 cdk_keydb_search_release (st
);
303 if (knode_is_pkey (knode
))
306 cdk_kbnode_release (knode
);
309 while (err
!= CDK_EOF
);
311 cdk_keydb_search_release (st
);
312 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;