예제 #1
0
파일: crl.c 프로젝트: randombit/hacrypto
/**
 * gnutls_x509_crl_list_import:
 * @crls: The structures to store the parsed CRLs. Must not be initialized.
 * @crl_max: Initially must hold the maximum number of crls. It will be updated with the number of crls available.
 * @data: The PEM encoded CRLs
 * @format: One of DER or PEM.
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
 *
 * This function will convert the given PEM encoded CRL list
 * to the native gnutls_x509_crl_t format. The output will be stored
 * in @crls.  They will be automatically initialized.
 *
 * If the Certificate is PEM encoded it should have a header of "X509 CRL".
 *
 * Returns: the number of certificates read or a negative error value.
 *
 * Since: 3.0
 **/
int
gnutls_x509_crl_list_import(gnutls_x509_crl_t * crls,
			    unsigned int *crl_max,
			    const gnutls_datum_t * data,
			    gnutls_x509_crt_fmt_t format,
			    unsigned int flags)
{
	int size;
	const char *ptr;
	gnutls_datum_t tmp;
	int ret, nocopy = 0;
	unsigned int count = 0, j;

	if (format == GNUTLS_X509_FMT_DER) {
		if (*crl_max < 1) {
			*crl_max = 1;
			return GNUTLS_E_SHORT_MEMORY_BUFFER;
		}

		count = 1;	/* import only the first one */

		ret = gnutls_x509_crl_init(&crls[0]);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		ret = gnutls_x509_crl_import(crls[0], data, format);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		*crl_max = 1;
		return 1;
	}

	/* move to the certificate
	 */
	ptr = memmem(data->data, data->size,
		     PEM_CRL_SEP, sizeof(PEM_CRL_SEP) - 1);
	if (ptr == NULL) {
		gnutls_assert();
		return GNUTLS_E_BASE64_DECODING_ERROR;
	}

	count = 0;

	do {
		if (count >= *crl_max) {
			if (!
			    (flags &
			     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
				break;
			else
				nocopy = 1;
		}

		if (!nocopy) {
			ret = gnutls_x509_crl_init(&crls[count]);
			if (ret < 0) {
				gnutls_assert();
				goto error;
			}

			tmp.data = (void *) ptr;
			tmp.size =
			    data->size - (ptr - (char *) data->data);

			ret =
			    gnutls_x509_crl_import(crls[count], &tmp,
						   GNUTLS_X509_FMT_PEM);
			if (ret < 0) {
				gnutls_assert();
				goto error;
			}
		}

		/* now we move ptr after the pem header 
		 */
		ptr++;
		/* find the next certificate (if any)
		 */
		size = data->size - (ptr - (char *) data->data);

		if (size > 0) {
			ptr =
			    memmem(ptr, size, PEM_CRL_SEP,
				   sizeof(PEM_CRL_SEP) - 1);
		} else
			ptr = NULL;

		count++;
	}
	while (ptr != NULL);

	*crl_max = count;

	if (nocopy == 0)
		return count;
	else
		return GNUTLS_E_SHORT_MEMORY_BUFFER;

      error:
	for (j = 0; j < count; j++)
		gnutls_x509_crl_deinit(crls[j]);
	return ret;
}
예제 #2
0
/*-
 * gnutls_x509_verify_certificate:
 * @cert_list: is the certificate list to be verified
 * @cert_list_length: holds the number of certificate in cert_list
 * @CA_list: is the CA list which will be used in verification
 * @CA_list_length: holds the number of CA certificate in CA_list
 * @CRL_list: not used
 * @CRL_list_length: not used
 *
 * This function will try to verify the given certificate list and
 * return its status (TRUSTED, EXPIRED etc.).  The return value
 * (status) should be one or more of the gnutls_certificate_status_t
 * enumerated elements bitwise or'd. Note that expiration and
 * activation dates are not checked by this function, you should
 * check them using the appropriate functions.
 *
 * This function understands the basicConstraints (2.5.29.19) PKIX
 * extension.  This means that only a certificate authority can sign
 * a certificate.
 *
 * However you must also check the peer's name in order to check if
 * the verified certificate belongs to the actual peer.
 *
 * The return value (status) should be one or more of the
 * gnutls_certificate_status_t enumerated elements bitwise or'd.
 *
 * GNUTLS_CERT_INVALID: the peer's certificate is not valid.
 *
 * GNUTLS_CERT_REVOKED: the certificate has been revoked.
 *
 * A negative error code is returned in case of an error.
 * GNUTLS_E_NO_CERTIFICATE_FOUND is returned to indicate that
 * no certificate was sent by the peer.
 -*/
int
gnutls_x509_verify_certificate (const gnutls_datum_t * cert_list,
				int cert_list_length,
				const gnutls_datum_t * CA_list,
				int CA_list_length,
				const gnutls_datum_t * CRL_list,
				int CRL_list_length)
{
  unsigned int verify;
  gnutls_x509_crt_t *peer_certificate_list = NULL;
  gnutls_x509_crt_t *ca_certificate_list = NULL;
  gnutls_x509_crl_t *crl_list = NULL;
  int peer_certificate_list_size = 0, i, x, ret;
  int ca_certificate_list_size = 0, crl_list_size = 0;

  if (cert_list == NULL || cert_list_length == 0)
    return GNUTLS_E_NO_CERTIFICATE_FOUND;

  /* generate a list of gnutls_certs based on the auth info
   * raw certs.
   */
  peer_certificate_list_size = cert_list_length;
  peer_certificate_list =
    gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
  if (peer_certificate_list == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  ca_certificate_list_size = CA_list_length;
  ca_certificate_list =
    gnutls_calloc (ca_certificate_list_size, sizeof (gnutls_x509_crt_t));
  if (ca_certificate_list == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  /* allocate memory for CRL
   */
  crl_list_size = CRL_list_length;
  crl_list = gnutls_calloc (crl_list_size, sizeof (gnutls_x509_crl_t));
  if (crl_list == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  /* convert certA_list to gnutls_cert* list
   */
  for (i = 0; i < peer_certificate_list_size; i++)
    {
      ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

      ret =
	gnutls_x509_crt_import (peer_certificate_list[i],
				&cert_list[i], GNUTLS_X509_FMT_DER);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
    }

  /* convert CA_list to gnutls_x509_cert* list
   */
  for (i = 0; i < ca_certificate_list_size; i++)
    {
      ret = gnutls_x509_crt_init (&ca_certificate_list[i]);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

      ret =
	gnutls_x509_crt_import (ca_certificate_list[i],
				&CA_list[i], GNUTLS_X509_FMT_DER);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
    }

#ifdef ENABLE_PKI
  /* convert CRL_list to gnutls_x509_crl* list
   */
  for (i = 0; i < crl_list_size; i++)
    {
      ret = gnutls_x509_crl_init (&crl_list[i]);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

      ret =
	gnutls_x509_crl_import (crl_list[i],
				&CRL_list[i], GNUTLS_X509_FMT_DER);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
    }
#endif

  /* Verify certificate 
   */
  ret =
    gnutls_x509_crt_list_verify (peer_certificate_list,
				 peer_certificate_list_size,
				 ca_certificate_list,
				 ca_certificate_list_size, crl_list,
				 crl_list_size, 0, &verify);

  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  ret = verify;

cleanup:

  if (peer_certificate_list != NULL)
    for (x = 0; x < peer_certificate_list_size; x++)
      {
	if (peer_certificate_list[x] != NULL)
	  gnutls_x509_crt_deinit (peer_certificate_list[x]);
      }

  if (ca_certificate_list != NULL)
    for (x = 0; x < ca_certificate_list_size; x++)
      {
	if (ca_certificate_list[x] != NULL)
	  gnutls_x509_crt_deinit (ca_certificate_list[x]);
      }
#ifdef ENABLE_PKI
  if (crl_list != NULL)
    for (x = 0; x < crl_list_size; x++)
      {
	if (crl_list[x] != NULL)
	  gnutls_x509_crl_deinit (crl_list[x]);
      }

  gnutls_free (crl_list);
#endif

  gnutls_free (ca_certificate_list);
  gnutls_free (peer_certificate_list);

  return ret;
}
예제 #3
0
void doit(void)
{
	int exit_val = 0;
	size_t i;
	int ret;
	gnutls_x509_trust_list_t tl;
	unsigned int verify_status;
	gnutls_x509_crl_t crl;
	gnutls_x509_crt_t ca;
	gnutls_datum_t tmp;

	/* The overloading of time() seems to work in linux (ELF?)
	 * systems only. Disable it on windows.
	 */
#ifdef _WIN32
	exit(77);
#endif

	ret = global_init();
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	gnutls_global_set_time_function(mytime);
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	for (i = 0; crl_list[i].name; i++) {

		if (debug)
			printf("Chain '%s' (%d)...\n", crl_list[i].name,
			       (int) i);

		if (debug > 2)
			printf("\tAdding CRL...");

		ret = gnutls_x509_crl_init(&crl);
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_x509_crl_init[%d]: %s\n",
				(int) i,
				gnutls_strerror(ret));
			exit(1);
		}

		tmp.data = (unsigned char *) *crl_list[i].crl;
		tmp.size = strlen(*crl_list[i].crl);

		ret =
		    gnutls_x509_crl_import(crl, &tmp,
					   GNUTLS_X509_FMT_PEM);
		if (debug > 2)
		printf("done\n");
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_x509_crl_import[%s]: %s\n",
				crl_list[i].name,
				gnutls_strerror(ret));
			exit(1);
		}

		gnutls_x509_crl_print(crl,
				      GNUTLS_CRT_PRINT_ONELINE,
				      &tmp);
		if (debug)
			printf("\tCRL: %.*s\n", 
			       tmp.size, tmp.data);
		gnutls_free(tmp.data);

		if (debug > 2)
			printf("\tAdding CA certificate...");

		ret = gnutls_x509_crt_init(&ca);
		if (ret < 0) {
			fprintf(stderr, "gnutls_x509_crt_init: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		tmp.data = (unsigned char *) *crl_list[i].ca;
		tmp.size = strlen(*crl_list[i].ca);

		ret =
		    gnutls_x509_crt_import(ca, &tmp, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fprintf(stderr, "gnutls_x509_crt_import: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (debug > 2)
			printf("done\n");

		gnutls_x509_crt_print(ca, GNUTLS_CRT_PRINT_ONELINE, &tmp);
		if (debug)
			printf("\tCA Certificate: %.*s\n", tmp.size,
			       tmp.data);
		gnutls_free(tmp.data);

		if (debug)
			printf("\tVerifying...");

		ret = gnutls_x509_crl_verify(crl, &ca, 1, crl_list[i].verify_flags,
						  &verify_status);
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_x509_crt_list_verify[%d]: %s\n",
				(int) i, gnutls_strerror(ret));
			exit(1);
		}

		if (verify_status != crl_list[i].expected_verify_result) {
			gnutls_datum_t out1, out2;
			gnutls_certificate_verification_status_print
			    (verify_status, GNUTLS_CRT_X509, &out1, 0);
			gnutls_certificate_verification_status_print(crl_list
								     [i].
								     expected_verify_result,
								     GNUTLS_CRT_X509,
								     &out2,
								     0);
			fail("chain[%s]:\nverify_status: %d: %s\nexpected: %d: %s\n", crl_list[i].name, verify_status, out1.data, crl_list[i].expected_verify_result, out2.data);
			gnutls_free(out1.data);
			gnutls_free(out2.data);

			if (!debug)
				exit(1);
		} else if (debug)
			printf("done\n");

		gnutls_x509_trust_list_init(&tl, 0);

		ret =
		    gnutls_x509_trust_list_add_cas(tl, &ca, 1, 0);
		if (ret != 1) {
			fail("gnutls_x509_trust_list_add_trust_mem\n");
			exit(1);
		}

		/* make sure that the two functions don't diverge */
		ret = gnutls_x509_trust_list_add_crls(tl, &crl, 1, GNUTLS_TL_VERIFY_CRL, crl_list[i].verify_flags);
		if (crl_list[i].expected_verify_result == 0 && ret < 0) {
			fprintf(stderr,
				"gnutls_x509_trust_list_add_crls[%d]: %s\n",
				(int) i, gnutls_strerror(ret));
			exit(1);
		}
		if (crl_list[i].expected_verify_result != 0 && ret > 0) {
			fprintf(stderr,
				"gnutls_x509_trust_list_add_crls[%d]: succeeded when it shouldn't\n",
				(int) i);
			exit(1);
		}

		if (debug)
			printf("\tCleanup...");

		gnutls_x509_trust_list_deinit(tl, 0);
		gnutls_x509_crt_deinit(ca);
		gnutls_x509_crl_deinit(crl);

		if (debug)
			printf("done\n\n\n");
	}

	gnutls_global_deinit();

	if (debug)
		printf("Exit status...%d\n", exit_val);

	exit(exit_val);
}
예제 #4
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)
{
  gnutls_pkcs12_bag_t bag = NULL;
  gnutls_x509_crt_t *_extra_certs = NULL;
  unsigned int _extra_certs_len = 0;
  gnutls_x509_crt_t *_chain = NULL;
  unsigned int _chain_len = 0;
  int idx = 0;
  int ret;
  size_t cert_id_size = 0;
  size_t key_id_size = 0;
  opaque cert_id[20];
  opaque key_id[20];
  int privkey_ok = 0;

  *key = NULL;
  
  if (crl)
    *crl = NULL;

  /* find the first private key */
  for (;;)
    {
      int elements_in_bag;
      int i;

      ret = gnutls_pkcs12_bag_init (&bag);
      if (ret < 0)
        {
          bag = NULL;
          gnutls_assert ();
          goto done;
        }

      ret = gnutls_pkcs12_get_bag (p12, idx, bag);
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
        break;
      if (ret < 0)
        {
          gnutls_assert ();
          goto done;
        }

      ret = gnutls_pkcs12_bag_get_type (bag, 0);
      if (ret < 0)
        {
          gnutls_assert ();
          goto done;
        }

      if (ret == GNUTLS_BAG_ENCRYPTED)
        {
          if (password == NULL)
            {
              ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
              goto done;
            }

          ret = gnutls_pkcs12_bag_decrypt (bag, password);
          if (ret < 0)
            {
              gnutls_assert ();
              goto done;
            }
        }

      elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
      if (elements_in_bag < 0)
        {
          gnutls_assert ();
          goto done;
        }

      for (i = 0; i < elements_in_bag; i++)
        {
          int type;
          gnutls_datum_t data;

          type = gnutls_pkcs12_bag_get_type (bag, i);
          if (type < 0)
            {
              gnutls_assert ();
              goto done;
            }

          ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
          if (ret < 0)
            {
              gnutls_assert ();
              goto done;
            }

          switch (type)
            {
            case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
              if (password == NULL)
                {
                  ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
                  goto done;
                }

            case GNUTLS_BAG_PKCS8_KEY:
              if (*key != NULL) /* too simple to continue */
                {
                  gnutls_assert ();
                  break;
                }

              ret = gnutls_x509_privkey_init (key);
              if (ret < 0)
                {
                  gnutls_assert ();
                  goto done;
                }

              ret = gnutls_x509_privkey_import_pkcs8
                (*key, &data, GNUTLS_X509_FMT_DER, password,
                 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
              if (ret < 0)
                {
                  gnutls_assert ();
                  gnutls_x509_privkey_deinit (*key);
                  goto done;
                }

              key_id_size = sizeof (key_id);
              ret =
                gnutls_x509_privkey_get_key_id (*key, 0, key_id,
                                                &key_id_size);
              if (ret < 0)
                {
                  gnutls_assert ();
                  gnutls_x509_privkey_deinit (*key);
                  goto done;
                }

              privkey_ok = 1;   /* break */
              break;
            default:
              break;
            }
        }

      idx++;
      gnutls_pkcs12_bag_deinit (bag);

      if (privkey_ok != 0)      /* private key was found */
        break;
    }

  if (privkey_ok == 0)          /* no private key */
    {
      gnutls_assert ();
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    }

  /* now find the corresponding certificate 
   */
  idx = 0;
  bag = NULL;
  for (;;)
    {
      int elements_in_bag;
      int i;

      ret = gnutls_pkcs12_bag_init (&bag);
      if (ret < 0)
        {
          bag = NULL;
          gnutls_assert ();
          goto done;
        }

      ret = gnutls_pkcs12_get_bag (p12, idx, bag);
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
        break;
      if (ret < 0)
        {
          gnutls_assert ();
          goto done;
        }

      ret = gnutls_pkcs12_bag_get_type (bag, 0);
      if (ret < 0)
        {
          gnutls_assert ();
          goto done;
        }

      if (ret == GNUTLS_BAG_ENCRYPTED)
        {
          ret = gnutls_pkcs12_bag_decrypt (bag, password);
          if (ret < 0)
            {
              gnutls_assert ();
              goto done;
            }
        }

      elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
      if (elements_in_bag < 0)
        {
          gnutls_assert ();
          goto done;
        }

      for (i = 0; i < elements_in_bag; i++)
        {
          int type;
          gnutls_datum_t data;
          gnutls_x509_crt_t this_cert;

          type = gnutls_pkcs12_bag_get_type (bag, i);
          if (type < 0)
            {
              gnutls_assert ();
              goto done;
            }

          ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
          if (ret < 0)
            {
              gnutls_assert ();
              goto done;
            }

          switch (type)
            {
            case GNUTLS_BAG_CERTIFICATE:
              ret = gnutls_x509_crt_init (&this_cert);
              if (ret < 0)
                {
                  gnutls_assert ();
                  goto done;
                }

              ret =
                gnutls_x509_crt_import (this_cert, &data, GNUTLS_X509_FMT_DER);
              if (ret < 0)
                {
                  gnutls_assert ();
                  gnutls_x509_crt_deinit (this_cert);
                  goto done;
                }

              /* check if the key id match */
              cert_id_size = sizeof (cert_id);
              ret =
                gnutls_x509_crt_get_key_id (this_cert, 0, cert_id, &cert_id_size);
              if (ret < 0)
                {
                  gnutls_assert ();
                  gnutls_x509_crt_deinit (this_cert);
                  goto done;
                }

              if (memcmp (cert_id, key_id, cert_id_size) != 0)
                { /* they don't match - skip the certificate */
                  if (extra_certs)
                    {
                      void *tmp = _extra_certs;
                      _extra_certs = gnutls_realloc (_extra_certs,
                                                     sizeof(_extra_certs[0]) *
                                                     ++_extra_certs_len);
                      if (!_extra_certs)
                        {
                          gnutls_assert ();
                          gnutls_free(tmp);
                          ret = GNUTLS_E_MEMORY_ERROR;
                          goto done;
                        }
                      _extra_certs[_extra_certs_len - 1] = this_cert;
                      this_cert = NULL;
                    }
                  else
                    {
                       gnutls_x509_crt_deinit (this_cert);
                    }
                }
              else
                {
                  if (_chain_len == 0)
                    {
                      _chain = gnutls_malloc (sizeof(_chain[0]) * (++_chain_len));
                      if (!_chain)
                        {
                          gnutls_assert ();
                          ret = GNUTLS_E_MEMORY_ERROR;
                          goto done;
                        }
                      _chain[_chain_len - 1] = this_cert;
                      this_cert = NULL;
                    }
                  else
                    {
                       gnutls_x509_crt_deinit (this_cert);
                    }
                }
              break;

            case GNUTLS_BAG_CRL:
              if (crl == NULL || *crl != NULL)
                {
                  gnutls_assert ();
                  break;
                }

              ret = gnutls_x509_crl_init (crl);
              if (ret < 0)
                {
                  gnutls_assert ();
                  goto done;
                }

              ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
              if (ret < 0)
                {
                  gnutls_assert ();
                  gnutls_x509_crl_deinit (*crl);
                  goto done;
                }
              break;

            case GNUTLS_BAG_ENCRYPTED:
              /* XXX Bother to recurse one level down?  Unlikely to
                 use the same password anyway. */
            case GNUTLS_BAG_EMPTY:
            default:
              break;
            }
        }

      idx++;
      gnutls_pkcs12_bag_deinit (bag);
    }

  if (_chain_len != 1)
    {
      ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
      goto done;
    }

  ret = make_chain(&_chain, &_chain_len, &_extra_certs, &_extra_certs_len);
  if (ret < 0)
    {
      gnutls_assert();
      goto done;
    }

  ret = 0;

done:
  if (bag)
    gnutls_pkcs12_bag_deinit (bag);

  if (ret < 0)
    {
      if (*key)
        gnutls_x509_privkey_deinit(*key);
      if (_extra_certs_len && _extra_certs != NULL)
        {
          unsigned int i;
          for (i = 0; i < _extra_certs_len; i++)
            gnutls_x509_crt_deinit(_extra_certs[i]);
          gnutls_free(_extra_certs);
        }
      if (_chain_len && _chain != NULL)
        {
          unsigned int i;
          for (i = 0; i < _chain_len; i++)
            gnutls_x509_crt_deinit(_chain[i]);
          gnutls_free(_chain);
        }
    }
  else 
    {
      if (extra_certs) 
        {
          *extra_certs = _extra_certs;
          *extra_certs_len = _extra_certs_len;
        }
      
      *chain = _chain;
      *chain_len = _chain_len;
    }

  return ret;
}
예제 #5
0
		/** Import */
		X509CRL(const std::string& crlstr)
		{
			int ret = gnutls_x509_crl_import(get(), Datum(crlstr).get(), GNUTLS_X509_FMT_PEM);
			ThrowOnError(ret, "Unable to load certificate revocation list");
		}
예제 #6
0
int
main (void)
{
  int rc;
  gnutls_certificate_credentials_t crt;
  gnutls_datum_t crldatum = { crl, strlen (crl) };
  gnutls_x509_crl_t crl;

  rc = gnutls_global_init ();
  if (rc)
    {
      printf ("gnutls_global_init rc %d: %s\n", rc, gnutls_strerror (rc));
      return 1;
    }

  rc = gnutls_certificate_allocate_credentials (&crt);
  if (rc)
    {
      printf ("gnutls_certificate_allocate_credentials rc %d: %s\n",
	      rc, gnutls_strerror (rc));
      return 1;
    }

  rc = gnutls_certificate_set_x509_crl_mem (crt, &crldatum,
					    GNUTLS_X509_FMT_PEM);
  if (rc != 1)
    {
      printf ("gnutls_certificate_set_x509_crl_mem num %d\n", rc);
      return 1;
    }

  rc = gnutls_x509_crl_init (&crl);
  if (rc)
    {
      printf ("gnutls_x509_crl_init rc %d: %s\n", rc, gnutls_strerror (rc));
      return 1;
    }

  rc = gnutls_x509_crl_import (crl, &crldatum, GNUTLS_X509_FMT_PEM);
  if (rc)
    {
      printf ("gnutls_x509_crl_import rc %d: %s\n", rc, gnutls_strerror (rc));
      return 1;
    }

  rc = gnutls_certificate_set_x509_crl (crt, &crl, 1);
  if (rc)
    {
      printf ("gnutls_certificate_set_x509_crl rc %d: %s\n",
	      rc, gnutls_strerror (rc));
      return 1;
    }

  gnutls_x509_crl_deinit (crl);

  gnutls_certificate_free_credentials (crt);

  gnutls_global_deinit ();

  return 0;
}