2 * Ick. This is (or at least started off as) a straight copy of
3 * parse_pkcs12() from GnuTLS lib/gnutls_x509.c, as of commit ID
4 * 77670476814c078bbad56ce8772b192a3b5736b6 on the gnutls_2_12_x
7 * We need to *see* the cert so that we can check its expiry, and
8 * we'll also want to get all the other certs in the PKCS#12 file
9 * rather than only the leaf node. Hopefully these changes can be
10 * merged back into GnuTLS as soon as possible, it can be made a
11 * public function, and this copy can die.
13 #define opaque unsigned char
14 #define gnutls_assert() do {} while(0)
17 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
18 * Free Software Foundation, Inc.
20 * Author: Nikos Mavrogiannopoulos
22 * This file WAS part of GnuTLS.
24 * The GnuTLS is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU Lesser General Public License
26 * as published by the Free Software Foundation; either version 2.1 of
27 * the License, or (at your option) any later version.
29 * This library is distributed in the hope that it will be useful, but
30 * WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32 * Lesser General Public License for more details.
34 * You should have received a copy of the GNU Lesser General Public
35 * License along with this library; if not, write to the Free Software
36 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
43 parse_pkcs12 (gnutls_certificate_credentials_t res,
46 gnutls_x509_privkey_t * key,
47 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
49 gnutls_pkcs12_bag_t bag = NULL;
52 size_t cert_id_size = 0;
53 size_t key_id_size = 0;
62 /* find the first private key */
68 ret = gnutls_pkcs12_bag_init (&bag);
76 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
77 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
85 ret = gnutls_pkcs12_bag_get_type (bag, 0);
92 if (ret == GNUTLS_BAG_ENCRYPTED)
94 ret = gnutls_pkcs12_bag_decrypt (bag, password);
102 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
103 if (elements_in_bag < 0)
109 for (i = 0; i < elements_in_bag; i++)
114 type = gnutls_pkcs12_bag_get_type (bag, i);
121 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
130 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
131 case GNUTLS_BAG_PKCS8_KEY:
132 if (*key != NULL) /* too simple to continue */
138 ret = gnutls_x509_privkey_init (key);
145 ret = gnutls_x509_privkey_import_pkcs8
146 (*key, &data, GNUTLS_X509_FMT_DER, password,
147 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
151 gnutls_x509_privkey_deinit (*key);
155 key_id_size = sizeof (key_id);
157 gnutls_x509_privkey_get_key_id (*key, 0, key_id,
162 gnutls_x509_privkey_deinit (*key);
166 privkey_ok = 1; /* break */
174 gnutls_pkcs12_bag_deinit (bag);
176 if (privkey_ok != 0) /* private key was found */
180 if (privkey_ok == 0) /* no private key */
183 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
186 /* now find the corresponding certificate
195 ret = gnutls_pkcs12_bag_init (&bag);
203 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
204 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
212 ret = gnutls_pkcs12_bag_get_type (bag, 0);
219 if (ret == GNUTLS_BAG_ENCRYPTED)
221 ret = gnutls_pkcs12_bag_decrypt (bag, password);
229 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
230 if (elements_in_bag < 0)
236 for (i = 0; i < elements_in_bag; i++)
241 type = gnutls_pkcs12_bag_get_type (bag, i);
248 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
257 case GNUTLS_BAG_CERTIFICATE:
258 if (*cert != NULL) /* no need to set it again */
264 ret = gnutls_x509_crt_init (cert);
272 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
276 gnutls_x509_crt_deinit (*cert);
280 /* check if the key id match */
281 cert_id_size = sizeof (cert_id);
283 gnutls_x509_crt_get_key_id (*cert, 0, cert_id, &cert_id_size);
287 gnutls_x509_crt_deinit (*cert);
291 if (memcmp (cert_id, key_id, cert_id_size) != 0)
292 { /* they don't match - skip the certificate */
293 gnutls_x509_crt_deinit (*cert);
305 ret = gnutls_x509_crl_init (crl);
312 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
316 gnutls_x509_crl_deinit (*crl);
321 case GNUTLS_BAG_ENCRYPTED:
322 /* XXX Bother to recurse one level down? Unlikely to
323 use the same password anyway. */
324 case GNUTLS_BAG_EMPTY:
331 gnutls_pkcs12_bag_deinit (bag);
338 gnutls_pkcs12_bag_deinit (bag);