openconnect-gui icon indicating copy to clipboard operation
openconnect-gui copied to clipboard

[Bug] SystemStore and LocalCertificate doesn't work in v1.4 on Windows for CAPI keys

Open ExSport opened this issue 8 years ago • 31 comments

It seems there is a problem with using separate cert and also using local certstore on Windows. Tested Windows 7 and 10, 64-bit, EN version with exactly same results so it doesn't seem it is only my computer specific problem.

1. Defining separate cert will freeze GUI upon SAVE button is pressed instead of asking for private key password 2. Using the SystemStore will not allow VPN connection due to the problem below:

2016-08-11 15:26 POST https://vpn-concentrator.int/
2016-08-11 15:26 Attempting to connect to server 1.2.3.4:443
2016-08-11 15:26 Using certificate file C:/Progs/OpenConnect/tmp-certp13236
2016-08-11 15:26 Using system key system:win:id=11ba3d87f7572ae5ac22674bd6b3f7232014592d;type=privkey
2016-08-11 15:26 Error importing system key system:win:id=11ba3d87f7572ae5ac22674bd6b3f7232014592d;type=privkey: The requested data were not available.
2016-08-11 15:26 Loading certificate failed. Aborting.
2016-08-11 15:26 Failed to open HTTPS connection to vpn-concentrator.int
2016-08-11 15:26 Authentication error; cannot obtain cookie
2016-08-11 15:26 Disconnected

UAC disabled, GUI run under admin permissions. Version v1.3 doesn't have "separate cert" bug but systemstore doesn't work same way as in v1.4 Thx

ExSport avatar Aug 11 '16 13:08 ExSport

Do you run build from source code or from release installer?

horar avatar Aug 14 '16 19:08 horar

When v1.4 wasn't officially released I tested it by compiling latest code. Now when you released it officially I tested it again but with exactly same symptoms for both builds and on two different versions of Windows OS.

ExSport avatar Aug 14 '16 19:08 ExSport

@horar Made some troubleshooting and found this about CredStore: My first suspicion was if problem is not CSP or CNG provider support as I tried to import them to different ones. Not real problem. Then created about 30 different certs until I found property which breaks reading private key and it is KEY_SPECIFICATION. My VPN cert is with AT_SIGNATURE and this doesn't work also for my other custom certs created. If I created cert with AT_KEYEXCHANGE, OpenConnect can read cert (no "The requested data were not available" message) but I can't test it completely as I can't fake original VPN cert to be used for real connection. But log seems promissing. Anyway also this working cert has still freeze problem when trying to import them as separate files created by openssl tool. It freezes again just before asking for private key password. It worked in v1.3 As it works in console I suppose it is GUI bug (it works for anyone?) and not problem with certs itself. And now how to add support for "KEY_SPEC=Signature"? Can it be done in OpenConnect itself or it requires fix in 3rd party libraries? Thx Btw. UAC enabled or disabled is blind way, no change in behavior when enabled/disabled.

ExSport avatar Aug 22 '16 17:08 ExSport

okey, thanks ... will look closer to freeze...

horar avatar Aug 22 '16 18:08 horar

Could you include gnutls' debugging messages to the log? If you set GNUTLS_DEBUG_LEVEL=4 in the environment of the server you will get more info about the issues.

From the description, I see there are two issues here. (1) issue loading certain keys from windows key store and (2) freeze issue when loading a private key and a certificate from files, right? It may be best to separate them as they are not really related.

For (1), with the gnutls API CNG keys are supported and CAPI keys are partially supported. Having the debugging messages from gnutls would help understand what doesn't work there. Also, is it a CNG key or legacy CAPI key you are trying to load?

About (2), you'll need to provide more information on what you are using. Is it a pkcs12 file? Is it a separate certificate and private key?

nmav avatar Aug 23 '16 08:08 nmav

