Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
  • Sign in / Register
  • GnuTLS GnuTLS
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 252
    • Issues 252
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
    • Requirements
  • Merge requests 18
    • Merge requests 18
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • gnutlsgnutls
  • GnuTLSGnuTLS
  • Issues
  • #1340
Closed
Open
Created Mar 18, 2022 by Benjamin Herrenschmidt@ozbenhContributor

p11tool fails to find certs with AWS KMS token (with possible fix ?)

Hi !

I am a contributor to this "soft" token which talks to AWS KMS: https://github.com/JackOfMostTrades/aws-kms-pkcs11

A given slot with this token has just two objects: A private key and a certificate.

Retrieving the certificate fails with p11tool consistently. The error seem to be a disconnect between those two functions in gnutls lib/pkcs11.c:

  • find_privkeys()

It properly finds the private key and reaches the following code:

	current = 0;
	while (pkcs11_find_objects
	       (sinfo->module, sinfo->pks, &ctx, 1, &count) == CKR_OK
	       && count == 1) {

		a[0].type = CKA_ID;
		a[0].value = certid_tmp;
		a[0].value_len = sizeof(certid_tmp);

		_gnutls_buffer_init(&list->key_ids[current]);

		if (pkcs11_get_attribute_value
		    (sinfo->module, sinfo->pks, ctx, a, 1) == CKR_OK) {
			ret = _gnutls_buffer_append_data(&list->key_ids[current],
						   a[0].value,
						   a[0].value_len);
			if (ret < 0)
				return gnutls_assert_val(ret);
			current++;
		}

		if (current > list->key_ids_size)
			break;
	}

	pkcs11_find_objects_final(sinfo);

	list->key_ids_size = current - 1;

There is only one iteration of the loop since there's only one object of type CKO_PRIVATE_KEY in the token. The retrieval of the attribute works fine, so we exist the loop with:

current = 1

We thus return from the function with

list->key_ids_size = 0

Now, this is called from this code in find_multi_objs_cb() (note: this is the only caller)

	memset(&plist, 0, sizeof(plist));

	if (find_data->flags & GNUTLS_PKCS11_OBJ_FLAG_WITH_PRIVKEY) {
		ret = find_privkeys(sinfo, tinfo, &plist);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		if (plist.key_ids_size == 0) {
			gnutls_assert();
			return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
		}
	}

As you can see, it will hit the case where plist.key_ids_size is 0 and fail. There seem to be a disconnect as to whether key_ids_size is 0 or 1 based between the caller and the callee....

Now I'm happy to send a pull request with a fix provided somebody can confirm that my analysis is correct. I can see two main approach to fix this:

  • Remove the "-1" when setting key_ids_size in find_privKeys(). This is IMHO the most obvious fix and provides the clearest semantic

  • Remvoe the second test in the caller

Recommendations ? Did I get something very wrong ? :-)

Edited Mar 18, 2022 by Benjamin Herrenschmidt
Assignee
Assign to
Time tracking