예제 #1
0
/**
 * gnutls_x509_crl_set_number - Set the CRL's number extension
 * @crl: a CRL of type #gnutls_x509_crl_t
 * @nr: The CRL number
 * @nr_size: Holds the size of the nr field.
 *
 * This function will set the CRL's number extension.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.8.0
 **/
int
gnutls_x509_crl_set_number (gnutls_x509_crl_t crl,
			    const void *nr, size_t nr_size)
{
  int result;
  gnutls_datum_t old_id, der_data;
  unsigned int critical;

  if (crl == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* Check if the extension already exists.
   */
  result =
    _gnutls_x509_crl_get_extension (crl, "2.5.29.20", 0, &old_id, &critical);

  if (result >= 0)
    _gnutls_free_datum (&old_id);
  if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* generate the extension.
   */
  result = _gnutls_x509_ext_gen_number (nr, nr_size, &der_data);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  result = _gnutls_x509_crl_set_extension (crl, "2.5.29.20", &der_data, 0);

  _gnutls_free_datum (&der_data);

  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  crl->use_extensions = 1;

  return 0;
}
예제 #2
0
/**
 * gnutls_pkcs11_copy_x509_crt2:
 * @token_url: A PKCS #11 URL specifying a token
 * @crt: The certificate to copy
 * @label: The name to be used for the stored data
 * @cid: The CKA_ID to set for the object -if NULL, the ID will be derived from the public key
 * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
 *
 * This function will copy a certificate into a PKCS #11 token specified by
 * a URL. Valid flags to mark the certificate: %GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED,
 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE, %GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE,
 * %GNUTLS_PKCS11_OBJ_FLAG_MARK_CA, %GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.4.0
 **/
int
gnutls_pkcs11_copy_x509_crt2(const char *token_url,
			    gnutls_x509_crt_t crt, const char *label,
			    const gnutls_datum_t *cid,
			    unsigned int flags)
{
	int ret;
	struct p11_kit_uri *info = NULL;
	ck_rv_t rv;
	size_t der_size, id_size, serial_size;
	gnutls_datum_t serial_der = {NULL, 0};
	uint8_t *der = NULL;
	uint8_t serial[128];
	uint8_t id[20];
	struct ck_attribute a[MAX_ASIZE];
	ck_object_class_t class = CKO_CERTIFICATE;
	ck_certificate_type_t type = CKC_X_509;
	ck_object_handle_t ctx;
	unsigned a_val;
	struct pkcs11_session_info sinfo;
	
	PKCS11_CHECK_INIT;

	ret = pkcs11_url_to_info(token_url, &info, 0);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret =
	    pkcs11_open_session(&sinfo, NULL, info,
				SESSION_WRITE |
				pkcs11_obj_flags_to_int(flags));
	p11_kit_uri_free(info);

	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	der_size = 0;
	ret =
	    gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, NULL,
				   &der_size);
	if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
		gnutls_assert();
		goto cleanup;
	}

	der = gnutls_malloc(der_size);
	if (der == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto cleanup;
	}

	ret =
	    gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, der,
				   &der_size);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	a[0].type = CKA_CLASS;
	a[0].value = &class;
	a[0].value_len = sizeof(class);

	a[1].type = CKA_ID;
	if (cid == NULL || cid->size == 0) {
		id_size = sizeof(id);
		ret = gnutls_x509_crt_get_subject_key_id(crt, id, &id_size, NULL);
		if (ret < 0) {
			id_size = sizeof(id);
			ret = gnutls_x509_crt_get_key_id(crt, 0, id, &id_size);
			if (ret < 0) {
			  gnutls_assert();
			  goto cleanup;
			}
		}

		a[1].value = id;
		a[1].value_len = id_size;
	} else {
		a[1].value = cid->data;
		a[1].value_len = cid->size;
	}

	a[2].type = CKA_VALUE;
	a[2].value = der;
	a[2].value_len = der_size;
	a[3].type = CKA_TOKEN;
	a[3].value = (void *) &tval;
	a[3].value_len = sizeof(tval);
	a[4].type = CKA_CERTIFICATE_TYPE;
	a[4].value = &type;
	a[4].value_len = sizeof(type);
	/* FIXME: copy key usage flags */

	a_val = 5;

	a[a_val].type = CKA_SUBJECT;
	a[a_val].value = crt->raw_dn.data;
	a[a_val].value_len = crt->raw_dn.size;
	a_val++;

	a[a_val].type = CKA_ISSUER;
	a[a_val].value = crt->raw_issuer_dn.data;
	a[a_val].value_len = crt->raw_issuer_dn.size;
	a_val++;

	serial_size = sizeof(serial);
	if (gnutls_x509_crt_get_serial(crt, serial, &serial_size) >= 0) {
		ret = _gnutls_x509_ext_gen_number(serial, serial_size, &serial_der);
		if (ret >= 0) {
			a[a_val].type = CKA_SERIAL_NUMBER;
			a[a_val].value = (void *) serial_der.data;
			a[a_val].value_len = serial_der.size;
			a_val++;
		}
	}

	if (label) {
		a[a_val].type = CKA_LABEL;
		a[a_val].value = (void *) label;
		a[a_val].value_len = strlen(label);
		a_val++;
	}

	mark_flags(flags, a, &a_val, sinfo.trusted);

	rv = pkcs11_create_object(sinfo.module, sinfo.pks, a, a_val, &ctx);
	if (rv != CKR_OK) {
		gnutls_assert();
		_gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}

	/* generated! 
	 */

	ret = 0;

      cleanup:
	gnutls_free(der);
	gnutls_free(serial_der.data);
	pkcs11_close_session(&sinfo);
	return ret;

}