Solved

Trouble using client certificates with Crypt-SSL 0.53 and ActiveState Perl build 811

Posted on 2007-11-24
5
2,417 Views
Last Modified: 2012-06-27
Hi all,

I'm trying to get Crypt-SSL to work with client certificates without much success. I am using Crypt-SSL 0.53 fetched from http://theoryx5.uwinnipeg.ca/ppms/Crypt-SSLeay.ppd and can use it just fine with LWP to fetch sites that don't use client certificates. When I use a client certificate, I get an error of "OPENSSL_Uplink(0284F020,06): no OPENSSL_Applink"  on line 414 in SSL.pm:

414:  $ctx->use_pkcs12_file($file ,$ENV{'HTTPS_PKCS12_PASSWORD'}) || die("failed to load $file: $!");

The certificate file exists where expected in c:\certs and also works fine in a browser. I exported the certificate from Internet Explorer in PKCS12 format.

Other pertinent info would include that I am using the ssleay32.dll and libeay32.dll from UWinnipeg (version 0.9.8.1) and updating to later ones (0.9.8.5 borrowed from Apache's SSL files) doesn't make any difference - same error.
 
Checking OpenSSL, the following link (http://www.openssl.org/support/faq.html#PROG2) seems to indicate this error means applink.c needs to be linked in to avoid the error. So, I ventured down the road of fetching Crypt-SSL 0.57 from CPAN, Visual C++ 2008 express from Microsoft (so I could get nmake) and tried building my own Crypt-SSL. This was a disaster as I could run Perl Makefile.pl but nmake choked with 50 warnings and errors and finally died with fatal error U1077 and return code '0x460'. Trying to resolve these errors is way beyond my C skills and time! Comments on the web seem to indicate very few hearty souls can build their own Crypt-SSL on Windows so I guess I knew it was a long shot to start with.

Attacking this from a different angle, I converted my PKCS12 certificate into separate PEM format files for the certificate and private keys and used these in place of the PKCS12 pfx certificate (see the commented lines in the code). I did this via OpenSSL commands:

Extract user key:
openssl pkcs12 -nocerts -in c:\certs\mycert.pfx -out c:\certs\userkey.pem

Extract User certificate:
openssl pkcs12 -clcerts -nokeys -i  c:\certs\mycert.pfx -out c:\certs\usercert.pem

Strip password from user key:
openssl rsa -in c:\certs\userkey.pem -out c:\certs\userkey_nopw.pem

But when I run the script, I get the following output:

SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:failed in SSLv3 read server hello A
SSL_connect:before/connect initialization
SSL_connect:SSLv2 write client hello A
SSL_connect:failed in SSLv2 read server hello A
500 SSL negotiation failed:
Press any key to continue . . .

So, I commented out the  '$ENV{HTTPS_VERSION} = 3' line to see if that would help and get the following:

SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL3 alert write:fatal:unknown CA
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:failed in SSLv3 read server hello A
SSL_connect:before/connect initialization
SSL_connect:SSLv2 write client hello A
SSL_connect:failed in SSLv2 read server hello A
500 SSL negotiation failed:
Press any key to continue . . .

So, hopefully I haven't overloaded this question with too much information but I feel I have banged on this from several different angles and hopefully that will help figure out the best way to go from here.

Thanks in advance!
#!/usr/bin/perl

use strict;

use LWP;

use LWP::UserAgent;
 

my $URI = 'https://client-website.com';

my $user = 'myusername';

my $pass = 'mypassword';
 

use LWP::UserAgent;

# CA Cert file downloaded from http://eca.orc.com/ecaroot.crt

#$ENV{HTTPS_CA_FILE}= 'c:/ca_certs/ecaroot.crt';

#$ENV{HTTPS_CA_DIR} = 'c:/ca_certs';
 

#$ENV{HTTPS_CERT_FILE} = "c:/certs/usercert.pem";

#$ENV{HTTPS_KEY_FILE}  = "c:/certs/userkey_nopw.pem";
 

$ENV{HTTPS_PKCS12_FILE}     = 'c:/certs/pkcs12cert.pfx';

$ENV{HTTPS_PKCS12_PASSWORD} = 'cert_password';

#$ENV{HTTPS_VERSION} = 3;
 

# Print SSL Debug stuff (omit this line if not debugging)

$ENV{HTTPS_DEBUG} = 1;
 

# define user agent

my $ua = LWP::UserAgent->new();

$ua->agent("Test/Perl/WebChecker_script");
 

# make request

my $request = HTTP::Request->new(GET => $URI);
 

# authenticate

$request->authorization_basic($user, $pass);
 

# except response

my $response = $ua->request($request);
 

# get content of response

my $content = $response->content();
 

# do whatever you need to do with the content here

print $content;
 

exit;

Open in new window

0
Comment
Question by:diegoslice
  • 2
5 Comments
 
LVL 19

Expert Comment

by:Kim Ryan
ID: 20353940
Not sure if this will help, but current version is 0.57. You could try using strawberry Perl on Windows if you want to use this version, see

http://search.cpan.org/~dland/Crypt-SSLeay-0.57/SSLeay.pm#Windows
0
 

Author Comment

by:diegoslice
ID: 20354843
Thanks for the link on Strawberry Perl. I had glossed over this when trying to build my own Crypt::SSLeay and took the time to install it and uninstall ActivePerl to make sure there were no conflicts. However, even after I install the latest version 0.57 version from CPAN, I get similar messages as before. For instance, when I run the script using my PKCS12 .pfx certificate, the response is:

OPENSSL_Uplink(100DF020,06): no OPENSSL_Applink

and when I run it using my pem formatted user certificate / private keys files I get

500 SSL negotiation failed:
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL3 alert write:fatal:unknown CA
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:failed in SSLv3 read server hello A
SSL_connect:before/connect initialization
SSL_connect:SSLv2 write client hello A
SSL_connect:failed in SSLv2 read server hello A

Clearly PKCS12 certificate support is lacking and using pem files, SSL negotiation is failing. If I look at my usercert.pem file, it looks similar to what I have below (with identifying info edited for public posting):

Bag Attributes
    localKeyID: 01 00 00 00
subject=/C=US/O=U.S. Government/OU=ECA/OU=ORC/OU=company
/CN=Lastname, Firstname.I.ORC1000099999.ID
issuer=/C=US/O=U.S. Government/OU=ECA/OU=Certification Authorities/CN=ORC ECA
-----BEGIN CERTIFICATE-----
MNNEPjCCA6egAwIBAgICeYQwQWYJKoZIhvcNAQEFBQAwazELSDkGA1UEBhMCVVMx
..... (lines deleted)...
0/fVUv7Lx56ceXkS4PlGiMXv32TCFp6DO+fkWeQhZ7wevA==
-----END CERTIFICATE-----

And looking at my usercert.pem private keys file:

-----BEGIN RSA PRIVATE KEY-----
FGICWwIBAAKBgQDGHTOVdo3XTvysWTh1OTinME1jQhqpPcxOBvKbDdyWQml7iInv
..... (lines deleted)...
Rf7cP02FJmftyH2RJ9iK0Pzjv4a7d1vwWqj3naIB4Q==
-----END RSA PRIVATE KEY-----

Now remember, this same certificate works in a browser to access the web site so:
1.) Did I not use the correct commands with openssl to convert the certificate? Do the 'Bag Attributes' and subsequent lines belong before the 'Begin Certificate' line? Deleting this info out and running the script without them still produces the '500 SSL negotiation failed: ' error and subsequent lines.
2.) Is there a bug in Perl, Crypt::SSLeay module, or openssl that is somehow impacting this?

I lean towards my pem certificates being formatted wrong but not sure where I might have made a mistake.

Thanks again for any and all help.

 
0
 

Accepted Solution

by:
diegoslice earned 0 total points
ID: 20390809
I found out what the problem was with my script. In the line:

#$ENV{HTTPS_CA_FILE}= 'c:/ca_certs/ecaroot.crt';

The CA file is not the certificate authority that created / signed my user certificate (ECA/ORC in this case) . Rather, it is the CA that the server's certificate is signed by. So, if the server's certificate was signed by Verisign, then Verisign's public certificate is used as the CA file.
0
 
LVL 1

Expert Comment

by:modus_operandi
ID: 20434162
Closed, 500 points refunded.
modus_operandi
EE Moderator
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

So you need a certificate so you can offer SSL encryption.  But which one should you get?  There are so many choices out there! Here is a generic overview of the main types of SSL certificates sold by the majority of commercial Certification Auth…
Imagine a situation that you have installed SSL (http://en.wikipedia.org/wiki/Secure_Sockets_Layer) Certificate on your Cisco ASA (Cisco Adaptive Security Appliance) firewall. Installation of SSL certificate on ASA is an another topic for which you …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now