Android SSL Error Handshake Failed - android

I have an android application that works on my home network and does not have these handshake errors. However when sending this app over to my client and testing it through their wifi network I get these logs.
E/chromium(15135): external/chromium/net/socket/ssl_client_socket_openssl.cc:792: [1211/175912:ERROR:ssl_client_socket_openssl.cc(792)] handshake failed; returned 0, SSL error code 5, net_error -107
W/chromium(15135): external/chromium/net/http/http_stream_factory_impl_job.cc:865: [1211/175912:WARNING:http_stream_factory_impl_job.cc(865)] Falling back to SSLv3 because host is TLS intolerant:
I have https URLS loaded in an android webview inside my application. I have no other information aside from these errors. Do you guys have any idea why this happens on a specific network, I am really out of ideas right now.

Recently I occurred a similar error during my test on connecting the specific server:
handshake failed; returned -1, SSL error code 1, net_error -103
I find some useful reason by searching from chromium source code,which indicates the meaning of ret code.Maybe it can help you find the reason.
SSL error code 5:
chromium//src/third_party/boringssl/src/include/openssl/ssl.h
/*
SSL_ERROR_SYSCALL indicates the operation failed externally to the library.
The caller should consult the system-specific error mechanism. This is
typically |errno| but may be something custom if using a custom |BIO|. It
may also be signaled if the transport returned EOF, in which case the
operation's return value will be zero.
*/
define SSL_ERROR_SYSCALL 5
net_error -107
// An SSL protocol error occurred.
NET_ERROR(SSL_PROTOCOL_ERROR, -107)
if you want to find more detail,the main function which print this log as below:
chromium//src/net/socket/ssl_server_socket_impl.cc
int SSLServerSocketImpl::DoHandshake() {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
int net_error = OK;
int rv = SSL_do_handshake(ssl_.get());
if (rv == 1) {
completed_handshake_ = true;
// The results of SSL_get_peer_certificate() must be explicitly freed.
bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl_.get()));
if (cert) {
// The caller does not take ownership of SSL_get_peer_cert_chain's
// results.
STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl_.get());
client_cert_ = CreateX509Certificate(cert.get(), chain);
if (!client_cert_.get())
return ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT;
}
} else {
int ssl_error = SSL_get_error(ssl_.get(), rv);
OpenSSLErrorInfo error_info;
net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer,
&error_info);
// SSL_R_CERTIFICATE_VERIFY_FAILED's mapping is different between client and
// server.
if (ERR_GET_LIB(error_info.error_code) == ERR_LIB_SSL &&
ERR_GET_REASON(error_info.error_code) ==
SSL_R_CERTIFICATE_VERIFY_FAILED) {
net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
}
// If not done, stay in this state
if (net_error == ERR_IO_PENDING) {
GotoState(STATE_HANDSHAKE);
} else {
LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code "
<< ssl_error << ", net_error " << net_error;
net_log_.AddEvent(
NetLogEventType::SSL_HANDSHAKE_ERROR,
CreateNetLogOpenSSLErrorCallback(net_error, ssl_error,
error_info));
}
}
return net_error;
}

Related

How to fix ExoPlayer error 'native window cannot handle protected buffers'

I keep getting an error when pausing ExoPlayer and putting my app in the background. The stream contains Widevine protected content and ads that are inserted on the server side.
I suspect this mixture of protected and unprotected content to be causing the error but have no idea where to start. Putting the app in the background and resuming it actually works once during the unprotected preroll ad but fails when trying it a second time in the main content.
SurfaceUtils logs the following message: native window cannot handle protected buffers: the consumer should either be a hardware composer or support hardware protection.
Does someone know what this actually means? Unfortunately I am not too familiar with the inner workings of ExoPlayer.
The code in SurfaceUtils.cpp that returns the error might be helpful here:
// Make sure to check whether either Stagefright or the video decoder
// requested protected buffers.
if (usage & GRALLOC_USAGE_PROTECTED) {
// Check if the ANativeWindow sends images directly to SurfaceFlinger.
int queuesToNativeWindow = 0;
err = nativeWindow->query(
nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &queuesToNativeWindow);
if (err != NO_ERROR) {
ALOGE("error authenticating native window: %s (%d)", strerror(-err), -err);
return err;
}
// Check if the consumer end of the ANativeWindow can handle protected content.
int isConsumerProtected = 0;
err = nativeWindow->query(
nativeWindow, NATIVE_WINDOW_CONSUMER_IS_PROTECTED, &isConsumerProtected);
if (err != NO_ERROR) {
ALOGE("error query native window: %s (%d)", strerror(-err), -err);
return err;
}
// Deny queuing into native window if neither condition is satisfied.
if (queuesToNativeWindow != 1 && isConsumerProtected != 1) {
ALOGE("native window cannot handle protected buffers: the consumer should either be a hardware composer or support hardware protection");
return PERMISSION_DENIED;
}
}

