Пример #1
0
/* This function will attempt to set the requested extension in
 * the given X509v3 certificate.
 *
 * Critical will be either 0 or 1.
 */
static int
add_extension(ASN1_TYPE asn, const char *root, const char *extension_id,
              const gnutls_datum_t * ext_data, unsigned int critical)
{
    int result;
    const char *str;
    char name[ASN1_MAX_NAME_SIZE];

    snprintf(name, sizeof(name), "%s", root);

    /* Add a new extension in the list.
     */
    result = asn1_write_value(asn, name, "NEW", 1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    if (root[0] != 0)
        snprintf(name, sizeof(name), "%s.?LAST.extnID", root);
    else
        snprintf(name, sizeof(name), "?LAST.extnID");

    result = asn1_write_value(asn, name, extension_id, 1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    if (critical == 0)
        str = "FALSE";
    else
        str = "TRUE";

    if (root[0] != 0)
        snprintf(name, sizeof(name), "%s.?LAST.critical", root);
    else
        snprintf(name, sizeof(name), "?LAST.critical");

    result = asn1_write_value(asn, name, str, 1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    if (root[0] != 0)
        snprintf(name, sizeof(name), "%s.?LAST.extnValue", root);
    else
        snprintf(name, sizeof(name), "?LAST.extnValue");

    result = _gnutls_x509_write_value(asn, name, ext_data);
    if (result < 0) {
        gnutls_assert();
        return result;
    }

    return 0;
}
Пример #2
0
/* Overwrite the given extension (using the index)
 * index here starts from one.
 */
static int
overwrite_extension (ASN1_TYPE asn, const char *root, unsigned int indx,
                     const gnutls_datum_t * ext_data, unsigned int critical)
{
  char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
  const char *str;
  int result;

  if (root[0] != 0)
    snprintf (name, sizeof (name), "%s.?%u", root, indx);
  else
    snprintf (name, sizeof (name), "?%u", indx);

  if (critical == 0)
    str = "FALSE";
  else
    str = "TRUE";

  _gnutls_str_cpy (name2, sizeof (name2), name);
  _gnutls_str_cat (name2, sizeof (name2), ".critical");

  result = asn1_write_value (asn, name2, str, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  _gnutls_str_cpy (name2, sizeof (name2), name);
  _gnutls_str_cat (name2, sizeof (name2), ".extnValue");

  result = _gnutls_x509_write_value (asn, name2, ext_data);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  return 0;
}
Пример #3
0
/* Encodes the bag into a SafeContents structure, and puts the output in
 * the given datum. Enc is set to non zero if the data are encrypted;
 */
int
_pkcs12_encode_safe_contents (gnutls_pkcs12_bag_t bag, ASN1_TYPE * contents,
			      int *enc)
{
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  int result;
  int i;
  const char *oid;

  if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc)
    {
      *enc = 1;
      return 0;			/* ENCRYPTED BAG, do nothing. */
    }
  else if (enc)
    *enc = 0;

  /* Step 1. Create the SEQUENCE.
   */

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
	&c2)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  for (i = 0; i < bag->bag_elements; i++)
    {

      oid = bag_to_oid (bag->element[i].type);
      if (oid == NULL)
	{
	  gnutls_assert ();
	  continue;
	}

      result = asn1_write_value (c2, "", "NEW", 1);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      /* Copy the bag type.
       */
      result = asn1_write_value (c2, "?LAST.bagId", oid, 1);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      /* Set empty attributes
       */
      result = write_attributes (bag, i, c2, "?LAST.bagAttributes");
      if (result < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}


      /* Copy the Bag Value
       */

      if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE ||
	  bag->element[i].type == GNUTLS_BAG_SECRET ||
	  bag->element[i].type == GNUTLS_BAG_CRL)
	{
	  gnutls_datum_t tmp;

	  /* in that case encode it to a CertBag or
	   * a CrlBag.
	   */

	  result =
	    _pkcs12_encode_crt_bag (bag->element[i].type,
				    &bag->element[i].data, &tmp);

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

	  result = _gnutls_x509_write_value (c2, "?LAST.bagValue", &tmp, 0);

	  _gnutls_free_datum (&tmp);

	}
      else
	{

	  result = _gnutls_x509_write_value (c2, "?LAST.bagValue",
					     &bag->element[i].data, 0);
	}

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

    }

  /* Encode the data and copy them into the datum
   */
  *contents = c2;

  return 0;

cleanup:
  if (c2)
    asn1_delete_structure (&c2);
  return result;

}
Пример #4
0
/**
 * gnutls_x509_crt_set_policy:
 * @cert: should contain a #gnutls_x509_crt_t structure
 * @policy: A pointer to a policy structure.
 * @critical: use non-zero if the extension is marked as critical
 *
 * This function will set the certificate policy extension (2.5.29.32).
 * Multiple calls to this function append a new policy.
 *
 * Note the maximum text size for the qualifier %GNUTLS_X509_QUALIFIER_NOTICE
 * is 200 characters. This function will fail with %GNUTLS_E_INVALID_REQUEST
 * if this is exceeded.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.1.5
 **/
int
gnutls_x509_crt_set_policy(gnutls_x509_crt_t crt,
			   struct gnutls_x509_policy_st *policy,
			   unsigned int critical)
{
	int result;
	unsigned i;
	gnutls_datum_t der_data, tmpd, prev_der_data = { NULL, 0 };
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
	const char *oid;

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

	result = _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0,
						&prev_der_data, NULL);
	if (result < 0 && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
		gnutls_assert();
		return result;
	}

	result =
	    asn1_create_element(_gnutls_get_pkix(),
				"PKIX1.certificatePolicies", &c2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	if (prev_der_data.data != NULL) {
		result =
		    asn1_der_decoding(&c2, prev_der_data.data,
				      prev_der_data.size, NULL);

		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}
	}

	/* 1. write a new policy */
	result = asn1_write_value(c2, "", "NEW", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	/* 2. Add the OID.
	 */
	result =
	    asn1_write_value(c2, "?LAST.policyIdentifier", policy->oid, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	for (i = 0; i < MIN(policy->qualifiers, GNUTLS_MAX_QUALIFIERS);
	     i++) {
		result =
		    asn1_write_value(c2, "?LAST.policyQualifiers", "NEW",
				     1);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		if (policy->qualifier[i].type == GNUTLS_X509_QUALIFIER_URI)
			oid = "1.3.6.1.5.5.7.2.1";
		else if (policy->qualifier[i].type ==
			 GNUTLS_X509_QUALIFIER_NOTICE)
			oid = "1.3.6.1.5.5.7.2.2";
		else {
			result =
			    gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
			goto cleanup;
		}

		result =
		    asn1_write_value(c2,
				     "?LAST.policyQualifiers.?LAST.policyQualifierId",
				     oid, 1);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		if (policy->qualifier[i].type == GNUTLS_X509_QUALIFIER_URI) {
			tmpd.data = (void *) policy->qualifier[i].data;
			tmpd.size = policy->qualifier[i].size;

			result =
			    _gnutls_x509_write_string(c2,
						      "?LAST.policyQualifiers.?LAST.qualifier",
						      &tmpd,
						      ASN1_ETYPE_IA5_STRING);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
		} else if (policy->qualifier[i].type ==
			   GNUTLS_X509_QUALIFIER_NOTICE) {
			tmpd.data = (void *) policy->qualifier[i].data;
			tmpd.size = policy->qualifier[i].size;

			if (tmpd.size > 200) {
				gnutls_assert();
				result = GNUTLS_E_INVALID_REQUEST;
				goto cleanup;
			}

			result = encode_user_notice(&tmpd, &der_data);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}

			result =
			    _gnutls_x509_write_value(c2,
						     "?LAST.policyQualifiers.?LAST.qualifier",
						     &der_data);
			_gnutls_free_datum(&der_data);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}
	}

	result = _gnutls_x509_der_encode(c2, "", &der_data, 0);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	result = _gnutls_x509_crt_set_extension(crt, "2.5.29.32",
						&der_data, 0);

	_gnutls_free_datum(&der_data);

	crt->use_extensions = 1;

      cleanup:
	asn1_delete_structure(&c2);
	_gnutls_free_datum(&prev_der_data);

	return result;
}
Пример #5
0
int
_pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type,
			const gnutls_datum_t * raw, gnutls_datum_t * out)
{
  int ret;
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

  if (type == GNUTLS_BAG_CERTIFICATE)
    {
      if ((ret = asn1_create_element (_gnutls_get_pkix (),
				      "PKIX1.pkcs-12-CertBag",
				      &c2)) != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = asn1_write_value (c2, "certId", X509_CERT_OID, 1);
      if (ret != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = _gnutls_x509_write_value (c2, "certValue", raw, 1);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

    }
  else
    {				/* CRL */
      if ((ret = asn1_create_element (_gnutls_get_pkix (),
				      "PKIX1.pkcs-12-CRLBag",
				      &c2)) != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = asn1_write_value (c2, "crlId", X509_CRL_OID, 1);
      if (ret != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  ret = _gnutls_asn2err (ret);
	  goto cleanup;
	}

      ret = _gnutls_x509_write_value (c2, "crlValue", raw, 1);
      if (ret < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
    }

  ret = _gnutls_x509_der_encode (c2, "", out, 0);

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

  asn1_delete_structure (&c2);

  return 0;


cleanup:

  asn1_delete_structure (&c2);
  return ret;
}