Erlang check .pem certificate is not revoked with .crl file - ssl

I am trying to implement offline check for certificate based on data from .CRL (certificate revoked list) files
I checked pkix validation and crl api but did not find any examples of using
Assume I have list of providers, list of CRL files of provider (revoked and partially revoked), and some .pem file to check
Any ideas how this check should be implemented?

You can use the crl_check and crl_cache options:
ssl:connect("www.google.com", 443,
[{verify, verify_peer},
{crl_check, true},
{crl_cache, {ssl_crl_hash_dir, {internal, [{dir, "/path/to/crls/"}]}}}]).
The ssl_crl_hash_dir module expects to find a directory containing all CRLs with file names in a very specific format, e.g. 1a2b3c4d.r0, where the first eight characters are a hash of certain parts of the certificate, and the trailing .r0 is a CRL revision number. The c_rehash utility, which comes with OpenSSL, can set up symlinks matching that format.
ssl_crl_hash_dir lets you do CRL checks completely offline, unlike ssl_crl_cache, which attempts to download CRLs from the designated server.
To prepare the CRL directory, let's say we downloaded Google's CRL:
wget http://crl.pki.goog/GTSGIAG3.crl
Unfortunately, it's in DER format, so c_rehash doesn't understand it (and neither will ssl_crl_hash_dir). Let's recode it:
openssl crl -in GTSGIAG3.crl -inform DER -outform PEM -out GTSGIAG3-pem.crl
Now, we can run c_rehash, giving the current directory as argument:
$ c_rehash .
Doing .
WARNING: GTSGIAG3.crl does not contain a certificate or CRL: skipping
It has created two symlinks for us:
$ ls -go
total 8
lrwxrwxrwx 1 16 Jul 23 16:28 6a909d98.r0 -> GTSGIAG3-pem.crl
lrwxrwxrwx 1 16 Jul 23 16:28 a11dd888.r0 -> GTSGIAG3-pem.crl
-rw-rw-r-- 1 635 Jul 23 03:15 GTSGIAG3.crl
-rw-rw-r-- 1 910 Jul 23 16:28 GTSGIAG3-pem.crl
The hashes in those symlinks are the ones returned by openssl crl -hash and openssl crl -hash_old:
$ openssl crl -hash -noout -in GTSGIAG3-pem.crl
6a909d98
$ openssl crl -hash_old -noout -in GTSGIAG3-pem.crl
a11dd888

Get serial numbers of revoked certificates:
{ok, Bytes} = file:read_file("/Users/Downloads/CA-4E6929B9-Delta.crl").
public_key:der_decode('CertificateList', Bytes).
Return
public_key:der_decode('CertificateList', Bytes).
{'CertificateList',{'TBSCertList',v2,
{'AlgorithmIdentifier',{1,2,804,2,1,1,1,1,3,1,1},
asn1_NOVALUE},
{rdnSequence,[[{'AttributeTypeAndValue',{2,5,4,10},
<<12,28,208,162,208,158,208,146,32,34,208,144,208,160,
208,162,...>>}],
[{'AttributeTypeAndValue',{2,5,4,11},
<<12,8,208,144,208,166,208,161,208,154>>}],
[{'AttributeTypeAndValue',{2,5,4,3},
<<12,49,208,144,208,166,208,161,208,154,32,34,77,65,...>>}],
[{'AttributeTypeAndValue',{2,5,4,5},
<<12,14,85,65,45,51,48,52,48,52,55,53,48,...>>}],
[{'AttributeTypeAndValue',{2,5,4,6},<<19,2,85,65>>}],
[{'AttributeTypeAndValue',{2,5,4,7},
<<12,8,208,154,208,184,209,151,208,178>>}]]},
{utcTime,"180720162130Z"},
{utcTime,"180720182130Z"},
[{'TBSCertList_revokedCertificates_SEQOF',447646493074184995506808756600724219093179699200,
{utcTime,"180715102900Z"},
[{'Extension',{2,5,29,21},false,<<10,1,0>>},
{'Extension',{2,5,29,24},
false,
<<24,15,50,48,49,56,48,55,49,...>>}]},
{'TBSCertList_revokedCertificates_SEQOF',447646493074184995506808756600724219093196476416,
{utcTime,"180715102900Z"},
[{'Extension',{2,5,29,21},false,<<10,1,0>>},
{'Extension',{2,5,29,24},
false,
<<24,15,50,48,49,56,48,55,...>>}]},
{'TBSCertList_revokedCertificates_SEQOF',447646493074184995506808756600868334281322663936,
{utcTime,"180715103000Z"}, ...
Check serialNumber of certificate is not in list

Related

Self-signed SLL certificate for Nextcloud Onion: "ERR_SSL_PROTOCOL_ERROR"

Context
After setting up a self-hosted nextcloud server on Ubuntu 22.10 over a tor domain, I created a self-signed SLL certificate using the script below:
Code
This script first
generates the certificate authority (CA) and SSL certificates, and then it adds the CA private key to: "/usr/local/share/ca-certificates/$ca_public_key_filename" and reloads the trusted ca certificates with:
sudo update-ca-certificates
It also adds the SSL prublic and private key and the full chain certificate into Nextcloud.
The fullchain.pem consists of the SSL certificate, followed by the CA certificate.
#!/usr/bin/env bash
# Here is the list of certificates and their description:
# First you create your own certificate authority.
CA_PRIVATE_KEY_FILENAME="ca-key.pem"
CA_PUBLIC_KEY_FILENAME="ca.pem"
# Same file as ca.pem except different file extension and content.
CA_PUBLIC_CERT_FILENAME="ca.crt"
# Then you create a SSL certificate.
SSL_PRIVATE_KEY_FILENAME="cert-key.pem"
# Then create a sign-request (for your own CA to sign your own SSL certificate)
CA_SIGN_SSL_CERT_REQUEST_FILENAME="cert.csr"
SIGNED_DOMAINS_FILENAME="extfile.cnf"
# Then create the signed public SSL cert.
SSL_PUBLIC_KEY_FILENAME="cert.pem"
# Then merge the CA and SLL cert into one.
MERGED_CA_SSL_CERT_FILENAME="fullchain.pem"
setup_tor_ssl() {
local onion_address="$1"
# Create domains accepted by certificate.
local domains
#domains="DNS:$onion_address,IP:127.0.0.1"
#domains="DNS:localhost,IP:$onion_address" # IP onion does not work
#domains="DNS:*.$onion_address" # Does not work.
#domains="DNS:$onion_address" # Does not work.
domains="DNS:localhost,DNS:$onion_address" # Works for localhost
echo "domains=$domains.end_without_space"
delete_target_files
# Generate and apply certificate.
generate_ca_cert "$CA_PRIVATE_KEY_FILENAME" "$CA_PUBLIC_KEY_FILENAME"
generate_ssl_certificate "$CA_PUBLIC_KEY_FILENAME" "$CA_PRIVATE_KEY_FILENAME" "$CA_SIGN_SSL_CERT_REQUEST_FILENAME" "$SIGNED_DOMAINS_FILENAME" "$SSL_PUBLIC_KEY_FILENAME" "$SSL_PRIVATE_KEY_FILENAME" "$domains"
verify_certificates "$CA_PUBLIC_KEY_FILENAME" "$SSL_PUBLIC_KEY_FILENAME"
merge_ca_and_ssl_certs "$SSL_PUBLIC_KEY_FILENAME" "$CA_PUBLIC_KEY_FILENAME" "$MERGED_CA_SSL_CERT_FILENAME"
install_the_ca_cert_as_a_trusted_root_ca "$CA_PUBLIC_KEY_FILENAME" "$CA_PUBLIC_CERT_FILENAME"
add_certs_to_nextcloud "$SSL_PUBLIC_KEY_FILENAME" "$SSL_PRIVATE_KEY_FILENAME" "$MERGED_CA_SSL_CERT_FILENAME"
}
generate_ca_cert() {
local ca_private_key_filename="$1"
local ca_public_key_filename="$2"
# Generate RSA
openssl genrsa -aes256 -out "$ca_private_key_filename" 4096
# Generate a public CA Cert
openssl req -new -x509 -sha256 -days 365 -key "$ca_private_key_filename" -out "$ca_public_key_filename"
}
generate_ssl_certificate() {
local ca_public_key_filename="$1"
local ca_private_key_filename="$2"
local ca_sign_ssl_cert_request_filename="$3"
local signed_domains_filename="$4"
local ssl_public_key_filename="$5"
local ssl_private_key_filename="$6"
local domains="$7"
# Example supported domains:
# DNS:your-dns.record,IP:257.10.10.1
# Create a RSA key
openssl genrsa -out "$ssl_private_key_filename" 4096
# Create a Certificate Signing Request (CSR)
openssl req -new -sha256 -subj "/CN=yourcn" -key "$ssl_private_key_filename" -out "$ca_sign_ssl_cert_request_filename"
# Create a `extfile` with all the alternative names
echo "subjectAltName=$domains" >>"$signed_domains_filename"
# optional
#echo extendedKeyUsage = serverAuth >> "$ca_sign_ssl_cert_request_filename"
# Create the public SSL certificate.
openssl x509 -req -sha256 -days 365 -in "$ca_sign_ssl_cert_request_filename" -CA "$ca_public_key_filename" -CAkey "$ca_private_key_filename" -out "$ssl_public_key_filename" -extfile "$signed_domains_filename" -CAcreateserial
}
verify_certificates() {
local ca_public_key_filename="$1"
local ssl_public_key_filename="$2"
openssl verify -CAfile "$ca_public_key_filename" -verbose "$ssl_public_key_filename"
}
merge_ca_and_ssl_certs() {
local ssl_public_key_filename="$1"
local ca_public_key_filename="$2"
local merged_ca_ssl_cert_filename="$3"
cat "$ssl_public_key_filename" >"$merged_ca_ssl_cert_filename"
cat "$ca_public_key_filename" >>"$merged_ca_ssl_cert_filename"
}
install_the_ca_cert_as_a_trusted_root_ca() {
local ca_public_key_filename="$1"
local ca_public_cert_filename="$2"
# The file in the ca-certificates dir must be of extension .crt:
openssl x509 -outform der -in "$ca_public_key_filename" -out "$ca_public_cert_filename"
# First remove any old cert if it existed.
sudo rm "/usr/local/share/ca-certificates/$ca_public_cert_filename"
sudo update-ca-certificates
# TODO: Verify target directory exists.
# On Debian & Derivatives:
#- Move the CA certificate (`"$ca_private_key_filename"`) into `/usr/local/share/ca-certificates/ca.crt`.
sudo cp "$ca_public_cert_filename" "/usr/local/share/ca-certificates/$ca_public_cert_filename"
# TODO: Verify target file exists.
# TODO: Verify target file MD5sum.
# Update the Cert Store with:
sudo update-ca-certificates
}
add_certs_to_nextcloud() {
local ssl_public_key_filename="$1"
local ssl_private_key_filename="$2"
local merged_ca_ssl_cert_filename="$3"
# First copy the files into nextcloud.
# Source: https://github.com/nextcloud-snap/nextcloud-snap/issues/256
# (see nextcloud.enable-https custom -h command).
#sudo cp ca.pem /var/snap/nextcloud/current/ca.pem
sudo cp "$ssl_public_key_filename" /var/snap/nextcloud/current/"$ssl_public_key_filename"
sudo cp "$ssl_private_key_filename" /var/snap/nextcloud/current/"$ssl_private_key_filename"
sudo cp "$merged_ca_ssl_cert_filename" /var/snap/nextcloud/current/"$merged_ca_ssl_cert_filename"
# CLI sudo /snap/bin/nextcloud.enable-https custom Says:
sudo /snap/bin/nextcloud.enable-https custom "/var/snap/nextcloud/current/$ssl_public_key_filename" "/var/snap/nextcloud/current/$ssl_private_key_filename" "/var/snap/nextcloud/current/$merged_ca_ssl_cert_filename"
}
delete_target_files() {
rm "$CA_PRIVATE_KEY_FILENAME"
rm "$CA_PUBLIC_CERT_FILENAME"
rm "$CA_PUBLIC_KEY_FILENAME"
rm "$SSL_PRIVATE_KEY_FILENAME"
rm "$CA_SIGN_SSL_CERT_REQUEST_FILENAME"
rm "$SIGNED_DOMAINS_FILENAME"
rm "$SSL_PUBLIC_KEY_FILENAME"
rm "$MERGED_CA_SSL_CERT_FILENAME"
sudo rm "/usr/local/share/ca-certificates/$CA_PUBLIC_KEY_FILENAME"
sudo rm "/usr/local/share/ca-certificates/$CA_PUBLIC_CERT_FILENAME"
sudo rm "/var/snap/nextcloud/current/$SSL_PUBLIC_KEY_FILENAME"
sudo rm "/var/snap/nextcloud/current/$SSL_PRIVATE_KEY_FILENAME"
sudo rm "/var/snap/nextcloud/current/$MERGED_CA_SSL_CERT_FILENAME"
}
Output
The output of this script can be read as:
$src/main.sh -h
domains=DNS:some_onion.onion,IP:127.0.0.1.end_without_space
rm: cannot remove 'ca.pem': No such file or directory
rm: cannot remove 'cert.csr': No such file or directory
rm: cannot remove 'extfile.cnf': No such file or directory
rm: cannot remove 'cert.pem': No such file or directory
rm: cannot remove 'fullchain.pem': No such file or directory
rm: cannot remove '/usr/local/share/ca-certificates/ca.pem': No such file or directory
Generating RSA private key, 4096 bit long modulus (2 primes)
................................................................................................................................................................................++++
...................................................................................................................................................................................................................................++++
e is 65537 (0x010001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:so
State or Province Name (full name) [Some-State]:state3
Locality Name (eg, city) []:locality3
Organization Name (eg, company) [Internet Widgits Pty Ltd]:org3
Organizational Unit Name (eg, section) []:orgunit3
Common Name (e.g. server FQDN or YOUR name) []:cn3
Email Address []:email3#email.com
Generating RSA private key, 4096 bit long modulus (2 primes)
...................................................................++++
.............................................++++
e is 65537 (0x010001)
Signature ok
subject=CN = yourcn
Getting CA Private Key
Enter pass phrase for ca-key.pem:
cert.pem: OK
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
Processing triggers for ca-certificates-java (20220719) ...
done.
Updating Mono key store
Mono Certificate Store Sync - version 6.8.0.105
Populate Mono certificate store from a concatenated list of certificates.
Copyright 2002, 2003 Motus Technologies. Copyright 2004-2008 Novell. BSD licensed.
Importing into legacy system store:
I already trust 124, your new list has 124
Import process completed.
Importing into BTLS system store:
I already trust 124, your new list has 124
Import process completed.
Done
done.
Installing custom certificate... done
Restarting apache... done
Error Message
After running the script successfully, I can manually import the ca.crt into brave at: brave://settings/certificates This ensures https works for https://localhost:81 . However, when I open the tor browser in brave, and visit the some_onion.onion it returns:
This site can’t provide a secure connection
some_onion.onion sent an invalid response.
ERR_SSL_PROTOCOL_ERROR
Question
How can I ensure the certificate is trusted on both the some_onion.onion link, as well as on localhost?
Doubt
I am unsure whether:
echo "subjectAltName=DNS:some_onion_link.onion"
is permitted. for an SSL certificate. I wonder why the tor version of Brave does not show why the certificate is not trusted.

How to Generate keystore.p12 from Certificate(.cer) , certificate chain(.p7b) and from key(.key and .pem)

I have the following files:
filename.key (RSA PRIVATE KEY)
filename.pem (CERTIFICATE REQUEST)
certificate.cer (CERTIFICATE)
CertificateChain.p7b
I have received these files from the CA including the certificate chain.
I need to generate 'keystore.p12' to configure SSL for spring boot application with the following information.
server:
port: 443
ssl:
key-store: keystore.p12
key-store-password: <your-password>
keyStoreType: PKCS12
keyAlias: <my alias>
Can anyone please help me to generate the 'keystore.p12'?
File extensions do not actually control the format or contents a file, although usually they should provide at least partial description. Similarly basenames (before the extension) should describe what is in the file, but do not always do so correctly. What matters is what is in the files.
.key is usually used for a lone privatekey, but look at it to make sure, and also to determine what format it is in because there are many. You should never get your privatekey from a CA; it should be generated locally, usually on the machine where it will be used and at least by the 'owner' or admin of that machine. There might be a sort-of exception if you are talking about a CA internal to a company, organization, agency, or office -- in that case the person running the CA may be the same person who is responsible for security on all the machines -- or vice versa, depending on your perspective -- and it may make sense for them to generate both the key and the cert.
.pem is used for lots of things in PEM format, and what the contents of that file is (or are) matters more than the fact of it being PEM. Look at the first line -----BEGIN (somewords)----- and see what the word(s) is(are). That should be followed either immediately or after a few header lines by data in base64 (a solid block of letters, digits, and the special characters + / =), then a matching -----END (somewords)----- line. If the END line is followed by a another similar block, or several, look at all of them.
.cer is commonly used for certificates in either 'DER' (binary) or 'PEM' (as above) format. .p7b is similarly used for 'dummy' PKCS7 messages containing certificates -- especially certificates used in a chain -- in either DER or PEM. More significantly, p7b is sometimes used for the whole chain including the end-entity (server) cert, and sometimes the rest of the chain excluding the EE cert, and it matters which. If you have OpenSSL -- or can get it (e.g. by installing a package, or for Windows I recommend the installer from http://www.slproweb.com/products/Win32OpenSSL.html ) or can move your data to a machine that has it -- then do:
# if the p7b file is in PEM format (you can see ----BEGIN PKCS7----- line)
openssl pkcs7 -in file.p7b -print_certs
# if the p7b file is in DER format (looks like garbage in a text editor or display)
openssl pkcs7 -in file.p7b -inform der -print_certs
# for now look only at the subject= and issuer= lines to see
# for each cert in the file who it is for, and if/how they chain
Then:
if the .key file is a privatekey in one of the PEM formats supported by OpenSSL you can use that; else if .key is a privatekey in some other format, or .pem is or includes a privatekey in some format, you'll need to convert and/or extract it: tell us more about what those files look like.
if the .p7b file is in PEM or DER format, put its expanded output (from above) in a file. If this includes the EE cert skip the next step.
if the .p7b file does not include the EE cert, but the .cer file is that cert, if in PEM format just append it to the file containing the .p7b output; if in DER format convert it with openssl x509 -in file.cer -inform der and append that.
if you now have the privatekey in one of the PEM formats supported by OpenSSL, and the cert chain including the EE cert in PEM format, do
openssl pkcs12 -export -in chain.pem -inkey key.pem -out newfile.p12 [-name x]
# the -name option provides the 'alias' used by Java
# if not specified it defaults to the numeral 1 (one)

How does the browser deal with missing intermediate certs

I've come across the site https://alpower.com, this site is only providing its own site certificate. Because of this I can't access the site properly with cURL as the cacerts used are only root certsificates.
The site is accessible in Firefox however. How exactly is Firefox able to verify the site's identity where as cURL isn't?
Browsers will cache intermediate certificates. So if the missing certificate was already provided by another site the browser will have it already and will use it. But, if you use a fresh browser profile you might get the same problems as you get with curl, because the intermediate certificate is not cached.
This is at least how it works with Firefox. Other browsers might look into the Authority Information Access section of the certificate and if they find the URL issuer certificate they will download the certificate to continue with the chain verification.
Most browsers are using the AIA information embedded in the certificate (see comment on browsers exceptions).
To expose the URL of the CA Issuer with openssl:
openssl x509 -in "YOUR_CERT.pem" -noout -text
There is a section Authority Information Access with CA Issuers - URI which would be the "parent" certificate (intermediate or root certificate).
This can be reproduced up to the root CA.
In a gist:
ssl_endpoint=<ENDPOINT:443>
# first, get the endpoint cert
echo | openssl s_client -showcerts -connect $ssl_endpoint 2>/dev/null | openssl x509 -outform PEM > endpoint.cert.pem
# then extract the intermediate cert URI
intermediate_cert_uri=$(openssl x509 -in endpoint.cert.pem -noout -text | (grep 'CA Issuers - URI:' | cut -d':' -f2-))
# and get the intermediate cert (convert it from DER to PEM)
curl -s "${intermediate_cert_uri}" | openssl x509 -outform PEM -inform DER > intermediate.cert.pem

After signing .mobileconfig profile it shows as "Unverified" - "The ceritifcate was signed by an unknown authority"

I'm trying to sign a configuration profile (CardDav) with my SSL certificate issued by networksolutions.com
NetworkSolutions.com should be one of the providers that's in iOS/OSX trusted ceritifcates according to this
I've also seen other configuration profiles signed by NetworkSolutions that were "Verified" just fine.
This is the Ruby code I use to sign the profile
ssl_key_str = File.read(Rails.root.join("config/ssl/server.key"))
ssl_key = OpenSSL::PKey::RSA.new(ssl_key_str)
ssl_cert_str = File.read(Rails.root.join("config/ssl/server.crt"))
ssl_cert = OpenSSL::X509::Certificate.new(ssl_cert_str)
signed_profile = OpenSSL::PKCS7.sign(ssl_cert, ssl_key, profile, [], OpenSSL::PKCS7::BINARY)
Also tried to sign with openssl:
openssl smime -sign -in apple_sync_profile-unsigned.mobileconfig -out signed.mobileconfig -signer server.crt -inkey server.key -certfile server.crt -outform der -nodetach
Still getting "Unverified"
Digging deeper by trying to open the mobileconfig file on my Mac, it shows "this certificate was signed by an unknown authority"
I tried to compare with this other profile that I downloaded and shows up as Verified but could not come up with any meanigful difference.
Any recommendations?
Is there any tool I could use to sign profile other than openssl which might be able to provide more insight?
How to Sign and verify a .mobileconfig file in apple
Export certificate from the key chain
keychain access --> Certifcates(LeftPanel)--> right click the particular certificate and export the certificate.
convert .p12 file to PEM file (converting use this link www.sslshopper.com/ssl-converter.html)
Eg: InnovCertificates.p12 to InnovCertificates.pem
Download Apple Root Certificate and Apple Intermediate Certificate
(For my .mobileconfig file verification i am used Apple Inc. Root Certificate(Apple Root Certificate) and
Application Integration Certificate (Apple Intermediate Certificate) certificates.
you can also use these certificates or other certificates that have in the apple certificates www.apple.com/certificateauthority/)
The download file is combination of certificate and keys . (Read the certificate in Terminal commands are following link info.ssl.com/article.aspx?id=12149)
From this certificate file we need extract certificate.
extract certificate from Apple Root Certificate. Then extract certificate from Apple Intermediate Certificate
openssl x509 -inform DER -outform PEM -in AppleIncRootCertificate.cer -out root.crt.pem
openssl x509 -inform DER -outform PEM -in AppleAAICA.cer -out Intermediate.crt.pem
open the two extracted file in text editor,
copy and paste the Intermediate.crt.pem to beginning of the root.crt.pem and save .then your root.crt.pem file is combination of two certificate.
Sign and verify the .mobileconfig file
Once you have all the files listed above, you will run a command like the following:
openssl smime -sign -in Example.mobileconfig -out SignedVerifyExample.mobileconfig -signer InnovCertificates.pem -certfile root.crt.pem -outform der -nodetach
The result .mobileconfig file is signed and verified.
Use full links:
renren.io/questions/637349/ios-mobileconfig-walkarounds
developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/smime.1ssl.html#//apple_ref/doc/man/1/smime
www.apple.com/certificateauthority/
www.rootmanager.com/iphone-ota-configuration/iphone-ota-setup-with-signed-mobileconfig.html
info.ssl.com/article.aspx?id=12149
www.sslshopper.com/ssl-converter.html
wiki.cac.washington.edu/display/infra/Extracting+Certificate+and+Private+Key+Files+from+a+.pfx+File
stackoverflow.com/questions/9277426/ios-mobileconfig-walkarounds
stackoverflow.com/questions/991758/how-to-get-an-openssl-pem-file-from-key-and-crt-files
discussions.apple.com/thread/2363234
My certificate was signed by a sub-CA and did not contain the full certificate chain. In order for the signing to be complete, you must provide a full server.crt certificate which contains the full chain of certificates.
Download the sub-certificates from your certificate provider (e.g: Startssl) and add them to your server certificate simply by cat server.crt ca-bundle.crt > server.crt)

Couldn't able to connect to APNS Sandbox server

I am trying to connect to Apple APNS server with the following observations:
1)port 2195 is open 2)With Valid key passphrase for APNS_SSLCertificate_Key.pem 3)Entrust certificate (2048) downloaded from https://www.entrust.net/downloads/binary/entrust_ssl_ca.cer
4)With the successful telnet response as below :
$ telnet gateway.sandbox.push.apple.com 2195 Trying 17.172.232.226...
Connected to gateway.sandbox.push-apple.com.akadns.net. Escape
character is '^]'.
But when i run the following openssl command in my server to test the APNS connectivity :
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert APNS_SSLCertificate_Key.pem -debug -showcerts -CAfile server-ca-cert.pem
I am getting error as follows:
unable to load certificate 57013:error:0906D06C:PEM
routines:PEM_read_bio:no start
line:/SourceCache/OpenSSL098/OpenSSL098-35/src/crypto/pem/pem_lib.c:650:Expecting:
TRUSTED CERTIFICATE
So please suggest how to resolve this problem
Thanks in advance ......
I ran into this same issue; what eventually resolved the error was to re-export the Entrust certificate from System Roots of OS/X Keychain Access application.
To be complete, I'll give a complete explanation of how I created the key/cert files (something which should have been in Apple's TechNote 2265: https://developer.apple.com/library/content/technotes/tn2265/_index.html)
Creating your APN-cert-and-key:
Run Keychain Access; select "login" Keychain and "My Certificates" category
Select the certificate with the name format of "Apple Development IOS Push Services: ..."
Export the certificate (in the menu, under "File" .. "Export Items")
Export to .p12 format.
This now contains your certificate and private key in an encrypted interchange format. The next step is to convert it to a passphrase protected .pem file
Using terminal, execute the following command (using your own filenames, of course):
openssl pkcs12 -in PushCertKey.p12 -out PushCertKey.pem
(You will need to enter the password for the .p12 file and provide another passphrase for the .pem file.)
If you really really really don't want a passphrase on the .pem file, try:
openssl pkcs12 -in PushCertKey.p12 -out PushCertKeyNoCrypt.pem -nodes
Creating CA Certificate file:
List item
Run Keychain Access application
Go to System Roots
Export the certificate named "Entrust.net Certification Authority (2048)" to a .pem file.
Note: My Roots container has four Entrust certificates; two of them with the name "Entrust.net Certification Authority (2048)" (but with different certificate extensions, via Get Info). Both of the "Entrust.net Certification Authority (2048)" certificates where effective in validating the trust chain; the other two Entrust certificates did not work. More significantly, the Entrust certificate pointed at by the Apple TechNote 2265 also does not work.
Make sure you export to .pem format; the default is .cer and this step is easy to miss.
Run the verification command:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCertKey.pem -debug -showcerts -CAfile "Entrust.net Certification Authority (2048).pem"
This server and process assume that your are connecting to Apple's Dev sandbox APN server; if you are trying to use the production APN server, you will need to use the correct server and port.
For more information on openssl, I suggest the following pages:
https://www.madboa.com/geek/openssl/
https://www.sslshopper.com/article-most-common-openssl-commands.html
http://gagravarr.org/writing/openssl-certs/general.shtml
SSL problems: Step wise fix.
Most of the problems are due to the private key issues, which can be resolved as follows.
Follow the following commands and create the .p12 using openssl.
You will need
developer_identity.cer <= download from Apple
mykey.p12 <= Your private key
Run these commands in your terminal where openssl is configured,installed or working:
openssl x509 -in developer_identity.cer -inform DER -out developer_identity.pem -outform PEM
openssl pkcs12 -nocerts -in mykey.p12 -out mykey.pem
openssl pkcs12 -export -inkey mykey.pem -in developer_identity.pem -out iphone_dev.p12
Final p12 that you will require is iphone_dev.p12 file and the passphrase that you had set.
Try again, hope your problem is fixed, as it always does for me. :)