No response to UnityWebRequest on build to http server

I've got an Android app I'm building with Unity that logs info on a simple python http server (hosted on a Digital Ocean Droplet). Here's my coroutine for poking the server:
IEnumerator pokeServer()
{
Debug.Log( "Establishing Server Connectivity..." );
using( var www = UnityWebRequest.Get( ServerURL ) )
{
Debug.Log( "Send Web Request" );
ServerStatus = ConnectionStatuses.AttemptingToConnect;
yield return www.SendWebRequest();
if( www.isNetworkError || www.isHttpError )
{
if( www.isNetworkError )
{
Debug.Log( "NETWORK ERROR: " + www );
}
else
{
Debug.Log( "HTTP ERROR: " + www );
}
ServerStatus = ConnectionStatuses.Unavailable;
}
else
{
Debug.Log( "Success! Server available!" );
ServerStatus = ConnectionStatuses.Connected;
}
}
}
If I run this on the Unity Editor, everything works fine. I can get a response from my server without issue. If I build and run this on an Android, the request is not sent to my server and I get no error message. The last line in the above code that's run is "yield return www.SendWebRequest();"
I've looked at the logcat, and there's no error. My server never gets any requests. However, if I poke "https://www.google.com," I do indeed get a response. This leads me to believe that this is some sort of http vs https issue, but I have no idea where to start. This code has been working for me for a very long time. Any advice would be very welcome!
I'd been using this phone from University of Pennsylvania's wireless network. It turns out that I can make an http request from a desktop but I can't do it from a phone. I took one of the devices home and tried it from my personal wifi and it all worked fine.

Android https request, ssl protocol failed

Background
SSLv3 protocol is insecure,after i read some articles, i use this solution to remove this protocol.
The method remove sslv3:
#Override
public void setEnabledProtocols(String[] protocols) {
if (protocols != null && protocols.length == 1 && "SSLv3".equals(protocols[0])) {
// no way jose
// see issue https://code.google.com/p/android/issues/detail?id=78187
List<String> enabledProtocols = new ArrayList<String>(Arrays.asList(delegate.getEnabledProtocols()));
for (String pro : enabledProtocols) {
VolleyLog.d(pro);
}
if (enabledProtocols.size() > 1) {
enabledProtocols.remove("SSLv3");
VolleyLog.d("Removed SSLv3 from enabled protocols");
} else {
VolleyLog.d("SSL stuck with protocol available for " + String.valueOf(enabledProtocols));
}
protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]);
}
super.setEnabledProtocols(protocols);
}
I use Volley as http client, here is my code to initialize a requestqueue:
HttpStack stack;
if (Build.VERSION.SDK_INT >= 9) {
// Use a socket factory that removes sslv3
// https://code.google.com/p/android/issues/detail?id=78187
stack = new HurlStack(null, new NoSSLv3Compat.NoSSLv3Factory());
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
Device and Environment
I am using Xiaomi M3 with MIUI ROM, which is based on Android 4.4.4.
When the setEnabledProtocols method is called, i print some log:
D/Volley: [1444] NoSSLv3SSLSocket.setEnabledProtocols: SSLv3
D/Volley: [1444] NoSSLv3SSLSocket.setEnabledProtocols: TLSv1
D/Volley: [1444] NoSSLv3SSLSocket.setEnabledProtocols: Removed SSLv3 from enabled protocols
Problem
When i try to load this image, failed, output:
NoConnectionError: javax.net.ssl.SSLHandshakeException:
javax.net.ssl.SSLProtocolException: SSL handshake terminated:
ssl=0x77f49768: Failure in SSL library, usually a protocol error
E/CachedHttp: error:1409443E:SSL routines:SSL3_READ_BYTES:tlsv1 alert
inappropriate fallback (external/openssl/ssl/s3_pkt.c:1256
0x77f4c280:0x00000003)
this image server supports the following protocols:
TLS 1.2、 TLS 1.1、 TLS 1.0、 SSL 3
Could you please help me to figure it out?
Did you check the size of keys. Enable debug log to see the exact issue. Probably is being caused by insufficient key size by the backend you are trying to connect to.
Enable JCE Unlimited for java 7
Identify handshake errors

How should GATT_CMD_STARTED (status=134) be interpreted?

I'm working on an android app where I need to communicate with a bluetooth LE device and in the middle of the communication I receive a callback:
onCharacteristicWrite()
...which is expected. But the status of the operation is 134 instead of 0 (=success).
This GATT status constant is not defined in the official API but here is a translation in one of many unofficial lists:
public static final int GATT_CMD_STARTED = 134;
See: https://code.google.com/r/naranjomanuel-opensource-broadcom-ble/source/browse/framework/java/src/com/broadcom/bt/service/gatt/GattConstants.java?r=983950f9b35407446bf082633d70c7655c206d22
The consequence, that I can see, in my app is that I do not get an expected callback to:
onCharacteristicChanged()
Does anybody know what GATT_CMD_STARTED means? Is it an error?
The description of the following function taken from the bludroid sources hint that something is not working correctly in your GATT server.
Commands seem to "queue up" there, as there must be pending requests or value confirmations as hinted in the comment before the if(...) clause.
It might be worth checking what exactly is going on before you do the writeCharacteristic(...) as it seems to not finish correctly or create hiccups in your server.
/*******************************************************************************
**
** Function attp_cl_send_cmd
**
** Description Send a ATT command or enqueue it.
**
** Returns GATT_SUCCESS if command sent
** GATT_CONGESTED if command sent but channel congested
** GATT_CMD_STARTED if command queue up in GATT
** GATT_ERROR if command sending failure
**
*******************************************************************************/
tGATT_STATUS attp_cl_send_cmd(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 cmd_code, BT_HDR *p_cmd)
{
tGATT_STATUS att_ret = GATT_SUCCESS;
if (p_tcb != NULL)
{
cmd_code &= ~GATT_AUTH_SIGN_MASK;
/* no pending request or value confirmation */
if (p_tcb->pending_cl_req == p_tcb->next_slot_inq ||
cmd_code == GATT_HANDLE_VALUE_CONF)
{
att_ret = attp_send_msg_to_l2cap(p_tcb, p_cmd);
if (att_ret == GATT_CONGESTED || att_ret == GATT_SUCCESS)
{
/* do not enq cmd if handle value confirmation or set request */
if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE)
{
gatt_start_rsp_timer (clcb_idx);
gatt_cmd_enq(p_tcb, clcb_idx, FALSE, cmd_code, NULL);
}
}
else
att_ret = GATT_INTERNAL_ERROR;
}
else
{
att_ret = GATT_CMD_STARTED;
gatt_cmd_enq(p_tcb, clcb_idx, TRUE, cmd_code, p_cmd);
}
}
else
att_ret = GATT_ERROR;
return att_ret;
}
Starts at line 469 in android sources.
The native GATT error and statuscodes can be found here.

