15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/metrics/histogram.h" 85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "crypto/ec_private_key.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/host_port_pair.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/channel_id_service.h" 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/ssl/ssl_config_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocket::SSLClientSocket() 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : was_npn_negotiated_(false), 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_spdy_negotiated_(false), 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated_(kProtoUnknown), 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) channel_id_sent_(false), 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signed_cert_timestamps_received_(false), 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stapled_ocsp_response_received_(false) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NextProto SSLClientSocket::NextProtoFromString( 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& proto_string) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto_string == "http1.1" || proto_string == "http/1.1") { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kProtoHTTP11; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proto_string == "spdy/2") { 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return kProtoDeprecatedSPDY2; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proto_string == "spdy/3") { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kProtoSPDY3; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (proto_string == "spdy/3.1") { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kProtoSPDY31; 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else if (proto_string == "h2-14") { 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // This is the HTTP/2 draft 14 identifier. For internal 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // consistency, HTTP/2 is named SPDY4 within Chromium. 39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return kProtoSPDY4; 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (proto_string == "quic/1+spdy/3") { 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return kProtoQUIC1SPDY3; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kProtoUnknown; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* SSLClientSocket::NextProtoToString(NextProto next_proto) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (next_proto) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kProtoHTTP11: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "http/1.1"; 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case kProtoDeprecatedSPDY2: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "spdy/2"; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kProtoSPDY3: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "spdy/3"; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kProtoSPDY31: 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "spdy/3.1"; 58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch case kProtoSPDY4: 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // This is the HTTP/2 draft 14 identifier. For internal 60a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // consistency, HTTP/2 is named SPDY4 within Chromium. 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return "h2-14"; 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case kProtoQUIC1SPDY3: 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return "quic/1+spdy/3"; 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch case kProtoUnknown: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "unknown"; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* SSLClientSocket::NextProtoStatusToString( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SSLClientSocket::NextProtoStatus status) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (status) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kNextProtoUnsupported: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "unsupported"; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kNextProtoNegotiated: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "negotiated"; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kNextProtoNoOverlap: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "no-overlap"; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocket::WasNpnNegotiated() const { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_npn_negotiated_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NextProto SSLClientSocket::GetNegotiatedProtocol() const { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return protocol_negotiated_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocket::IgnoreCertError(int error, int load_flags) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == OK || load_flags & LOAD_IGNORE_ALL_CERT_ERRORS) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == ERR_CERT_COMMON_NAME_INVALID && 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID)) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == ERR_CERT_DATE_INVALID && 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (load_flags & LOAD_IGNORE_CERT_DATE_INVALID)) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error == ERR_CERT_AUTHORITY_INVALID && 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID)) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocket::set_was_npn_negotiated(bool negotiated) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_npn_negotiated_ = negotiated; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocket::was_spdy_negotiated() const { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_spdy_negotiated_; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocket::set_was_spdy_negotiated(bool negotiated) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return was_spdy_negotiated_ = negotiated; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocket::set_protocol_negotiated(NextProto protocol_negotiated) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated_ = protocol_negotiated; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocket::WasChannelIDSent() const { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_id_sent_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocket::set_channel_id_sent(bool channel_id_sent) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_id_sent_ = channel_id_sent; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SSLClientSocket::set_signed_cert_timestamps_received( 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool signed_cert_timestamps_received) { 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) signed_cert_timestamps_received_ = signed_cert_timestamps_received; 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SSLClientSocket::set_stapled_ocsp_response_received( 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool stapled_ocsp_response_received) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stapled_ocsp_response_received_ = stapled_ocsp_response_received; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// static 1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SSLClientSocket::RecordChannelIDSupport( 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ChannelIDService* channel_id_service, 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool negotiated_channel_id, 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool channel_id_enabled, 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool supports_ecc) { 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Since this enum is used for a histogram, do not change or re-use values. 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enum { 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DISABLED = 0, 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CLIENT_ONLY = 1, 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CLIENT_AND_SERVER = 2, 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CLIENT_NO_ECC = 3, 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CLIENT_BAD_SYSTEM_TIME = 4, 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CLIENT_NO_CHANNEL_ID_SERVICE = 5, 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CHANNEL_ID_USAGE_MAX 1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } supported = DISABLED; 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (negotiated_channel_id) { 1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supported = CLIENT_AND_SERVER; 1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else if (channel_id_enabled) { 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!channel_id_service) 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) supported = CLIENT_NO_CHANNEL_ID_SERVICE; 1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else if (!supports_ecc) 1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supported = CLIENT_NO_ECC; 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else if (!channel_id_service->IsSystemTimeValid()) 1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supported = CLIENT_BAD_SYSTEM_TIME; 1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else 1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supported = CLIENT_ONLY; 1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported, 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CHANNEL_ID_USAGE_MAX); 1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// static 1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool SSLClientSocket::IsChannelIDEnabled( 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const SSLConfig& ssl_config, 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ChannelIDService* channel_id_service) { 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!ssl_config.channel_id_enabled) 1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!channel_id_service) { 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DVLOG(1) << "NULL channel_id_service_, not enabling channel ID."; 1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!crypto::ECPrivateKey::IsSupported()) { 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DVLOG(1) << "Elliptic Curve not supported, not enabling channel ID."; 1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!channel_id_service->IsSystemTimeValid()) { 1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DVLOG(1) << "System time is not within the supported range for certificate " 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "generation, not enabling channel ID."; 1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::vector<uint8_t> SSLClientSocket::SerializeNextProtos( 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<std::string>& next_protos) { 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Do a first pass to determine the total length. 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t wire_length = 0; 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (std::vector<std::string>::const_iterator i = next_protos.begin(); 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i != next_protos.end(); ++i) { 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (i->size() > 255) { 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(WARNING) << "Ignoring overlong NPN/ALPN protocol: " << *i; 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (i->size() == 0) { 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(WARNING) << "Ignoring empty NPN/ALPN protocol"; 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) wire_length += i->size(); 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) wire_length++; 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Allocate memory for the result and fill it in. 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<uint8_t> wire_protos; 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) wire_protos.reserve(wire_length); 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (std::vector<std::string>::const_iterator i = next_protos.begin(); 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i != next_protos.end(); i++) { 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (i->size() == 0 || i->size() > 255) 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) wire_protos.push_back(i->size()); 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) wire_protos.resize(wire_protos.size() + i->size()); 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) memcpy(&wire_protos[wire_protos.size() - i->size()], 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i->data(), i->size()); 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(wire_protos.size(), wire_length); 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return wire_protos; 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 236