示例#1
0
/* This function will convert an attribute value, specified by the OID,
 * to a string. The result will be a null terminated string.
 *
 * res may be null. This will just return the res_size, needed to
 * hold the string.
 */
int
_gnutls_x509_dn_to_string(const char *oid, void *value,
			  int value_size, gnutls_datum_t * str)
{
	const struct oid_to_string *oentry;
	int ret;
	gnutls_datum_t tmp;
	size_t size;

	if (value == NULL || value_size <= 0) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	oentry = get_oid_entry(oid);
	if (oentry == NULL) {	/* unknown OID -> hex */
 unknown_oid:
		str->size = value_size * 2 + 2;
		str->data = gnutls_malloc(str->size);
		if (str->data == NULL)
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

		size = str->size;
		ret = data2hex(value, value_size, str->data, &size);
		if (ret < 0) {
			gnutls_assert();
			gnutls_free(str->data);
			return ret;
		}
		str->size = size;
		return 0;
	}

	if (oentry->asn_desc != NULL) {	/* complex */
		ret =
		    decode_complex_string(oentry, value, value_size, &tmp);
		if (ret < 0) {
			/* we failed decoding -> handle it as unknown OID */
			goto unknown_oid;
		}
	} else {
		ret =
		    _gnutls_x509_decode_string(oentry->etype, value,
					       value_size, &tmp);
		if (ret < 0) {
			/* we failed decoding -> handle it as unknown OID */
			goto unknown_oid;
		}
	}

	ret = str_escape(&tmp, str);
	_gnutls_free_datum(&tmp);

	if (ret < 0)
		return gnutls_assert_val(ret);

	return 0;
}
示例#2
0
/* Reads a value from an ASN1 tree, then interprets it as the provided
 * type of string and returns the output in an allocated variable.
 *
 * Note that this function always places a null character
 * at the end of a readable string value (which is not accounted into size)
 */
int
_gnutls_x509_read_string(ASN1_TYPE c, const char *root,
			 gnutls_datum_t * ret, unsigned int etype)
{
	int len = 0, result;
	size_t slen;
	uint8_t *tmp = NULL;
	unsigned rtype;

	result = asn1_read_value_type(c, root, NULL, &len, &rtype);
	if (result != ASN1_MEM_ERROR) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		return result;
	}

	if (rtype == ASN1_ETYPE_BIT_STRING)
		len /= 8;

	tmp = gnutls_malloc((size_t) len + 1);
	if (tmp == NULL) {
		gnutls_assert();
		result = GNUTLS_E_MEMORY_ERROR;
		goto cleanup;
	}

	result = asn1_read_value(c, root, tmp, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	if (rtype == ASN1_ETYPE_BIT_STRING)
		len /= 8;

	/* Extract the STRING.
	 */
	slen = (size_t) len;

	result = _gnutls_x509_decode_string(etype, tmp, slen, ret);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}
	gnutls_free(tmp);

	return 0;

      cleanup:
	gnutls_free(tmp);
	return result;
}
示例#3
0
文件: pkcs12.c 项目: gnutls/gnutls
/* Decodes the SafeContents, and puts the output in
 * the given bag. 
 */
