Active directory certificate service not starting - certificate-authority

Operating System Win server 2012 R2
I am creating Root CA in Active directory certificate service.
I am using my custom RSA KSP, (Key Storage Provider) based on CNG(Cryptographic Next Gen. API).
My certificate is created in c:\windows\system32\certsrv\certenroll\mycert.crt
All seems well, I open and see my certificates, it seems ok and signatre is also ok.
.........................................
My certsvc is not starting is is saying.
Signature is not valid.
The cryptographic sinature is invalid, oxc000a000.
Also, .crl is nor created.
When I verify my certificate using
certutil -verify
is says..
cannot check leaf certificate revocation status.
I am not able to check, what's going wrong.
Can I get some hint, what's going on with my CA.
Thanks In Advance.

I figured it out, just after posting the question.
When Microsoft ROOT CA is passing signature, in CNG signinig api.
It is expecting that we must prepend the NID, or oid and then sign it.
and return the same signed bytes.

Related

When an Azure key vault says "one or more x.509 properties are invalid", how can I debug what is wrong with my certificate?

I am trying to generate X509 certificates in C# code (using the class X509Certificate2) and upload these certificates to an Azure Key Vault. When I try to upload them (programmatically or via the Azure Portal in a browser), I get the following error message:
The specified X.509 certificate content is invalid. Error: one or more x.509 properties are invalid.
How can I debug what is wrong with my certificate generation? Is it documented what combinations of X509 properties are acceptable? If so, where can I read about it?
Output from certutil -dump foo.pfx:
> certutil -dump E:\Raven\Certificates\test2.pfx
Enter PFX password:
================ Certificate 0 ================
================ Begin Nesting Level 1 ================
Element 0:
Serial Number: 86ae932f199f419115e8087f3f0cb6df747bd2adf966d46aab194f4283849635
Issuer: CN=intermediate CA
NotBefore: 24-01-2022 11:22
NotAfter: 25-01-2022 11:22
Subject: O=foo, CN=bar
Non-root Certificate
Cert Hash(sha1): a700464f1708cec627eabcd007ef574d1f0fc140
---------------- End Nesting Level 1 ----------------
Provider = Microsoft Software Key Storage Provider
Private key is NOT plain text exportable
Signature test passed
CertUtil: -dump command completed successfully.
In my case it turned out to be two things:
The serial number. I was using RandomNumberGenerator.GetBytes(32) to generate serial numbers, which was apparently bad. The vault is happier if I do Guid.NewGuid().ToByteArray().
The flags (enum X509KeyUsageFlags). I tested several combinations of flags, and it turns out that whenever I use the flag X509KeyUsageFlags.KeyEncipherment the vault will reject the certificate.
I don't know why. I suppse that if you use the KeyEncipherment flag, there is some other invariant that the certificate needs to obey.
In any case, when I fix the serial numbers and remove this flag, it appears that the vault accepts my certificates.
If I fix only the serial number but keep the KeyEncipherment flag, I get this error message:
Unsupported key operation(s): "wrapKey", "unwrapKey". Supported values are "sign", "verify".

IIS 7 Error "A specified logon session does not exist. It may already have been terminated." when using https

