TLS certificate subject (CN, OU and O) - ssl

I'm a newbie with Hashicorp Vault and PKI so bear with me :)
I've recently set up an intermediate CA and went through the motions of creating roles etc.
I then proceeded and generated a certificate using one of the roles, like so :
vault write -field=certificate test/pki/issue/server common_name="Bla bla" OU="Test OU" organization="Test Org" format="pem_bundle" > testhost.pem
However when I checked the subject of the cert, like so :
vault read -field=certificate test/pki/cert/53-5c-e6-7e-2d-56-4e-72-f7-db-a2-5c-6a-89-33-f9-43-52-58-92 | openssl x509 -noout -subject
Its giving me this :
subject= /O=Test Org/OU=Test OU/CN=Bla bla
Is there any way I could change it to :
subject= CN=Bla bla,OU=Test OU,O=Test Org
If this isnt possible, I understand, just would like to check. Thanks!

The order in the subject= line is determined by openssl, which follows RFC 1779's definition of string representations of Distinguished Names for the x.500 standard. "Subject" is a type of Distinguished Name for identifying the certificate. Attributes for the Subject are listed from most general (e.g., Country) to most specific (e.g., Common Name).
(RFC 1779 updates RFC 1485, and is updated by 2253 and RFC 4514, and likely others.)

wondering which OS you use.linux based, you can change the below file with your intended details.
/etc/ssl/openssl.cnf
countryName = Country Name (2 letter code)
countryName_default = IN
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Karnataka
localityName = Bangalore (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = XXXX
re-order the above as per your need, and then generate user certs again.

Related

Weird SSL common name mismatch

Today I came across a weird case of cn mismatch. I have two domains:
kpmg.talentsource.rs and
www.kpmg.talentsource.rs
both have prod.q.ssl.global.fastly.net as their CNAME
they have the same A records and certificates.
Nevertheless:
https://kpmg.talentsource.rs (OK)
https://www.kpmg.talentsource.rs (CN mismatch)
https://www.ssllabs.com/ssltest/analyze.html?d=kpmg.talentsource.rs&s=151.101.65.62
https://www.ssllabs.com/ssltest/analyze.html?d=www.kpmg.talentsource.rs&s=151.101.65.62
Note: none of the two has the kpmg.talentsource.rs in neither the the CN nor the SAN
Any ideas why this is happening?
The certificate has a Subject Alternative Name of *.talentsource.rs (among many others unrelated one).
Per X.509/TLS rules, a * matches only one level/label, it does not cross the dot so to say. So *.talentsource.rs matches an hostname of kpmg.talentsource.rs but NOT www.kpmg.talentsource.rs, hence the browser error.
You need either to add www.kpmg.talentsource.rs or *.kpmg.talentsource.rs as a SAN (note that it has talentsource.rs already in the list too) in this certificate or stop using www.kpmg.talentsource.rs at all (a redirection will not solve the problem as you still need the TLS handshake to complete first before getting the HTTP Location: header, so you still need appropriate certificate).

Which is the private key?

I bought a ssl certificate for my site, but I do not know which one is the private key.
Here are the available files:
CACertificate-INTERMEDIATE-1.cer
CACertificate-ROOT-2.cer
PKCS7.p7b
ServerCertificate.cer
Meta: this is not a programming or development Q and will likely be voted offtopic.
None of them.
The (normal) sequence is:
you generate a key pair, or a private key which implies the matching public key, on your machine
you create a CSR (Certificate Signing Request) containing your public key, which is signed using your private key. With some software steps 1 and 2 are combined.
you send or submit the CSR to a CA, and also provide proof of identity and if applicable payment; the details of this step can vary depending on the CA you use, the type of cert you request (especially the validation), and who or what you are
the CA validates your identity (and payment) and 'issues' a certificate for you
the CA gives you your cert, plus the related CA certs needed to form a trust chain; this is often one intermediate plus a root (as in your Q) but other combinations are possible.
You are looking only at step 5. You need to look back at step 1 (and possibly 2).

Format Public key

I am working on signing certificate with HSM, and I need to format the CA public key and output it. I read the EMV Book and the format as follows:
Field Name Length Description Format
Registered
Application Provider 5 Identifies the payment system to b
Identifier (RID) which the Certification Authority
Public Key is associated
Certification
Authority Public Key 1 Identifies the Certification
Index Authority Public Key in b
conjunction with the RID
Certification
Authority Hash 1 Identifies the hash algorithm used b
Algorithm Indicator to produce the Hash Result in the
digital signature scheme
Certification
Authority Public Key 1 Identifies the digital signature
Algorithm Indicator algorithm to be used with the b
Certification Authority Public Key
Certification
Authority Public Key Var. Value of the modulus part of the b
Modulus (max Certification Authority Public Key
248)
Certification
Authority Public Key 1 or 3 Value of the exponent part of the b
Exponent Certification Authority Public Key,
equal to 3 or 216 + 1
Certification
Authority Public Key 20 A check value calculated on the b
Check Sum36 concatenation of all parts of the
Certification Authority Public Key
(RID, Certification Authority
Public Key Index, Certification
Authority Public Key Modulus,
Certification Authority Public Key
Exponent) using SHA-1
I am writing the code with Visual Basic.net.How can I format this in the code and output? I made a Class named PublicKey, and there has three functions, ExportPublicKey, FormatPublicKey and WritePublicKeyToFile.
Can anyone help? Thank you very much.
What ever you have given is the minimum required data to be available in the terminal to validate Issuer Public Key Certificate signed by CA Private Key. On the terminal you will have the CA Public key list which you will match with the data from the card(using RID and exponent from card), get the correct CA Pubic key and open the certificate. But your requirement "format the CA public key and output it" makes no sense to me.
The format of Issuer Public Key certificate will be as below.
On a HSM Racal 9000, the command to generate a certificate will be EW, however I have not used it ever.
Note : The above are based my understanding of your issue. If you think my understanding meets your requirement, go through the whole section which explains about Offline Data Authentication. It is very interesting. Otherwise gently ignore ;)

