Esempio n. 1
0
/* This will encode and write the AttributeTypeAndValue field.
 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
 * In all cases only one value is written.
 */
int
_gnutls_x509_encode_and_write_attribute(const char *given_oid,
					ASN1_TYPE asn1_struct,
					const char *where,
					const void *_data,
					int data_size, int multi)
{
	const uint8_t *data = _data;
	char tmp[128];
	int result;
	const struct oid_to_string *oentry;

	oentry = get_oid_entry(given_oid);
	if (oentry == NULL) {
		gnutls_assert();
		_gnutls_debug_log("Cannot find OID: %s\n", given_oid);
		return GNUTLS_E_X509_UNSUPPORTED_OID;
	}

	/* write the data (value)
	 */

	_gnutls_str_cpy(tmp, sizeof(tmp), where);
	_gnutls_str_cat(tmp, sizeof(tmp), ".value");

	if (multi != 0) {	/* if not writing an AttributeTypeAndValue, but an Attribute */
		_gnutls_str_cat(tmp, sizeof(tmp), "s");	/* values */

		result = asn1_write_value(asn1_struct, tmp, "NEW", 1);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto error;
		}

		_gnutls_str_cat(tmp, sizeof(tmp), ".?LAST");
	}

	if (oentry->asn_desc != NULL) {	/* write a complex string API */
		result =
		    write_complex_string(asn1_struct, tmp, oentry, data,
					 data_size);
		if (result < 0)
			return gnutls_assert_val(result);
	} else {		/* write a simple string */

		gnutls_datum_t td;

		td.data = (void *) data;
		td.size = data_size;
		result =
		    _gnutls_x509_write_string(asn1_struct, tmp, &td,
					      oentry->etype);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}
	}

	/* write the type
	 */
	_gnutls_str_cpy(tmp, sizeof(tmp), where);
	_gnutls_str_cat(tmp, sizeof(tmp), ".type");

	result = asn1_write_value(asn1_struct, tmp, given_oid, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result = 0;

      error:
	return result;
}
Esempio n. 2
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. 3
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;

	switch (type) {
	case 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_string(c2, "certValue", raw,
					      ASN1_ETYPE_OCTET_STRING);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		break;

	case GNUTLS_BAG_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_string(c2, "crlValue", raw,
					      ASN1_ETYPE_OCTET_STRING);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		break;

	case GNUTLS_BAG_SECRET:
		if ((ret = asn1_create_element(_gnutls_get_pkix(),
					       "PKIX1.pkcs-12-SecretBag",
					       &c2)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}

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

		ret =
		    _gnutls_x509_write_string(c2, "secretValue", raw,
					      ASN1_ETYPE_OCTET_STRING);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		break;

	default:
		gnutls_assert();
		asn1_delete_structure(&c2);
		return GNUTLS_E_UNIMPLEMENTED_FEATURE;
	}

	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;
}