Пример #1
0
int
_gnutls_x509_get_dn(ASN1_TYPE asn1_struct,
		    const char *asn1_rdn_name, gnutls_datum_t * dn)
{
	gnutls_buffer_st out_str;
	int k2, k1, result;
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	uint8_t value[MAX_STRING_LEN];
	gnutls_datum_t td = { NULL, 0 }, tvd = {
	NULL, 0};
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	int len;

	_gnutls_buffer_init(&out_str);

	k1 = 0;
	do {
		k1++;
		/* create a string like "tbsCertList.issuer.rdnSequence.?1"
		 */
		if (asn1_rdn_name[0] != 0)
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u",
				 asn1_rdn_name, k1);
		else
			snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u",
				 k1);

		len = sizeof(value) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer1, value, &len);

		if (result == ASN1_ELEMENT_NOT_FOUND) {
			if (k1 == 1) {
				gnutls_assert();
				result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
				goto cleanup;
			}
			break;
		}

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

		k2 = 0;

		do {		/* Move to the attibute type and values
				 */
			k2++;

			if (tmpbuffer1[0] != 0)
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "%s.?%u", tmpbuffer1, k2);
			else
				snprintf(tmpbuffer2, sizeof(tmpbuffer2),
					 "?%u", k2);

			/* Try to read the RelativeDistinguishedName attributes.
			 */

			len = sizeof(value) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer2, value,
					    &len);

			if (result == ASN1_ELEMENT_NOT_FOUND)
				break;
			if (result != ASN1_VALUE_NOT_FOUND) {
				gnutls_assert();
				result = _gnutls_asn2err(result);
				goto cleanup;
			}

			/* Read the OID 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".type");

			len = sizeof(oid) - 1;
			result =
			    asn1_read_value(asn1_struct, tmpbuffer3, oid,
					    &len);

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

			/* Read the Value 
			 */
			_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
					tmpbuffer2);
			_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
					".value");

			len = 0;

			result =
			    _gnutls_x509_read_value(asn1_struct,
						    tmpbuffer3, &tvd);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