Verify user identity on my site, using SSL Certificates

I need to register companies on my site for an electronic procurement system. Up to now these were local companies I could meet physically and give credentials to, but now they can be companies based anywhere in the world.
The solution is to have an online registration process whereby they submit a third party certificate. So say Verisign says they are 'Company X' so I register them as Company X and issue them credentials.
How can I implement this on my site? Do I simply give them a field in the registration form where they upload their certificate file? Do I then manually check these certificates in my back office? How does one check this manually? Is there a way to automate this process?
Once they have an account, should I simply request the credentials I issue them with to log in, or can all future logins request the same certificate file? In these a particular format for certificates I can request or should I allow a number of common formats that different certificate vendors provide?
Thanks in advance.
Being able to provide a certificate does unfortunately not prove anything. A certificate is completely public, and anyone can get a hold of the SSL certificate for any website. The certificate contains a public key. Proving ownership of the corresponding private key is what's required.
This is possible to do, but it requires that your users are technical enough to know how to run scripts and/or OpenSSL terminal commands so that they can sign something with their private key. Having the users upload their private key is of course a big no-no, as it means you can now act as the user, and that would require an enormous amount of trust in you to discard the private key after you've verified it.
From a technical perspective, you can do the verification by creating some kind of challenge, for example a random string, and have the user encrypt this string with their private key. If you decrypt this string with the public key in the certificate, and get the original string back, then you know that they have possession of the corresponding private key.
Here's a self-contained Ruby script that demonstrates this, with comments indicating which part of it is run on your side, and which part is run on their side.
require "openssl"
## This happens on the client side. They generate a private key and a certificate.
## This particular certificate is not signed by a CA - it is assumed that a CA
## signature check is already done elsewhere on the user cert.
user_keypair = OpenSSL::PKey::RSA.new(2048)
user_cert = OpenSSL::X509::Certificate.new
user_cert.not_before = Time.now
user_cert.subject = OpenSSL::X509::Name.new([
["C", "NO"],
["ST", "Oslo"],
["L", "Oslo"],
["CN", "August Lilleaas"]
])
user_cert.issuer = user_cert.subject
user_cert.not_after = Time.now + 1000000000 # 40 or so years
user_cert.public_key = user_keypair.public_key
user_cert.sign(user_keypair, OpenSSL::Digest::SHA256.new)
File.open("/tmp/user-cert.crt", "w+") do |f|
f.write user_cert.to_pem
end
## This happens on your side - generate a random phrase, and agree on a digest algorithm
random_phrase = "A small brown fox"
digest = OpenSSL::Digest::SHA256.new
## The client signs (encrypts a cheksum) the random phrase
signature = user_keypair.sign(digest, random_phrase)
## On your side, verify the signature using the user's certificate.
your_user_cert = OpenSSL::X509::Certificate.new(File.new("/tmp/user-cert.crt"))
puts your_user_cert.public_key.verify(digest, signature, random_phrase + "altered")
# => falase
puts your_user_cert.public_key.verify(digest, signature, random_phrase)
# => true
## On your side - attempting to verify with another public key/keypair fails
malicious_keypair = OpenSSL::PKey::RSA.new(2048)
puts malicious_keypair.public_key.verify(digest, signature, random_phrase)
Note that this script does not take into account the CA verification step - you also obviously want to verify that the user's certificate is verified by a CA, such as Verisign that you mentioned, because anyone can issue a certificate and hold a private key for foo.com - it's the CA signature of the certificate that provides authenticity guarantees.

What subject to use for SetClientCertificate?

I'm trying to send a request with:
ActiveXObject("WinHttp.WinHttpRequest.5.1")
however this requires a client certificate to do so (which we have been provided).
Having tested in PHP cURL I can do so with:
curl_setopt($SOAP, CURLOPT_SSLCERT,$filepathtocertificate);
Which works fine. However I must use IIS running asp(javascript) and point to the certificate store of the machine the script is running on with:
SetClientCertificate("LOCAL_MACHINE\\Personal\\Certificate subject");
for our actual deployment. The MS documentation (http://msdn.microsoft.com/en-us/library/windows/desktop/aa384055(v=vs.85).aspx) suggests that the path above has to state the 'subject' of the certificate, however the certificate seems to have several subjects and no combination of several or all of them seems to yeild any results and I am stuck with the following error before the request is even sent:
WinHttp.WinHttpRequest error '80072f0c'
A certificate is required to complete client authentication
Looking in the certificate store and using other scripts in the same folder show they are definitely there but have subjects like:
C=US, O=Organisation NAme, OU="Another Organisation Name, Inc.", CN=Organisation Name Root
Or similar.
Any advice on what parameters SetClientCertificate needs to be given to select and send certificates in the certificate store would be much appreciated.
I had a lot of trouble with this same issue - using winhttp 5.1 from a scripting language to set a client certificate before a send.
I had used mmc with the certificates snap-in to import the certificate in CURRENT_USER \ Personal - but the Winhttp SetClientCertificate didn't seem to be doing anything, nor was I able to pick up any error code or message so it was a case of repeated trial and error - the SetClientCertificate string should be something like "Location\store\subject" eg "CURRENT_USER\Personal\My Certificate" (or \ \ if your language requires \ to be escaped) -the final part being 'subject' which is not as clear as it should be. Under MMC the subject is broken into many elements.
I eventually got it working by dropping the location and store - they were the defaults so I may have been fortunate - and providing just the subject field - the value I used for the subject field was the value in the line "CN = " under subject (when the cert is opened under mmc) - but this (perhaps coincidentally) was also the value in the 'Issued To' column on the main mmc certificate list. In my case it worked - clearly if there is a cert with these two values different then you'd need to try each.
Hope this helps if somebody is similarly stuck.
This is a very old question yet I had to find an answer today. The answer provided above by #JSL helped me. If you only provide the certificate subject name then it works! So it is clear that there is a mistake in the way full path is specified.
I got the right info for Windows 7 from this link https://msdn.microsoft.com/en-us/library/windows/desktop/aa384076(v=vs.85).aspx
here is VBA script that works.
Dim objHttp As New WinHttp.WinHttpRequest
objHttp.Open "GET", url, False
objHttp.SetClientCertificate "CURRENT_USER\My\TestCert"
objHttp.send
Valid locations are LOCAL_MACHINE and CURRENT_USER and
Valid store names are "MY", "Root", and "TrustedPeople".
Remember to escape the backslashes in C++, C# etc.