Bug 1088563 - GnuTLS does not support non-SHA1 MAC on PKCS#12 files
Summary: GnuTLS does not support non-SHA1 MAC on PKCS#12 files
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: gnutls
Version: 20
Hardware: Unspecified
OS: Unspecified
unspecified
high
Target Milestone: ---
Assignee: Nikos Mavrogiannopoulos
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2014-04-16 18:25 UTC by Evan McNabb
Modified: 2014-09-02 06:44 UTC (History)
5 users (show)

Fixed In Version: gnutls-3.1.26-1.fc20
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2014-09-02 06:44:28 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
gnutls patch (11.19 KB, patch)
2014-08-13 15:52 UTC, David Woodhouse
no flags Details | Diff
Disable MAC verification in OpenConnect (687 bytes, patch)
2014-08-13 15:57 UTC, David Woodhouse
no flags Details | Diff
gnutls.c with applied patch (64.18 KB, text/x-csrc)
2014-08-16 02:50 UTC, Christian Fritz
no flags Details

Description Evan McNabb 2014-04-16 18:25:15 UTC
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:

Comment 1 David Woodhouse 2014-07-08 16:23:55 UTC
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?

Comment 2 Christian Fritz 2014-08-03 21:43:56 UTC
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.

Comment 3 David Woodhouse 2014-08-04 09:09:00 UTC
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.

Comment 4 David Woodhouse 2014-08-04 09:13:23 UTC
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---'?

Comment 5 Christian Fritz 2014-08-08 03:42:57 UTC
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.

Comment 6 David Woodhouse 2014-08-08 12:37:21 UTC
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)

Comment 7 Christian Fritz 2014-08-09 23:58:32 UTC
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.

Comment 8 Nikos Mavrogiannopoulos 2014-08-10 08:46:47 UTC
(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.

Comment 9 Christian Fritz 2014-08-10 15:53:50 UTC
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.

Comment 10 Nikos Mavrogiannopoulos 2014-08-10 21:37:57 UTC
I'll see whether a fix for f20 is possible.

Comment 11 Nikos Mavrogiannopoulos 2014-08-11 08:49:04 UTC
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.

Comment 12 Christian Fritz 2014-08-13 15:48:45 UTC
Nikos,

Thanks, but I'm actually on ubuntu. Maybe Evan, the original poster, could try this and report back if he's reading this.

Comment 13 David Woodhouse 2014-08-13 15:52:50 UTC
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.

Comment 14 David Woodhouse 2014-08-13 15:57:08 UTC
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...

Comment 15 Christian Fritz 2014-08-14 01:26:18 UTC
Thanks, David. I applied the patch and did a make clean all. Same result/error.

Comment 16 Christian Fritz 2014-08-14 01:27:34 UTC
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?

Comment 17 Nikos Mavrogiannopoulos 2014-08-14 07:23:00 UTC
(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.

Comment 18 David Woodhouse 2014-08-14 09:00:11 UTC
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.

Comment 19 Christian Fritz 2014-08-16 02:50:16 UTC
Created attachment 927282 [details]
gnutls.c with applied patch

Comment 20 Christian Fritz 2014-08-16 02:50:41 UTC
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.

Comment 21 David Woodhouse 2014-08-16 21:50:18 UTC
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

Comment 22 Christian Fritz 2014-08-17 01:51:24 UTC
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).

Comment 23 Christian Fritz 2014-08-17 01:52:57 UTC
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.

Comment 24 Nikos Mavrogiannopoulos 2014-08-17 10:03:48 UTC
What is the gnutls version number in use?

Comment 25 Nikos Mavrogiannopoulos 2014-08-17 10:10:19 UTC
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.

Comment 26 David Woodhouse 2014-08-17 12:26:02 UTC
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.

Comment 27 Christian Fritz 2014-08-18 01:31:44 UTC
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.

Comment 28 Nikos Mavrogiannopoulos 2014-08-18 07:45:40 UTC
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.

Comment 30 Nikos Mavrogiannopoulos 2014-08-19 10:54:56 UTC
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.

Comment 31 Fedora Update System 2014-08-25 11:09:12 UTC
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

Comment 32 Fedora Update System 2014-08-27 01:33:49 UTC
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).

Comment 33 Fedora Update System 2014-09-02 06:44:28 UTC
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.


Note You need to log in before you can comment on or make changes to this bug.