Example #1
0
File: tpm.c Project: gnutls/gnutls
/**
 * gnutls_pubkey_import_tpm_url:
 * @pkey: The public key
 * @url: The URL of the TPM key to be imported
 * @srk_password: The password for the SRK key (optional)
 * @flags: should be zero
 *
 * This function will import the given private key to the abstract
 * #gnutls_privkey_t type. 
 *
 * Note that unless %GNUTLS_PUBKEY_DISABLE_CALLBACKS
 * is specified, if incorrect (or NULL) passwords are given
 * the PKCS11 callback functions will be used to obtain the
 * correct passwords. Otherwise if the SRK password is wrong
 * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.1.0
 *
 **/
int
gnutls_pubkey_import_tpm_url(gnutls_pubkey_t pkey,
			     const char *url,
			     const char *srk_password, unsigned int flags)
{
	struct tpmkey_url_st durl;
	gnutls_datum_t fdata = { NULL, 0 };
	int ret;

	CHECK_INIT;

	ret = decode_tpmkey_url(url, &durl);
	if (ret < 0)
		return gnutls_assert_val(ret);

	if (durl.filename) {

		ret = gnutls_load_file(durl.filename, &fdata);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		ret =
		    gnutls_pubkey_import_tpm_raw(pkey, &fdata,
						 GNUTLS_TPMKEY_FMT_CTK_PEM,
						 srk_password, flags);
		if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
			ret =
			    gnutls_pubkey_import_tpm_raw(pkey, &fdata,
							 GNUTLS_TPMKEY_FMT_RAW,
							 srk_password,
							 flags);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	} else if (durl.uuid_set) {
		if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS)
			ret =
			    import_tpm_pubkey(pkey, NULL, 0, &durl.uuid,
					      durl.storage, srk_password);
		else
			ret =
			    import_tpm_pubkey_cb(pkey, NULL, 0, &durl.uuid,
						 durl.storage,
						 srk_password);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	ret = 0;
      cleanup:
	gnutls_free(fdata.data);
	clear_tpmkey_url(&durl);
	return ret;
}
Example #2
0
static int decode_tpmkey_url(const char *url, struct tpmkey_url_st *s)
{
	char *p;
	size_t size;
	int ret;
	unsigned int i, j;

	if (strstr(url, "tpmkey:") == NULL)
		return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);

	memset(s, 0, sizeof(*s));

	p = strstr(url, "file=");
	if (p != NULL) {
		p += sizeof("file=") - 1;
		size = strlen(p);
		s->filename = gnutls_malloc(size + 1);
		if (s->filename == NULL)
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

		ret = unescape_string(s->filename, p, &size, ';');
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		s->filename[size] = 0;
	} else if ((p = strstr(url, "uuid=")) != NULL) {
		char tmp_uuid[33];
		uint8_t raw_uuid[16];

		p += sizeof("uuid=") - 1;
		size = strlen(p);

		for (j = i = 0; i < size; i++) {
			if (j == sizeof(tmp_uuid) - 1) {
				break;
			}
			if (c_isalnum(p[i]))
				tmp_uuid[j++] = p[i];
		}
		tmp_uuid[j] = 0;

		size = sizeof(raw_uuid);
		ret =
		    _gnutls_hex2bin(tmp_uuid, strlen(tmp_uuid), raw_uuid,
				    &size);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		memcpy(&s->uuid.ulTimeLow, raw_uuid, 4);
		memcpy(&s->uuid.usTimeMid, &raw_uuid[4], 2);
		memcpy(&s->uuid.usTimeHigh, &raw_uuid[6], 2);
		s->uuid.bClockSeqHigh = raw_uuid[8];
		s->uuid.bClockSeqLow = raw_uuid[9];
		memcpy(&s->uuid.rgbNode, &raw_uuid[10], 6);
		s->uuid_set = 1;
	} else {
		return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
	}

	if ((p = strstr(url, "storage=user")) != NULL)
		s->storage = TSS_PS_TYPE_USER;
	else
		s->storage = TSS_PS_TYPE_SYSTEM;

	return 0;

      cleanup:
	clear_tpmkey_url(s);
	return ret;
}