int
_pkcs12_decode_safe_contents(const gnutls_datum_t * content,
			     gnutls_pkcs12_bag_t bag)
{
	char oid[MAX_OID_SIZE], root[MAX_NAME_SIZE];
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
	int len, result;
	int bag_type;
	gnutls_datum_t attr_val;
	gnutls_datum_t t;
	int count = 0, attributes, j;
	unsigned i;

	/* Step 1. Extract 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;
	}

	result =
	    asn1_der_decoding(&c2, content->data, content->size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	/* Count the number of bags
	 */
	result = asn1_number_of_elements(c2, "", &count);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto cleanup;
	}

	bag->bag_elements = MIN(MAX_BAG_ELEMENTS, count);

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

		snprintf(root, sizeof(root), "?%u.bagId", i + 1);

		len = sizeof(oid);
		result = asn1_read_value(c2, root, oid, &len);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		/* Read the Bag type
		 */
		bag_type = oid2bag(oid);

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

		/* Read the Bag Value
		 */

		snprintf(root, sizeof(root), "?%u.bagValue", i + 1);

		result =
		    _gnutls_x509_read_value(c2, root,
					    &bag->element[i].data);
		if (result < 0) {
			gnutls_assert();
			goto cleanup;
		}

		if (bag_type == GNUTLS_BAG_CERTIFICATE
		    || bag_type == GNUTLS_BAG_CRL
		    || bag_type == GNUTLS_BAG_SECRET) {
			gnutls_datum_t tmp = bag->element[i].data;
			bag->element[i].data.data = NULL;
			bag->element[i].data.size = 0;

			result =
			    _pkcs12_decode_crt_bag(bag_type, &tmp,
						   &bag->element[i].data);
			_gnutls_free_datum(&tmp);
			if (result < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}

		/* read the bag attributes
		 */
		snprintf(root, sizeof(root), "?%u.bagAttributes", i + 1);

		result = asn1_number_of_elements(c2, root, &attributes);
		if (result != ASN1_SUCCESS
		    && result != ASN1_ELEMENT_NOT_FOUND) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto cleanup;
		}

		if (attributes < 0)
			attributes = 1;

		if (result != ASN1_ELEMENT_NOT_FOUND)
			for (j = 0; j < attributes; j++) {

				snprintf(root, sizeof(root),
					 "?%u.bagAttributes.?%u", i + 1,
					 j + 1);

				result =
				    _gnutls_x509_decode_and_read_attribute
				    (c2, root, oid, sizeof(oid), &attr_val,
				     1, 0);

				if (result < 0) {
					gnutls_assert();
					continue;	/* continue in case we find some known attributes */
				}

				if (strcmp(oid, KEY_ID_OID) == 0) {
					result =
					    _gnutls_x509_decode_string
					    (ASN1_ETYPE_OCTET_STRING,
					     attr_val.data, attr_val.size,
					     &t, 1);

					_gnutls_free_datum(&attr_val);
					if (result < 0) {
						gnutls_assert();
						_gnutls_debug_log
						    ("Error decoding PKCS12 Bag Attribute OID '%s'\n",
						     oid);
						continue;
					}

					_gnutls_free_datum(&bag->element[i].local_key_id);
					bag->element[i].local_key_id.data = t.data;
					bag->element[i].local_key_id.size = t.size;
				} else if (strcmp(oid, FRIENDLY_NAME_OID) == 0 && bag->element[i].friendly_name == NULL) {
					result =
					    _gnutls_x509_decode_string
					    (ASN1_ETYPE_BMP_STRING,
					     attr_val.data, attr_val.size,
					     &t, 1);

					_gnutls_free_datum(&attr_val);
					if (result < 0) {
						gnutls_assert();
						_gnutls_debug_log
						    ("Error decoding PKCS12 Bag Attribute OID '%s'\n",
						     oid);
						continue;
					}

					gnutls_free(bag->element[i].friendly_name);
					bag->element[i].friendly_name = (char *) t.data;
				} else {
					_gnutls_free_datum(&attr_val);
					_gnutls_debug_log
					    ("Unknown PKCS12 Bag Attribute OID '%s'\n",
					     oid);
				}
			}


		bag->element[i].type = bag_type;

	}

	result = 0;

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

}
示例#4
0
文件: tpm.c 项目: randombit/hacrypto
static int load_key(TSS_HCONTEXT tpm_ctx, TSS_HKEY srk,
		    const gnutls_datum_t * fdata,
		    gnutls_tpmkey_fmt_t format, TSS_HKEY * tpm_key)
{
	int ret, err;
	gnutls_datum_t asn1 = { NULL, 0 };

	if (format == GNUTLS_TPMKEY_FMT_CTK_PEM) {
		gnutls_datum_t td;

		ret =
		    gnutls_pem_base64_decode_alloc("TSS KEY BLOB", fdata,
						   &asn1);
		if (ret) {
			gnutls_assert();
			_gnutls_debug_log
			    ("Error decoding TSS key blob: %s\n",
			     gnutls_strerror(ret));
			return ret;
		}

		ret =
		    _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
					       asn1.data, asn1.size, &td);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		gnutls_free(asn1.data);
		asn1.data = td.data;
		asn1.size = td.size;
	} else {		/* DER */

		UINT32 tint2;
		UINT32 type;

		asn1.size = fdata->size;
		asn1.data = gnutls_malloc(asn1.size);
		if (asn1.data == NULL) {
			gnutls_assert();
			return GNUTLS_E_MEMORY_ERROR;
		}

		tint2 = asn1.size;
		err =
		    Tspi_DecodeBER_TssBlob(fdata->size, fdata->data, &type,
					   &tint2, asn1.data);
		if (err != 0) {
			gnutls_assert();
			ret = tss_err(err);
			goto cleanup;
		}

		asn1.size = tint2;
	}

	/* ... we get it here instead. */
	err = Tspi_Context_LoadKeyByBlob(tpm_ctx, srk,
					 asn1.size, asn1.data, tpm_key);
	if (err != 0) {
		gnutls_assert();
		ret = tss_err(err);
		goto cleanup;
	}

	ret = 0;

      cleanup:
	gnutls_free(asn1.data);

	return ret;
}