Description of problem: Connections initiated with p12 certs fail when using OpenConnect 5: # rpm -q openconnect openconnect-5.02-1.fc20.x86_64 # openconnect --certificate test-vpn.p12 --no-cert-check --reconnect-timeout 150 --no-dtls server.example.com POST https://server.example.com/ Attempting to connect to server 1.2.3.4:443 Loading certificate failed: No certificate found in file Loading certificate failed. Aborting. Failed to open HTTPS connection to server.example.com GET https://server.example.com/ Attempting to connect to server 1.2.3.4:443 Loading certificate failed: No certificate found in file Loading certificate failed. Aborting. Failed to open HTTPS connection to server.example.com Failed to obtain WebVPN cookie Using the same cert on an older version of OpenConnect (4.08 from EPEL) succeeds: # rpm -q openconnect openconnect-4.08-1.el6.x86_64 # openconnect --certificate test-vpn.p12 --no-cert-check --reconnect-timeout 150 --no-dtls server.example.com Attempting to connect to server 1.2.3.4:443 Enter PKCS#12 pass phrase: Using client certificate '/O=Red Hat, Inc./OU=XXXX /OU=XXXX /OU=XXXX/CN=Evan McNabb/emailAddress=XXXX' SSL negotiation with server.example.com Server certificate verify failed: unable to get local issuer certificate Connected to HTTPS on server.example.com GET https://server.example.com/ Got HTTP response: HTTP/1.0 302 Temporary moved Attempting to connect to server 4.3.2.1:443 ... connection succeeds ... This has been reported in other distros: https://bugs.archlinux.org/task/35523 "openconnect 5 is using gnutls now instead of openssl. please report this issue upstream an paste the link here." Version-Release number of selected component (if applicable): openconnect-5.02-1.fc20 How reproducible: Every time. Steps to Reproduce: 1. 2. 3. Actual results: Expected results: Additional info:
Hm, I use PKCS#12 certs all the time without problem. Is there something different about yours? Do you actually have a passphrase on the cert, or is it empty? If so, this may be fixed by OpenConnect 6.00 in rawhide. If not, are you able to get me a similar PKCS#12 file which is failing, for testing?
I've had the same problem. I was able to work around it for now by compiling openconnect from source (v 6.00) using ./configure --without-gnutls What's also strange is that gnutls-bin was able to read the cert just fine. But somehow it didn't work in openconnect when it was using libgnults.
Hm, that's sad. I was hoping this was due to using an empty passphrase on the cert, and that it would be fixed by 6.00. Do you have a passphrase on this cert? Are you able to provide a dummy/expired/test cert which OpenConnect/GnuTLS cannot parse OpenConnect/OpenSSL can? Once upon a time we had a way to tell OpenConnect what type of cert it was using, and it'll be a little more explicit in its error reporting if it *knows* it's supposed to be a PKCS#12 file. There's no command-line for it any more but can you try explicitly setting vpninfo->cert_type = CERT_TYPE_PKCS12? And perhaps adding some more debugging in load_pkcs12_certificate() in gnutls.c so we can see precisely where it's going wrong? Thanks.
Looking at the gnutls-bin source, the only obvious difference that jumps out at me is that it'll accept PKCS#12 in PEM form instead of just DER. Is your certificate in a text file starting '---BEGIN PKCS12---'?
No, the file I have is in binary format. I'll try recompiling with the cert type set and will let you know if that helps.
It won't "help" but it might give a little more clue where it's failing. Which I suspect will be in gnutls_pkcs12_import() but I don't know why. Ideally you'd be able to let us have a sample of such a file along with its passphrase (actually, did you ever answer my question about whether it has one?). But if it's really in gnutls_pkcs12_import() and you now get an error 'Failed to import PKCS12# file: ...' then knowing that precise error might help, and it may also be possible to debug it a little *without* knowing the passphrase, so maybe you could let us have a 'live' file to debug... Applying this patch to enable GnuTLS debugging should also be enlightening... --- a/gnutls.c +++ b/gnutls.c @@ -2166,12 +2166,19 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final) } } +static void log_func(int level, const char *str) +{ + fputs(str, stderr); +} + void openconnect_init_ssl(void) { #ifdef _WIN32 openconnect__win32_sock_init(); #endif gnutls_global_init(); + gnutls_global_set_log_level(255); + gnutls_global_set_log_function (log_func); } int openconnect_sha1(unsigned char *result, void *data, int datalen)
When I run with -v I get this error: Failed to process PKCS#12 file: The given memory buffer is too short to hold parameters. This happens with or without forcing the cert type in vpninfo to be CERT_TYPE_PKCS12. Unfortunately this is for a cert I use at work and I don't have the means to create certs for testing that I could share with you. And yes, my cert does have a passphrase, but bear in mind that I'm not the original poster (whose issue may be different but seemingly similar to mine). Just to not get confused.
(In reply to Christian Fritz from comment #7) > When I run with -v I get this error: > > Failed to process PKCS#12 file: The given memory buffer is too short to hold > parameters. It would help if you could recompile and re-run openconnect with the options David suggested. What I suspect is that the file uses a MAC other than SHA1, and gnutls assumes it will be SHA1 as the RSA's PKCS #12 document says 'for this version of this standard, the hash function should be SHA-1'. I'll see to address this in gnutls, but it could be useful to have an option that skips the MAC verification in PKCS #12 in openconnect as well.
Here is the (censored, [...]) error with the patch applied: POST https://[...] Attempting to connect to server [...] Using certificate file /home/[...].p12 ASSERT: common.c:888 ASSERT: common.c:956 ASSERT: pkcs12.c:79 ASSERT: pkcs12.c:1057 Failed to process PKCS#12 file: The given memory buffer is too short to hold parameters. ASSERT: x509.c:3199 Loading certificate failed: No certificate found in file Loading certificate failed. Aborting.
I'll see whether a fix for f20 is possible.
I've put a version of gnutls that supports PKCS #12 MAC verification with algorithms other than SHA1 at: http://people.redhat.com/nmavrogi/fedora/gnutls/ If that solves the issue for you I'll roll a bug fix release.
Nikos, Thanks, but I'm actually on ubuntu. Maybe Evan, the original poster, could try this and report back if he's reading this.
Created attachment 926513 [details] gnutls patch If you can't use the GnuTLS package, this is the GnuTLS patch that Nikos added to it. I'll also make an OpenConnect patch for testing, as he suggested, that just disables the MAC verification.
Created attachment 926514 [details] Disable MAC verification in OpenConnect This patches openconnect to disable the MAC verification. You now have to pass the correct passphrase in with the '--key-password=' option, since it no longer *checks* it...
Thanks, David. I applied the patch and did a make clean all. Same result/error.
To clarify: I applied the patch to gnutls.c. I have not yet tried to compile gnutls from source with the patch from Nikos. Would that still be useful or is this hypothesis refuted already by the test of the deactivation of the mac verification in openconnect?
(In reply to Christian Fritz from comment #15) > Thanks, David. I applied the patch and did a make clean all. Same > result/error. I believe you may have used the old openconnect binary or the new binary uses the system libopenconnect. If not please provide the ASSERT errors reported, and the version of gnutls used.
If you still saw 'Failed to process PKCS#12 file' then you definitely weren't running the version of the library which has the gnutls.c patch. That patch puts "#if 0" around the only instance of that message. (In reply to Nikos Mavrogiannopoulos from comment #17) > I believe you may have used the old openconnect binary or the new binary > uses the system libopenconnect. If not please provide the ASSERT errors > reported, and the version of gnutls used. It should warn when that happens, something like this: WARNING: This version of openconnect is v6.00-121-gc170989-dirty but the libopenconnect library is v6.00-114-g731bed6 It's best just to run ./openconnect from the build directory, which will definitely use the correct version of the library from the build tree too.
Created attachment 927282 [details] gnutls.c with applied patch
well, what can I say? the gnutls.c file has the patch applied (attached for verification), I did a make clean all, and I'm running ./openconnect. But I still get that said error.
There is precisely one instance of the phrase 'Fail to process PKCS#12 file' in the OpenConnect source code, and you commented it out with a #if 0. If you are still seeing that message, consult an exorcist :) I have occasionally (albeit only on Solaris) seen libtool's wrappers fail to work, and still invoke things with the *system* library instead of the local one. Please could you double-check that you don't see the WARNING that I showed in comment 18? Can you show the full output of ./openconnect --version? Can you also try invoking the actual executable in the .libs/ directory directly? From the build dir, run: LD_LIBRARY_PATH=`pwd`/.libs .libs/openconnect
oh, I'm sorry. You are right. The error has changed very subtly and I didn't notice. Instead of 'Failed to process PKCS#12 file: The given memory buffer is too short to hold parameters.', it now says 'Failed to load PKCS#12 certificate: The given memory buffer is too short to hold parameters.' (which is just outside of the #if 0 block).
Here is the full error incl. asserts: Attempting to connect to server [..] Using certificate file /home/[..].p12 ASSERT: common.c:888 ASSERT: common.c:956 ASSERT: pkcs12.c:79 ASSERT: pkcs12.c:608 Failed to load PKCS#12 certificate: The given memory buffer is too short to hold parameters. Loading certificate failed. Aborting.
What is the gnutls version number in use?
From what I suspect you are using something like gnutls 2.12.x. That is too old, and not supported upstream. I'd suggest to upgrade to gnutls 3.2.x and resent the assert values. Otherwise we may be in a wild goose chase with bugs that have been fixed years ago.
I've regenerated my own VPN certificate with a SHA256 MAC for testing. The hack to disable password testing in OpenConnect's gnutls.c does work, and your patch to fix the problem correctly does also work when applied to Fedora 20's gnutls-3.1.25.1.fc20 package.
Nikos was right. I was using libgnutls-dev 2.12.x. I've installed 3.2.11 now and now I'm getting a new error: ASSERT: common.c:952 ASSERT: common.c:1095 ASSERT: pkcs12.c:75 ASSERT: pkcs12.c:594 Failed to load PKCS#12 certificate: ASN1 parser: Error in DER parsing. Loading certificate failed. Aborting.
I'm afraid I can do very little about this error without having the pkcs12 file or a way to generate it. The file contains an invalid encoding of an octet string and gnutls is pretty strict with it. I'm very curious what was used to generate that file.
It seems that this is a separate issue and I've opened #1131461, for that reason. I believe that the last error is due to BER encoding of the PKCS #12 file.
gnutls-3.1.26-1.fc20 has been submitted as an update for Fedora 20. https://admin.fedoraproject.org/updates/gnutls-3.1.26-1.fc20
Package gnutls-3.1.26-1.fc20: * should fix your issue, * was pushed to the Fedora 20 testing repository, * should be available at your local mirror within two days. Update it with: # su -c 'yum update --enablerepo=updates-testing gnutls-3.1.26-1.fc20' as soon as you are able to. Please go to the following url: https://admin.fedoraproject.org/updates/FEDORA-2014-9772/gnutls-3.1.26-1.fc20 then log in and leave karma (feedback).
gnutls-3.1.26-1.fc20 has been pushed to the Fedora 20 stable repository. If problems still persist, please make note of it in this bug report.