<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html lang="en">
<head>
<meta content="text/html; charset=US-ASCII" http-equiv="Content-Type">
<title>
GitLab
</title>


<style>img {
max-width: 100%; height: auto;
}
</style>
</head>
<body>
<div class="content">

<p class="details" style="font-style: italic; color: #666;">
<a href="https://gitlab.com/ozbenh">Benjamin Herrenschmidt</a> created an issue: <a href="https://gitlab.com/gnutls/gnutls/-/issues/1340">#1340</a>
</p>
<div class="md">
<p dir="auto">Hi !</p>
<p dir="auto">I am a contributor to this "soft" token which talks to AWS KMS: <a href="https://github.com/JackOfMostTrades/aws-kms-pkcs11" rel="nofollow noreferrer noopener" target="_blank">https://github.com/JackOfMostTrades/aws-kms-pkcs11</a></p>
<p dir="auto">A given slot with this token has just two objects: A private key and a certificate.</p>
<p dir="auto">Retrieving the certificate fails with p11tool consistently. The error seem to be a disconnect between those two functions in gnutls lib/pkcs11.c:</p>
<ul dir="auto">
<li>find_privkeys()</li>
</ul>
<p dir="auto">It properly finds the private key and reaches the following code:</p>
<div class="gl-relative markdown-code-block js-markdown-code">
<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true" style="border-radius: 2px; margin: 0 0 8px; padding: 8px 12px; border: 1px solid #dbdbdb;"><code><span id="LC1" class="line" lang="plaintext"> current = 0;</span>
<span id="LC2" class="line" lang="plaintext">       while (pkcs11_find_objects</span>
<span id="LC3" class="line" lang="plaintext">              (sinfo->module, sinfo->pks, &ctx, 1, &count) == CKR_OK</span>
<span id="LC4" class="line" lang="plaintext">              && count == 1) {</span>
<span id="LC5" class="line" lang="plaintext"></span>
<span id="LC6" class="line" lang="plaintext">               a[0].type = CKA_ID;</span>
<span id="LC7" class="line" lang="plaintext">               a[0].value = certid_tmp;</span>
<span id="LC8" class="line" lang="plaintext">               a[0].value_len = sizeof(certid_tmp);</span>
<span id="LC9" class="line" lang="plaintext"></span>
<span id="LC10" class="line" lang="plaintext">              _gnutls_buffer_init(&list->key_ids[current]);</span>
<span id="LC11" class="line" lang="plaintext"></span>
<span id="LC12" class="line" lang="plaintext">              if (pkcs11_get_attribute_value</span>
<span id="LC13" class="line" lang="plaintext">                  (sinfo->module, sinfo->pks, ctx, a, 1) == CKR_OK) {</span>
<span id="LC14" class="line" lang="plaintext">                      ret = _gnutls_buffer_append_data(&list->key_ids[current],</span>
<span id="LC15" class="line" lang="plaintext">                                                 a[0].value,</span>
<span id="LC16" class="line" lang="plaintext">                                                 a[0].value_len);</span>
<span id="LC17" class="line" lang="plaintext">                      if (ret < 0)</span>
<span id="LC18" class="line" lang="plaintext">                              return gnutls_assert_val(ret);</span>
<span id="LC19" class="line" lang="plaintext">                      current++;</span>
<span id="LC20" class="line" lang="plaintext">              }</span>
<span id="LC21" class="line" lang="plaintext"></span>
<span id="LC22" class="line" lang="plaintext">              if (current > list->key_ids_size)</span>
<span id="LC23" class="line" lang="plaintext">                      break;</span>
<span id="LC24" class="line" lang="plaintext">      }</span>
<span id="LC25" class="line" lang="plaintext"></span>
<span id="LC26" class="line" lang="plaintext">      pkcs11_find_objects_final(sinfo);</span>
<span id="LC27" class="line" lang="plaintext"></span>
<span id="LC28" class="line" lang="plaintext">      list->key_ids_size = current - 1;</span></code></pre>
<copy-code></copy-code>
</div>
<p dir="auto">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:</p>
<div class="gl-relative markdown-code-block js-markdown-code">
<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true" style="border-radius: 2px; margin: 0 0 8px; padding: 8px 12px; border: 1px solid #dbdbdb;"><code><span id="LC1" class="line" lang="plaintext">current = 1</span></code></pre>
<copy-code></copy-code>
</div>
<p dir="auto">We thus return from the function with</p>
<div class="gl-relative markdown-code-block js-markdown-code">
<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true" style="border-radius: 2px; margin: 0 0 8px; padding: 8px 12px; border: 1px solid #dbdbdb;"><code><span id="LC1" class="line" lang="plaintext">list->key_ids_size = 0</span></code></pre>
<copy-code></copy-code>
</div>
<p dir="auto">Now, this is called from this code in find_multi_objs_cb() (note: this is the only caller)</p>
<div class="gl-relative markdown-code-block js-markdown-code">
<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true" style="border-radius: 2px; margin: 0 0 8px; padding: 8px 12px; border: 1px solid #dbdbdb;"><code><span id="LC1" class="line" lang="plaintext"> memset(&plist, 0, sizeof(plist));</span>
<span id="LC2" class="line" lang="plaintext"></span>
<span id="LC3" class="line" lang="plaintext">       if (find_data->flags & GNUTLS_PKCS11_OBJ_FLAG_WITH_PRIVKEY) {</span>
<span id="LC4" class="line" lang="plaintext">               ret = find_privkeys(sinfo, tinfo, &plist);</span>
<span id="LC5" class="line" lang="plaintext">               if (ret < 0) {</span>
<span id="LC6" class="line" lang="plaintext">                       gnutls_assert();</span>
<span id="LC7" class="line" lang="plaintext">                       return ret;</span>
<span id="LC8" class="line" lang="plaintext">               }</span>
<span id="LC9" class="line" lang="plaintext"></span>
<span id="LC10" class="line" lang="plaintext">              if (plist.key_ids_size == 0) {</span>
<span id="LC11" class="line" lang="plaintext">                      gnutls_assert();</span>
<span id="LC12" class="line" lang="plaintext">                      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;</span>
<span id="LC13" class="line" lang="plaintext">              }</span>
<span id="LC14" class="line" lang="plaintext">      }</span></code></pre>
<copy-code></copy-code>
</div>
<p dir="auto">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....</p>
<p dir="auto">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:</p>
<ul dir="auto">
<li>
<p>Remove the "-1" when setting key_ids_size in find_privKeys(). This is IMHO the most
obvious fix and provides the clearest semantic</p>
</li>
<li>
<p>Remvoe the second test in the caller</p>
</li>
</ul>
<p dir="auto">Recommendations ? Did I get something very wrong ? :-)</p>
</div>

</div>
<div class="footer" style="margin-top: 10px;">
<p style="font-size: small; color: #666;">

<br>
Reply to this email directly or <a href="https://gitlab.com/gnutls/gnutls/-/issues/1340">view it on GitLab</a>.
<br>
You're receiving this email because of your account on gitlab.com.
If you'd like to receive fewer emails, you can
<a href="https://gitlab.com/-/sent_notifications/421cd821bba0ded1f0e60ab84899db37/unsubscribe">unsubscribe</a>
from this thread or
adjust your notification settings.
<script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","action":{"@type":"ViewAction","name":"View Issue","url":"https://gitlab.com/gnutls/gnutls/-/issues/1340"}}</script>


</p>
</div>
</body>
</html>