Generate .pem certificate with PHP for PayPal - ssl

i need some help with the follow issue.
A multi user e commerce application uses .pem format certificates to encrypt paypal buttons, until now all certificates was generate with the Linux console with openssl commands.
So far everything works fine, but isn't a practical process if the client has many users, we want users can generate their certificates from their admin panel.
I found the follow script to generate the certificate:
$dn = array("countryName" => 'GB', "stateOrProvinceName" => 'State', "localityName" => 'SomewhereCity', "organizationName" => 'MySelf', "organizationalUnitName" => 'Whatever', "commonName" => 'mySelf', "emailAddress" => 'user#domain.com');
$privkeypass = '1234';
$numberofdays = 365;
$privkey = openssl_pkey_new();
$csr = openssl_csr_new($dn, $privkey);
$sscert = openssl_csr_sign($csr, null, $privkey, $numberofdays);
openssl_x509_export($sscert, $publickey);
openssl_pkey_export($privkey, $privatekey, $privkeypass);
openssl_csr_export($csr, $csrStr);
echo $privatekey; // Will hold the exported PriKey
echo $publickey; // Will hold the exported PubKey
echo $csrStr; // Will hold the exported Certificate
The output of this script generates me three blocks
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----
As a test, I copied the entire block ----- BEGIN CERTIFICATE ----- ----- END CERTIFICATE ----- and stick it in a text file with the .crt extension.
then I'll paypal account and try to upload the certificate, but PayPal tells me that the file is not in .pem format
The certificate you are trying to upload is not in the proper format. The certificate must be in .pem format.
Actually I have not much experience with ssl functions of PHP and so I turn to you, if anyone can give me some light over this issue, I appreciate it from now.

I've tested ran your code and sent the result to this verify page
https://www.sslshopper.com/certificate-decoder.html
Seems to generate a correct certificate if you just print the public key and test that.
Seems to be a difference in format between crt and cer for the keys though mainly due to encoding.
https://support.ssl.com/Knowledgebase/Article/View/19/0/der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-convert-them
Test a different encoding or file extension.

Related

How do I correctly install certificates to make soap request on windows 10

I need to make a request to a soap service and it is protected with certificates.
I have installed the certificates as far as I am able to tell. However the soap request fails with handshake errors.
I have a bunch of certificate files given to me but I have no idea which ones are which.
So I have as follows (names changed to protect information)
MyCertificationAuthority.pem
MyCert.pem
MyCert2.pem
then I have what looks to be the same things in a different format.
MyCertificationAuthority.p7b
MyCert.p7b
then I have a single file named MyCert.pem but is smaller in file size than the other one of the same name and contains simply
-----BEGIN NEW CERTIFICATE REQUEST----- a lot of characters
-----END NEW CERTIFICATE REQUEST-----
I was told that this was the private key file, however if I check it using
openssl rsa
then it errors.
I have double clicked on the p7b files and installed the certificates in them using the default options and I have those certificates in the Certificate Management app in windows.
3 are in the Third Part Certification Authorities folder
1 ended up in the Other People folder (which I have also copied into the Trusted Root Certification Authorities Folder)
4 have ended up in the Intermediate Certification Authorities Folder
All were installed for local computer rather than current user.
Now I am led to believe I should have a private key file too. However I can not find where this could be.
What am I doing wrong? Where would I normally get the private key file from?
I would have thought the service side has the private key in order to verify that our certificate is valid?
MyCert.pem is as follows (with the actual data removed for privacy reasons)
subject=CN=********************** issuer=CN=************************
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE----- subject=CN=**************** issuer=CN=*****************
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=CN=********************** issuer=CN=***********************
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

SSL/TLS Configuration on server

