# Webproject + Tomcat + SSL



## brauner1990 (25. Jan 2011)

Guten Morgen Community!

Ich habe ein Webproject aktuell, dieses soll sich mit einem Server verbinden, welcher SSL gesichert ist. Das Projekt läuft auf einem Tomcat 6.0.

Das SSL Zertifikat ist selbst erstellt und selber signiert, also kein VeriSign o.ä., heruntergeladen habe ich es mir via der Export Funktion von Firefox und integriert habe ich es in die Java Umgebung mithilfe der Anleitung (http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html) . Aber trotz dieses Einbinden bekomme ich eine Exception.

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Der Stacktrace sieht wie folgt aus, er stammt aus der Catalina-Log-Datei des Tomcats.


```
SCHWERWIEGEND: null
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 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:1584)
        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(ClientHandshaker.java:848)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1116)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1100)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)

        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:960)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
        at java.net.URL.openStream(URL.java:1007)
        at helfer.Hilfe.getQuelltextFromUrl(Hilfe.java:79)
        at helfer.Hilfe.getLinkToChartPicture(Hilfe.java:35)
        at helfer.Hilfe.saveImageToTargetPath(Hilfe.java:127)
        at strutsActions.TestActionSupport.validate(TestActionSupport.java:31)
        at com.opensymphony.xwork2.validator.ValidationInterceptor.doBeforeInvocation(ValidationInterceptor.java:249)
        at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:261)
        at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)

        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)

        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)

        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)

        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)

        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
        at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
        at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
        at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
        at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:574)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1527)
        at java.lang.Thread.run(Thread.java:595)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java: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(ClientHandshaker.java:841)
        ... 71 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
        ... 76 more
```

Könnt ihr mir da vlt weiterhelfen?
Ich bedanke mich schonmal und wünsche einen schönen Tag zu haben.


----------



## tagedieb (26. Jan 2011)

Ich habe nicht ganz verstanden welche Verbindung nicht funktioniert.
Es sieht so aus als ob die Verbindung zum Webserver funktioniert, jedoch die Verbindung aus deiner Applikation auf eine URL innerhalb oder ausserhalb desselben Servers fehlschlaegt.




> at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:960)
> at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
> at java.net.URL.openStream(URL.java:1007)
> at helfer.Hilfe.getQuelltextFromUrl(Hilfe.java:79)        at helfer.Hilfe.getLinkToChartPicture(Hilfe.java:35)
> ...




Hast du deine Certificat auch im 'truststore' von Tomcat abgelegt?


```
keytool -import -alias root -keystore <your_keystore_filename> \
    -trustcacerts -file <filename_of_the_chain_certificate>
```


Desweiteren bin ich mir nicht sicher ob Tomcat und Java dieselben Keystores verwenden.
Versuch mal das System Property 
	
	
	
	





```
javax.net.debug=ssl
```
 oder 
	
	
	
	





```
javax.net.debug=all
```
 zu setzen. Da solltest du zusaetzliche Informationen erhalten in welchem key- truststore er nach den Certificaten sucht.


----------



## brauner1990 (26. Jan 2011)

tagedieb hat gesagt.:


> Ich habe nicht ganz verstanden welche Verbindung nicht funktioniert.
> Es sieht so aus als ob die Verbindung zum Webserver funktioniert, jedoch die Verbindung aus deiner Applikation auf eine URL innerhalb oder ausserhalb desselben Servers fehlschlaegt.


Also mein Webinterface läuft auf Server 1, verbinden soll sich die Geschäftslogik hinterm Webinterface mit Server 2, dieser ist SSL gesichert.



tagedieb hat gesagt.:


> Hast du deine Certificat auch im 'truststore' von Tomcat abgelegt?
> 
> ```
> keytool -import -alias root -keystore <your_keystore_filename> \
> ...


Ob ich die expliziet im Tomcat gelegt habe....kp....aber bei der JRE habe ich es.



tagedieb hat gesagt.:


> Desweiteren bin ich mir nicht sicher ob Tomcat und Java dieselben Keystores verwenden.
> Versuch mal das System Property
> 
> 
> ...



Werde ich ausprobieren, tippe ja dies soll in die log4j.properties geschrieben werden.


----------



## brauner1990 (26. Jan 2011)

UPDATE

Habe nun einen TrustManager eingebaut, habe jetzt kein 
	
	
	
	





```
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
```
 Fehler mehr, nun ist es ein 
	
	
	
	





```
HTTPS hostname wrong
```
.

Obwohl ich einen ALL TrustManager eingebaut habe


----------



## maki (26. Jan 2011)

*verschoben*

Für welche URL ist das Zertifikat ausgestellt und welche URL nutzt du um auf den Server zuzugreifen?


----------



## brauner1990 (26. Jan 2011)

Die URL ist auf die TLD ausgestellt, aber via eigens erstellten Zertifikat. Aber der ALLTrustmanager sollte das doch eigentlich ignorieren, oder wo soll das Problem liegen? Meine URL ist eine SubDomain mit verschachtelung, also 
	
	
	
	





```
https://sub.top.de/down/file.php?param1=value1&param2=value2[/c]


[SIZE="3"][COLOR="Red"]UPDATE[/COLOR][/SIZE]
OTon der Infos von Firefox über das Zertifikat
Ausgestellt für
CN=**
O=SomeOrganiation
OU=SomeOrganiationUnit
Seriennummer=**
Ausgestellt von
CN=**
O=SomeOrganiation
OU=SomeOrganiationUnit

