What subject to use for SetClientCertificate? - ssl

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.

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).

changing password ldapmodify over SSL to AD 2008 R2 fails with 0000052D: SvcErr: DSID-031A1248, problem 5003 (WILL_NOT_PERFORM)

When attempting an ldapmodify to set the unicode password (with the correct encoding) over SSL(636), the operation fails and Active Directory returns the following error code:
0000052D: SvcErr: DSID-031A1248, problem 5003 (WILL_NOT_PERFORM), data
0
I found countless threads and answers on resolving WILL_NOT_PERFORM but I am hoping someone knows the meaning of the exact codes above.
Every other solution points to password complexity, min pw age before the modify, SSL requirement, encoding requirement, and some others.
We have set the min pw age to 0, ensured we met the pw complexity requirements, encoded in UTF16LE=>base64, submitted the operation over SSL with 256 bit encryption and trusted/verified certificates, and we still receive this message.
The ldapadds/modifies are being performed by an automated tool which has successfully worked on other AD 2008 R2 instances so we know the password reqs, encodings, and SSL requirements are satisfied by the tool. We also tested with manual ldapmodify via LDIF and receive the same message.
Can anyone shed some light on any other possible permission, bug, UAC related setting, or way to decrypt the exact error code above?
Any help would be greatly appreciated! :)
I could only guess about your environment setup, but try to perform these steps:
Check if this password really could be setup through AD interface on server
Ensure you wrap you password with double quotes before encoding (i.e. it should be "password", not password
Check if you use unicodePwd attribute to set the password
So my ldapmodify entry to set password to StrongPassword! looks like:
dn: CN=User,CN=Users,DC=corp,DC=example,DC=org
changetype: modify
replace: unicodePwd
unicodePwd:: IgBTAHQAcgBvAG4AZwBQAGEAcwBzAHcAbwByAGQAIQAiAA==
Note unicodePwd has two colons

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.

Email Authentication with Mailchimp and Bluehost

Can someone please help me get this right. I've been trying for days and just can't do it.
This is what mail chimp is asking me to do.
Set a TXT (SPF) record for averyburch.com to:
v=spf1 include:servers.mcsv.net ?all
Set the CNAME record for k1._domainkey.averyburch.com to:
dkim.mcsv.net
So I have entered the following in my bluehost DNS zone editor. But it's not authenticating. I've waited 48 hours.
CNAME
k1._domainkey points to dkim.mcsv.net
TXT
# txt value is: v=spf1 a mx ptr include:bluehost.com include:servers.mcsv.net ?all
I did enter exactly k1._domainkey.averyburch.com but the control panel seems to change it to k1._domainkey. Everything in the spf record is the bluehost default setting apart from include:servers.mcsv.net which i added.
Can someone please tell me what I'm messing up. I'm not experienced with this. Thanks so much.
This is instructions I followed from someone else on another forum that worked perfectly the first time:
Hey all,
I have been looking into this because of wanting to use DKIM support
for MailChimp emails. Most of this stuff is above my pay grade, but I
was able to successfully set up DKIM. Here's how it went:
Here are the instructions from MailChimp:
DKIM: Create a CNAME record for k1._domainkey.[example.com] with this
value: dkim.mcsv.net
SPF: Create a TXT record for [example.com] with: v=spf1
include:servers.mcsv.net ?all
I then logged into my Bluehost account: cPanel -> DNS Zone Editor
I chose the domain I wanted in the dropdown menu and filled out the
following:
Host Record: k1._domainkey.[example.com] TTL: 14400 (the default)
Type: CNAME Points To: dkim.mcsv.net
Then I clicked "Add Record," and it added successfully.
Then I filled out another entry:
Host Record: [example.com] TTL: 14400 (the default) Type: TXT Points
To: v=spf1 include:servers.mcsv.net ?all**
"Add Record," and it was all set. Both entries showed up in the list
below.
I was able to use this methods for two domains, and MailChimp verified
that it went through, and they have authenticated DKIM and SPF
records.
Hope that helps. Thanks for the thread.
So there are a couple of issues that are immediately apparent:
The DKIM key is malformed. Looking at the DNS the key record is "k=rsa; p=MIGfMA0GCSqG...". That's missing the initial prefix. It should be "v=DKIM1;k=rsa;p=MIGfMA0GCSqG...". Ideally if you fix that, DKIM signatures will start working
The SPF record you've got in place exceeds the allowed domain lookup limit of 10. You can see some info here - https://dmarcian.com/spf-survey/averyburch.com . Solving this for situations like yours is non-trivial. (Full disclosure, my company ValiMail is about to roll out tech to address a number of common email authentication issues, including this one).
For the moment, assuming DKIM starts working, I wouldn't worry too much about the SPF issue.
Make the DKIM change noted above, and see if that at least gets DKIM authentication working. If you want some visibility, you may also want to add a DMARC record so you can see whether email is authenticating or failing.

2 DKIM on same domain

We are using an external service for our newsletter, which has required the followin DKIM setup in our domain gipote.dk:
_domainkey.gipote.dk. 43200 IN TXT "o=~"
default._domainkey.gipote.dk. 43200 IN TXT "k=rsa\; p=MIGf...ibnrkoqQIDAQAB"
(I truncated the public key for purpose of readability...)
However we are also sending out e-mail from our own server, which I would also like to sign.
Is it possible to have more than one public-key TXT record in our domain gipote.dk? If so, how should it be set up?
EDIT: I do not have access to the private key, that is used by the newsletter service. So I will not be able to just install that on my own server.
/ Carsten
I found out, that the answer is YES :-)
"default" can easily be replaced with another selector name.
Yes you can change the default to another selector.
BUT if you do the domain it is on will no longer verify the domain.
You need to Add a second key NOT CHANGE whats existing
using Google mail you end up with
default._domainkey "v=DKIM1; k=rsa; p=MIIBIj....."
google._domainkey "v=DKIM1; k=rsa; p=MIGfMA......"