I am working on CentOS 7. I have three blocks in text :
CSR:
-----BEGIN CERTIFICATE REQUEST-----
...
-----END CERTIFICATE REQUEST-----
Public key:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
Private key:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
Also, I have archieve with:
mydomain.crt
mydomain.ca-bundle
and
AddTrustExternalCARoot.crt
COMODORSAAddTrustCA.crt
COMODORSADomainValidationSecureServerCA.crt
As I understand I need to convert CSR,Private Key, Public Key to right format files ?
Than, add :
CSR and Private Key to /etc/nginx.conf
And set it via .conf by names ?
But could anyone help me convert CSR,Private Key and Public Key to right formats ?
Thank you !
You can discard the CSR or keep it for your reference. A CSR (Certificate Signing Request) is a document asking for a certificate, you already have the certificate, so the request is now only of historical interest.
You should put the private key text, including that header and footer, but no blank lines, into a file, let's call that privkey.pem. The private key is very important, you web server software needs to be able to read it in order to function, but nobody else should ever see this file and you should not keep copies of it where they may be stolen.
You also need the mydomain.crt file, and the mydomain.ca-bundle, you should concatenate them together, you can do this (carefully) with a text editor and save the result as fullchain.pem, or if you're comfortable on a Unix command line you can write
cat mydomain.crt mydomain.ca-bundle > fullchain.pem
In your nginx.conf you should find or create a server block, and set parameters as follows, but with the correct full path names.
ssl_certificate /full/path/to/fullchain.pem
ssl_certificate_key /full/path/to/privkey.pem

Create pfx file from Symantec code signing certificate

We have a password-protected pfx file, expiring in a few days, which we use to sign our exes.
We have renewed our SSL certificate from Symantec, but all we have received is a bunch of data:
Below is your Code Signing certificate:
-----BEGIN CERTIFICATE-----
base-64 encoded data
-----END CERTIFICATE-----
Below is the intermediate CA certificate:
-----BEGIN CERTIFICATE-----
base-64 encoded data
-----END CERTIFICATE-----
Below is your certificate in pkcs7 format:
-----BEGIN CERTIFICATE-----
base-64 encoded data
-----END CERTIFICATE-----
I have seen a few tutorials to create pfx files from .cer and .key files, but the fun part is, Symantec doesn't use the same terminology as the rest of the world. So I don't know which is which. And no single tutorial explains what should be in the files, so I can't go from there either. So, I don't know how to create the .key file, for instance.
Thanks!
It turns out that the main requirement is to install the certificate on a browser, from the computer that has made the request for a new certificate.
Then, most browsers (IE, FF, Chrome) can export it to PFX from the installed certificates list.
More info can be found here:
http://blog.ksoftware.net/2011/07/exporting-your-code-signing-certificate-to-a-pfx-file/
http://blog.ksoftware.net/2011/07/exporting-your-code-signing-certificate-to-a-pfx-file-from-firefox/
https://knowledge.verisign.com.sg/support/code-signing-support/index?page=content&id=AR190&actp=search&viewlocale=en_US&searchid=1360582675798

OPENSSL connection to a public server gives X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY

