How to find out the path for OpenSSL trusted certificates? - certificate

How can I find out where my OpenSSL installation is looking for installed (trusted) certificates?
It is sometimes /etc/ssl/cert, but I have a new system and it is not working with this path.

The default path where certificates are looked up might be different on each platform. You can lookup your system configuration using the following command:
$ openssl version -d
OPENSSLDIR: "/etc/pki/tls"

This C snippet, compiled against OpenSSL, will tell you:
#include <stdlib.h>
#include <stdio.h>
#include <openssl/x509.h>
int main()
{
const char *dir;
dir = getenv(X509_get_default_cert_dir_env());
if (!dir)
dir = X509_get_default_cert_dir();
puts(dir);
return 0;
}

The path you are looking for is the "Directory for OpenSSL files". As #tnbt answered, openssl version -d (or -a) gives you the path to this directory. OpenSSL looks here for a file named cert.pem and a subdirectory certs/. Certificates it finds there are treated as trusted by openssl s_client and openssl verify (source: the article, What certificate authorities does OpenSSL recognize?).
% openssl version -d
OPENSSLDIR: "/opt/local/etc/openssl"
% ls -l /opt/local/etc/openssl/cert*
lrwxr-xr-x 1 root admin 40 29 Nov 02:05 /opt/local/etc/openssl/cert.pem -> /opt/local/share/curl/curl-ca-bundle.crt
% head -10 /opt/local/etc/openssl/cert.pem
##
## Bundle of CA Root Certificates
##
## Certificate data from Mozilla as of: Fri Nov 24 08:00:26 2017 GMT
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
## file (certdata.txt). This file can be found in the mozilla source tree:
## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
##
...[rest of file omitted]...
It turns out that the installer which installed OpenSSL on my system also installed cert.pem as a symlink to a bundle of Certificate Authority certificates from the tool cUrl . Those in turn came from Mozilla.
You might have nothing installed in this file or directory, or you might have a different set of certificates. This will affect which server certificates OpenSSL verifies.
OpenSSL commands like s_client support, I think since version 1.1, options -no-CAfile and -no-CApath. These let you ignore the certificates in this file and directory respectively, for the duration of one command. (I can't reproduce this because I am still using version 1.0.2, and it lacks those options.)

How can I find out, where my openssl installed is looking for installed certificates (trusted)?
You can't. OpenSSL trusts nothing by default, and it does not go looking for certs. You have to instruct it what to trust. There's even a FAQ topic covering it: Why does <SSL program> fail with a certificate verify error?:
This problem is usually indicated by log messages saying something
like "unable to get local issuer certificate" or "self signed
certificate". When a certificate is verified its root CA must be
"trusted" by OpenSSL this typically means that the CA certificate must
be placed in a directory or file and the relevant program configured
to read it. The OpenSSL program 'verify' behaves in a similar way and
issues similar error messages: check the verify(1) program manual page
for more information.
Caf's answer is kind of correct, but OpenSSL does not use it and there's nothing there...
$ grep -R X509_get_default_cert_dir *
...
crypto/x509/x509_def.c:const char *X509_get_default_cert_dir(void)
...
In the above, notice it does not hit on anything in the apps/ directory. apps/ is where all the OpenSSL samples and utilities are, like openssl req, openssl rsa, openssl dsa, openssl x509, openssl sign, openssl verify, etc.
Then:
$ cat crypto/x509/x509_def.c
...
const char *X509_get_default_cert_dir(void)
{ return(X509_CERT_DIR); }
...
$ grep -R X509_CERT_DIR *
crypto/cryptlib.h:#define X509_CERT_DIR OPENSSLDIR "/certs"
And finally:
$ ls /usr/local/ssl/certs/
$
Like I said, its not used and there's nothing there.

Related

Password incorrect importing certificate on 2012 server

When i try to import certificate on server 2012 it say password incorrect.
I have check this post:
"The password you entered is incorrect" when importing .pfx files to Windows certificate store
And i exported:
openssl.exe pkcs12 -in 'C:\cert.p12' -out C:\key.pem And created the new cert: openssl.exe pkcs12 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in 'C:\key.pem' -out 'C:\newcert.pfx' -name "newcert"
But when i try to import in server 2012 keep saying password incorrect.
The top answer in that post adds -nomac, which you didn't. Instead of turning off the MAC entirely, you could also try -macalg sha1.
--Something witty here questioning the use of a 10 year old OS (that only has 13 months of security updates remaining)--
For those who need it, i finally got it. Before execute the command from the other post, you have to export .key and .crt from your .p12 or .pfx certificate.

Where do I get PEM encoded Private Keys and and DER encoded Certificate paths on Mac?

I am trying to use the new SPM Collection signing utility found at https://github.com/apple/swift-package-collection-generator/tree/main/Sources/PackageCollectionSigner
But I honestly don't know how to get the necessary files.
Here is the definition:
USAGE: package-collection-sign <input-path> <output-path> <private-key-path> [<cert-chain-paths> ...] [--verbose]
ARGUMENTS:
<input-path> The path to the package collection file to be signed
<output-path> The path to write the signed package collection to
<private-key-path> The path to certificate's private key (PEM encoded)
<cert-chain-paths> Paths to all certificates (DER encoded) in the chain. The certificate used for signing must be first and the root
certificate last.
I understand the input-path and output-paths arguments but where do I get the PEM encoded private key and the DER encoded path chains?
Sorry if I am being naive, but this is just an area I have no experience with.
Any help about how I get/generate these files would be helpful.
thank you.
The private key you can generate yourself on the command line
openssl genrsa -out private.pem 2048
chmod 600 private.pem
Once you have the key, you will need to request a certificate that uses it. This can also be done on the command line:
openssl req -new -key private.pem -out signing.csr
Once you have that, you can go to developer.apple.com and click on the "Certificates, Identifiers and Profiles" section, then click on the "Certificates" tab. Click the blue plus button, choose the "Swift Package Collection Certificate" option and click Continue.
It will ask you to upload a CSR, so click Choose File and select the signing.csr file you just created. Download the generated certificate and rename it to signing.cer and you should be ready to go.
*Once you're done this, you can delete the signing.csr file.

Install self-signed certificate to personal store from .cer file using c++

I try to create a certificate for testing purposes in two steps. First, I create a self-signed certificate which establishes my own Certification Authority (CA). Second, I use that root certificate to sign a test server certificate which will be placed in personal certificate store. I open an administrative command prompt and enter the following:
Step 1:
MakeCert -pe -n "CN=TestCA" -b 01/01/2015 -e 01/01/2020 -ss my -sr currentuser -a sha256 -sky signature -len 2048 -r "TestCA.cer"
Step 2:
MakeCert -pe -n "CN=localhost" -b 01/01/2015 -e 01/01/2020 -eku 1.3.6.1.5.5.7.3.1 -in "TestCA" -is my -ir currentuser -ss my -sr currentuser -a sha256 -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -len 2048 "Localhost.cer"
Following those steps, everything works fine. After that, I try to install those certificates via c++ application. It seems to be fine when I check those certificates in certmgr.msc, however, client always fail to connect to server since then. After deleting certificate "localhost" from personal certificate store, then do step 2 using MakeCert.exe again. Client can success to connect to server. Maybe there is something important that I was missing. If anyone knows it, please give me some suggestions. By the way, my client and server are running in the same computer. My codes are shown below.
HCERTSTORE hMyCertStore = NULL;
if(hMyCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM, // The store provider type
0, // The encoding type is
// not needed
NULL, // Use the default HCRYPTPROV
CERT_SYSTEM_STORE_CURRENT_USER, // Set the store location in a
// registry location
L"MY" // The store name as a Unicode
// string
))
{
printf("The system store was created successfully.\n");
}
else
{
printf("An error occurred during creation "
"of the system store!\n");
exit(1);
}
CRYPTUI_WIZ_IMPORT_SRC_INFO importSrc;
memset(&importSrc, 0, sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO));
importSrc.dwSize = sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO);
importSrc.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_FILE;
importSrc.pwszFileName = L"C:\\Temp\\MakeCert\\localhost.cer";
importSrc.pwszPassword = L"";
importSrc.dwFlags = CRYPT_EXPORTABLE | CRYPT_USER_PROTECTED;
if (CryptUIWizImport(CRYPTUI_WIZ_NO_UI,
NULL,
NULL,
&importSrc,
hMyCertStore) == 0)
{
printf("CryptUIWizImport error %d\n", GetLastError());
}
Any help would be greatly appreciated.
Clement
I've found the difference between MakeCert and my application. After installing by MakeCert, I opened certificate dialog's General tab, then I found there is a string "You have a private key that corresponds to this certificate, but using my application, there is no string in the dialog. I think that I've missed some steps during the install procedure. If anyone know, please give me some suggestion.
Thanks.
Clement