Hi @nmav Yes it can be separated but until yesterday I had no further info why certstore is broken so I reported it as one CERT issue. Now I know that only some specific certs are not supported so now it seems logical that both issues should be divided. When you are creating cert with legacy (not CNG) key for CAPI/CSP providers, all providers have same behavior. It means if cert is created with key for SIGNATURE, it doesn't work. If EXCHANGE purpose is used, OpenConnect likes cert in store. image As I don't know how to force "GNUTLS_DEBUG_LEVEL=4" in Windows (I added it to environment variable but no log is created in TEMP folder) so I am adding some trace when it frezes: image

0   ntoskrnl.exe    RtlUnicodeToMultiByteSize + 0x44e   0xfffff80002342036  C:\windows\system32\ntoskrnl.exe
1   ntoskrnl.exe    RtlCopySidAndAttributesArray + 0x1c0d   0xfffff8000235bf0d  C:\windows\system32\ntoskrnl.exe
2   ntoskrnl.exe    RtlCopySidAndAttributesArray + 0x1d15   0xfffff8000235c015  C:\windows\system32\ntoskrnl.exe
3   ntoskrnl.exe    KeSynchronizeExecution + 0x3a23 0xfffff80002084ed3  C:\windows\system32\ntoskrnl.exe
4   ntdll.dll   NtTerminateThread + 0xa 0x7778deea  C:\windows\SYSTEM32\ntdll.dll
5   wow64.dll   Wow64EmulateAtlThunk + 0xe4d2   0x7328c03a  C:\windows\SYSTEM32\wow64.dll
6   wow64.dll   Wow64SystemServiceEx + 0xd7 0x7327d18f  C:\windows\SYSTEM32\wow64.dll
7   wow64cpu.dll    TurboDispatchJumpAddressEnd + 0x2d  0x73202776  C:\windows\SYSTEM32\wow64cpu.dll
8   wow64.dll   Wow64SystemServiceEx + 0x1ce    0x7327d286  C:\windows\SYSTEM32\wow64.dll
9   wow64.dll   Wow64LdrpInitialize + 0x42a 0x7327c69e  C:\windows\SYSTEM32\wow64.dll
10  ntdll.dll   RtlIsDosDeviceName_U + 0x1f7c4  0x777b5284  C:\windows\SYSTEM32\ntdll.dll
11  ntdll.dll   LdrInitializeThunk + 0xe    0x7776b63e  C:\windows\SYSTEM32\ntdll.dll
12  ntdll.dll   NtTerminateThread + 0x12    0x779400d6  C:\windows\SysWOW64\ntdll.dll
13  ntdll.dll   RtlExitUserThread + 0x39    0x7797698d  C:\windows\SysWOW64\ntdll.dll
14  ntdll.dll   RtlFindMessage + 0x5c4  0x77980491  C:\windows\SysWOW64\ntdll.dll
15  kernel32.dll    BaseThreadInitThunk + 0x12  0x76f7337a  C:\windows\syswow64\kernel32.dll
16  ntdll.dll   RtlInitializeExceptionChain + 0x63  0x77959882  C:\windows\SysWOW64\ntdll.dll
17  ntdll.dll   RtlInitializeExceptionChain + 0x36  0x77959855  C:\windows\SysWOW64\ntdll.dll

I am using PEM files extracted from PFX file by OpenSSL. Same separate certs works on v1.3 but not in v1.4. EDIT: To be more clear, certs does work in both versions when used in CONSOLE. In GUI version only v1.3 works.

openssl pkcs12 -in cert.pfx -clcerts -nokeys -out vpncert.pem
openssl pkcs12 -in cert.pfx -nocerts -out vpnkey.pem

Windows 7 x64, Windows Server 2008 R2 x64, Windows 10 x64. EDIT: One additional note is, when tested on working v1.3, after closing private key PEM file, it reads "libgnutls-30.dll" library which doesn't happen with v1.4

ExSport avatar Aug 23 '16 14:08 ExSport

As I don't know how to force "GNUTLS_DEBUG_LEVEL=4" in Windows (I added it to environment variable but no log is created in TEMP folder) so I am adding some trace when it frezes:

