Core: Socket::SSLServerNameIndicator, used in HttpRequest; fixes problems with connecting to some https server

git-svn-id: svn://ultimatepp.org/upp/trunk@10990 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2017-04-08 21:32:22 +00:00
parent 7b15d8a262
commit c9bb56577b
5 changed files with 32 additions and 4 deletions

View file

@ -446,13 +446,15 @@ void HttpRequest::Start()
p = ssl ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;
String h = use_proxy ? ssl ? ssl_proxy_host : proxy_host : host;
LLOG("Using " << (use_proxy ? "proxy " : "") << h << ":" << p);
SSLServerNameIndication(host);
StartPhase(DNS);
if(IsNull(GetTimeout()) && timeout == INT_MAX) {
if(WhenWait) {
addrinfo.Start(h, p);
while(addrinfo.InProgress()) {
Sleep(GetWaitStep());
Sleep(GetWaitStep());
WhenWait();
if(msecs(start_time) >= timeout)
break;

View file

@ -128,7 +128,7 @@ class TcpSocket : NoCopy {
One<SSL> ssl;
One<SSLInfo> sslinfo;
String cert, pkey;
String cert, pkey, sni;
bool asn1;
struct SSLImp;
@ -238,6 +238,7 @@ public:
bool IsSSL() const { return ssl; }
bool SSLHandshake();
void SSLCertificate(const String& cert, const String& pkey, bool asn1);
void SSLServerNameIndication(const String& name);
const SSLInfo *GetSSLInfo() const { return ~sslinfo; }
void Clear();

View file

@ -89,7 +89,14 @@ void TcpSocket::SSLImp::SetSSLResError(const char *context, int res)
socket.SetSockError(context);
return;
}
socket.SetSockError(context, code, GetErrorText(code));
String txt = GetErrorText(code);
int err = ERR_get_error();
if(err) {
char h[260];
ERR_error_string(err, h);
txt << "; " << h;
}
socket.SetSockError(context, code, txt);
}
bool TcpSocket::SSLImp::IsAgain(int res) const
@ -125,6 +132,13 @@ bool TcpSocket::SSLImp::Start()
SetSSLError("Start: SSL_new");
return false;
}
if(socket.sni.GetCount()) {
Buffer<char> h(socket.sni.GetCount() + 1);
strcpy(~h, ~socket.sni);
SSL_set_tlsext_host_name(ssl, h);
}
if(!SSL_set_fd(ssl, (int)socket.GetSOCKET())) {
SetSSLError("Start: SSL_set_fd");
return false;

View file

@ -961,6 +961,11 @@ void TcpSocket::SSLCertificate(const String& cert_, const String& pkey_, bool as
asn1 = asn1_;
}
void TcpSocket::SSLServerNameIndication(const String& name)
{
sni = name;
}
void TcpSocket::Clear()
{
ClearError();

View file

@ -277,12 +277,18 @@ tring][@(0.0.255) `&]_[*@3 pkey], [@(0.0.255) bool]_[*@3 asn1])&]
(Note that clients usually do not need certificates, this is
usually used on accepting sockets.)&]
[s3;%% &]
[s4; &]
[s5;:Upp`:`:TcpSocket`:`:SSLServerNameIndication`(const Upp`:`:String`&`): [@(0.0.255) v
oid]_[* SSLServerNameIndication]([@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&
]_[*@3 name])&]
[s2;%% Sets [^https`:`/`/cs`.wikipedia`.org`/wiki`/Server`_Name`_Indication^ SNI]
for SSL connection.&]
[s3;%% &]
[s4;%% &]
[s5;:TcpSocket`:`:GetSSLInfo`(`)const: [@(0.0.255) const]_[_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#SSLInfo`:`:struct^ S
SLInfo]_`*[* GetSSLInfo]()_[@(0.0.255) const]&]
[s2;%% Returns information about established (after handshake) SSL
connection or NULL if such information is not available.&]
[s2;%% &]
[s3;%% &]
[s4;%% &]
[s5;:TcpSocket`:`:Timeout`(int`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ T