예제 #1
0
int main(void)
{
	int rc;
	gnutls_certificate_credentials_t crt;
	gnutls_datum_t crldatum = { (uint8_t *) crl, strlen(crl) };
	gnutls_x509_crl_t crl;

	rc = global_init();
	if (rc) {
		printf("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 < 0) {
		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;
}
예제 #2
0
/**
 * gnutls_certificate_set_x509_crl:
 * @res: is a #gnutls_certificate_credentials_t type.
 * @crl_list: is a list of trusted CRLs. They should have been verified before.
 * @crl_list_size: holds the size of the crl_list
 *
 * This function adds the trusted CRLs in order to verify client or
 * server certificates.  In case of a client this is not required to
 * be called if the certificates are not verified using
 * gnutls_certificate_verify_peers2().  This function may be called
 * multiple times.
 *
 * Returns: number of CRLs processed, or a negative error code on error.
 *
 * Since: 2.4.0
 **/
int
gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res,
				gnutls_x509_crl_t * crl_list,
				int crl_list_size)
{
	int ret, i, j;
	gnutls_x509_crl_t *new_crl = gnutls_malloc(crl_list_size * sizeof(gnutls_x509_crl_t));
	unsigned flags = GNUTLS_TL_USE_IN_TLS;

	if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
		flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;

	if (!new_crl)
		return GNUTLS_E_MEMORY_ERROR;

	for (i = 0; i < crl_list_size; i++) {
		ret = gnutls_x509_crl_init(&new_crl[i]);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		ret = _gnutls_x509_crl_cpy(new_crl[i], crl_list[i]);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	ret =
	    gnutls_x509_trust_list_add_crls(res->tlist, new_crl,
				    crl_list_size, flags, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	free(new_crl);
	return ret;

      cleanup:
	for (j = 0; j < i; j++)
		gnutls_x509_crl_deinit(new_crl[j]);
	free(new_crl);

	return ret;
}
예제 #3
0
파일: pkcs12.c 프로젝트: gnutls/gnutls
/**
 * gnutls_pkcs12_simple_parse:
 * @p12: A pkcs12 type
 * @password: optional password used to decrypt the structure, bags and keys.
 * @key: a structure to store the parsed private key.
 * @chain: the corresponding to key certificate chain (may be %NULL)
 * @chain_len: will be updated with the number of additional (may be %NULL)
 * @extra_certs: optional pointer to receive an array of additional
 *	       certificates found in the PKCS12 structure (may be %NULL).
 * @extra_certs_len: will be updated with the number of additional
 *		   certs (may be %NULL).
 * @crl: an optional structure to store the parsed CRL (may be %NULL).
 * @flags: should be zero or one of GNUTLS_PKCS12_SP_*
 *
 * This function parses a PKCS12 structure in @pkcs12 and extracts the
 * private key, the corresponding certificate chain, any additional
 * certificates and a CRL. The structures in @key, @chain @crl, and @extra_certs
 * must not be initialized.
 *
 * The @extra_certs and @extra_certs_len parameters are optional
 * and both may be set to %NULL. If either is non-%NULL, then both must
 * be set. The value for @extra_certs is allocated
 * using gnutls_malloc().
 * 
 * Encrypted PKCS12 bags and PKCS8 private keys are supported, but
 * only with password based security and the same password for all
 * operations.
 *
 * Note that a PKCS12 structure may contain many keys and/or certificates,
 * and there is no way to identify which key/certificate pair you want.
 * For this reason this function is useful for PKCS12 files that contain 
 * only one key/certificate pair and/or one CRL.
 *
 * If the provided structure has encrypted fields but no password
 * is provided then this function returns %GNUTLS_E_DECRYPTION_FAILED.
 *
 * Note that normally the chain constructed does not include self signed
 * certificates, to comply with TLS' requirements. If, however, the flag 
 * %GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED is specified then
 * self signed certificates will be included in the chain.
 *
 * Prior to using this function the PKCS #12 structure integrity must
 * be verified using gnutls_pkcs12_verify_mac().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.1.0
 **/
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;
	uint8_t cert_id[20];
	uint8_t key_id[20];
	int privkey_ok = 0;
	unsigned int i;
	int elements_in_bag;

	*key = NULL;

	if (crl)
		*crl = NULL;

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

		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) {
			gnutls_pkcs12_bag_deinit(bag);
			bag = NULL;
			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 < (unsigned)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;
				}

				FALLTHROUGH;
			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();
					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();
					goto done;
				}

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

		idx++;
		gnutls_pkcs12_bag_deinit(bag);
		bag = NULL;

		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 (;;) {
		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) {
			gnutls_pkcs12_bag_deinit(bag);
			bag = NULL;
			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 < (unsigned)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);
					this_cert = NULL;
					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);
					this_cert = NULL;
					goto done;
				}

				if (memcmp(cert_id, key_id, cert_id_size) != 0) {	/* they don't match - skip the certificate */
					_extra_certs =
						gnutls_realloc_fast
						(_extra_certs,
						 sizeof(_extra_certs
							[0]) *
						 ++_extra_certs_len);
					if (!_extra_certs) {
						gnutls_assert();
						ret =
							GNUTLS_E_MEMORY_ERROR;
						goto done;
					}
					_extra_certs
						[_extra_certs_len -
						 1] = this_cert;
					this_cert = NULL;
				} else {
					if (chain && _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);
						this_cert = NULL;
					}
				}
				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);
					*crl = NULL;
					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);
		bag = NULL;
	}

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

		ret =
		    make_chain(&_chain, &_chain_len, &_extra_certs,
			       &_extra_certs_len, flags);
		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);
			*key = NULL;
		}
		if (crl != NULL && *crl != NULL) {
			gnutls_x509_crl_deinit(*crl);
			*crl = NULL;
		}
		if (_extra_certs_len && _extra_certs != NULL) {
			for (i = 0; i < _extra_certs_len; i++)
				gnutls_x509_crt_deinit(_extra_certs[i]);
			gnutls_free(_extra_certs);
		}
		if (_chain_len && _chain != NULL) {
			for (i = 0; i < _chain_len; i++)
				gnutls_x509_crt_deinit(_chain[i]);
			gnutls_free(_chain);
		}

		return ret;
	}

	if (extra_certs && _extra_certs_len > 0) {
		*extra_certs = _extra_certs;
		*extra_certs_len = _extra_certs_len;
	} else {
		if (extra_certs) {
			*extra_certs = NULL;
			*extra_certs_len = 0;
		}
		for (i = 0; i < _extra_certs_len; i++)
			gnutls_x509_crt_deinit(_extra_certs[i]);
		gnutls_free(_extra_certs);
	}

	if (chain != NULL) {
		*chain = _chain;
		*chain_len = _chain_len;
	}

	return ret;
}
예제 #4
0
int tls_revoke_analyzer(requiem_client_profile_t *cp, gnutls_x509_privkey key,
                        gnutls_x509_crt crt, uint64_t revoked_analyzerid)
{
        int ret, i;
        size_t len, dsize;
        gnutls_datum data;
        gnutls_x509_crl crl;
        uint64_t analyzerid;
        char crlfile[PATH_MAX], buf[65535];

        ret = gnutls_x509_crl_init(&crl);
        requiem_client_profile_get_tls_server_crl_filename(cp, crlfile, sizeof(crlfile));

        ret = access(crlfile, R_OK);
        if ( ret == 0 ) {
                ret = _requiem_load_file(crlfile, &data.data, &dsize);
                if ( ret < 0 ) {
                        fprintf(stderr, "error loading '%s': %s.\n", crlfile, requiem_strerror(ret));
                        return ret;
                }

                data.size = (unsigned int) dsize;

                ret = gnutls_x509_crl_import(crl, &data, GNUTLS_X509_FMT_PEM);
                if ( ret < 0 ) {
                        fprintf(stderr, "error importing CRL: %s.\n", gnutls_strerror(ret));
                        return -1;
                }
        }

        for ( i = 0; i < gnutls_x509_crl_get_crt_count(crl); i++ ) {
                len = sizeof(analyzerid);
                gnutls_x509_crl_get_crt_serial(crl, i, (unsigned char *) &analyzerid, &len, NULL);

                if ( analyzerid == revoked_analyzerid )
                        return 0;
        }

        ret = gnutls_x509_crl_set_crt_serial(crl, &revoked_analyzerid, sizeof(revoked_analyzerid), time(NULL));
        if ( ret < 0 ) {
                fprintf(stderr, "error setting CRL certificate serial: %s.\n", gnutls_strerror(ret));
                return -1;
        }

        gnutls_x509_crl_set_version(crl, 2);
        gnutls_x509_crl_set_next_update(crl, time(NULL));
        gnutls_x509_crl_set_this_update(crl, time(NULL));

        ret = gnutls_x509_crl_sign(crl, crt, key);
        if ( ret < 0 ) {
                fprintf(stderr, "error signing CRL: %s.\n", gnutls_strerror(ret));
                return -1;
        }

        len = sizeof(buf);
        ret = gnutls_x509_crl_export(crl, GNUTLS_X509_FMT_PEM, buf, &len);
        if ( ret < 0 ) {
                fprintf(stderr, "error exporting certificate revocation list: %s\n", gnutls_strerror(ret));
                gnutls_x509_crl_deinit(crl);
                return -1;
        }

        gnutls_x509_crl_deinit(crl);

        unlink(crlfile);
        ret = save_buf(crlfile, requiem_client_profile_get_uid(cp),
                       requiem_client_profile_get_gid(cp), (unsigned char *) buf, len);
        if ( ret < 0 ) {
                fprintf(stderr, "error saving private key.\n");
                return -1;
        }

        return 1;
}
예제 #5
0
/*-
  * gnutls_x509_verify_certificate - This function verifies given certificate list
  * @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 (1,
		   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 (1, 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 (1, 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;
}
예제 #6
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);
}
예제 #7
0
/**
 * 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 zero 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.
 **/
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;
}
			RAIICRL()
			{
				ThrowOnError(gnutls_x509_crl_init(&crl), "gnutls_x509_crl_init() failed");
			}