The gnutls log should be appended to openconnect's log in the log window.

nmav avatar Aug 24 '16 14:08 nmav

Oh, as I see now this log is only available if openconnect-gui is compiled with special GNUTLS_DEBUG flag. Otherwise the errors are printed to stderr and in windows I don't know where that goes. @horar would it make sense to always set the gnutls_global_set_log_function always to allow enabling gnutls debug logs on normal builds?

nmav avatar Aug 24 '16 14:08 nmav

Hi @nmav @horar It is stored in profile folder like C:\Users\username\AppData\Local\Temp It generates file vpnc.log for logging "vpnc-script.js" output and openconnect-gui.XXXXXX which is always empty (also in v1.3) In LOG from GUI there is nothing visible as logging starts there at time of connection and not configuration. And also there will be visible nothing as clicking on SAVE should elevate window asking for private key password but it will freeze whole OpenConnect GUI including LOG window. Will try to compile it with your change about gnutls debugging if anything change...but as I said no log is created on filesystem right now so if it will be passed to LOG in GUI, I will not see it as it will totally freeze :) Thx

ExSport avatar Aug 24 '16 15:08 ExSport

@nmav yes, for degugging purposes it may help, I suggest add either command line switch or menu settings (on/off) ... from gnutls documentation the level higher that 0 could be handled by solutions (1), but it could be dangerous

horar avatar Aug 24 '16 15:08 horar

@ExSport 'vpnc.log' is temporary file, removed after loading into application log-window (real file-system logging is planned for 1.5/1.6)

horar avatar Aug 24 '16 15:08 horar

