Пример #1
0
static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
{
	struct sc_object_id oid;
	int i = 0;
	char tmp[12];
	char sbuf[(sizeof tmp)*SC_MAX_OBJECT_ID_OCTETS];

	if (sc_asn1_decode_object_id(buf, buflen, &oid)) {
		printf("decode error");
		return;
	}

	sbuf[0] = 0;
	for (i = 0; (i < SC_MAX_OBJECT_ID_OCTETS) && (oid.value[i] != -1); i++)   {

		if (i)
			strcat(sbuf, ".");
		sprintf(tmp, "%d", oid.value[i]);
		strcat(sbuf, tmp);
	}
	printf("%s", sbuf);
}
Пример #2
0
/* Get a component of Distinguished Name (e.i. subject or issuer) USING the oid tag.
 * dn can be either cert->subject or cert->issuer.
 * dn_len would be cert->subject_len or cert->issuer_len.
 *
 * Common types:
 *   CN:      struct sc_object_id type = {{2, 5, 4, 3, -1}};
 *   Country: struct sc_object_id type = {{2, 5, 4, 6, -1}};
 *   L:       struct sc_object_id type = {{2, 5, 4, 7, -1}};
 *   S:       struct sc_object_id type = {{2, 5, 4, 8, -1}};
 *   O:       struct sc_object_id type = {{2, 5, 4, 10, -1}};
 *   OU:      struct sc_object_id type = {{2, 5, 4, 11, -1}};
 *
 * if *name is NULL, sc_pkcs15_get_name_from_dn will allocate space for name.
 */
int
sc_pkcs15_get_name_from_dn(struct sc_context *ctx, const u8 *dn, size_t dn_len,
	const struct sc_object_id *type, u8 **name, size_t *name_len)
{
	const u8 *rdn = NULL;
	const u8 *next_ava = NULL;
	size_t rdn_len = 0;
	size_t next_ava_len = 0;
	int rv;

	rdn = sc_asn1_skip_tag(ctx, &dn, &dn_len, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &rdn_len);
	if (rdn == NULL)
		LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of Distiguished Name");

	for (next_ava = rdn, next_ava_len = rdn_len; next_ava_len; ) {
		const u8 *ava, *dummy, *oidp;
		struct sc_object_id oid;
		size_t ava_len, dummy_len, oid_len;

		/* unwrap the set and point to the next ava */
		ava = sc_asn1_skip_tag(ctx, &next_ava, &next_ava_len, SC_ASN1_TAG_SET | SC_ASN1_CONS, &ava_len);
		if (ava == NULL)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of AVA");

		/* It would be nice to use sc_asn1_decode here to parse the entire AVA, but we are missing 1 critical
		 *	function in the templates: the ability to accept any tag for value. This prevents us from just
		 *	grabbing the value as is out of the template. AVA's can have tags of PRINTABLE_STRING,
		 *	TELETEXSTRING, T61STRING or UTF8_STRING with PRINTABLE_STRING and UTF8_STRING being the most common.
		 * The other feature that would be nice is returning a pointer to our requested data using the space
		 *	of the parent (basically what this code is doing here), rather than allocating and copying.
		 */

		/* unwrap the sequence */
		dummy = ava; dummy_len = ava_len;
		ava = sc_asn1_skip_tag(ctx, &dummy, &dummy_len, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &ava_len);
		if (ava == NULL)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of AVA");

		/* unwrap the oid */
		oidp = sc_asn1_skip_tag(ctx, &ava, &ava_len, SC_ASN1_TAG_OBJECT, &oid_len);
		if (ava == NULL)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of AVA OID");

		/* Convert to OID */
		rv = sc_asn1_decode_object_id(oidp, oid_len, &oid);
		if (rv != SC_SUCCESS)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of AVA OID");

		if (sc_compare_oid(&oid, type) == 0)
			continue;

		/* Yes, then return the name */
		dummy = sc_asn1_skip_tag(ctx, &ava, &ava_len, ava[0] & SC_ASN1_TAG_PRIMITIVE, &dummy_len);
		if (*name == NULL) {
			*name = malloc(dummy_len);
			if (*name == NULL)
				LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
			*name_len = dummy_len;
		}

		*name_len = MIN(dummy_len, *name_len);
		memcpy(*name, dummy, *name_len);
		LOG_FUNC_RETURN(ctx, SC_SUCCESS);
	}

	LOG_FUNC_RETURN(ctx, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
}