Package Family Name changed with new code signing cert

Previously we have one code signing cert, every thing working fine. Recently cert expired so we taken new cert from Comodo and released new build with that cert.
So here is the problem: Package Family Name Changed with that new cert, so I am not able to upgrade old installed apps with this new build packaged with new cert.
Need solution for this to maintain Package Family Name as constant or for new cert's also we need to provide upgrade for older apps.
How can we achieve this?
Error msg while upgrading package from PowerShell:
Add-AppxPackage : Deployment failed with HRESULT: 0x80073CF3, Package failed
updates, dependency or conflict validation.
Windows cannot install package df70dbc9-455c-4c32-b052-7ac2943630b7_1.0.193.1_x64__qbsrcgy0j364g
because a different package df70dbc9-455c-4c32-b052-7ac2943630b7_1.0.0.191_x64__hs446qhh7vdt4
with the same name is already installed. Remove package
df70dbc9-455c-4c32-b052-7ac2943630b7_1.0.0.191_x64__hs446qhh7vdt4 before
installing.
NOTE: For additional information, look for [ActivityId]
b0deec37-ac10-0001-81fd-deb010acd101 in the Event Log or use the command line
Get-AppxLog -ActivityID b0deec37-ac10-0001-81fd-deb010acd101
At C:\Users\\Desktop\\myappName_1.0.193.1_x64_Test\Add-AppDevPackage.ps1:388 char:13
+ Add-AppxPackage -Path $DeveloperPackagePath.FullName -DependencyPath ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\Users\myuser....193.1_x64.appx:String) [Add-AppxPackage], IOException
+ FullyQualifiedErrorId : DeploymentError,Microsoft.Windows.Appx.PackageManager.Commands.AddAppxPackageCommand
Error: Could not install the app.
The Package Family Name (PFN) suffix (in your case hs446qhh7vdt4) is a hash of the certificate's subject (AKA subject name):
certutil -dump foo.pfx
Enter PFX password:
================ Certificate 0 ================
================ Begin Nesting Level 1 ================
Element 0:
Serial Number: xxxxxxxxxxxxxxxxx
Issuer: CN=Microsoft, O=Contoso, L=Redmond, S=Washington, C=US
NotBefore: 11/1/2016 12:00 AM
NotAfter: 11/1/2017 12:00 AM
Subject: CN=Microsoft, O=Contoso, L=Redmond, S=Washington, C=US <== THIS IS HASHED
If you make sure the new cert you generate has the same subject, you'll get the same PFN. Note that you might not be able to generate store certs from within Visual Studio (at the time of writing, it can't parse complex subjects like the one above with multiple 'parts' like CN=X, O=Y). In that case you'll have to create your own, but it must comply with the store validations.
Luckily, there's a simple command that generates the exact certificate you need. Open a Visual Studio developer prompt and run (one line):
makecert -sv foo.pvk -n "CN=Contoso, O=Contoso, L=Redmond, S=Washington, C=US"
foo.cer -b 11/01/2016 -e 11/01/2017 -r -cy end -a sha256 -eku 1.3.6.1.5.5.7.3.3
Make sure to replace the validity dates (no more than a year apart!) as well as the subject (taken from your previous cert using certutil -dump). The names of the output cert (cer) and private key (pvk) are meaningless. That command will generate foo.pvk and foo.cer, which you will then be able to combine to a pfx like so:
PVK2PFX -pvk foo.pvk -spc foo.cer -pfx foo.pfx
Another option for advanced generation
In case you have more advanced cert requirements, you should be able to use certreq (haven't tested it though). Create a file named cert.inf with the following contents:
[Version]
Signature = "$Windows NT$"
[Strings]
szOID_ENHANCED_KEY_USAGE = "2.5.29.37"
szOID_CODE_SIGNING = "1.3.6.1.5.5.7.3.3"
szOID_BASIC_CONSTRAINTS2 = "2.5.29.19"
[NewRequest]
Subject = "CN=Contoso, O=Contoso, L=Redmond, S=Washington, C=US"
Exportable = true
HashAlgorithm = Sha256
KeyLength = 2048
RequestType = Cert
ValidityPeriod = "Years"
ValidityPeriodUnits = "1"
[Extensions]
%szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_CODE_SIGNING%"
%szOID_BASIC_CONSTRAINTS2% = "{text}"
Replace the subject and validity period, and adjust any advanced settings you need per the docs (or more likely found on the web). Then do the following:
certreq -new cert.inf cert.cer
Double-click the resulting cert.cer and install it to the Trusted Root Certificate Authorities store (either user or machine).
certreq -accept -user cert.cer OR certreq -accept -machine cert.cer (depending on the store you picked in the previous step).
Go to the Personal store in the cert manager (user or machine scope, depending on what you picked above) and find the cert you just installed. Double-click it and copy the serial number from the details tab (I encountered some voodoo here where the cert would only show up after a long time, or after I installed a different cert (with a different subject name).
certutil -exportpfx -p "YOUR_PFX_PASS" my SERIAL_NUMBER foo.pfx (replace the password and the serial number with their actual values)
You should now have a valid store pfx.
Yet another option for even more advanced generation
Use OpenSSL. Pretty sure it can do all the above and more, but I haven't tried it personally so you'll have to figure it out - and hopefully share here once you do!

Can SSL cert be used to digitally sign files?

I want to ask a thing about digital signing I am not very sure.
Instead of creating a self signed certificate to use to sign some (PDF) files, I wanted to take my SSL cert which have my data already verified.
But the question is: Can a SSL cert be used to digital sign files or is it incompatible in some manner?
EDIT: To clarify, this question is not about how to sign PDFs, is only about if a SSL cert can be used (or converted in any way) to sign files.
To support digital signing certificate must have digitalSignature option in it's keyUsage field (and codeSigning option in it's extendedKeyUsage field if your want to sign programs with it).
Signing may be done with existing tools or manually (java example, you are not asking for it, but this code snippet might be useful anyway):
byte[] bytesToSign = loadMyData();
KeyStore ks = KeyStore.getInstance("pkcs12", "SunJSSE");
ks.load(new FileInputStream("cert.p12"), "passwd1".toCharArray());
PrivateKey privateKey = (PrivateKey) ks.getKey("myalias", "passwd2".toCharArray());
Signature sig = Signature.getInstance("SHA1withRSA", ks.getProvider());
sig.initSign(privateKey);
sig.update(bytesToSign);
byte[] signature = sig.sign();
To make your own not self-signed certificate with openssl see this SO answer.
Also curious about signing PDF's - aren't separate hash sums of these files enough in your case?
edit: if you want any sign, not exactly X.509 sign by existing tools, you can extract RSA key from your cert and do signing without bothering about keyUsage field.
At the core, the certificate is just a normal RSA public key that's been signed by several authorities.
So yes, definitely possible.
Though I don't know of any easy-to-use widespread tools for the end-user for this.
Yes, you can sign and verify the signature of files using SSL certificates
Here is an example:
SSLCERT='/XXXX/ssl/certs/fqdn.pem'
SSLKEY='/XXXX/ssl/private_keys/fqdn.pem'
# You might not need to specify a CA
CACERTFILE='/XXXX/ssl/certs/ca.pem'
# File to sign
FILE='YYYYYYY'
# Signs, needs ${SSLKEY} and ${FILE}
openssl dgst -sha512 -sign ${SSLKEY} -out ${FILE}.sha512 ${FILE}
# Then transfer the following files to another server:
# - ${CACERTFILE}
# - ${SSLCERT}
# - ${FILE}
# - ${FILE}.sha512
# Check the certificate is valid
openssl verify -verbose -CAfile ${CACERTFILE} ${SSLCERT}
# Extract the pub key from the cert
openssl x509 -in ${SSLCERT} -pubkey -noout > ${SSLCERT}.pub
# Check the signature
openssl dgst -sha512 -verify ${SSLCERT}.pub -signature ${FILE}.sha512 ${FILE}