Esempio n. 1
0
/**
 * gnutls_x509_crt_set_crl_dist_points2:
 * @crt: a certificate of type #gnutls_x509_crt_t
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
 * @data: The data to be set
 * @data_size: The data size
 * @reason_flags: revocation reasons
 *
 * This function will set the CRL distribution points certificate extension.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.6.0
 **/
int
gnutls_x509_crt_set_crl_dist_points2(gnutls_x509_crt_t crt,
				     gnutls_x509_subject_alt_name_t type,
				     const void *data,
				     unsigned int data_size,
				     unsigned int reason_flags)
{
	int result;
	gnutls_datum_t der_data = { NULL, 0 };
	gnutls_datum_t oldname = { NULL, 0 };
	unsigned int critical;

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

	/* Check if the extension already exists.
	 */
	result =
	    _gnutls_x509_crt_get_extension(crt, "2.5.29.31", 0, &oldname,
					   &critical);

	_gnutls_free_datum(&oldname);

	if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	/* generate the extension.
	 */
	result =
	    _gnutls_x509_ext_gen_crl_dist_points(type, data, data_size,
						 reason_flags, &der_data);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

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

	_gnutls_free_datum(&der_data);

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

	crt->use_extensions = 1;

	return 0;

}
Esempio n. 2
0
/**
 * gnutls_x509_crt_set_subject_key_id:
 * @cert: a certificate of type #gnutls_x509_crt_t
 * @id: The key ID
 * @id_size: Holds the size of the subject key ID field.
 *
 * This function will set the X.509 certificate's subject key ID
 * extension.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crt_set_subject_key_id(gnutls_x509_crt_t cert,
				   const void *id, size_t id_size)
{
	int result;
	gnutls_datum_t old_id, der_data;
	gnutls_datum_t d_id;
	unsigned int critical;

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

	/* Check if the extension already exists.
	 */
	result =
	    _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 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.
	 */
	d_id.data = (void*)id;
	d_id.size = id_size;

	result = gnutls_x509_ext_export_subject_key_id(&d_id, &der_data);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	result =
	    _gnutls_x509_crt_set_extension(cert, "2.5.29.14", &der_data,
					   0);

	_gnutls_free_datum(&der_data);

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

	cert->use_extensions = 1;

	return 0;
}
Esempio n. 3
0
/**
 * gnutls_x509_crt_cpy_crl_dist_points:
 * @dst: a certificate of type #gnutls_x509_crt_t
 * @src: the certificate where the dist points will be copied from
 *
 * This function will copy the CRL distribution points certificate
 * extension, from the source to the destination certificate.
 * This may be useful to copy from a CA certificate to issued ones.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crt_cpy_crl_dist_points(gnutls_x509_crt_t dst,
				    gnutls_x509_crt_t src)
{
	int result;
	gnutls_datum_t der_data;
	unsigned int critical;

	if (dst == NULL || src == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	/* Check if the extension already exists.
	 */
	result =
	    _gnutls_x509_crt_get_extension(src, "2.5.29.31", 0, &der_data,
					   &critical);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	result =
	    _gnutls_x509_crt_set_extension(dst, "2.5.29.31", &der_data,
					   critical);
	_gnutls_free_datum(&der_data);

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

	dst->use_extensions = 1;

	return 0;
}
Esempio n. 4
0
/**
 * gnutls_x509_crt_get_name_constraints:
 * @crt: should contain a #gnutls_x509_crt_t type
 * @nc: The nameconstraints intermediate type
 * @flags: zero or %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND
 * @critical: the extension status
 *
 * This function will return an intermediate type containing
 * the name constraints of the provided CA certificate. That
 * structure can be used in combination with gnutls_x509_name_constraints_check()
 * to verify whether a server's name is in accordance with the constraints.
 *
 * When the @flags is set to %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, then if 
 * the @nc structure is empty
 * this function will behave identically as if the flag was not set.
 * Otherwise if there are elements in the @nc structure then only the
 * excluded constraints will be appended to the constraints.
 *
 * Note that @nc must be initialized prior to calling this function.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
 * if the extension is not present, otherwise a negative error value.
 *
 * Since: 3.3.0
 **/