How to implement GCM HTTP server in Python while avoiding my server's IP being blacklisted by Google?

I'm using Apache, WSGI (mod_wsgi) and Python, to implement a GCM HTTP server as describe in the Android Developer website:
developer.android.com/google/gcm/server.html
At first the code I've implemented on the server side to handle message sending to GCM was as the following:
def send_to_gcm(data):
url = 'https://android.googleapis.com/gcm/send'
no = 1
while True:
try:
request = Request(url=url, data=json.dumps(data))
request.add_header('Authorization','key=AIzXXX')
request.add_header('Content-Type', 'application/json')
res = urlopen(request)
if res.getcode() == 200: return
except Exception: pass
no += 1
#Discard the message
if no == 16: return
#Exponential backoff
tts = randint(2**(no-1), (2**no) -1)
sleep(tts)
data = dict(registration_id=[regid], data=dict(mymessage=themessage))
thread = Thread(target=send_to_gcm, args=(data,))
thread.start()
After a while (about a day) GCM stopped to accept the messages sent by the Server. So I started to dig here and there in the documentation of GCM and I found an important part of the specification I missed before:
developer.android.com/google/gcm/http.html#response
"Honor the Retry-After header if it's included in the response from the GCM server. ... Senders that cause problems risk being blacklisted. ... Happens when the HTTP status code is between 501 and 599, or when the error field of a JSON object in the results array is Unavailable."
So i patched my server code as follow:
def send_to_gcm(data, environ):
url = 'https://android.googleapis.com/gcm/send'
no = 1
while True:
try:
request = Request(url=url, data=json.dumps(data))
request.add_header('Authorization','key=AIzXXX')
request.add_header('Content-Type', 'application/json')
res = urlopen(request)
if res.getcode() == 200: return
except HTTPError as error:
if error.headers.has_key('Retry-After'):
try: tts = int(response_headers['Retry-After'])
except ValueError:
until = datetime.strptime(response_headers, '%a, %d %b %Y %H:%M:%S GMT')
diff = until - datetime.now()
tts = int(diff.total_seconds()) +1
sleep(tts)
no += 1
#Discard the message
if no == 16: return
#Exponential backoff
tts = randint(2**(no-1), (2**no) -1)
sleep(tts)
But actually it's likely my server has been blacklisted and for any request sent I receive a 401 status code and an "Unauthorized" error message. Here my questions:
Is there something wrong in my latest server implementation?
Will the static IP address of my server be unbanned and if yes when?
I was searching for the same subject.
This module may help you
https://github.com/geeknam/python-gcm

Categories

Resources