#define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( &out_str, x,y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
			/*   The encodings of adjoining RelativeDistinguishedNames are separated
			 *   by a comma character (',' ASCII 44).
			 */

			/*   Where there is a multi-valued RDN, the outputs from adjoining
			 *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
			 *   character.
			 */
			if (k1 != 1) {	/* the first time do not append a comma */
				if (k2 != 1) {	/* adjoining multi-value RDN */
					STR_APPEND("+");
				} else {
					STR_APPEND(",");
				}
			}

			ldap_desc =
			    gnutls_x509_dn_oid_name(oid,
						    GNUTLS_X509_DN_OID_RETURN_OID);

			STR_APPEND(ldap_desc);
			STR_APPEND("=");

			result =
			    _gnutls_x509_dn_to_string(oid, tvd.data,
						      tvd.size, &td);
			if (result < 0) {
				gnutls_assert();
				_gnutls_debug_log
				    ("Cannot parse OID: '%s' with value '%s'\n",
				     oid, _gnutls_bin2hex(tvd.data,
							  tvd.size,
							  tmpbuffer3,
							  sizeof
							  (tmpbuffer3),
							  NULL));
				goto cleanup;
			}

			DATA_APPEND(td.data, td.size);
			_gnutls_free_datum(&td);
			_gnutls_free_datum(&tvd);
		}
		while (1);
	}
	while (1);

	result = _gnutls_buffer_to_datum(&out_str, dn, 1);
	if (result < 0)
		gnutls_assert();

	goto cleanup1;

      cleanup:
	_gnutls_buffer_clear(&out_str);
      cleanup1:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;

}
Пример #2
0
static int append_elements(ASN1_TYPE asn1_struct, const char *asn1_rdn_name, gnutls_buffer_st *str, int k1, unsigned last)
{
	int k2, result, max_k2;
	int len;
	uint8_t value[MAX_STRING_LEN];
	char tmpbuffer1[ASN1_MAX_NAME_SIZE];
	char tmpbuffer2[ASN1_MAX_NAME_SIZE];
	char tmpbuffer3[ASN1_MAX_NAME_SIZE];
	const char *ldap_desc;
	char oid[MAX_OID_SIZE];
	gnutls_datum_t td = { NULL, 0 };
	gnutls_datum_t tvd = { NULL, 0 };

	/* create a string like "tbsCertList.issuer.rdnSequence.?1"
	 */
	if (asn1_rdn_name[0] != 0)
		snprintf(tmpbuffer1, sizeof(tmpbuffer1), "%s.?%u",
			 asn1_rdn_name, k1);
	else
		snprintf(tmpbuffer1, sizeof(tmpbuffer1), "?%u",
			 k1);

	len = sizeof(value) - 1;
	result =
	    asn1_read_value(asn1_struct, tmpbuffer1, value, &len);

	if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS) { /* expected */
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	k2 = 0;

	result = asn1_number_of_elements(asn1_struct, tmpbuffer1, &max_k2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	do {		/* Move to the attibute type and values
				 */
		k2++;

		if (tmpbuffer1[0] != 0)
			snprintf(tmpbuffer2, sizeof(tmpbuffer2),
				 "%s.?%u", tmpbuffer1, k2);
		else
			snprintf(tmpbuffer2, sizeof(tmpbuffer2),
				 "?%u", k2);

		/* Try to read the RelativeDistinguishedName attributes.
		 */

		len = sizeof(value) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer2, value,
				    &len);

		if (result == ASN1_ELEMENT_NOT_FOUND)
			break;
		if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS) { /* expected */
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		/* Read the OID 
		 */
		_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
				tmpbuffer2);
		_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
				".type");

		len = sizeof(oid) - 1;
		result =
		    asn1_read_value(asn1_struct, tmpbuffer3, oid,
				    &len);

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

		/* Read the Value 
		 */
		_gnutls_str_cpy(tmpbuffer3, sizeof(tmpbuffer3),
				tmpbuffer2);
		_gnutls_str_cat(tmpbuffer3, sizeof(tmpbuffer3),
				".value");

		len = 0;

		result =
		    _gnutls_x509_read_value(asn1_struct,
					    tmpbuffer3, &tvd);
		if (result < 0) {
			gnutls_assert();
			goto cleanup;
		}
#define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( str, y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
#define DATA_APPEND(x,y) if ((result=_gnutls_buffer_append_data( str, x,y)) < 0) { \
	gnutls_assert(); \
	goto cleanup; \
}
		/*   The encodings of adjoining RelativeDistinguishedNames are separated
		 *   by a comma character (',' ASCII 44).
		 */

		ldap_desc =
		    gnutls_x509_dn_oid_name(oid,
					    GNUTLS_X509_DN_OID_RETURN_OID);

		STR_APPEND(ldap_desc);
		STR_APPEND("=");

		result =
		    _gnutls_x509_dn_to_string(oid, tvd.data,
					      tvd.size, &td);
		if (result < 0) {
			gnutls_assert();
			_gnutls_debug_log
			    ("Cannot parse OID: '%s' with value '%s'\n",
			     oid, _gnutls_bin2hex(tvd.data,
						  tvd.size,
						  tmpbuffer3,
						  sizeof
						  (tmpbuffer3),
						  NULL));
			goto cleanup;
		}

		DATA_APPEND(td.data, td.size);
		_gnutls_free_datum(&td);
		_gnutls_free_datum(&tvd);

		/*   Where there is a multi-valued RDN, the outputs from adjoining
		 *   AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
		 *   character.
		 */
		if (k2 < max_k2) {
			STR_APPEND("+");
		} else if (!last) {
			STR_APPEND(",");
		}
	}
	while (1);

	result = 0;

 cleanup:
	_gnutls_free_datum(&td);
	_gnutls_free_datum(&tvd);
	return result;
}