int gnutls_x509_crt_get_name_constraints(gnutls_x509_crt_t crt,
					 gnutls_x509_name_constraints_t nc,
					 unsigned int flags,
					 unsigned int *critical)
{
	int ret;
	gnutls_datum_t der = { NULL, 0 };

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

	ret =
	    _gnutls_x509_crt_get_extension(crt, "2.5.29.30", 0, &der,
					   critical);
	if (ret < 0)
		return gnutls_assert_val(ret);

	if (der.size == 0 || der.data == NULL)
		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);

	ret = gnutls_x509_ext_import_name_constraints(&der, nc, flags);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = 0;

 cleanup:
	_gnutls_free_datum(&der);

	return ret;

}
Esempio n. 5
0
/**
 * gnutls_x509_crt_set_issuer_alt_name:
 * @crt: a certificate of type #gnutls_x509_crt_t
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
 * @data: The data to be set
 * @data_size: The size of data to be set
 * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. 
 *
 * This function will set the issuer alternative name certificate
 * extension. It can set the same types as gnutls_x509_crt_set_subject_alt_name().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.3.0
 **/
int
gnutls_x509_crt_set_issuer_alt_name(gnutls_x509_crt_t crt,
				     gnutls_x509_subject_alt_name_t type,
				     const void *data,
				     unsigned int data_size,
				     unsigned int flags)
{
	int result;
	gnutls_datum_t der_data = { NULL, 0 };
	gnutls_datum_t prev_der_data = { NULL, 0 };
	unsigned int critical = 0;

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

	/* Check if the extension already exists.
	 */

	if (flags == GNUTLS_FSAN_APPEND) {
		result =
		    _gnutls_x509_crt_get_extension(crt, "2.5.29.18", 0,
						   &prev_der_data,
						   &critical);
		if (result < 0
		    && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
			gnutls_assert();
			return result;
		}
	}

	/* generate the extension.
	 */
	result =
	    _gnutls_x509_ext_gen_subject_alt_name(type, data, data_size,
						  &prev_der_data,
						  &der_data);

	if (flags == GNUTLS_FSAN_APPEND)
		_gnutls_free_datum(&prev_der_data);

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

	result =
	    _gnutls_x509_crt_set_extension(crt, "2.5.29.18", &der_data,
					   critical);

	_gnutls_free_datum(&der_data);

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

	crt->use_extensions = 1;

	return 0;

      finish:
	_gnutls_free_datum(&prev_der_data);
	return result;
}
Esempio n. 6
0
/**
 * gnutls_x509_crt_set_policy:
 * @crt: 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,
			   const struct gnutls_x509_policy_st *policy,
			   unsigned int critical)
{
	int ret;
	gnutls_datum_t der_data = {NULL, 0}, prev_der_data = { NULL, 0 };
	gnutls_x509_policies_t policies = NULL;

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

	ret = gnutls_x509_policies_init(&policies);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

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


	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
		ret = gnutls_x509_ext_import_policies(&prev_der_data,
			policies, 0);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	ret = gnutls_x509_policies_set(policies, policy);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = gnutls_x509_ext_export_policies(policies, &der_data);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

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

	crt->use_extensions = 1;

 cleanup:
 	if (policies != NULL)
	 	gnutls_x509_policies_deinit(policies);
	_gnutls_free_datum(&prev_der_data);
	_gnutls_free_datum(&der_data);

	return ret;
}
Esempio n. 7
0
/**
 * gnutls_x509_crt_set_authority_info_access:
 * @crt: Holds the certificate
 * @what: what data to get, a #gnutls_info_access_what_t type.
 * @data: output data to be freed with gnutls_free().
 *
 * This function sets the Authority Information Access (AIA)
 * extension, see RFC 5280 section 4.2.2.1 for more information.  
 *
 * The type of data stored in @data is specified via @what which
 * should be #gnutls_info_access_what_t values.
 *
 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
 * URI.  
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0
 **/
