Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cURL not working with some specif pkcs11 URLs with GnuTLS backend #16249

Closed
charles2910 opened this issue Feb 7, 2025 · 6 comments
Closed

cURL not working with some specif pkcs11 URLs with GnuTLS backend #16249

charles2910 opened this issue Feb 7, 2025 · 6 comments
Assignees

Comments

@charles2910
Copy link
Contributor

charles2910 commented Feb 7, 2025

Hi, this is the only known pending bug from our switch from openssl to gnutls backend on Debian. We've mentioned it to Daniel at FOSDEM and I'm forwarding to you guys because I lack the hardware (HSM) and the knowledge to dig deeper here - and we're also near the Debian freeze for the next stable release, but we should be able to upload new version up until may.

The original report is:

We have been heavily using curl to make API requests using smartcard
authentication. We have a private key and certificate on a Yubikey, and
we use curl to perform a pkcs11-authenticated login to get an API token.

Unfortunately, according to the curl man page, pkcs11 support is only
available if curl is built against openssl.

After some back and forth with the reporter and you on the issue tracker, some new info come by:

>>>>> "Samuel" == Samuel Henrique <samueloph@debian.org> writes:
    Samuel> This seems to be the biggest threat to the GnuTLS switch so
    Samuel> far.

    Samuel> In the meantime, if any of you could provide an easy
    Samuel> reproducer, it would save us a bit of time.

So, for example with a yubikey with the PIV application configured, I
can log into vault using the following code on bookworm:
    curl_args = []
    if args.insecure: curl_args.append('-k')
    curl_args.extend(['-E', args.pkcs11_url, '--key-type', 'eng'])
    curl_args.extend(['--request', 'POST'])
    if args.renew:
        url ='v1/auth/token/renew-self'
        curl_args.extend(['--header', f'x-vault-token: {args.renew}'])
    else:
        url = 'v1/auth/cert/login'

    # sh has a bug where fd 0 is never considered a tty because 0 is falsy so we dup fd 0
    result = sh.curl(*curl_args, f'{args.vault}{url}', _err=2, _in=os.dup(0))


Where args .pkcs11_url is initialized to
    parser.add_argument('--pkcs11-url', '--pkcs11-uri',
                        default = "pkcs11:manufacturer=piv_II",

And the easy reproducer:

I try something like
curl --cert 'pkcs11:manufacturer=piv_II'
And I get an error:
curl: (3) URL rejected: Port number was not a decimal number between 0
and 65535

Yet I think that's a valid pkcs11 URL.

I've checked the pkcs11 RFC and indeed it seems to be a valid pkcs11 URL.

It would be really nice if we could sort this one out. I'll tag also the other cURL maintainers (@samueloph and @sergiodj)

I expected the following

Using the HSM for pkcs11

curl/libcurl version

curl 8.8.0, 8.9.1

operating system

Debian

@vszakats vszakats changed the title cURL not working with some specif pkcs11 URLs with GNUtls backend cURL not working with some specif pkcs11 URLs with GnuTLS backend Feb 11, 2025
@tatsuhiro-t
Copy link
Contributor

tatsuhiro-t commented Feb 24, 2025

In #14925, I found that curl supports pkcs11 URI if --pass is given.
#14925 (comment)

Making libcurl always use gnutls_certificate_set_x509_key_file2 would fix this.

@charles2910
Copy link
Contributor Author

Hi, @tatsuhiro-t.

Are you saying curl with gnutls only supports a pkcs11 url if --pass is added as an option?

I'm asking that because I relayed your comment to the person who reported the bug to us, but maybe it wasn't clear to them --pass should also be used.

Making libcurl always use gnutls_certificate_set_x509_key_file2 would fix this.

I think this would make it behave the same way as using the openssl backend (no need to use --pass option to make it work), right? If so, I think it would be nice to fix this :-)

@tatsuhiro-t
Copy link
Contributor

Are you saying curl with gnutls only supports a pkcs11 url if --pass is added as an option?

yes, at least curl behaved like that when I last tested.

Making libcurl always use gnutls_certificate_set_x509_key_file2 would fix this.

I think this would make it behave the same way as using the openssl backend (no need to use --pass option to make it work), right? If so, I think it would be nice to fix this :-)

The current implementation looks the same as when gnutls_certificate_set_x509_key_file2 was first introduced 10 years ago, back then, it was relatively new, and falling back to gnutls_certificate_set_x509_key_file, which does not support pkcs11 was reasonable. I think we can now make curl always use gnutls_certificate_set_x509_key_file2.

icing added a commit to icing/curl that referenced this issue Feb 25, 2025
refs curl#16249

Always use `gnutls_certificate_set_x509_key_file2()` for loading keys
and certificates, even without a password, since this function
support pkcs11 urls.

Thanks to @tatsuhiro-t for finding this out.
@icing
Copy link
Contributor

icing commented Feb 25, 2025

I did the change @tatsuhiro-t described in #16472. Thanks for finding this! @charles2910, hope this helps.

@tatsuhiro-t
Copy link
Contributor

Note that I could not make softhsm2 and p11tool remove PIN. I also found that the error message "curl: (3) URL rejected: Port number was not a decimal number between 0" is quite suspicious. It is most likely the user failed to specify --cert and URL correctly.

@icing icing self-assigned this Feb 28, 2025
@bagder
Copy link
Member

bagder commented Feb 28, 2025

I also found that the error message "curl: (3) URL rejected: Port number was not a decimal number between 0" is quite suspicious.

My thinking as well. It smells like a wrong command line somehow.

@bagder bagder closed this as completed in 794dfe7 Feb 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants