From c1458a3c19138571ce9a09e1009053a999a60900 Mon Sep 17 00:00:00 2001 From: Norbert Nagold Date: Sun, 3 Jun 2012 16:09:04 +0200 Subject: [PATCH] add ankiweb-cert to ssl --- res/raw/ankiweb_cert | Bin 0 -> 1400 bytes .../exchangeit/EasySSLSocketFactory.java | 136 ------------------ .../exchangeit/EasyX509TrustManager.java | 93 ------------ src/com/ichi2/libanki/Sched.java | 1 - .../ichi2/libanki/sync/BasicHttpSyncer.java | 30 +++- 5 files changed, 28 insertions(+), 232 deletions(-) create mode 100644 res/raw/ankiweb_cert delete mode 100644 src/com/byarger/exchangeit/EasySSLSocketFactory.java delete mode 100644 src/com/byarger/exchangeit/EasyX509TrustManager.java diff --git a/res/raw/ankiweb_cert b/res/raw/ankiweb_cert new file mode 100644 index 0000000000000000000000000000000000000000..4a06e6e3d5267f9a0c7276b0dcd2f648a0402cad GIT binary patch literal 1400 zcmZQzU|?imU=X>wpl`$fgVWyg-_ZAw_$at|vTV>J1_t&Sj0}99c_pbuxv43ci6yDd zjzIP1n`Zy~0o266z#5@vYG4VZr45=`#SNO6|1V%>Vq{_xWcWX)LSy=z<$sQ!Y*dh( zT;y%Q%f_kI=F#?@mywZ`mBFCUklTQhjX9KsO_<5u$xzxr62##U7IH621=>@j;G3A2 zoRL}#WEu(>@PQ=Rh1r7>bJFsQQVgXGBtRlu!h+8Ex%nyi3eJuSKAE|hC8;Tf;s&B1 zIc8zLfc)ajlFYKy;9wu10s}d5UPD6zOG8rwFo*(jO@LezBV$ubQ_Cm=e?vtBd5~6a zVF{P~+{Da01?T*{lA`<^g|Nh&%oL!rQVc~5gdj?|kxYk)G7EDj=4EG=rzYv;rIr{p zF)AT@n~{})xrvdV0VvMJ)WpchaD?}}Swz&)XPF9*wO;4FzkO`!PLJJNSNtjuyP5w> ze2=)L`s22kPny4-f7dK|6KHU2=Uj<58dtTShvnb)oB46U=kUc!H+IL$2{8LS5erD$ z_JcWQPg26GfX;{67Y-gcG3oN&2^nhBob`8n(3udwyj5biU&yWClZkQ>KH+oTNxR;U zGd|XJY3uCi3l#hQ*vt~uer!LvkJngY%f|iF8@#SZds;bOn7Mb`mh%(uO*;24qcKg- zraJeaz)_a{zavj*`=y(0IN!bH(`+_B<7eOe`*q*Hsg=L3Ecob3+JQxa7PmZvKK1{d zrV}PFzvJd^o}~v5tXH4>blz)+$$M_yQxIB`6|y(om5G^=fpKvY<0)W>90LcvtTKy) zfmnmcj#Gj!*$gXhAD(jTg{0P=-KJuOOAKUz0WZtPBE}*j>2go9YiV2Jf1$W@*Zm(Z z_`y-O5S&J2`577iv#>BTu`V#+0Vx*-@tF)5AevQK#0*5(IJDV-NsyhH5zb;Va04k; zV6iu_HLzym1}b1-+++w$$m|9>23jz6OpIc386_nJR{Hwo<>h(>(BxHIoTHbVpR4a2 z5NwbMGDn^z$soZ%e}V1-?KVxQhU6l!B4AogP6Vq)No(WUr*5+Sxc7pe(p0L&-fO4$h1}d`AYR~VHInRiWr(o{hNP6 zyYFt^v}K$TbNbe`izr;(9k0dNQ_i|n_si^$7OBspWUKc563XgbUHaJTr>{6;7X$m; z8NYY0Pwe3+kp5sLw3kzK>%R&exvL6|K@6v*#Ce&!%!@VE8rH3n{+``G|4=wraLAeq zuP3=3aaM?Y;i9*#|LmUHS-SVW2n%t?#t9v?vUXU>vcJXj=<~*|qVAA#$;O!KTdb2` z<@}GC(dn(*sGaqw?c|5!&M6CORy;at`_}eN;KYJAUsVNe@CN)*<)8bjPx$^v_T6G- y0#hF{7C9Gx%+R)aXS>&vUD)x;TLG>_2D_KW)(ktW>gtqlI_$UE5fa3saRva#C+TSb literal 0 HcmV?d00001 diff --git a/src/com/byarger/exchangeit/EasySSLSocketFactory.java b/src/com/byarger/exchangeit/EasySSLSocketFactory.java deleted file mode 100644 index 66186ba4a6..0000000000 --- a/src/com/byarger/exchangeit/EasySSLSocketFactory.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.byarger.exchangeit; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; - -import org.apache.http.conn.ConnectTimeoutException; -import org.apache.http.conn.scheme.LayeredSocketFactory; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -/** - * This socket factory will create ssl socket that accepts self signed - * certificate - * - * @author olamy - * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse - * $ - * @since 1.2.3 - */ -public class EasySSLSocketFactory implements LayeredSocketFactory { - - private SSLContext sslcontext = null; - - private static SSLContext createEasySSLContext() throws IOException { - try { - SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, new TrustManager[] { new EasyX509TrustManager( - null) }, null); - return context; - } catch (Exception e) { - throw new IOException(e.getMessage()); - } - } - - private SSLContext getSSLContext() throws IOException { - if (this.sslcontext == null) { - this.sslcontext = createEasySSLContext(); - } - return this.sslcontext; - } - - /** - * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, - * java.lang.String, int, java.net.InetAddress, int, - * org.apache.http.params.HttpParams) - */ - public Socket connectSocket(Socket sock, String host, int port, - InetAddress localAddress, int localPort, HttpParams params) - throws IOException, UnknownHostException, ConnectTimeoutException { - int connTimeout = HttpConnectionParams.getConnectionTimeout(params); - int soTimeout = HttpConnectionParams.getSoTimeout(params); - - InetSocketAddress remoteAddress = new InetSocketAddress(host, port); - SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket()); - - if ((localAddress != null) || (localPort > 0)) { - // we need to bind explicitly - if (localPort < 0) { - localPort = 0; // indicates "any" - } - InetSocketAddress isa = new InetSocketAddress(localAddress, - localPort); - sslsock.bind(isa); - } - - sslsock.connect(remoteAddress, connTimeout); - sslsock.setSoTimeout(soTimeout); - return sslsock; - - } - - /** - * @see org.apache.http.conn.scheme.SocketFactory#createSocket() - */ - public Socket createSocket() throws IOException { - return getSSLContext().getSocketFactory().createSocket(); - } - - /** - * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket) - */ - public boolean isSecure(Socket socket) throws IllegalArgumentException { - return true; - } - - /** - * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, - * java.lang.String, int, boolean) - */ - public Socket createSocket(Socket socket, String host, int port, - boolean autoClose) throws IOException, UnknownHostException { - return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); - } - - // ------------------------------------------------------------------- - // javadoc in org.apache.http.conn.scheme.SocketFactory says : - // Both Object.equals() and Object.hashCode() must be overridden - // for the correct operation of some connection managers - // ------------------------------------------------------------------- - - public boolean equals(Object obj) { - return ((obj != null) && obj.getClass().equals( - EasySSLSocketFactory.class)); - } - - public int hashCode() { - return EasySSLSocketFactory.class.hashCode(); - } - -} diff --git a/src/com/byarger/exchangeit/EasyX509TrustManager.java b/src/com/byarger/exchangeit/EasyX509TrustManager.java deleted file mode 100644 index 0bbcd1ef19..0000000000 --- a/src/com/byarger/exchangeit/EasyX509TrustManager.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.byarger.exchangeit; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -/** - * @author olamy - * @version $Id: EasyX509TrustManager.java 765355 2009-04-15 20:59:07Z evenisse $ - * @since 1.2.3 - */ -public class EasyX509TrustManager - implements X509TrustManager -{ - - private X509TrustManager standardTrustManager = null; - - /** - * Constructor for EasyX509TrustManager. - */ - public EasyX509TrustManager( KeyStore keystore ) - throws NoSuchAlgorithmException, KeyStoreException - { - super(); - TrustManagerFactory factory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); - factory.init( keystore ); - TrustManager[] trustmanagers = factory.getTrustManagers(); - if ( trustmanagers.length == 0 ) - { - throw new NoSuchAlgorithmException( "no trust manager found" ); - } - this.standardTrustManager = (X509TrustManager) trustmanagers[0]; - } - - /** - * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType) - */ - public void checkClientTrusted( X509Certificate[] certificates, String authType ) - throws CertificateException - { - standardTrustManager.checkClientTrusted( certificates, authType ); - } - - /** - * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType) - */ - public void checkServerTrusted( X509Certificate[] certificates, String authType ) - throws CertificateException - { - if ( ( certificates != null ) && ( certificates.length == 1 ) ) - { - certificates[0].checkValidity(); - } - else - { - standardTrustManager.checkServerTrusted( certificates, authType ); - } - } - - /** - * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() - */ - public X509Certificate[] getAcceptedIssuers() - { - return this.standardTrustManager.getAcceptedIssuers(); - } - -} diff --git a/src/com/ichi2/libanki/Sched.java b/src/com/ichi2/libanki/Sched.java index 61297be855..3e0be160bf 100644 --- a/src/com/ichi2/libanki/Sched.java +++ b/src/com/ichi2/libanki/Sched.java @@ -30,7 +30,6 @@ import android.util.Log; import android.util.Pair; import com.ichi2.anki.AnkiDroidApp; -import com.ichi2.async.DeckTask.TaskData; import org.json.JSONArray; import org.json.JSONException; diff --git a/src/com/ichi2/libanki/sync/BasicHttpSyncer.java b/src/com/ichi2/libanki/sync/BasicHttpSyncer.java index ae33e5356c..e4cb06e8c8 100644 --- a/src/com/ichi2/libanki/sync/BasicHttpSyncer.java +++ b/src/com/ichi2/libanki/sync/BasicHttpSyncer.java @@ -16,9 +16,10 @@ package com.ichi2.libanki.sync; +import com.ichi2.anki2.R; + import android.util.Log; -import com.byarger.exchangeit.EasySSLSocketFactory; import com.ichi2.anki.AnkiDroidApp; import com.ichi2.async.Connection; import com.ichi2.libanki.Collection; @@ -34,6 +35,7 @@ import org.apache.http.conn.params.ConnPerRouteBean; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.SingleClientConnManager; @@ -57,6 +59,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringWriter; import java.io.UnsupportedEncodingException; +import java.security.KeyStore; import java.util.zip.GZIPOutputStream; public class BasicHttpSyncer implements HttpSyncer { @@ -152,7 +155,7 @@ public class BasicHttpSyncer implements HttpSyncer { SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); - schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443)); + schemeRegistry.register(new Scheme("https", newSslSocketFactory(), 443)); HttpParams params = new BasicHttpParams(); params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30); @@ -326,4 +329,27 @@ public class BasicHttpSyncer implements HttpSyncer { public HttpResponse register(String user, String pw) { return null; } + + private SSLSocketFactory newSslSocketFactory() { + try { + KeyStore trusted = KeyStore.getInstance("BKS"); + InputStream in = AnkiDroidApp.getInstance().getApplicationContext().getResources().openRawResource(R.raw.ankiweb_cert); + try { + trusted.load(in, "mysecret".toCharArray()); + } finally { + in.close(); + } + SSLSocketFactory sf = new SSLSocketFactory(trusted); + sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); + return sf; + } catch (Exception e) { + Log.e(AnkiDroidApp.TAG, "Certificate error"); + // to update the ankiweb.cert: + // 1. get http://bouncycastle.org/download/bcprov-jdk16-145.jar + // 2. keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/ankiweb_cert" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret + // 3. copy ankiweb_cert to res/raw/ + throw new AssertionError(e); + } + } + }