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

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".

Related

URI to identify certificates

Are there some commonly used or standardized URI schemes or patterns that are used to identify SSL certificates, for example for description in linked data applications? The URI does not necessarily have to be resolvable, but it should be unique for a given certificate (and not something arbitrary).
For example, the fingerprint of the certificate used by stackoverflow.com is F4:AB:EB:33:1E:28:CC:EB:20:DA:7F:C1:8C:A9:55:90:C0:ED:1F:4E:63:F5:2B:63:7B:23:B9:BC:06:66:5E:64. A hypothetical example could be therefore something like urn:cert:thumbprint:F4ABEB331E28CCEB20DA7FC18CA95590C0ED1F4E63F52B637B23B9BC06665E64.
I have managed to find RFC 7512 that describes the pkcs11: scheme which has the serial attribute, but as far as I know, the serial does not have to be unique, only when coupled with the identifier of the certificate authority, but I don't think you can specify that in pkcs11:. I wasn't able to find anything else.
It is my own case for establishing TLS to get URI (I'm using SafeNet eToken) issuing command:
p11tool --list-all-certs 'pkcs11:model=eToken'
The result looks like this (sensitive data is masked):
Object 0:
URL: pkcs11:model=eToken;manufacturer=SafeNet%2C%20Inc.;serial=01234567;token=AlexXXXXXXXXXXXXXXXX;id=%00%11%22%33%44%55%66%77;object=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;type=cert
Type: X.509 Certificate (RSA-2021)
Expires: Xxx Apr 01 01:23:45 2021
Label: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ID: 00:11:22:33:44:55:66:77
The URL
URL: pkcs11:model=eToken;manufacturer=SafeNet%2C%20Inc.;serial=01234567;token=AlexXXXXXXXXXXXXXXXX;id=%00%11%22%33%44%55%66%77;object=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;type=cert
is contains serial number of token itself serial=01234567 and id of object on token id=%00%11%22%33%44%55%66%77. Unique couple.
UPDATE
In your case serial is not the serial number of a certificate, it's a serial number of token on which object (certificate) is located. You are mismatching the terms.

Sending client certificate with JMeter load test

I am attempting to use a certificate with JMeter and can see that it appears to be loaded fine from the logs.
INFO o.a.j.u.SSLManager: JmeterKeyStore Location: certificate.jks type jks
INFO o.a.j.u.SSLManager: KeyStore created OK
INFO o.a.j.u.SSLManager: Total of 1 aliases loaded OK from keystore
Yet, when I send the Http Request, the results from the server just keep stating 'Client Certificate Not Provided'.
Below are the parameters I've used on the command line.
-D javax.net.ssl.keyStoreType=jks
-D javax.net.ssl.keyStore=certificate.jks
-D javax.net.ssl.keyStorePassword=password123
All the examples I can find simply state that if I configure the Jmeter element 'KeyStore Configuration' with the alias, it should send the certificate with the requests. It does not seem to be doing so. For the record, I have also tried to use the p12 cert and set the type to pkcs12 with the same results.
What am I missing?
In fact given you have only one certificate you don't need the Keystore Configuration at all, just remove it from the test plan and your setup should start working normally
Most probably your Keystore Configuration is not correct, for instance the "variable name holding certificate alias" is not set or doesn't match the record in the keystore
Check its value using Debug Sampler and make sure that certificate with this alias exists in the keystore. You can see a working sample in How to Use Multiple Certificates When Load Testing Secure Websites article

Firebase Trigger E-Mail Hostname/IP does not match certificate's altnames

I am using the extension "Trigger E-Mail" in Firebase. When I try to send an e-mail and I get the following error:
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames
Does this mean the loaded certificate must contain my hostname to work? Sorry, I just have started studying certificates. If I am right then one solution would be to add my hostname into the certificate. As I am using a thirdparty mailprovider. UPDATE: The smtp server uses a shared certificate which doesnt include any other domain and it will never happen.
Similar posts using nodejs tell to set the following configuration:
{ rejectUnauthorized : false }
First I cannot set his configuration into the Extension, secondly I do not want to remove the security feature.
What do you recommend?

Active directory certificate service not starting

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.

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.

Resources