@horar Thanks for info, I know it is temporary file only and only for logging script output but now I know there is no way how to see GNUTLS_DEBUG output as whole GUI will hang when clicking on SAVE :( So hard to help with finding root cause... EDIT: Anyway if OpenConnect will support SIGNATURE type key, then fixing freezes with separate files will be low priority as user will use CertStore instead (as exporting it via OpenSSL is not available on Windows by default so it is a workaround for not working CredStore)

ExSport avatar Aug 24 '16 15:08 ExSport

openssl pkcs12 -in cert.pfx -clcerts -nokeys -out vpncert.pem
openssl pkcs12 -in cert.pfx -nocerts -out vpnkey.pem

I can verify that the interface freezes with these keys (I attach a pair of keys to reproduce). However you can use -nodes on the key export to work-around the freeze.

keys.zip

nmav avatar Aug 24 '16 15:08 nmav

@nmav Wow, beautiful hint. Will test it as soon as possible. Btw. I edited my previous post :+1:

The option -nodes is not the English word "nodes", but rather is "no DES". When given as an argument, it means OpenSSL will not encrypt the private key in a PKCS#12 file.
To encrypt the private key, you can omit -nodes and your key will be encrypted with 3DES-CBC. To encrypt the key, OpenSSL prompts you for a password and it uses that password to generate an encryption key using the key-derivation function EVP_BytesToKey.
Depending on your version of OpenSSL and compiled options, you may be able to provide these options in place of -nodes:
-des          encrypt private keys with DES
-des3         encrypt private keys with triple DES (default)
-idea         encrypt private keys with idea
-seed         encrypt private keys with seed
-aes128, -aes192, -aes256
              encrypt PEM output with cbc aes
-camellia128, -camellia192, -camellia256
              encrypt PEM output with cbc camellia

Good to know about this nice parameter. Thanks!

ExSport avatar Aug 24 '16 15:08 ExSport

Btw, a pfx (pkcs12) file should have worked as well. However trying one it seems that auto-detection fails. If I PEM-encode the PKCS12 file it seems to try to load from it (prompts for password) but cannot properly load it. That may have been something wrong in my original code. @horar I'm unable to debug it at this point (I no longer have my qt5 environment), but I attach the p12 files I used for testing (password is 'foobar').

What I tried:

  • Setting "client.p12" as certificate and clicking save: works - both key and cert are read
  • Setting "client.p12.pem" as certificate and clicking save: works - both key and cert are read
  • Setting "client.p12" as certificate and as key and clicking save: doesn't work
  • Setting "client.p12.pem" as certificate and as key and clicking save: doesn't work

A solution could be to clarify in the interface whether a key is needed or not.

p12.zip

nmav avatar Aug 24 '16 15:08 nmav

@nmav okey, no problem, will check/debug this at eventing

horar avatar Aug 24 '16 15:08 horar

@nmav Yay you are right. Providing pfx/pkcs12 directly in user cert line only, it asks for pwd and can detect if pwd is OK or not but as you said it doesn't work but there is no freeze. Never imagined that it is possible to use PFX directly and it is not required to define "User Key" as many users think they have to extract it separately so they does these hackish steps with OpenSSL. Now I tested PFX file directly in v1.3, loaded it in "User Certificate" only (User Key stays empty) and OpenConnect works! So freeze problem is in v1.4 only and it seems you already know where :+1: but unfortunately SIGNATURE type key doesn't work in both of them. Btw. it will be much more user friendly to see "name" of the Certificate: image If you will import cert to certstore, it has empty "Friendly Name" of the cert but other apps shows them as "Issued To". In OpenConnect when no friendly name is defined, it shows "Subject Key Identifier" instead (as friendly name is empty). For non-tech user it is quite hard to find which one should be used if there are more then only one but it is only cosmetics :+1: Thx!

ExSport avatar Aug 24 '16 16:08 ExSport

@nmav just quick-try with above zip (1.4.0 and devel) on Win10 with following results: p12@certificate -> accepted pem@certificate -> ASN1 parser: Error in TAG p12@cert+key -> Cannot import user key. Error in parsing pem@cert+key -> ASN1 parser: Error in TAG

oc-1.4.0.zip

One observation - when key/certificate error-dialog is raised; all other widgets (main window and log window) doesn't raise error-dialog. I have to change it, we should not block event-loop.

(I will try do look closer...)

horar avatar Aug 24 '16 19:08 horar

I forgot this ... with loglevel 12; but with release DLL's there is not so much details

oc_p12@cert+key_loglevel12.zip

horar avatar Aug 24 '16 19:08 horar

I'll split the bugs identified here and open different issues for simplicity. We can keep this bug for the windows trust store.

nmav avatar Aug 25 '16 11:08 nmav

For that to be addressed I'll need some debugging output from @ExSport once we have a version of openconnect-gui which can enable gnutls debugging. Note that it is low-priority since CAPI keys are legacy keys.

nmav avatar Aug 25 '16 11:08 nmav

Thanks for splitting it. I have it planned later today :+1:

ExSport avatar Aug 25 '16 14:08 ExSport

@nmav @horar As I don't have debug environment, I can provide only keys for testing. But I have to note that it is not a problem of CAPI keystore as KEY for EXCHANGE works but not with KEY for SIGNATURE:

CryptoAPI providers :
 0. RSA_FULL      ( 1) - Microsoft Base Cryptographic Provider v1.0
 1. DSS_DH        (13) - Microsoft Base DSS and Diffie-Hellman Cryptographic Provider
 2. DSS           ( 3) - Microsoft Base DSS Cryptographic Provider
 3. RSA_FULL      ( 1) - Microsoft Base Smart Card Crypto Provider
 4. DH_SCHANNEL   (18) - Microsoft DH SChannel Cryptographic Provider
 5. RSA_FULL      ( 1) - Microsoft Enhanced Cryptographic Provider v1.0
 6. DSS_DH        (13) - Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider
 7. RSA_AES       (24) - Microsoft Enhanced RSA and AES Cryptographic Provider
 8. RSA_SCHANNEL  (12) - Microsoft RSA SChannel Cryptographic Provider
 9. RSA_FULL      ( 1) - Microsoft Strong Cryptographic Provider <<<=======| 

CryptoAPI provider types:
 0. RSA_FULL      ( 1) - RSA Full (Signature and Key Exchange) <<<======| this one is attached
 1. DSS           ( 3) - DSS Signature
 2. RSA_SCHANNEL  (12) - RSA SChannel
 3. DSS_DH        (13) - DSS Signature with Diffie-Hellman Key Exchange
 4. DH_SCHANNEL   (18) - Diffie-Hellman SChannel
 5. RSA_AES       (24) - RSA Full and AES

OCDebug!-certs.zip Pwd for keys is OCDebug! I forgot to change "Issued to" so both says that works but SIGN doesn't. EDIT: Unfortunately I can't obtain newer certs for VPN as PKI is running on 2003 and it is not possible to ask maintainers of PKI for different key :(

ExSport avatar Aug 25 '16 14:08 ExSport

@horar @nmav Compiled gnutls-debug-easy branch and tested loading SIGNING cert from certstore + using env:GNUTLS_DEBUG_LEVEL=4:

ASSERT: ../../lib/system-keys-win.c:612
POST https://vpn.conc.com/
Attempting to connect to server 1.2.3.4:443
Using certificate file C:/Progs/OpenConnect 1.4/tmp-certp10840
Using system key system:win:id=11ba3d87f7572ae5ac22674bd6b3f7232014592d;type=privkey;name=non-working%20cert
Error importing system key system:win:id=11ba3d87f7572ae5ac22674bd6b3f7232014592d;type=privkey;name=non-working%20cert: The requested data were not available.
Loading certificate failed. Aborting.
Failed to open HTTPS connection to vpn.conc.com
Authentication error; cannot obtain cookie
Disconnected

There is no deeper logging visible... Btw. this ASSERT info is logged in only ~1 try from 10.

ExSport avatar Aug 26 '16 12:08 ExSport

@horar @nmav Anything I can test for you? Next time I will try GNUTLS_DEBUG_LEVEL=11 if anything will change: https://gnutls.org/manual/html_node/Core-TLS-API.html#gnutls_005fglobal_005fset_005flog_005flevel

ExSport avatar Aug 31 '16 13:08 ExSport

hi, I'm looking to that freeze - I have some ideas

Btw. I'm debugging the freeze and last command is call into openconnect library:

int ret = gnutls_x509_privkey_import2(*privkey, raw, GNUTLS_X509_FMT_PEM, NULL, 0);

Yeah, going check the callbacks... looks like a deadlock

horar avatar Aug 31 '16 19:08 horar

okey, just find a reason for freezing (#128)

horar avatar Aug 31 '16 20:08 horar

Using system key system:win:id=11ba3d87f7572ae5ac22674bd6b3f7232014592d;type=privkey;name=non-working%20cert Error importing system key system:win:id=11ba3d87f7572ae5ac22674bd6b3f7232014592d;type=privkey;name=non-working%20cert: The requested data were not available.`` Loading certificate failed. Aborting.```

I'd have expected additional logging between these lines. I cannot really see how _gnutls_privkey_import_system_url() can fail without printing anything in debug log.

nmav avatar Sep 01 '16 06:09 nmav

What kind of key did you generate with AT_SIGNATURE? Was it RSA? Trying with a debug level of 9 would help.

nmav avatar Sep 01 '16 06:09 nmav

Hi @nmav Now I see v1.4.1 doesn't include debug patch and now I am not sure if I tested with latest released version or compiled debug branch so will retest it. I attached certs already 7 days ago and relink it here: https://github.com/openconnect/openconnect-gui/files/437273/OCDebug.-certs.zip Yes, it is RSA -you can check it directly with certutil on pfx cert I provided. EDIT: Used compiled DEVELOP branch now and same problem. No deeper debug with also value 11. Btw. there is a bug in GUI v1.3 and v1.4 too...will create separate Issue #131

ExSport avatar Sep 01 '16 10:09 ExSport