habe nur  ge"*" wo es kein Standart war....aber CN war jeweils the same
```


----------



## tagedieb (27. Jan 2011)

Wenn der Hostname nicht mit dem Zertifikat ueberein steht musst du ein 
	
	
	
	





```
HostnameVerifier
```
 verwenden

siehe Beispiel


----------



## brauner1990 (27. Jan 2011)

Habe es nun gelöst!

1. Zertifikat in die JRE eingebunden
2. ALL Trust Manager eingebunden
3. HostnameVerifier eingebunden

Quelltexte sehen dann so aus

```
public HostnameVerifier getHostnameVerifier() {
        HostnameVerifier hv = new HostnameVerifier() {

            public boolean verify(String string, SSLSession ssls) {
                return true;
            }
        };
        return hv;

    }

    public TrustManager[] getAllTrustingTrustManager() {
        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) {
                }
            }
        };
        return trustAllCerts;
    }
```

Und das Zertifikat war ein HostnameZertifikat, selbst erstellt und signiert.


----------



## tagedieb (27. Jan 2011)

So hast du natuerlich die Identifikation des Servers sowie die Ueberpruefung des Zertifikats ausgehebelt.

Aber wenn es dir nur um die SSL Verschluesselung geht ist dein Code ok.


Mir ist immer noch nicht klar ob du das Zertifikat auch auf dem Server1 importiert hat. Dieses benoetigt er um das Zertifikat, welches Server2 fuer den SSL Aufbau verwendet zu ueberpruefen. Da es sich um ein Selfsigned Zertifikat handelt sind die beiden identlisch und muessen auf dem Client wie auf dem Server installiert sein.

Da du deinen eigenen TrustManager verwendest ist das importieren des Zertifikats auf dem Client (Server1) nicht mehr noetig.


----------



## brauner1990 (31. Jan 2011)

Neues Problem bei dieser Aufgabenstellung!

Also das mit dem SSL funktioniert alles soweit, ja, das einbinden war eigentlich überflüssig.

Ich versuche den Quelltext auszulesen, aber leider ist dieser immer gleich, obwohl er anders sein sollte.
Ich lese mit JAVA den Quelltext aus, und will diesen dann mit der Session rüberschieben auf die HP, leider ist der Quelltext immer der Gleiche obwohl sämtliche Buffer genullt werden beim Seitenladen.


----------



## tagedieb (1. Feb 2011)

Quelltext == HTML Code ?


Wie und wo stellst du fest ob sich der HTML Code veraendert hat?
Gib beim Lesen die HTTP Headers *Content-Length* und *Last Modified* aus, dass sollte helfen ob der Inhalt gleich oder verschieden sein sollte.

Wenn du die Seite direkt mit dem Browser aufrufst kriegst du dann auch immer die gleiche Seite?


----------



## brauner1990 (1. Feb 2011)

Nein, nicht direkt. Ich bekomme ein HTML Gerüst welches immer gleich ist. Innerhalb dieses HTML Gerüstes wird eine map definiert, welche wiederum sich verändert und das TempFile welches als IMG eingebunden wird, verändert sich auch immer.


----------



## tagedieb (1. Feb 2011)

:bahnhof: Ich verstehe jetzt nicht was genau nicht funktioniert. Soweit ich verstanden habe bekommst du immer denselben Inhalt, welcher jedoch unterschiedlich sein sollte? Und wo, wann liest du die Image Datei?

Ich denke ohne deinen Sourcecode koennen wir hier nicht weiterhelfen.


----------



## brauner1990 (1. Feb 2011)

Ok, ich erklär es mal anders, vlt war ich nen bisschen verwirrt beim tippen.

Server1 (S1) liefert Server2 (S2) einen Quelltext.

Auf S2 arbetiet Java und fordert von S1 den Quelltext an. Dieser generiert auf eine mir unbekannte Art und weise den kompletten Quelltext mit einer Referenz auf eine Temporäres Image Objekt. 
Den Quelltext auszulesen und diesen zu interpretieren ist kein Problem (Quelltext in den StringBuilder diesen toString auf der meiner Website).
Nur dieses f**ki*g TempImage bricht mir den Hals. Dieses existiert solange die Seite geladen wird, sprich solange wie der Reload ausgeführt wird. Beim Testen auf der Originalseite, mit ausgeschaltetem Cache, konnte ich es mir nicht in der MedienAnsicht von Firefox angucken.

In meinem Quellcode darf weder via Referenz noch sonst irgendwie ein Rückschluss auf die Original URL bestehen.

Hoffe diese Beschreibung ist nun besser verständlich.


----------



## tagedieb (2. Feb 2011)

Wo ist nun das Problem beim Lesen des Image?

Du musst ja auch das Image runterladen und die Image URL im HTML Code aendern, damit es ueber den Server 1 geladen werden kann.

Ueberleg dir mal ob du nicht einfach einen ReverseProxy verwenden willst, der waere genau fuer solche Sachen ausgelegt. (Sofern du den HTML Code nicht anderweitig veraendern oder engaenzen musst).


----------



## brauner1990 (2. Feb 2011)

Gibt es bereits OpenSourceLösungen in Java, oder muss ich mir erst selber einen ReverseProxy schreiben?

Kann ich diesen so Schreiben das dieser im Tomcat läuft?


----------

