Getting a web server certificate in ruby - ruby

I'm trying to write some ruby code to grab the Common Name (CN) value from a web server's SSL certificate but there doesn't seem to be any simple way to do this in ruby.

Well, I would beg to differ. It's documented well enough but not too many examples are available, which makes it a bit, but not too complicated :)
require 'openssl'
raw_cert = File.read (path_to_your_cert) # if your cert is in PEM or DER format
OR
raw_cert = OpenSSL::PKCS12.new(File.read(path_to_your_cert), your_pwd) # If you want to read a .p12 cert
cert = OpenSSL::X509::Certificate.new(raw_cert)
cert.subject
=> **************/CN=<Your Common Name>/***************
So you can parse cert.subject to find out the common name you need.
You can read more in-depth on SSL certs at http://ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/X509/Certificate.html

Related

Load Keystore from Beanshell in Jmeter

I'm trying to load a Keystore with multiple certificates from a Beanshell.
Here is my code :
import org.apache.jmeter.util.SSLManager;
setStrictJava(true);
String COMMON_PATH = vars.get("COMMON_PATH");
String KEY = "******";
String PATH = COMMON_PATH + "/keystore.jks";
System.setProperty("javax.net.ssl.keyStore",PATH);
System.setProperty("javax.net.ssl.keyStorePassword",KEY);
System.setProperty("https.use.cached.ssl.context","false");
SSLManager.getInstance().reset();
This code works but it only loads the first certificate of the Keystore .. which annoys me. How can I load the Keystore with every certificate?
Damien
The correct way of dealing with multiple SSL certificates residing in the keystore is using Keystore Configuration element like it's described in the How to Use Multiple Certificates When Load Testing Secure Websites article.
Also be aware that you can put your keystore path and password to the system.properties file so you won't have to go for scripting.
If you for any reason want to do this programmatically consider switching to JSR223 Test Elements and Groovy language

Signed PDF verification in Origami with an Adobe PKCS#7 certificate

Summarized and clarified:
Using origami, extracting a certificate from a signed pdf (signed within e.g. Adobe Reader) I cannot verify the signature:
origami = Origami::PDF.read(File.open('/path/to/file.pdf', 'r'))
pdf_signature = origami.signature[:Contents]
cert = OpenSSL::PKCS7.new(pdf_signature).certificates.first
origami.verify(trusted_certs: [cert]) #=> false
As far as I can tell, this should always be true. So maybe Adobe uses a different byte range that it takes a SHA of when signing the PDF? How do I get that verify to work?
If it's any help, after tiptoing through the changes on origami master, I was able to get the exact OpenSSL error from the storecontext: V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY - I presume it means from the X509::Store it sets up.
Full background
I'm trying to verify the digital signature of a PDF. Here's what I've got:
A PDF that I've signed using Adobe Acrobat (tried both Pro 10 and Reader DC)
The key was generated in Acrobat Pro, I have access to the .p12, or exporting as FDF, PKCS#7 or just "Certificate File". Have also tried loading this "Certificate File" via Apple's "Keychain Access" and exporting that as a .pem This gives the same result as OpenSSL::PKCS7.new(File.read('/path/to/exported.p7c')).certificates.first.to_pem which gives the same result as:
openssl pkcs7 -print_certs -inform der -in pkcs7file.p7c -out certificate.cer
So, I'm pretty sure I've extracted the certificate correctly.
Also, I can verify that exact same certificate is embedded in the PDF -
pdf_signature = origami.signature[:Contents]
OpenSSL::PKCS7.new(pdf_signature).certificates.first.to_pem #=> Same as above
With the Origami gem, I've tried loading the certificate and attempting verification:
cert = OpenSSL::X509::Certificate.new(File.read('/path/to/pem.cer'))
Origami::PDF.read(File.open('/path/to/file.pdf', 'r')).verify(trusted_certs: [cert])
Origami's output confirms the document has been signed, but the verify(..) method returns false.
Note that working through the code from this excellent answer works fine, but it only seems to work if you generate the X.509 keypair using openssl (e.g. the ruby-land bindings as per that code). Unfortunately I'm required to use the pre-existing Adobe-blessed signatures from the user's machines.
That said, aside from this I have very few restraints; I can ask the users to export their certificate in any other way that is useful to us (I can even run some simple code on their machines if necessary), though I mustn't transmit the private key in the procedure. I don't have to use Origami for the verification, but it does have to be a command accessible from ruby on an ubuntu server. The users are all running on Macs with reasonably up-to-date software.
I've gotten a little further from my original issue, but not by much:
Certificates require the correct extensions
In the original code from Harry Fairbanks' very useful answer, the extensions are paramount:
extension_factory = OpenSSL::X509::ExtensionFactory.new
extension_factory.issuer_certificate = cert
extension_factory.subject_certificate = cert
cert.add_extension extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
cert.add_extension extension_factory.create_extension('keyUsage', 'digitalSignature,keyCertSign')
cert.add_extension extension_factory.create_extension('subjectKeyIdentifier', 'hash')
So... following the rest of that answer, if you save the certificate to a pemfile, the extensions do not also get saved.
I was able to create a PDF, sign it with Origami using the key I exported from Acrobat reader, and then do the following:
cert = OpenSSL::PKCS7.new(pdf_signature).certificates.first
origami.verify(trusted_certs: [cert]) #=> false
## ... then run the extension factory snippet above
origami.verify(trusted_certs: [cert]) #=> true
Success! In fact, even Adobe Acrobat Reader was happy - which I couldn't get it to do with the self-signed certificate that Origami generated.
... however, when I sign the document using Adobe Acrobat Reader, with the same key, perform the same magical incantation on the cert, I still get false from the verify call.
Note: I have been told that this actually works for some people. Not sure why it failed for me - when I have a chance to play, will give it another go. Will mark this as answered for now!
It's possible the ciphers are different. It could be that the Adobe cipher is not the same one that the openssl is using and would then fail the verification check. Take a look at this. Details on ciphers
This might be useful too openssl commands

OpenSSL public key for Firefox extension signing

I'm trying to bring back an old extension I made for Firefox 1.5 written in JavaScript. One of the changes introduced in Firefox 3.0 was the need for extension updates secured via either HTTPS or PKI. Since I can't use an SSL solution on my website, I need to use the PKI solution.
So, first up is generating the private and public keys. I was able to create CA and client (code signing) certificates using OpenSSL by following this guide. So, how I have two key and certificate pairs: ca.crt, ca.key, code.crt and code.key.
Now, I have to put the public key into the install.rdf's <em:updateKey> field. I did this with the command openssl -in code.key -outform DER -pubout and copied the resulting output (sans the ^-----.* lines) into my install.rdf. Now, the public key generated in this way is base64-encoded and ends with a couple equals signs. I haven't seen any examples that actually have these trailing characters. Is that OK, or did I pass the wrong options to OpenSSL?
Aside from this, using uhura to sign my update.rdf seems fairly straight-forward, but again there are no trailing =='s, which seems odd from the output I got via the OpenSSL command above.
Any help would be greatly appreciated!
I was able to get this working using a localhost webserver configuration. The OpenSSL command is the correct one to use in this case and the trailing padding is a coincidence, but it works when fetching updates.

ArgumentError (A secret is required to generate an integrity hash for cookie session data

I am getting this error while running rails application and here is the complete Error
ArgumentError (A secret is required to generate an integrity hash for
cookie session data. Use config.secret_token = "some secret phrase of
at least 30 characters"in config/initializers/secret_token.rb):**
I use rvm 1.9.3 and rails 3.2.13.
Any help appreciated.
Thanks in advance.
The message is pretty straight forward. Check in the config/initializers/secret_token.rb file for the config.secret_token setting and configure it if it is not there.
Generate secret token using:
rake secret
It will return
=> '3eb6db5a9026c547c72708438d496d942e976b252138db7e4e0ee5edd7539457d3ed0fa02ee5e7179420ce5290462018591adaf5f42adcf855da04877827def2'
then edit your file or create new one:
# config/initializers/secret_token.rb
# Be sure to restart your server when you modify this file.
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
MyApp::Application.config.secret_token = '3eb6db5a9026c547c72708438d496d942e976b252138db7e4e0ee5edd7539457d3ed0fa02ee5e7179420ce5290462018591adaf5f42adcf855da04877827def2'
I ran into this when using the figaro gem to keep my keys secret.
application.yml will not be there if you clone the project to a new location. This is desirable behavior, because we don't want the wider internet to be able to check out all of our secret information.
If this is your issue. You will need to copy the application.yml from its original location, or generate new keys to replace the ones that were there.
Yes. The string is right:
config.secret_token = "..."
But, for me - redmine can fly after i put this string into the config/application.rb file.

Get the issuing CA for a given certificate

I have a variable of type PCCERT_CONTEXT which contains a certificate (this is actually the certificate of the digital signer of a given executable file.) I need to get the certificate or at least the name of the issuing CA. I've tried using CertOpenStore and WTHelperCertFindIssuerCertificate, but have had no success. I would appreciate any help.
Regards,
Alireza
Maybe CertGetIssuerCertificateFromStore()?
You probably want CertGetCertificateChain http://msdn.microsoft.com/en-us/library/aa376078(VS.85).aspx
The CERT_CONTEXT contains the CERT_INFO structure.
The CERT_INFO structure contains a pointer to the Issuer as a CERT_NAME_BLOB.

Resources