[Webtest] Re: webtest cannot handle the lack of a secure certificate in our test environment

Ralf Müller Ralf Müller
Mon, 11 Dec 2006 09:19:52 +0100


Hi,

as far as I understand it, you have to add the certificate of your 
webpage to your keystore of trusted certificates.
This goes something like this:

use IE to save the certificate as DER encoded X.509 certificate
use the java keytool to import it in a keystore:

keytool -import -v -trustcacerts -file <the exported certificate file>
  -keystore trust.keystore -alias <unique alias for the certificate>

tell webtest to use this keystore:

<property name="webtest.connectioninitializer"
  value="com.canoo.webtest.security.SunJsseBaseConnectionInitializer" />
<property name="webtest.truststore.file" value="certs/<your keystore 
file>" />
<property name="webtest.truststore.passphrase" value="<password for the 
keystore" />

This works! But make sure that you get the path to your files etc. 
right, because the error messages you get when something is wrong will 
not really be helpfull :-(

Best Regards,
Ralf

John and Pip wrote:
> Hi All,
> 
> I am testing a secure website, and have not problem in the production 
> system, hitting and logging into 
> https://registration.airnewzealand.com/spr/login/login.jsp 
> <https://registration.airnewzealand.com/spr/login/login.jsp>
> 
> However, in our test environment, if you access this page in IE you see 
> a popup saying "Unable to verify the identity of 
> registration.airnewzealand.com <http://registration.airnewzealand.com> 
> as a trusted site." etc etc.
> 
> When I try to log in on this page in the test environment (by using a 
> proxy) using the following code:
> 
> <?xml version="1.0"?>
> <!DOCTYPE project SYSTEM " WebTest.dtd">
> <project name="OLH" basedir="." default="main">
>     <property name="webtest.home" location="..\.."/>
>     <import file="${ webtest.home}/lib/taskdef.xml"/>
>     <target name="main">
>         <setproxy proxyhost="10.16.32.33 <http://10.16.32.33>" 
> proxyport="4005" />   <!-- set to FT3 direct proxy -->       
>         <webtest name="ISIS SFF NZ Search">
> <config
>                 host="any"
>                 port="1234"
>                 protocol="http"
>                 basepath=""
>                 summary="true"
>                 saveresponse="true"
>                 resultpath="..\webtest-results"
>                 resultfile="results.xml"
>                 showhtmlparseroutput="false"
>                 autorefresh="true"
>                 haltonfailure="false"
>                 timeout="120">
>                 <option name="RedirectEnabled" value="true" />
>                 <header name="User-Agent" value="WebTest" />
> </config>
>             <steps>
>                    <groovy>
>                        def logFile = new File('./webtest.log')
>                     logFile.append("\nTest Start\n")
>                     logFile.append(step.context.webClient.toString())
>                       logFile.append("\nTest End\n")
>                    </groovy>
>                 <invoke 
> url="https://registration.airnewzealand.com/spr/login/login.jsp"/>
>                 <!-- This fails with a "connection timed out error. It 
> also fails in this format: 
> https://registration.airnewzealand.com/spr?login?login.jsp -->   
>                 <verifyTitle text="Air New Zealand - My Account"/>
>                 <verifyText text="Login"/>
>                 <setInputField name="username" value="966594"/>
>                 <setInputField name="password" 
> value="password01"/>                <!-- Qual value -->
>                 <clickButton description="Click image button: " 
> name="image"/>
>                 <verifyTitle text="Air New Zealand - My Airpoints Account"/>
>                 <verifyText text="My Airpoints Account"/>                  
>              </steps>
>         </webtest>
>     </target>
> </project>
> 
> I get:
> 
> C:\WebTest\doc\ISIS>webtest -debug -f testFT3.xml  > out.txt
> 
> BUILD FAILED
> C:\WebTest\doc\ISIS\testFT3.xml:8: Canoo Webtest: R_1438.
> Test failed.
> Exception raised: com.canoo.webtest.engine.StepExecutionException: 
> Unexpected ex
> ception caught: javax.net.ssl.SSLHandshakeException: 
> sun.security.validator.Vali
> datorException: PKIX path building failed: 
> sun.security.provider.certpath.SunCer
> tPathBuilderException: unable to find valid certification path to 
> requested targ
> et, Step: InvokePage at C:\WebTest\doc\ISIS\testFT3.xml:32:  with 
> (taskName="inv
> oke")com.canoo.webtest.engine.StepExecutionException: Unexpected 
> exception caugh
> t: javax.net.ssl.SSLHandshakeException: 
> sun.security.validator.ValidatorExceptio
> n: PKIX path building failed: 
> sun.security.provider.certpath.SunCertPathBuilderE
> xception: unable to find valid certification path to requested target, 
> Step: Inv
> okePage at C:\WebTest\doc\ISIS\testFT3.xml:32:  with (taskName="invoke")
>         at 
> com.canoo.webtest.steps.Step.handleUnexpectedException(Step.java:413)
> 
> [rest of the stack below if you are interested]
> 
> and the relevant bit of the webtest debug output is:
> 
> Build sequence for target(s) `main' is [main]
> Complete build sequence is [main, ]
> 
> main:
>  [setproxy] Setting proxy to 10.16.32.33:4005 <http://10.16.32.33:4005>
> Setting project property: webtest.version -> Canoo Webtest: R_1438.
> Adding reference: ant.PropertyHelper
> Adding reference: ant.PropertyHelper
> [Fatal Error] :-1:-1: Premature end of file.
> 
> A developer here has passed on this code to work around a similar 
> problem in httpunit:
> 
>   private static void trustAll()
>   {
>     TrustManager[] trustAllCerts = new TrustManager[] { new 
> X509TrustManager()
>     {
> 
>       public java.security.cert.X509Certificate [] getAcceptedIssuers()
>       {
>         return null;
>       }
> 
>       public void 
> checkClientTrusted(java.security.cert.X509Certificate[] certs, String 
> authType)
>       {
>       }
> 
>       public void checkServerTrusted( 
> java.security.cert.X509Certificate[] certs, String authType)
>       {
>       }
>     } };
> 
>     HostnameVerifier hostnameVerifier = new HostnameVerifier()
>     {
>       public boolean verify(String rserver, SSLSession sses)
>       {
> 
>         if (!rserver.equals(sses.getPeerHost()))
>         {
>           if (!warnedCertificates.contains(sses.getPeerHost()))
>           {
>             warnedCertificates.add(sses.getPeerHost());
>             log.warn("certificate <" + sses.getPeerHost() + "> does not 
> match host <" + rserver + ">");
>           }
>         }
> 
>         return true;
>       }
>     };
> 
> Unfortunately I do not have access to him to work on htmlunit if in fact 
> there is a similar issue there, and I am not a java developer so don't 
> fancy my chances messing with the htmlunit internals.
> 
> Can anyone confirm whether this is a defect (limitation?) in htmlunit, 
> and whether I should open an issue, and hopefully a solution so I can 
> continue writing my webtests? Thanks.
> 
> regards,
>         John
> 
> 
> 
>         at 
> com.canoo.webtest.steps.AbstractBrowserAction.handleUnexpectedExcepti
> on(AbstractBrowserAction.java:120)
>         at com.canoo.webtest.steps.request.TargetHelper.protectedGoto 
> (TargetHelp
> er.java:115)
>         at 
> com.canoo.webtest.steps.request.AbstractTargetAction.gotoTarget(Abstr
> actTargetAction.java:106)
>         at 
> com.canoo.webtest.steps.request.AbstractTargetAction.doExecute(Abstra
> ctTargetAction.java:78)
>         at com.canoo.webtest.steps.Step.execute(Step.java:106)
>         at 
> org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
>         at org.apache.tools.ant.Task.perform (Task.java:364)
>         at 
> com.canoo.webtest.ant.TestStepSequence.executeSteps(TestStepSequence.
> java:43)
>         at 
> com.canoo.webtest.ant.TestStepSequence.doExecute(TestStepSequence.jav
> a:31)
>         at com.canoo.webtest.steps.Step.execute (Step.java:106)
>         at org.apache.tools.ant.Task.perform(Task.java:364)
>         at com.canoo.webtest.ant.WebtestTask.execute(WebtestTask.java:164)
>         at 
> org.apache.tools.ant.UnknownElement.execute(UnknownElement.java :275)
>         at org.apache.tools.ant.Task.perform(Task.java:364)
>         at org.apache.tools.ant.Target.execute(Target.java:341)
>         at org.apache.tools.ant.Target.performTasks(Target.java:369)
>         at 
> org.apache.tools.ant.Project.executeSortedTargets(Project.java:1216)
>         at org.apache.tools.ant.Project.executeTarget(Project.java:1185)
>         at 
> org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExe
> cutor.java:40)
>         at org.apache.tools.ant.Project.executeTargets(Project.java:1068)
>         at org.apache.tools.ant.Main.runBuild(Main.java:668)
>         at org.apache.tools.ant.Main.startAnt(Main.java:187)
>         at org.apache.tools.ant.launch.Launcher.run(Launcher.java:246)
>         at org.apache.tools.ant.launch.Launcher.main(Launcher.java:67)
> Caused by: javax.net.ssl.SSLHandshakeException: 
> sun.security.validator.Validator
> Exception: PKIX path building failed: 
> sun.security.provider.certpath.SunCertPath
> BuilderException: unable to find valid certification path to requested 
> target
>         at com.sun.net.ssl.internal.ssl.Alerts.getSSLException 
> (Alerts.java:150)
>         at 
> com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1
> 476)
>         at 
> com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
>         at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE 
> (Handshaker.java:168)
>         at 
> com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien
> tHandshaker.java:847)
>         at 
> com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHa
> ndshaker.java :106)
>         at 
> com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:4
> 95)
>         at 
> com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.jav
> a:433)
>         at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord 
> (SSLSocketImpl.j
> ava:815)
>         at 
> com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SS
> LSocketImpl.java:1025)
>         at 
> com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.
> java:619)
>         at 
> com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.ja
> va:59)
>         at 
> java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65
> )
>         at java.io.BufferedOutputStream.flush 
> (BufferedOutputStream.java:123)
>         at 
> org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream
> (HttpConnection.java:827)
>         at 
> org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$Http
> ConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.ja
> va:1525)
>         at 
> org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodB
> ase.java:1975)
>         at org.apache.commons.httpclient.HttpMethodBase.execute 
> (HttpMethodBase.j
> ava:993)
>         at 
> org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(Htt
> pMethodDirector.java:397)
>         at 
> org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMe
> thodDirector.java:170)
>         at 
> org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.jav
> a:396)
>         at 
> org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.jav
> a:346)
>         at 
> com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebCo
> nnection.java:126)
>         at 
> com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnect
> ion(WebClient.java:1371)
>         at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse 
> (WebClient.jav
> a:1329)
>         at 
> com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:322)
>         at 
> com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:389)
>         at com.canoo.webtest.steps.request.TargetHelper.getResponse 
> (TargetHelper
> .java:69)
>         at 
> com.canoo.webtest.steps.request.AbstractTargetAction.getResponse(Abst
> ractTargetAction.java:68)
>         at 
> com.canoo.webtest.steps.request.InvokePage.findTarget(InvokePage.java
> :134)
>         at 
> com.canoo.webtest.steps.request.AbstractTargetAction$1.call(AbstractT
> argetAction.java:108)
>         at 
> com.canoo.webtest.steps.request.TargetHelper.protectedGoto(TargetHelp
> er.java:88)
>         ... 22 more
> Caused by: sun.security.validator.ValidatorException: PKIX path building 
> failed:
>  sun.security.provider.certpath.SunCertPathBuilderException: unable to 
> find vali
> d certification path to requested target
>         at 
> sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)
>         at 
> sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.jav
> a:145)
>         at sun.security.validator.Validator.validate (Validator.java:203)
>         at 
> com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(
> X509TrustManagerImpl.java:172)
>         at 
> com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted (
> SSLContextImpl.java:320)
>         at 
> com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien
> tHandshaker.java:840)
>         ... 49 more
> Caused by: sun.security.provider.certpath.SunCertPathBuilderException : 
> unable to
>  find valid certification path to requested target
>         at 
> sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCert
> PathBuilder.java:236)
>         at java.security.cert.CertPathBuilder.build 
> (CertPathBuilder.java:194)
>         at 
> sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
>         ... 54 more
> 
>         at 
> com.canoo.webtest.ant.WebtestTask.stopBuildIfNeeded(WebtestTask.java:
> 228)
>         at com.canoo.webtest.ant.WebtestTask.execute(WebtestTask.java:175)
>         at 
> org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
>         at org.apache.tools.ant.Task.perform(Task.java :364)
>         at org.apache.tools.ant.Target.execute(Target.java:341)
>         at org.apache.tools.ant.Target.performTasks(Target.java:369)
>         at 
> org.apache.tools.ant.Project.executeSortedTargets(Project.java :1216)
>         at org.apache.tools.ant.Project.executeTarget(Project.java:1185)
>         at 
> org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExe
> cutor.java:40)
>         at org.apache.tools.ant.Project.executeTargets (Project.java:1068)
>         at org.apache.tools.ant.Main.runBuild(Main.java:668)
>         at org.apache.tools.ant.Main.startAnt(Main.java:187)
>         at org.apache.tools.ant.launch.Launcher.run(Launcher.java:246)
>         at org.apache.tools.ant.launch.Launcher.main(Launcher.java:67)
> 
> Total time: 4 seconds
> 
> C:\WebTest\doc\ISIS>
> 
> 
> Incidentally, the above has the test environment password which is 
> different to the production one so you can't run it against the public 
> page.