I am writing a very basic SSL client to connect to a HTTPS web server. I can connect and process the request/response just fine. However OpenSSL is reporting UNABLE_TO_GET_ISSUER_CERT_LOCALLY, but so far I choose to ignore the error :-). Now I want to solve that part of the problem.
I am testing by connecting to a public SSL server on HTTPS, such as Google or Yahoo, and checking the return of SSL_get_verify_result(...).
As I understand it, I need the CA pem files for that specific site so that OpenSSL can verify the chain to a trusted certificate authority. In this case, that would be the authority that signed the certs for Google or Yahoo.
To get the PEM files which I expect should work, I opened my FireFox, navigated to those sites, and performed a View Certificate and exported each one up the list. So for example, I have a file called "GeoTrustGlobalCA.pem" which all looks good. In fact, when I went to the GeoTrust site directly and downloaded their root certificate, it is identical to the one I exported from FireFox, as I would expect.
So, for example with Google which showed two certificates in the tree in FireFox, I load each one with:
result = SSL_CTX_load_verify_locations(ctx,"GoogleInternetAuthorityG2.pem",NULL);
if (result == 0) {
puts("Opps... Can't load the certificate");
}
result = SSL_CTX_load_verify_locations(ctx,"GeoTrustGlobalCA.pem",NULL);
if (result == 0) {
puts("Opps... Can't load the certificate");
}
After that, the usual stuff to connect and communicate:
BIO_set_conn_hostname(bio, "www.google.com:https");
And get no errors when loading or connecting.
However, the verification does not work.
result = SSL_get_verify_result(ssl);
printf("The Verify Result is %d \n",result);
I get the return UNABLE_TO_GET_ISSUER_CERT_LOCALLY (error code 20).
So, am I missing some concept here? Wouldn't this give me the X509_V_OK result because it has the trusted certificates? There were only two that were up the chain from google.com, and I used them.
The second call to SSL_CTX_load_verify_locations is replacing the certificate from the first call.
You should combine your roots into a single file:
$ cat my-trusted-roots.pem
-----BEGIN CERTIFICATE-----
... (CA certificate in base64 encoding) ...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (CA certificate in base64 encoding) ...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (CA certificate in base64 encoding) ...
-----END CERTIFICATE-----
And then load that single file with SSL_CTX_load_verify_locations. See the OpenSSL docs on SSL_CTX_load_verify_locations. In partuclar, the NOTES section:
If CAfile is not NULL, it points to a file of CA certificates in PEM
format. The file can contain several CA certificates identified by
-----BEGIN CERTIFICATE-----
... (CA certificate in base64 encoding) ...
-----END CERTIFICATE-----
sequences. Before, between, and after the certificates text is allowed
which can be used e.g. for descriptions of the certificates.
Just bike shedding here...
result = SSL_get_verify_result(ssl);
printf("The Verify Result is %d \n",result);
That's one of three tests you need to perform.
The second test you need to perform is below. Anonymous Diffie-Hellman (ADH) does not use a certificate, so you need to check for that.
X509* cert = SSL_get_peer_certificate(ssl);
if(cert) X509_free(cert);
if(cert == NULL)
/* Error - Anonymous Diffie-Hellman */
SSL_get_peer_certificate bumps the reference count on the certificate, so you need a matching call to X509_free.
The third test you need to perform is hostname matching. OpenSSL 1.1.0 WILL perform hostname matching (and other name matching, like PKCS9 email addresses); but lesser versions, like 0.9.8 and 1.0.1, DO NOT perform the matching.
Thanks to this post I could finally get the SSL/TLS Client to work on Windows. I built openssl using MSYS2. I had to make some changes to the openssl-bio-fetch.tar.gz code so it could build/run in Windows/MSYS2, mostly adjusting the Makefile includes and setting -DNDEBUG to avoid the Posix signals.
However when running the code I got:
$ ./openssl-bio-fetch.exe
Warning: thread locking is not implemented
verify_callback (depth=1)(preverify=0)
Issuer (cn): DigiCert High Assurance EV Root CA
Subject (cn): DigiCert SHA2 Extended Validation Server CA
Error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
certificate verify failed
I had to download the 2 .pem files:
DigiCert High Assurance EV Root CA
DigiCert SHA2 Extended Validation Server CA
AND PASTE THE CERTIFICATES TO THE SAME .pem FILE ALREADY IN USE BY THE CODE: random-org-chain.pem
Thank You!

How do I split a multi-valued p12 certificate into separate certificates

I am attempting to integrate with Apple PNs and I currently have a p12 certificate that has both the Sandbox and Production certs within it. But I have read that Java SSL will only read the first one, and that for JavaPNS (the APN client I am using), says to use separate certs for this reason.
So using something like openssl, how can take my current cert and separate it out into 2 new certs, one for the Sandbox and one for Production.
This has nothing to do with APN, it's just about splitting a p12 cert.
As you previously mentioned you can use OpenSSL to change the p12 format to a PEM format, the PEM format would be accepted but also not secure with a password so make sure you get what you need.
openssl pkcs12 -in yourcertificates.p12 -out certificates.pem -nodes
This will put everything in one file, so you will have to open the PEM file in a text editor and take out the required files.
Certificates are separated by
-----BEGIN CERTIFICATE-----
Content
-----END CERTIFICATE-----
Keys would be separated by
-----BEGIN RSA PRIVATE KEY-----
Content
-----END RSA PRIVATE KEY-----
Please update your question if you need anymore information.