15 Replies Last post: Jul 9, 2008 12:39 AM by Paul Hammer   1 2 Previous Next
Click to view Guy Hill's profile Pro 8 posts since
Jun 27, 2008

Jun 27, 2008 9:27 AM

Bypassing Certificate of Authority - SSL from http to https

Hi All, I am new with Selenium and eventuelly I am new to this forum and I have no idea if this topic has been dealt with already or not. I have a project that involves some SSL validation that will prompt the user to accept the Certificate of Authority. Everything works fine but when i reach that stage, i keep getting the 404 error page.

Is there any way of bypassing this certificate issue and finish the automated test? When i do the test manually, everything works fine.

Click to view Bob's profile Pro 15 posts since
Jun 13, 2008

Hello Guy,

 

My understanding of Selenium is that because it uses Javascript to do its testing, it is bound by the Same Origin Policy which does not allow it to make the change you want from http to https. I have not really come across this in my testing, but my suggestion would be to use an experimental browser, such as *chrome instead of *firefox, or *iehta for Internet Explorer. Here is a webpage from the FAQ of Selenium RC that may answer some of your questions.

 

http://wiki.openqa.org/display/SRC/Selenium+RC+FAQ#SeleniumRCFAQ-Whenfirststarti ngtheserver%2CIgetthiserrormessage%3A%22%28Unsupportedmajor.minorversion49.0%29% 22

 

Hope this helps!

Click to view Paul Hammer's profile Pro 12 posts since
Jun 11, 2008

A co-worker and I ended up coming up with a solution for this ourselves:

 

Abstract

========

The problem here is to eliminate the certificate pop up at the start of running an RC test.

These steps have been written using the following software:

 

Firefox 2.0.0.14

Java 1.5

Selenium RC 0.9.2

 

Prerequisites:

 

These steps assume the above SW is installed and running.

 

 

Steps:

 

Create the proxy.pac file

Create a new file /proxy.pac, in the correct location for your site, with this contents:

 

function FindProxyForURL(url, host) {

if(shExpMatch(url, '/selenium-server/')) {

return 'PROXY localhost:4444; DIRECT';

}

}

 

 

Create a new firefox profile

Bring down all sessions of firefox

from a command window, Type "firefox -P" (the firefox profile window appears)

Click Create Profile (the create profile window appears)

Click Next

Type the new profile name "selenium-https-profile"

Click Finish

Click "selenium-https-profile" in the selection list (this sets the profile to use in future sessions)

Click Exit

 

 

Add the proxy.pac and the cybervillian certificate to the profile

from a command window, Type "firefox"

Select Edit|Preferences

Click Advanced

Click the Network tab

under Connections, Click Settings

Click "Automatic proxy configuration URL"

Type: https://<localPath>/proxy.pac

Click OK

Click Advanced

Click the Encryption tab

Click View Certificates

Click Import

Search to /selenium/selenium-remote-control-0.9.2/selenium-server-0.9.2/sslSupport/cyberV illiansCA.cer

Click Open

Click OK

Click Close

Click to view cytoe1's profile Expert 38 posts since
May 6, 2008

I got around this problem as follows:

  1. create a firefox profile

  2. get the public certificate from the https site

  3. import this certificate into the firefox profile you created (#1) using certutil

  4. When starting the server, specify this firefox profile (#1)

The code you probably want to see is the part that gets the certificate:

 

I get the certificate by establishing a connection to the https site and then querying for the key. To do this, you must use a proivder that disables certficicate checking:

 

import java.security.KeyStore;
import java.security.Provider;
import java.security.cert.X509Certificate;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;

/* The following code disables certificate checking.
* Use the Security.addProvider and Security.setProperty
* calls to enable it */
public class NaiveProvider extends Provider {
private static final long serialVersionUID = 1L;
public NaiveProvider() {
super( "MyProvider", 1.0, "Trust certificates" );
put( "TrustManagerFactory.TrustAllCertificates",
MyTrustManagerFactory.class.getName() );
}
protected static class MyTrustManagerFactory
extends TrustManagerFactorySpi {
public MyTrustManagerFactory() {}
@Override
protected void engineInit( KeyStore keystore ) {}
@Override
protected void engineInit(
ManagerFactoryParameters mgrparams ) {}
@Override
protected TrustManager[] engineGetTrustManagers() {
return new TrustManager[] {
new MyX509TrustManager()
};
}
}
protected static class MyX509TrustManager
implements X509TrustManager {
public void checkClientTrusted(
X509Certificate[] chain, String authType) {}
public void checkServerTrusted(
X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}

 

 

Now use the provider above to get the certificate:

 

/**
* get the top certificate in certificate chain from a remote system
* @param u
* @return
* @throws Exception
*/
public static X509Certificate getSSLCertificate(URL u) throws Exception {
Security.addProvider( new NaiveProvider() );
Security.setProperty(
"ssl.TrustManagerFactory.algorithm",
"TrustAllCertificates");

URLConnection uc = u.openConnection();

HttpsURLConnection ucs = (HttpsURLConnection) uc;
ucs.connect();
Certificate[] certificates = ucs.getServerCertificates();

// get the top certificate in certificate chain
X509Certificate xCert = ((X509Certificate)certificates[0]);
log("Retrieved certificate for: "+xCert.getIssuerX500Principal(), true);
return xCert;
}

 

Here's a method to write the certificate:

 

/**
* Writes X509 certificate to a PEM file
* @param xCert
* @param file
* @throws Exception
*/
public static void writePEM(X509Certificate xCert, String file) throws Exception {
File derFile = new File(file);
FileOutputStream fos = new FileOutputStream(derFile);

fos.write(certStart.getBytes());
fos.write(Base64.encode(xCert.getEncoded()).getBytes());
fos.write(certEnd.getBytes());
fos.flush();
fos.close();
}

 

After writing the certificate to file, you can then import it into your firefox profile.

I have all these steps automated in my testng based infrastucture.

The resason I use a specific firefox profile (instead of the default) is so I can be sure where to import the certificate to. This profile also provides a way to control certain browser settings.

 

Hope this helps.

Click to view Paul Hammer's profile Pro 12 posts since
Jun 11, 2008

Hi clearspace,

 

These are the steps I ended up taking. I posted my solution just this morning.

 

Thanks!

 

PaulJH

 

Date: Sun, 29 Jun 2008 22:28:26 -0500

From: clearspace@openqa.org

To: paul_hammer@hotmail.com

Subject: Selenium Remote Control Bypassing Certificate of Authority - SSL from http to https

 

I got around this problem as follows:

  1. create a firefox profile

  2. get the public certificate from the https site

  3. import this certificate into the firefox profile you created (#1) using certutil

  4. When starting the server, specify this firefox profile (#1)

The code you probably want to see is the part that gets the certificate:

I get the certificate by establishing a connection to the https site and then querying for the key. To do this, you must use a proivder that disables certficicate checking:

import java.security.KeyStore;
import java.security.Provider;
import java.security.cert.X509Certificate;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;

/* The following code disables certificate checking.
* Use the Security.addProvider and Security.setProperty
* calls to enable it */
public class NaiveProvider extends Provider {
private static final long serialVersionUID = 1L;
public NaiveProvider() {
super( "MyProvider", 1.0, "Trust certificates" );
put( "TrustManagerFactory.TrustAllCertificates",
MyTrustManagerFactory.class.getName() );
}
protected static class MyTrustManagerFactory
extends TrustManagerFactorySpi {
public MyTrustManagerFactory() {}
@Override
protected void engineInit( KeyStore keystore ) {}
@Override
protected void engineInit(
ManagerFactoryParameters mgrparams ) {}
@Override
protected TrustManager[] engineGetTrustManagers() {
return new TrustManager[] {
new MyX509TrustManager()
};
}
}
protected static class MyX509TrustManager
implements X509TrustManager {
public void checkClientTrusted(
X509Certificate[] chain, String authType) {}
public void checkServerTrusted(
X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}

Now use the provider above to get the certificate:

/**
* get the top certificate in certificate chain from a remote system
* @param u
* @return
* @throws Exception
*/
public static X509Certificate getSSLCertificate(URL u) throws Exception {
Security.addProvider( new NaiveProvider() );
Security.setProperty(
"ssl.TrustManagerFactory.algorithm",
"TrustAllCertificates");

URLConnection uc = u.openConnection();

HttpsURLConnection ucs = (HttpsURLConnection) uc;
ucs.connect();
Certificate[] certificates = ucs.getServerCertificates();

// get the top certificate in certificate chain
X509Certificate xCert = ((X509Certificate)certificates[0]);
log("Retrieved certificate for: "+xCert.getIssuerX500Principal(), true);
return xCert;
}

Here's a method to write the certificate:

/**
* Writes X509 certificate to a PEM file
* @param xCert
* @param file
* @throws Exception
*/
public static void writePEM(X509Certificate xCert, String file) throws Exception {
File derFile = new File(file);
FileOutputStream fos = new FileOutputStream(derFile);

fos.write(certStart.getBytes());
fos.write(Base64.encode(xCert.getEncoded()).getBytes());
fos.write(certEnd.getBytes());
fos.flush();
fos.close();
}

After writing the certificate to file, you can then import it into your firefox profile.

The resason I use a specific firefox profile (instead of the default) is so I can be sure where to import the certificate to. This profile also provides a way to control certain browser settings.

Hope this helps.

 

>

Click to view cytoe1's profile Expert 38 posts since
May 6, 2008

not sure I follow. The main difference is you are using the cybervillans certificate way (described on the selenium rc site), while I'm using the public certificate from the https server I'm testing against.

Click to view cytoe1's profile Expert 38 posts since
May 6, 2008

Out of curiosity, what did you use to click the accept? When I used Watij (dirves IE), I wrote a C++ hack using the capicom com interface. It worked most of the time, but wasn't the prettiest thing.

Click to view Paul Hammer's profile Pro 12 posts since
Jun 11, 2008

But doesn't this defeat the purpose of doing all this work to get around the certificate?

 

What I have found is that the first time the browser comes up after a machine is rebooted, is that if the "use this permanently" option is chosen and "ACCEPT" is clicked, after that the certificate window no longer appears.

 

BTW, what other program is used to click "ACCEPT"?

 

PaulJH

 

Date: Tue, 1 Jul 2008 08:43:38 -0500

From: clearspace@openqa.org

To: paul_hammer@hotmail.com

Subject: Selenium Remote Control Bypassing Certificate of Authority - SSL from http to https

 

Hi all,

thank you for your different answers to this issue. I finallement solve this problem by creating a new firefox profile as you have advised. Everything works fine but when it reaches the place where the certificate has to be accepted, i use a separate program that will click on "ACCEPT" of the certificate.

Regards

 

>

Click to view poojabeam's profile Pro 13 posts since
May 12, 2008

Did anyone try the same on Safari browser. Please coment on that.

 

Thanks,

pooja

Click to view Paul Hammer's profile Pro 12 posts since
Jun 11, 2008

Cool. Thanks.

 

Paul

 

Date: Wed, 2 Jul 2008 08:18:58 -0500

From: clearspace@openqa.org

To: paul_hammer@hotmail.com

Subject: Selenium Remote Control Bypassing Certificate of Authority - SSL from http to https

 

The program that I use to select anything on the certificate pop up box and ACCEPTING it is "AUTOIT". It's great and it can do anything.

 

>

Click to view Paul Hammer's profile Pro 12 posts since
Jun 11, 2008

Thanks!

 

Date: Wed, 2 Jul 2008 08:18:58 -0500

From: clearspace@openqa.org

To: paul_hammer@hotmail.com

Subject: Selenium Remote Control Bypassing Certificate of Authority - SSL from http to https

 

The program that I use to select anything on the certificate pop up box and ACCEPTING it is "AUTOIT". It's great and it can do anything.

 

>

More Like This

  • Retrieving data ...