I am trying to create Client Certificates Authentication for my asp.net Website.
In order to create client certificates, I need to create a Certificate Authority first:
makecert.exe -r -n “CN=My Personal CA” -pe -sv MyPersonalCA.pvk -a
sha1 -len 2048 -b 01/01/2013 -e 01/01/2023 -cy authority
MyPersonalCA.cer
Then, I have to import it to IIS 7, but since it accepts the .pfx format, i convert it first
pvk2pfx.exe -pvk MyPersonalCA.pvk -spc MyPersonalCA.cer -pfx MyPersonalCA.pfx
After importing MyPersonalCA.pfx, I try to add the https site binding to my Web Site and choose the above as SSL Certificate, but I get the following error:
Any suggestions?
I ran across this same issue, but fixed it a different way. I believe the account I was using changed from the time I initially attempted to set up the certificate to the time where I returned to finish the work, thus creating the issue. What the issue is, I don't know, but I suspect it has to do with some sort of hash from the current user and that is inconsistent in some scenarios as the user is modified or recreated, etc.
To fix it, I ripped out of both IIS and the Certificates snap-in (for Current User and Local Computer) all references of the certificate in question:
Next, I imported the *.pfx file into the certs snap-in in MMC, placing it in the Local Computer\Personal node:
Right-click the Certificates node under Personal (under Local Computer as the root)
All Tasks -> Import
Go through the Wizard to import your *.pfx
From that point, I was able to return to IIS and find it in the Server Certificates. Finally, I went to my site, edited the bindings and selected the correct certificate. It worked because the user was consistent throughout the process.
To the point mentioned in another answer, you shouldn't have to resort to marking it as exportable as that's a major security issue. You're effectively allowing anyone who can get to the box with a similar set of permissions to take your cert with them and import it anywhere else. Obviously that's not optimal.
Security warning: what the checkbox really means is that the certificate can be read by users that shouldn't be able to read it. Such as the user running the IIS worker process. In production use the other answer instead.
Happened to me too, and was fixed by ensuring that "Allow this certificate to be exported" is checked when you import it:
(thanks to this post!)
This must be some kind of IIS bug, but I found the solution.
1- Export MyPersonalCA.pfx from IIS.
2- Convert it to .pem:
openssl pkcs12 -in MyPersonalCA.pfx -out MyPersonalCA.pem -nodes
3- Convert it back to .pfx:
openssl pkcs12 -export -in MyPersonalCA.pem -inkey MyPersonalCA.pem -out MyPersonalCA.pfx
4- Import it back to IIS.
We had the same issue due to incorrectly importing the certificate into the Current User Personal certificate store. Removing it from the Current User Personal store and importing it into the Local Machine Personal certificate store solved the problem.
Nobody probably cares about this anymore, but I just faced this issue with my IIS 7 website binding. The way I fixed it was going to the Certificate Authority and finding the certificate issued to the server with the issue. I verified the user account that requested the certificate. I Then logged into the IIS server using RDP with that account. I was able to rebind the https protocol using that account only. No exports, reissuing, or extension changing hacks were needed.
Instead of importing the cert from IIS, do it from MMC.
Then goto IIS for binding.
In our case this problem occurred because we have installed the certificate in a Virtual Machine and made an image of it for further use.
When creating another VM from the image previously created the certificate sends the message.
To avoid this be sure to install the certificate on every new VM installed.
According to the MSDN blog post, this can happen when the current user account doesn't have permission to access the private key file which is under the folder "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys". Apparently this can be resolved by granting the user account / user group Full Access permission to the above folder.
I've come across the same issue, and was able to resolve it by simply re-importing the .pfx file with the Allow this certificate ti be exported checkbox selected.
However, this method imposes a security risk - as any user who has
access to your IIS server will be able to export your certificate with
the private key.
In my case, only I have access to my IIS server - therefore it was not a huge risk.
I got this error due to wrong openssl command-line during export PKCS #12 certificate. -certfile key was wrong. I exported certificate again and it was imported successfully.
We found another cause for this. If you are scripting the certificate install using PowerShell and used the Import-PfxCertificate command. This will import the certificate. However, the certificate imported cannot be bound to a website in IIS with the same error as this question mentions. You can list certificates using this command and see why:
certutil -store My
This lists the certificates in your Personal store and you will see this property:
Provider = Microsoft Software Key Storage Provider
This storage provider is a newer CNG provider and is not supported by IIS or .NET. You cannot access the key. Therefore you should use certutil.exe to install certificates in your scripts. Importing using the Certificate Manager MMC snap-in or IIS also works but for scripting, use certutil as follows:
certutil -f -p password -importpfx My .\cert.pfx NoExport
See this article for more information: https://windowsserver.uservoice.com/forums/295065-security-and-assurance/suggestions/18436141-import-pfxcertificate-needs-to-support-legacy-priv
Guys after trying almost every single solution to no avail i ended up finding my solution to '“A specified logon session does not exist. It may already have been terminated.” when using https" below
Verify your pfx cert is healthy with correct private key
Run certutil and locate the certs 'unique Container name' - i used certutil -v -store my
3.Navigate to C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys and locate the system file that corresponds to your Container name found above
Check permissions and ensure 'system' has full control to file.
Once applied i then checked IIS and was able to apply to https without error
I had the same issue. Solved by removing the certificate from de personal store (somebody put in it) and from the webhosting. All done through the IIS manager. Then I added again to the webhosting store (with everything checked) and I can use HTTPS again...
In my case it was because the World Wide Publishing Service user didn't have permissions to the certificate. After installing the certificate, access the certificates module in MMC and right-click the certificate with the issue. Select "Manage Private Keys..." from the "All Tasks" menu and add the above user. This was SYSTEM user in my case.
I was getting a this error when trying to bind localhost pfx cert for my development machine.
Before i tried any of this above, tried something simpler first.
Closed any localhost dev site i had openned.
Stopped my IIS server and closed the manager
run the manager as Admin
Added all my https bindings, no errors or issues this time.
restarted iis
Everything seems to work after that.
I was getting same error whilst binding the certificate, but fixed after deleting the certificate and importing again through mmc console.
In my case, it has been fixed by using certutil -repairstore command. I was getting following error, when trying to add certificate to Web Binding on IIS using powershell:
A specified logon session does not exist. It may already have been terminated.
I fixed it by running:
certutil.exe -repairstore $CertificateStoreName $CertThumbPrint
where CertificateStoreName is store name, and CertThumbPrint is the thumbprint of imported certificate.
I recieved this error message when trying to use the following powershell command:
(Get-WebBinding -Port 443 -Name
"WebsiteName").AddSslCertificate("<CertificateThumbprint>", "My")
The solution for me was to go into certificate manager and give IIS_IUSRS user permission to see the certificate.
These are the steps I followed:
Move the certificate into [Personal > Certificates]
Right click [All Tasks > Manage Private Keys]
Add the IIS_IUSRS user (which is located on the local computer not in your domain if you're attached to one)
Give read permission
I managed to fix this problem by importing the SSL certificate PFX file using Windows Certificate Manager.
http://windows.microsoft.com/en-us/windows-vista/view-or-manage-your-certificates
I just had this issue today and feel compelled to post my solution in the hope that you will lose less hair than I've just done.
After trying the solutions above, we had to re-issue the SSL certificate from the SSL provider (RapidSSL issuing as a reseller for GeoTrust).
There was no cost with this process, just the five minute wait while the confirmation emails (admin#) arrived, and we gained access again.
Once we had the response, we used IIS > Server Certificates to install it. We did not need the MMC snap-in.
https://knowledge.rapidssl.com/support/ssl-certificate-support/index?page=content&id=SO5757
We kept a remote desktop window to the server open throughout, to avoid any issues with differing login accounts/sessions, etc. I do believe it is an IIS bug as another expert believes, as we only have one RDC account. What is most infuriating is that the very same certificate has been working perfectly for two months before suddenly "breaking".
In my case I imported a newer version of a certificate (PFX for IIS) from StartSSL just recently and forgot to remove the old one, which somehow caused this error (now two certs sort of the same). I removed both of them, imported the proper one, and now it works.
I was able to fix this problem by removing the then importing it by double clicking the certificate.
For me, the fix was to delete the cert from IIS and re-import it, but into the "personal" certificate store instead of "web hosting"
According to the below, this is fine, at least for my own circumstances.
What's the difference between the Personal and Web Hosting certificate store?
Also, should it make any difference, I imported the certificate via the wizard after double clicking on it on the local machine, instead of via the IIS import method. After this the certificate was available in IIS automatically.
Here's what worked for me:
Step 1: Open up a Run window and type "mmc"
Step 2: Click File > Add/Remove Snap In
Step 3: Add > Certificates, Click OK
Step 4: Choose "Computer Account", then "Local Computer" and proceed.
Step 5: Hit OK
Step 6: Right click the Certificates folder on: Console Root > Certificates (Local Computer) > Personal > Certificates
Step 7: Select All Tasks > Import (Please note that the "Local Machine" is selected on the next window)
Step 8: Browse your .pfx file
Step 9: Then go to the IIS and create https binding
Try :
Go into IIS and delete "VSTS Dev Router" web site and "VSTS Dev Router Pool" application pool.
Run “certlm.msc” and open Personal/Certificates
Delete any cert named “*.vsts.me” and "vsts.me"
Re-deploy

QT ssl error on hotmail.com: The issuer certificate of a locally looked up certificate could not be found

When I use QtWebkit (which uses QSslSocket internally) to connect to www.hotmail.com, I got the following ssl errors after logging in:
The issuer certificate of a locally looked up certificate could not be found
The root CA certificate is not trusted for this purpose
No certifiates could be verified.
I could get the same errors at mail.yahoo.com before logging in.
I have found that secure connection to these two servers triggers the ssl errors:
https://gfx8.hotmail.com
https://csc.beap.bc.yahoo.com
There is a small ssl demo program included with QT called securesocketclient. I can produce the same errors if I use this little client to connect to port 443 of the above two servers. I am 99% certain this is a bug with QT since we have produced this issue on many development systems. It affects linux, mac and windows QT. It affects QT 4.7.4 all the way to QT 4.8.4 (didn't try earlier versions). The bug is reproduced with openssl 0.9.8.
Some people might falsely claim that the bug is fixed by using openssl 1.0.0 with precompiled QT binary. That's wrong since the precompiled QT binary is compiled with openssl 0.9.8 header files. Openssl 0.9.8 is not binary compatible with openssl 1.0.0. Some of the structure memebers will be misinterpreted if you compile QT with one version of openssl but use another version of openssl binary. I did a lot of step-and-trace into QT and openssl source code to arrive at this conclusion.
Since hotmail and yahoo email are extremely popular websites, I'd consider this bug is a serious bug in terms of security for QT. I already reported it to QT bug system (https://bugreports.qt.io/browse/QTBUG-23625) and I doubt when digia will ever get their hands on it based on my past experience.
Please feel free to share your thoughts on how to fix this bug. I do know how to call ignoreSslErrors and pretend there is no problem. But that's not how openssl is intended to be used.
Some updates from further investigation on this issue.
The certificate path for https://gfx8.hotmail.com is:
Root CA: Versign Class 3 Public Primary Certification Authority - G5
Intermediate CA: Versign Class 3 Extended Validation SSL SGC CA
Server Certificate: gfx-ecn.hotmail.com
The root CA does sit in the Windows certificate store and is loaded properly at startup. I guess perhaps somehow QT doesn't get the intermediate certificate. I run a test with the openssl command line program as shown below:
openssl s_client -showcerts -connect gfx8.hotmail.com:443
The output is here:
CONNECTED(000001AC) depth=0 1.3.6.1.4.1.311.60.2.1.3 = US,
1.3.6.1.4.1.311.60.2.1.2 = Washington, bu sinessCategory = Private Organization, serialNumber = 600413485, C = US, postalC ode = 98052,
ST = Washington, L = Redmond, street = 1 Microsoft Way, O = Microso ft
Corporation, OU = Windows Azure CDN, CN = gfx-ecn.hotmail.com
verify error:num=20:unable to get local issuer certificate verify
return:1
depth=0 1.3.6.1.4.1.311.60.2.1.3 = US, 1.3.6.1.4.1.311.60.2.1.2 =
Washington, bu sinessCategory = Private Organization, serialNumber =
600413485, C = US, postalC ode = 98052, ST = Washington, L = Redmond,
street = 1 Microsoft Way, O = Microso ft Corporation, OU = Windows
Azure CDN, CN = gfx-ecn.hotmail.com
verify error:num=27:certificate not trusted verify return:1
depth=0 1.3.6.1.4.1.311.60.2.1.3 = US, 1.3.6.1.4.1.311.60.2.1.2 =
Washington, bu sinessCategory = Private Organization, serialNumber =
600413485, C = US, postalC ode = 98052, ST = Washington, L = Redmond,
street = 1 Microsoft Way, O = Microso ft Corporation, OU = Windows
Azure CDN, CN = gfx-ecn.hotmail.com
verify error:num=21:unable to verify the first certificate verify
return:1
Certificate chain 0
s:/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Washington/businessCategory=Private
Organization/serialNumber=600413485/C=US/postalCode=98052/ST=Washington/L=Redmond/street=1
Microsoft Way/O=Microsoft Corporation/OU=Windows Azure
CDN/CN=gfx-ecn.hotmail.com i:/C=US/O=VeriSign, Inc./OU=VeriSign
Trust Network/OU=Terms of use at https://www.verisign.com/rpa
(c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA
-----BEGIN CERTIFICATE-----
MIIG0DCCBbigAwIBAgIQfRbsuTLd2GrmU38TPnVOCTANBgkqhkiG9w0BAQUFADCB
vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
HhcNMTIxMTA3MDAwMDAwWhcNMTQxMTA4MjM1OTU5WjCCAR0xEzARBgsrBgEEAYI3
PAIBAxMCVVMxGzAZBgsrBgEEAYI3PAIBAhMKV2FzaGluZ3RvbjEdMBsGA1UEDxMU
UHJpdmF0ZSBPcmdhbml6YXRpb24xEjAQBgNVBAUTCTYwMDQxMzQ4NTELMAkGA1UE
BhMCVVMxDjAMBgNVBBEUBTk4MDUyMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD
VQQHFAdSZWRtb25kMRgwFgYDVQQJFA8xIE1pY3Jvc29mdCBXYXkxHjAcBgNVBAoU
FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEaMBgGA1UECxQRV2luZG93cyBBenVyZSBD
RE4xHDAaBgNVBAMUE2dmeC1lY24uaG90bWFpbC5jb20wggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQC+jRmBRv2iw1N2LirFdhgqmZ3G+BBc8gAn50O6TT1u
zNqrjicf3KJ+BDHSGcnkysvWovwnUhDhMzAWf521iYi2lFZqC3txewGvjrKM0Gqz
DhHrF+bzvNjyrIION89354cFxU1eK2okegYHkWIuyPHyCN6PFGK52OlkBixb34xv
WvAZfjSu/hr+f+lkedFZvJdd6KS4e8N/tGJ/dndfmReaKSiNFWBFbwhkndLdXU3p
ZnVLCysETMuUoIsDIPcgDfji1XkoKLsri9WijVhjNH1MFf/t6/g4PpWqZGl4si3t
yQ0rdefDGfgX8lvq63aXnaap4SbjTYLviFRle/PMkXV7AgMBAAGjggJmMIICYjCB
0AYDVR0RBIHIMIHFghBnZngxLmhvdG1haWwuY29tghBnZngyLmhvdG1haWwuY29t
ghBnZngzLmhvdG1haWwuY29tghBnZng0LmhvdG1haWwuY29tghBnZng1LmhvdG1h
aWwuY29tghBnZng2LmhvdG1haWwuY29tghBnZng3LmhvdG1haWwuY29tghBnZng4
LmhvdG1haWwuY29tghRncmFwaGljcy5ob3RtYWlsLmNvbYIIYS5nZngubXOCE2dm
eC1lY24uaG90bWFpbC5jb20wCQYDVR0TBAIwADAdBgNVHQ4EFgQUH0b2ApITW9WB
/LA+oaz+2ZnW/dwwDgYDVR0PAQH/BAQDAgWgMD4GA1UdHwQ3MDUwM6AxoC+GLWh0
dHA6Ly9FVkludGwtY3JsLnZlcmlzaWduLmNvbS9FVkludGwyMDA2LmNybDBEBgNV
HSAEPTA7MDkGC2CGSAGG+EUBBxcGMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3
LnZlcmlzaWduLmNvbS9jcHMwNAYDVR0lBC0wKwYIKwYBBQUHAwEGCCsGAQUFBwMC
BglghkgBhvhCBAEGCisGAQQBgjcKAwMwHwYDVR0jBBgwFoAUTkPIHXbvN1N6T/JY
b5TzOOLVvd8wdgYIKwYBBQUHAQEEajBoMCsGCCsGAQUFBzABhh9odHRwOi8vRVZJ
bnRsLW9jc3AudmVyaXNpZ24uY29tMDkGCCsGAQUFBzAChi1odHRwOi8vRVZJbnRs
LWFpYS52ZXJpc2lnbi5jb20vRVZJbnRsMjAwNi5jZXIwDQYJKoZIhvcNAQEFBQAD
ggEBAFdVsrzkxJ6aRnaGIO1hbCDlekEMCT6OTlZXckzZeaIrNfSFLXHe89pWkRr1
AKz43nnM0pLxVuEHRE9pMZH6Om7SjqU5BR1qd6xp+ZJhuJA2I2319PCSbKCpv67X
82J8/JKjH8e4fpOzb70dKUlNNr7x0aIMYuCq6unXXZQ5u83Uny42jcIQWLOlZRKC
dYSqW3JalTYVZNvdEoQVuUEJJLcY1qMVJ9NFtdnrzrmcpK+52+nZQXbCkM7W8Vl1
WM/dbOnqsu0+SIPZ4Q2wIAnT1azmBvxZ2ULvzW98HIAn4/RdPuimnox8T9R2yrv1
xd5P6oAZWvmnX6e461m6HohhhDw=
-----END CERTIFICATE-----
Server certificate
subject=/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Washington/businessCategory=Private
Organization/serialNumber=600413485/C=US/postalCode=98052/ST=Washington/L=Redmond/street=1
Microsoft Way/O=Microsoft Corporation/OU=Windows Azure
CDN/CN=gfx-ecn.hotmail.com issuer=/C=US/O=VeriSign, Inc./OU=VeriSign
Trust Network/OU=Terms of use at https://www.verisign.com/rpa
(c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA
No client certificate CA names sent
SSL handshake has read 1933 bytes and written 480 bytes
New, TLSv1/SSLv3, Cipher is AES256-SHA Server public key is 2048 bit
Secure Renegotiation IS supported Compression: NONE Expansion: NONE
SSL-Session:
Protocol : SSLv3
Cipher : AES256-SHA
Session-ID: 3CC559C15AF17B09346C371A1CB292DF77C272A37FDC4DF69EEE0EE9CC067B5C
Session-ID-ctx:
Master-Key: F626E23FDCC89B1329FD4F5D1ED5A940F0CB14A1C377BFDB6ABA6238B91F9C11390EC16FD117C090B3171FBEE762B792
Key-Arg : None
PSK identity: None
PSK identity hint: None
Start Time: 1355423684
Timeout : 7200 (sec)
Verify return code: 21 (unable to verify the first certificate)
From the output of openssl, we can see that the openssl program produces similar errors (which makes it look more like an openssl bug?). We also notice that the hotmail server only returns the server certificate but does not return the intermediate certificate. That's probably what caused the error. I tried the same ssl command with other https servers. They also return both server certificates and intermediate certificates. Some of the banking sites I've tested even returned the entire certificate chain all the way to the root CA. So, the question is, if the intermediate certificate is not returned, how and where am I supposed to get it from? How does other browsers like IE and chrome handle this?
More findings here.
Actually, both of the two servers I mentioned are used to download in-page components for hotmail and yahoo mail. The yahoo mail main login page itself does return the full certificate chain. When other browsers access the main page, it will store the intermediate certificates locally for later use. However, QTWebkit doesn't cache the intermediate certificates automatically, therefore causing the problem. If I access the server https://gfx8.hotmail.com directly with a fresh copy of firefox, I get the same error. But if I access https:/www.hotmail.com first and then log into hotmail, there is no error although some components are downloaded from the gfx8 server after login. I found QTWebkit neither loads the intermediate certificates from system certificate store, nor does it add intermediate certificates to the system certificate store. It doesn't cache intermediate certificates internally in memory either. That will cause problem for some servers which doesn't return the complete certificate chain.
I did try saving the intermediate certificates to PEM file and load it at startup of my application. It works fine on Windows and Linux. But somehow, it has no effect on Mac. Don't know why.
In order to support secure connections in your application, without ignorig ssl errors, you must have the root certificates of all the domains that the site you're loading is accessing, so for example if it accesses a CDN(chech in the net panel of your browser), get that server's certificates also (you can download them from chrome for example, by viewing the current site's certificates, and get the whole chain, but separately download them).
After you stored all these certificates in one separate folder, add this code somewhere after the initialization of your application, it will load all of them at the beginning, so QT can access them:
import os
from PySide.QtNetwork import QSsl, QSslConfiguration, QSslCertificate
from PySide.QtCore import QFile, QIODevice
def load_certs(cert_path):
# cert_path is a string "/path/to/cert/files"
ssl_config = QSslConfiguration.defaultConfiguration()
ssl_config.setProtocol(QSsl.SecureProtocols)
certs = ssl_config.caCertificates()
for cert_filename in os.listdir(cert_path):
if os.path.splitext(cert_filename)[1] in ('.cer', '.crt', '.pem'):
cert_filepath = os.path.join(cert_path, cert_filename)
cert_file = QFile(cert_filepath)
cert_file.open(QIODevice.ReadOnly)
cert = QSslCertificate(cert_file)
certs.append(cert)
ssl_config.setCaCertificates(certs)
QSslConfiguration.setDefaultConfiguration(ssl_config)
Now when a site requires certificate validation, it won't fail. However openssl has indeed problems with it's TLS implementation on Debian systems, and in those cases you will experience problems such as pages never load, or similar errors when you don't have valid certificates. In those cases you have to force using SSLv3 for those pages, to get them work. You can achieve that by binding a custom virtual function to QNetworkAccessManager's createRequest, and overriding the ssl protocol for each request. That way you don't have to rely on older ssl version for all sites(because you could set the default ssl protocol globally too, but that's not the best idea), only for those which are problematic:
class Browser(object):
def __init__(self):
self.network_manager = QNetworkAccessManager()
self.network_manager.createRequest = self._create_request
self.web_page = QWebPage()
self.web_page.setNetworkAccessManager(self.network_manager)
self.web_view = QWebView()
self.web_view.setPage(self.web_page)
self._override_ssl = None
def _create_request(self, operation, request, data):
ssl_protocols = {'sslv2': QSsl.SslV2,
'sslv3': QSsl.SslV3,
'tlsv1': QSsl.TlsV1,
'tlsv1sslv3': QSsl.TlsV1SslV3,
'unknownprotocol': QSsl.UnknownProtocol,
'secureprotocols': QSsl.SecureProtocols}
if self._override_ssl is not None:
ssl_config = QSslConfiguration.defaultConfiguration()
ssl_config.setProtocol(ssl_protocols[self._override_ssl])
request.setSslConfiguration(ssl_config)
reply = QNetworkAccessManager.createRequest(self.network_manager,
operation,
request,
data)
return reply
def override_ssl(self, protocol_id):
# protocol id is a string like 'sslv3' or 'tlsv1'
self._override_ssl = protocol_id
Ok I typed most of the code from memory, please report if something doesn't work.

Certificate validation failed

Actors
-Asp.net site - Client
-Wcf services - Server
Both applications runs on IIS-7.
I want to make integration test between the two applications. The client access the Server through 'https'.
I have created a certificate and assigned it to the server. I also added the certificate to the 'Trusted Root Certification Authorities' to be considered a valid certificate. When I 'hit' the server's services through my browser (IE, chrome...) the certificate appears to be valid. But when my client application tries to access the server then I get the following error:
Could not establish trust relationship for the SSL/TLS secure channel with authority **** --->
The remote certificate is invalid according to the validation procedure.
Is there any way to skip the validation procedure or to make the certificate valid for my client application?
Just to know:
1. I cannot purchase a certificate because I will only use it for testing purposes.
2. I cannot make any changes on any of the application's code (server-client)
I finally managed to figured it out.
The problem was a previous (expired) certificate with the same name that was already added to the 'Trusted Root Certification Authorities'. Every time I was installing my new certificate through the 'Certificate Import Wizard' (or through MMC) the wizard informed me that it was successfully added. However, it was keeping the instance of the previous certificate without overwriting it.
Modify the validation callback to always return true:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, policyErrors) => true;
Or does that violate the 'no changes to code' condition?
How did you install the certificate into your trusted root store?
If you went through a browser to do it, most likely you only added it to the current user. Try adding it through the MMC snap-in for the Local Computer Account instead; this is where we install our self-signed IIS Express certificates and WCF seems happy with them.

WCF Certificate Authentication without installing on the Client

Our setup includes a WCF service and a number of clients written by us. Some of the clients include Silverlight applications, whereas others include Web and Windows applications.
I (think) I would like to authenticate clients based on X.509 certificates. Typically you would install a private key on the client to encrypt (aka digitaly sign) the messages. The server can the use the clients public key to de-crypt it to ensure the message has not been changed and prove the message is from who we expect (aka authenticated).
I dont want to install a certificate on a client machine. Its a hassel to deploy, and we cant really ask our clients to do it. I was speaking to someone the other day who sugested embeding the cert in a client assembly, reading it and using that. Is that possible?
It would be great if someone could point me to an example.
Thanks in advance,
David
Yes, you can load X509certificate2 by passing a certificate byte array with a password like
var certificate = new X509Certificate2(theByteArrary, "password");
To get the certificate byte array, you can simply copy paste the contents in .pfx file, which is a combination of .cer (public key) and .pvk (private key)
and then you can load this certificate on your client by doing:
var channelFactory = new ChannelFactory<IYourService>();
channelFactory.Credentials.ClientCertificate.Certificate =
clientCertificate;
If you use auto-generated client proxy, or you prefer configure the certificate via .config file then you might want to have a look at this from codeproject
Here is a suggestion. Could also be tweaked to use an embedded certificate.
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx

Resources