+/* Checks if the extra_certs contain certificates that may form a chain
+ * with the first certificate in chain (it is expected that chain_len==1)
+ * and appends those in the chain.
+ */
+static int make_chain(gnutls_x509_crt_t **chain, unsigned int *chain_len,
+ gnutls_x509_crt_t **extra_certs, unsigned int *extra_certs_len)
+{
+unsigned int i;
+
+ if (*chain_len != 1)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ i = 0;
+ while(i<*extra_certs_len)
+ {
+ /* if it is an issuer but not a self-signed one */
+ if (gnutls_x509_crt_check_issuer((*chain)[*chain_len - 1], (*extra_certs)[i]) != 0 &&
+ gnutls_x509_crt_check_issuer((*extra_certs)[i], (*extra_certs)[i]) == 0)
+ {
+ *chain = gnutls_realloc (*chain, sizeof((*chain)[0]) *
+ ++(*chain_len));
+ if (*chain == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ (*chain)[*chain_len - 1] = (*extra_certs)[i];
+
+ (*extra_certs)[i] = (*extra_certs)[*extra_certs_len-1];
+ (*extra_certs_len)--;
+
+ i=0;
+ continue;
+ }
+ i++;
+ }
+ return 0;
+}
+
+/**
+ * gnutls_pkcs12_simple_parse:
+ * @p12: the PKCS#12 blob.
+ * @password: optional password used to decrypt PKCS#12 blob, bags and keys.
+ * @key: a structure to store the parsed private key.
+ * @chain: the corresponding to key certificate chain
+ * @chain_len: will be updated with the number of additional
+ * @extra_certs: optional pointer to receive an array of additional
+ * certificates found in the PKCS#12 blob.
+ * @extra_certs_len: will be updated with the number of additional
+ * certs.
+ * @crl: an optional structure to store the parsed CRL.
+ * @flags: should be zero
+ *
+ * This function parses a PKCS#12 blob in @p12blob and extracts the
+ * private key, the corresponding certificate chain, and any additional
+ * certificates and a CRL.
+ *
+ * The @extra_certs_ret and @extra_certs_ret_len parameters are optional
+ * and both may be set to %NULL. If either is non-%NULL, then both must
+ * be.
+ *
+ * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
+ * supported. Encrypted PKCS#8 private keys are supported. However,
+ * only password based security, and the same password for all
+ * operations, are supported.
+ *
+ * The private keys may be RSA PKCS#1 or DSA private keys encoded in
+ * the OpenSSL way.
+ *
+ * PKCS#12 file may contain many keys and/or certificates, and there
+ * is no way to identify which key/certificate pair you want. You
+ * should make sure the PKCS#12 file only contain one key/certificate
+ * pair and/or one CRL.
+ *
+ * It is believed that the limitations of this function is acceptable
+ * for most usage, and that any more flexibility would introduce
+ * complexity that would make it harder to use this functionality at
+ * all.
+ *
+ * If the provided structure has encrypted fields but no password
+ * is provided then this function returns %GNUTLS_E_DECRYPTION_FAILED.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since: 3.1
+ **/
+int
+gnutls_pkcs12_simple_parse (gnutls_pkcs12_t p12,
+ const char *password,
+ gnutls_x509_privkey_t * key,
+ gnutls_x509_crt_t ** chain,
+ unsigned int * chain_len,
+ gnutls_x509_crt_t ** extra_certs,
+ unsigned int * extra_certs_len,
+ gnutls_x509_crl_t * crl,
+ unsigned int flags)