Title was: X509Store on Unix scans only for PFX files
Currently, the only extension supported by the code is PFX. As far as I understand, this extension is commonly used for certificates that will contain a private key on Windows. On Unix I would expect certificate extensions such as .der or .pem, similar to the ones in OpenSSL's store.
This is only an inconvenience as I've found that a .cer (base64 encoded) can be simply renamed to .pfx and placed in ~/.dotnet/corefx/cryptography/x509store/root to simulate the My\Root store.
/cc @bartonjs
The directory isn't a considered an extensibility point. Use new X509Store(X509StoreName.Root, X509StoreLocation.CurrentUser) with OpenFlags.ReadWrite.
@bartonjs In most server situations I'd expect that the app won't have the ability to _write_ certificates, especially from the Trusted Root store. I also expect that an administrator can easily install the certificate without the help of a dev.
Regardless if the directory is meant for that purpose or not, please provide (and document) a way to manage certs w/o the need of code.
@CIPop Does Windows document a way to alter the trust store without their API? AFAIK they don't.
LocalMachine\Root is always read-only on Linux; managed by the normal OpenSSL-based-tools-process for the distro. So that's the administrator/server scenario.
CurrentUser\Root is always able to be opened as write (on Linux and Windows).
Does Windows document a way to alter the trust store without their API?
In Windows, a system admin can manage certificates via MMC.exe or CertMgr.msc.
How would a sys-admin achieve this in Linux when using .Net Core?
For system trust, they'd follow their distro's rules. (e.g. for Ubuntu)
http://kb.kerio.com/product/kerio-connect/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html gives a good overview for Windows, macOS and a couple of Linux distros.
User trust (which is what that directory structure is about) is:
certutil.exe -addstore -user ... or MMC (or a couple other UI ways)security add-trusted-cert or the Keychain Access program (or a couple of other UI ways)Since each Linux distro has different procedures for properly updating the root trust, it's not easy to give good system management tooling.
I like the powershell idea.
Unfortunately they don't support this just yet: https://github.com/PowerShell/PowerShell/issues/1865
@bartonjs I'm trying to read a cert from the store in Linux and can't seem to find it in .NET.
My test.crt was copied to /usr/local/share/ca-certificates/test.crt and then ran update-ca-certificates confirming it was added.
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
I can also run the following command and see my cert:
`awk -v cmd='openssl x509 -noout -subject' '
/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt`
Results
...
subject= /C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
subject= /C=US/O=thawte, Inc./OU=(c) 2007 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G2
subject= /C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2008 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G3
subject= /C=US/ST=Indiana/L=Indianapolis/O=Software in the Public Interest/OU=hostmaster/CN=Certificate Authority/[email protected]
subject= /CN=TestCert
However, looping through the following in .NET shows no certs:
var certStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
certStore.Open(OpenFlags.Read);
var certs = string.Empty;
foreach(var c in certStore.Certificates)
{
// print c
}
Changing it to StoreLocation.LocalMachine then shows all the certs from my earlier print command (thawte Primary Root CA, thawte Primary Root CA - G2, etc), except my test cert that I added.
Any ideas?
@kspearrin Was the cert you added self-issued (Subject == Issuer)? If not, it gets relegated to LocalMachine\CA (Intermediates).
CurrentUser\Root is a store that belongs to your user account, so the cert you added in a system directory not showing up there isn't surprising, the only supported way to get something in CU\Root is via the .NET API :smile:.
Assuming you're using Ubuntu (from update-ca-certificates) the place that OpenSSL (and thus us) will really look is
/usr/lib/ssl/certs should be a symlink to /etc/ssl/certs)These paths are determined by concatenating /certs/ and /cert.pem to
$ grep OPENSSLDIR /usr/include/x86_64-linux-gnu/openssl/opensslconf.h
#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
#define OPENSSLDIR "/usr/lib/ssl"
(Only the #define is relevant, mine is from Ubuntu 16.04)
ls -alr | head should help you find if your new cert got linked into the correct directory by the updater tool.
Then there are two relevant things:
How to add a cert to the CurrentUser\My store without .NET API on Ubuntu 16.04? I saw @bartonjs reply that there is no generic Linux way yet, but Ubuntu specific way would suffice for me for now. What folder should I copy the cert to?
@dmitry606 There is no supported way to add certificates to any CurrentUser store on Linux without using the .NET API.
Most helpful comment
For system trust, they'd follow their distro's rules. (e.g. for Ubuntu)
http://kb.kerio.com/product/kerio-connect/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html gives a good overview for Windows, macOS and a couple of Linux distros.
User trust (which is what that directory structure is about) is:
certutil.exe -addstore -user ...or MMC (or a couple other UI ways)security add-trusted-certor the Keychain Access program (or a couple of other UI ways)Since each Linux distro has different procedures for properly updating the root trust, it's not easy to give good system management tooling.