1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/openssl_ssl_util.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <errno.h> 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <openssl/err.h> 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <openssl/ssl.h> 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/lazy_instance.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/location.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/values.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "crypto/openssl_util.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/net_errors.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace net { 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SslSetClearMask::SslSetClearMask() 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : set_mask(0), 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) clear_mask(0) { 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SslSetClearMask::ConfigureFlag(long flag, bool state) { 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (state ? set_mask : clear_mask) |= flag; 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Make sure we haven't got any intersection in the set & clear options. 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_EQ(0, set_mask & clear_mask) << flag << ":" << state; 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass OpenSSLNetErrorLibSingleton { 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OpenSSLNetErrorLibSingleton() { 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crypto::EnsureOpenSSLInit(); 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Allocate a new error library value for inserting net errors into 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // OpenSSL. This does not register any ERR_STRING_DATA for the errors, so 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // stringifying error codes through OpenSSL will return NULL. 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net_error_lib_ = ERR_get_next_error_library(); 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned net_error_lib() const { return net_error_lib_; } 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned net_error_lib_; 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::LazyInstance<OpenSSLNetErrorLibSingleton>::Leaky g_openssl_net_error_lib = 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LAZY_INSTANCE_INITIALIZER; 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)unsigned OpenSSLNetErrorLib() { 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return g_openssl_net_error_lib.Get().net_error_lib(); 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint MapOpenSSLErrorSSL(uint32_t error_code) { 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(ERR_LIB_SSL, ERR_GET_LIB(error_code)); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DVLOG(1) << "OpenSSL SSL error, reason: " << ERR_GET_REASON(error_code) 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << ", name: " << ERR_error_string(error_code, NULL); 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (ERR_GET_REASON(error_code)) { 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_READ_TIMEOUT_EXPIRED: 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_TIMED_OUT; 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNKNOWN_CERTIFICATE_TYPE: 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNKNOWN_CIPHER_TYPE: 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE: 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNKNOWN_PKEY_TYPE: 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNKNOWN_SSL_VERSION: 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_NOT_IMPLEMENTED; 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNSUPPORTED_SSL_VERSION: 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_NO_CIPHER_MATCH: 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_NO_SHARED_CIPHER: 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY: 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION: 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNSUPPORTED_PROTOCOL: 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE: 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE: 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED: 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED: 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN: 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_ACCESS_DENIED: 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_UNKNOWN_CA: 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_BAD_SSL_CLIENT_AUTH_CERT; 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE: 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_DECOMPRESSION_FAILURE_ALERT; 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_BAD_RECORD_MAC: 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_BAD_RECORD_MAC_ALERT; 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_DECRYPT_ERROR: 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_DECRYPT_ERROR_ALERT; 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_UNRECOGNIZED_NAME: 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_UNRECOGNIZED_NAME_ALERT; 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED: 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_UNSAFE_NEGOTIATION; 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case SSL_R_BAD_DH_P_LENGTH: 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY; 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // SSL_R_UNKNOWN_PROTOCOL is reported if premature application data is 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // received (see http://crbug.com/42538), and also if all the protocol 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // versions supported by the server were disabled in this socket instance. 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Mapped to ERR_SSL_PROTOCOL_ERROR for compatibility with other SSL sockets 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // in the former scenario. 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_UNKNOWN_PROTOCOL: 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSL_HANDSHAKE_FAILURE: 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_DECRYPTION_FAILED: 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC: 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG: 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_DIGEST_CHECK_FAILED: 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_ENCRYPTED_LENGTH_TOO_LONG: 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST: 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_EXCESSIVE_MESSAGE_SIZE: 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_EXTRA_DATA_IN_MESSAGE: 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_GOT_A_FIN_BEFORE_A_CCS: 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_INVALID_COMMAND: 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_INVALID_STATUS_RESPONSE: 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_INVALID_TICKET_KEYS_LENGTH: 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // SSL_do_handshake reports this error when the server responds to a 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // ClientHello with a fatal close_notify alert. 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_AD_REASON_OFFSET + SSL_AD_CLOSE_NOTIFY: 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE: 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(joth): SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE may be returned from the 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // server after receiving ClientHello if there's no common supported cipher. 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ideally we'd map that specific case to ERR_SSL_VERSION_OR_CIPHER_MISMATCH 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // to match the NSS implementation. See also http://goo.gl/oMtZW 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE: 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_NO_CERTIFICATE: 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER: 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_DECODE_ERROR: 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED: 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION: 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_INTERNAL_ERROR: 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_NO_RENEGOTIATION: 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_RECORD_OVERFLOW: 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_TLSV1_ALERT_USER_CANCELLED: 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_PROTOCOL_ERROR; 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_R_CERTIFICATE_VERIFY_FAILED: 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The only way that the certificate verify callback can fail is if 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the leaf certificate changed during a renegotiation. 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_SERVER_CERT_CHANGED; 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case SSL_AD_REASON_OFFSET + SSL3_AD_INAPPROPRIATE_FALLBACK: 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ERR_SSL_INAPPROPRIATE_FALLBACK; 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(WARNING) << "Unmapped error reason: " << ERR_GET_REASON(error_code); 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ERR_SSL_PROTOCOL_ERROR; 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::Value* NetLogOpenSSLErrorCallback(int net_error, 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int ssl_error, 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const OpenSSLErrorInfo& error_info, 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NetLog::LogLevel /* log_level */) { 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::DictionaryValue* dict = new base::DictionaryValue(); 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dict->SetInteger("net_error", net_error); 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dict->SetInteger("ssl_error", ssl_error); 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_info.error_code != 0) { 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dict->SetInteger("error_lib", ERR_GET_LIB(error_info.error_code)); 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dict->SetInteger("error_reason", ERR_GET_REASON(error_info.error_code)); 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_info.file != NULL) 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dict->SetString("file", error_info.file); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_info.line != 0) 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dict->SetInteger("line", error_info.line); 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return dict; 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid OpenSSLPutNetError(const tracked_objects::Location& location, int err) { 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Net error codes are negative. Encode them as positive numbers. 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch err = -err; 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (err < 0 || err > 0xfff) { 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // OpenSSL reserves 12 bits for the reason code. 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTREACHED(); 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch err = ERR_INVALID_ARGUMENT; 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ERR_put_error(OpenSSLNetErrorLib(), 0, err, 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch location.file_name(), location.line_number()); 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int MapOpenSSLError(int err, const crypto::OpenSSLErrStackTracer& tracer) { 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OpenSSLErrorInfo error_info; 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return MapOpenSSLErrorWithDetails(err, tracer, &error_info); 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint MapOpenSSLErrorWithDetails(int err, 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const crypto::OpenSSLErrStackTracer& tracer, 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OpenSSLErrorInfo* out_error_info) { 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *out_error_info = OpenSSLErrorInfo(); 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (err) { 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_ERROR_WANT_READ: 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_ERROR_WANT_WRITE: 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_IO_PENDING; 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_ERROR_SYSCALL: 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "OpenSSL SYSCALL error, earliest error code in " 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "error queue: " << ERR_peek_error() << ", errno: " 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << errno; 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ERR_FAILED; 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case SSL_ERROR_SSL: 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Walk down the error stack to find an SSL or net error. 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32_t error_code; 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const char* file; 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int line; 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch do { 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_code = ERR_get_error_line(&file, &line); 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (ERR_GET_LIB(error_code) == ERR_LIB_SSL) { 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_error_info->error_code = error_code; 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_error_info->file = file; 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_error_info->line = line; 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return MapOpenSSLErrorSSL(error_code); 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (ERR_GET_LIB(error_code) == OpenSSLNetErrorLib()) { 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_error_info->error_code = error_code; 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_error_info->file = file; 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out_error_info->line = line; 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Net error codes are negative but encoded in OpenSSL as positive 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // numbers. 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return -ERR_GET_REASON(error_code); 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } while (error_code != 0); 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ERR_FAILED; 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(joth): Implement full mapping. 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(WARNING) << "Unknown OpenSSL error " << err; 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ERR_SSL_PROTOCOL_ERROR; 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciNetLog::ParametersCallback CreateNetLogOpenSSLErrorCallback( 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int net_error, 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int ssl_error, 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const OpenSSLErrorInfo& error_info) { 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return base::Bind(&NetLogOpenSSLErrorCallback, 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net_error, ssl_error, error_info); 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace net 239