openconnect-gui
openconnect-gui copied to clipboard
[Bug] SystemStore and LocalCertificate doesn't work in v1.4 on Windows for CAPI keys
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
Do you run build from source code or from release installer?
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.
@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.
okey, thanks ... will look closer to freeze...
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?
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.
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:
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
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.
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?
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
@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
@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 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)
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.
@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!
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.
@nmav okey, no problem, will check/debug this at eventing
@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:
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!
@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
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...)
I forgot this ... with loglevel 12; but with release DLL's there is not so much details
I'll split the bugs identified here and open different issues for simplicity. We can keep this bug for the windows trust store.
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.
Thanks for splitting it. I have it planned later today :+1:
@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 :(
@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.
@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
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
okey, just find a reason for freezing (#128)
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.
What kind of key did you generate with AT_SIGNATURE? Was it RSA? Trying with a debug level of 9 would help.
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