Пользовательская обработка SSL перестала работать на Android 2.2 FroYo

Для моего приложения, Transdroid, я подключаюсь к удаленным серверам через HTTP и, необязательно, безопасно через HTTPS. Для этих HTTPS-соединений с HttpClient я использую собственную реализацию SSL-сокета factory, чтобы убедиться, что самозаверяющие сертификаты работают. В принципе, я принимаю все и игнорирую каждую проверку любого сертификата.

Это работает отлично уже некоторое время, но больше не работает для Android 2.2 FroYo. При попытке подключения он возвращает исключение:

java.io.IOException: SSL handshake failure: I/O error during system call, Broken pipe

Вот как я инициализирую HttpClient:

    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", new PlainSocketFactory(), 80));
    registry.register(new Scheme("https", (trustAll ? new FakeSocketFactory() : SSLSocketFactory.getSocketFactory()), 443));
    client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);

Я использую FakeSocketFactory и FakeTrustManager, источник которых можно найти здесь.

Опять же, я не понимаю, почему это внезапно прекратило работу или даже то, что означает ошибка "Сломанная труба". Я видел сообщения в Twitter о том, что Seesmic и Twidroid терпят неудачу с поддержкой SSL на FroYo, но я не уверен, связано ли это.

Спасибо за любые указания/помощь!

Ответ 1

Вот ответ, которому большое спасибо, полезному разработчику Seesmic, желающему поделиться исправлением:

В пользовательском сокете factory создание сокета (с createSocket), по-видимому, было специально изменено для реализации SSLSocketFactory. Итак, старый:

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket();
    }

Требуется изменить на:

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
    }

И потом он снова работал у меня!

ОБНОВЛЕНИЕ:. Пока это популярный ответ, позвольте мне обновить ссылку на рабочий код. Этот сокет с поддержкой SSl factory, который поддерживает современные протоколы (TLS 1.1+), SNI и необязательно позволяет принять все сертификаты (небезопасно, игнорирует все SSL-сертификаты) или самозаверяющие сертификаты (по хэшу SHA-1).

Ответ 2

Дополнительная информация по этой проблеме http://code.google.com/p/android/issues/detail?id=10472 Это зафиксировало проблему SSL, которую мы получили для HTC Desire, когда мы обновили Android 2.2.