int
gnutls_x509_crt_set_authority_info_access(gnutls_x509_crt_t crt,
					  int what, gnutls_datum_t * data)
{
	int ret;
	gnutls_datum_t der = { NULL, 0 };
	gnutls_datum_t new_der = { NULL, 0 };
	gnutls_x509_aia_t aia_ctx = NULL;
	const char *oid;
	unsigned int c;

	if (crt == NULL)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	ret = gnutls_x509_aia_init(&aia_ctx);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &der,
					     &c);
	if (ret >= 0) {		/* decode it */
		ret = gnutls_x509_ext_import_aia(&der, aia_ctx, 0);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	if (what == GNUTLS_IA_OCSP_URI)
		oid = GNUTLS_OID_AD_OCSP;
	else if (what == GNUTLS_IA_CAISSUERS_URI)
		oid = GNUTLS_OID_AD_CAISSUERS;
	else
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
	ret = gnutls_x509_aia_set(aia_ctx, oid, GNUTLS_SAN_URI, data);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = gnutls_x509_ext_export_aia(aia_ctx, &new_der);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_x509_crt_set_extension(crt, GNUTLS_OID_AIA,
					     &new_der, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	crt->use_extensions = 1;

      cleanup:
      	if (aia_ctx != NULL)
      		gnutls_x509_aia_deinit(aia_ctx);
	_gnutls_free_datum(&new_der);
	_gnutls_free_datum(&der);

	return ret;
}
Esempio n. 8
0
/**
 * gnutls_x509_crt_set_key_purpose_oid:
 * @cert: a certificate of type #gnutls_x509_crt_t
 * @oid: a pointer to a null terminated string that holds the OID
 * @critical: Whether this extension will be critical or not
 *
 * This function will set the key purpose OIDs of the Certificate.
 * These are stored in the Extended Key Usage extension (2.5.29.37)
 * See the GNUTLS_KP_* definitions for human readable names.
 *
 * Subsequent calls to this function will append OIDs to the OID list.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 **/
int
gnutls_x509_crt_set_key_purpose_oid(gnutls_x509_crt_t cert,
				    const void *oid, unsigned int critical)
{
	int ret;
	gnutls_datum_t old_id = {NULL,0};
	gnutls_datum_t der = {NULL,0};
	gnutls_x509_key_purposes_t p = NULL;

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

	ret = gnutls_x509_key_purpose_init(&p);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* Check if the extension already exists.
	 */
	ret =
	    _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &old_id,
					   NULL);

	if (ret >= 0) {
		ret = gnutls_x509_ext_import_key_purposes(&old_id, p, 0);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	ret = gnutls_x509_key_purpose_set(p, oid);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = gnutls_x509_ext_export_key_purposes(p, &der);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_x509_crt_set_extension(cert, "2.5.29.37",
						&der, critical);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	cert->use_extensions = 1;

	ret = 0;
 cleanup:
	_gnutls_free_datum(&der);
	_gnutls_free_datum(&old_id);
	if (p != NULL)
		gnutls_x509_key_purpose_deinit(p);

	return ret;

}
Esempio n. 9
0
/**
 * gnutls_x509_crt_set_crl_dist_points2:
 * @crt: a certificate of type #gnutls_x509_crt_t
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
 * @data: The data to be set
 * @data_size: The data size
 * @reason_flags: revocation reasons
 *
 * This function will set the CRL distribution points certificate extension.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.6.0
 **/
int
gnutls_x509_crt_set_crl_dist_points2(gnutls_x509_crt_t crt,
				     gnutls_x509_subject_alt_name_t type,
				     const void *data,
				     unsigned int data_size,
				     unsigned int reason_flags)
{
	int ret;
	gnutls_datum_t der_data = { NULL, 0 };
	gnutls_datum_t old_der = { NULL, 0 };
	unsigned int critical;
	gnutls_x509_crl_dist_points_t cdp = NULL;
	gnutls_datum_t san;

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

	ret = gnutls_x509_crl_dist_points_init(&cdp);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* Check if the extension already exists.
	 */
	ret =
	    _gnutls_x509_crt_get_extension(crt, "2.5.29.31", 0, &old_der,
					   &critical);

	if (ret >= 0 && old_der.data != NULL) {
		ret = gnutls_x509_ext_import_crl_dist_points(&old_der, cdp, 0);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	san.data = (void*)data;
	san.size = data_size;
	ret = gnutls_x509_crl_dist_points_set(cdp, type, &san, reason_flags);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* generate the extension.
	 */
	ret =
	    gnutls_x509_ext_export_crl_dist_points(cdp, &der_data);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret =
	    _gnutls_x509_crt_set_extension(crt, "2.5.29.31", &der_data, 0);

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

	crt->use_extensions = 1;
	ret = 0;
 cleanup:
	_gnutls_free_datum(&der_data);
	_gnutls_free_datum(&old_der);
	if (cdp != NULL)
		gnutls_x509_crl_dist_points_deinit(cdp);

	return ret;

}
Esempio n. 10
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;
}
Esempio n. 11
0
/**
 * gnutls_x509_crt_set_authority_info_access:
 * @crt: Holds the certificate
 * @what: what data to get, a #gnutls_info_access_what_t type.
 * @data: output data to be freed with gnutls_free().
 *
 * This function sets the Authority Information Access (AIA)
 * extension, see RFC 5280 section 4.2.2.1 for more information.  
 *
 * The type of data stored in @data is specified via @what which
 * should be #gnutls_info_access_what_t values.
 *
 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
 * URI.  
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0
 **/
int
gnutls_x509_crt_set_authority_info_access(gnutls_x509_crt_t crt,
					  int what, gnutls_datum_t * data)
{
	int ret, result;
	gnutls_datum_t aia = { NULL, 0 };
	gnutls_datum_t der_data = { NULL, 0 };
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
	const char *oid;
	unsigned int c;

	if (crt == NULL)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	oid = what_to_oid(what);
	if (oid == NULL)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	ret = asn1_create_element(_gnutls_get_pkix(),
				  "PKIX1.AuthorityInfoAccessSyntax", &c2);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(ret);
	}

	ret = _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &aia,
					     &c);
	if (ret >= 0) {		/* decode it */
		ret = asn1_der_decoding(&c2, aia.data, aia.size, NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}
	}

	/* generate the extension.
	 */
	/* 1. create a new element.
	 */
	result = asn1_write_value(c2, "", "NEW", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

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

	/* accessLocation is a choice */
	result =
	    asn1_write_value(c2, "?LAST.accessLocation",
			     "uniformResourceIdentifier", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	result =
	    asn1_write_value(c2,
			     "?LAST.accessLocation.uniformResourceIdentifier",
			     data->data, data->size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

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

	ret = _gnutls_x509_crt_set_extension(crt, GNUTLS_OID_AIA,
					     &der_data, 0);
	if (ret < 0)
		gnutls_assert();

	crt->use_extensions = 1;

      cleanup:
	_gnutls_free_datum(&der_data);
	_gnutls_free_datum(&aia);
	asn1_delete_structure(&c2);

	return ret;
}
Esempio n. 12
0
/**
 * gnutls_x509_crt_set_key_purpose_oid:
 * @cert: a certificate of type #gnutls_x509_crt_t
 * @oid: a pointer to a null terminated string that holds the OID
 * @critical: Whether this extension will be critical or not
 *
 * This function will set the key purpose OIDs of the Certificate.
 * These are stored in the Extended Key Usage extension (2.5.29.37)
 * See the GNUTLS_KP_* definitions for human readable names.
 *
 * Subsequent calls to this function will append OIDs to the OID list.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 **/
int
gnutls_x509_crt_set_key_purpose_oid(gnutls_x509_crt_t cert,
				    const void *oid, unsigned int critical)
{
	int result;
	gnutls_datum_t old_id, der_data;
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

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

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

	/* Check if the extension already exists.
	 */
	result =
	    _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &old_id,
					   NULL);

	if (result >= 0) {
		/* decode it.
		 */
		result =
		    asn1_der_decoding(&c2, old_id.data, old_id.size, NULL);
		_gnutls_free_datum(&old_id);

		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			asn1_delete_structure(&c2);
			return _gnutls_asn2err(result);
		}

	}

	/* generate the extension.
	 */
	/* 1. create a new element.
	 */
	result = asn1_write_value(c2, "", "NEW", 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&c2);
		return _gnutls_asn2err(result);
	}

	/* 2. Add the OID.
	 */
	result = asn1_write_value(c2, "?LAST", oid, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&c2);
		return _gnutls_asn2err(result);
	}

	result = _gnutls_x509_der_encode(c2, "", &der_data, 0);
	asn1_delete_structure(&c2);

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

	result = _gnutls_x509_crt_set_extension(cert, "2.5.29.37",
						&der_data, critical);

	_gnutls_free_datum(&der_data);

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

	cert->use_extensions = 1;

	return 0;

}