Revisión | 121f3e090a645baec25b19239242ab91e7617aee (tree) |
---|---|
Tiempo | 2021-11-21 21:33:54 |
Autor | dyknon <dyknon@user...> |
Commiter | dyknon |
SNI support
@@ -3,12 +3,12 @@ Date: Sun, 21 Nov 2021 18:48:30 +0900 | ||
3 | 3 | Subject: Add SNI support |
4 | 4 | |
5 | 5 | --- |
6 | - SSLBridge.cpp | 52 +++++++++++++++++++++++++++------------------------- | |
7 | - SSLBridge.hpp | 3 ++- | |
8 | - 2 files changed, 29 insertions(+), 26 deletions(-) | |
6 | + SSLBridge.cpp | 84 +++++++++++++++++++++++++++++++++++++---------------------- | |
7 | + SSLBridge.hpp | 7 ++++- | |
8 | + 2 files changed, 59 insertions(+), 32 deletions(-) | |
9 | 9 | |
10 | 10 | diff --git a/SSLBridge.cpp b/SSLBridge.cpp |
11 | -index b9259ad..832adc7 100644 | |
11 | +index b9259ad..93f2b7c 100644 | |
12 | 12 | --- a/SSLBridge.cpp |
13 | 13 | +++ b/SSLBridge.cpp |
14 | 14 | @@ -26,15 +26,13 @@ X509* SSLBridge::getServerCertificate() { |
@@ -51,42 +51,72 @@ index b9259ad..832adc7 100644 | ||
51 | 51 | SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY); |
52 | 52 | } |
53 | 53 | |
54 | -@@ -71,18 +70,30 @@ void SSLBridge::setServerName() { | |
54 | +@@ -70,32 +69,64 @@ void SSLBridge::setServerName() { | |
55 | + free(serverNameStr); | |
55 | 56 | } |
56 | 57 | |
58 | ++int SSLBridge::cert_cb(SSL *ssl, void *self){ | |
59 | ++ ((SSLBridge *)self)->setupServerCert(); | |
60 | ++ return 1; | |
61 | ++} | |
62 | ++ | |
57 | 63 | void SSLBridge::handshakeWithClient(CertificateManager &manager, bool wildcardOK) { |
64 | +- Certificate *leaf; | |
65 | +- std::list<Certificate*> *chain; | |
58 | 66 | + ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); |
59 | - Certificate *leaf; | |
60 | - std::list<Certificate*> *chain; | |
61 | - | |
62 | -+ /* Server handshake */ | |
63 | -+ if (SSL_connect(serverSession) < 0) { | |
64 | -+ Logger::logError("Error on SSL Connect."); | |
65 | -+ throw SSLConnectionError(); | |
66 | -+ } | |
67 | -+ cache->setNewSessionId(serverSession, SSL_get1_session(serverSession), | |
68 | -+ serverAddress.to_bytes().data(), | |
69 | -+ serverAddress.to_bytes().size()); | |
67 | ++ this->wildcardOK = wildcardOK; | |
68 | ++ this->certman = &manager; | |
70 | 69 | + |
71 | 70 | + /* Client handhake */ |
72 | - ip::tcp::endpoint endpoint = getRemoteEndpoint(); | |
73 | - manager.getCertificateForTarget(endpoint, wildcardOK, getServerCertificate(), &leaf, &chain); | |
71 | + | |
72 | +- ip::tcp::endpoint endpoint = getRemoteEndpoint(); | |
73 | +- manager.getCertificateForTarget(endpoint, wildcardOK, getServerCertificate(), &leaf, &chain); | |
74 | 74 | - |
75 | -+ | |
76 | - setServerName(); | |
75 | +- setServerName(); | |
77 | 76 | - |
78 | -+ | |
79 | 77 | SSL_CTX *clientContext = SSL_CTX_new(SSLv23_server_method()); |
80 | 78 | - buildClientContext(clientContext, leaf, chain); |
81 | 79 | + buildClientContext(clientContext); |
80 | ++ SSL_CTX_set_cert_cb(clientContext, SSLBridge::cert_cb, this); | |
82 | 81 | |
83 | 82 | SSL *clientSession = SSL_new(clientContext); |
84 | -+ useCertkey(clientSession, leaf, chain); | |
83 | ++ this->clientSession = clientSession; | |
85 | 84 | SSL_set_fd(clientSession, clientSocket->native_handle()); |
86 | 85 | |
87 | 86 | if (SSL_accept(clientSession) == 0) { |
88 | -@@ -93,9 +104,9 @@ void SSLBridge::handshakeWithClient(CertificateManager &manager, bool wildcardOK | |
89 | - this->clientSession = clientSession; | |
87 | + Logger::logError("SSL Accept Failed!"); | |
88 | + throw SSLConnectionError(); | |
89 | + } | |
90 | ++ setServerName(); | |
91 | ++} | |
92 | + | |
93 | +- this->clientSession = clientSession; | |
94 | ++void SSLBridge::setupServerCert(){ | |
95 | ++ ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); | |
96 | ++ ip::tcp::endpoint endpoint = getRemoteEndpoint(); | |
97 | ++ Certificate *leaf; | |
98 | ++ std::list<Certificate*> *chain; | |
99 | ++ | |
100 | ++ /* handle SNI */ | |
101 | ++ int sntype = SSL_get_servername_type(clientSession); | |
102 | ++ if(sntype == TLSEXT_NAMETYPE_host_name){ | |
103 | ++ const char *sname = SSL_get_servername(clientSession, sntype); | |
104 | ++ SSL_set_tlsext_host_name(serverSession, sname); | |
105 | ++ } | |
106 | ++ | |
107 | ++ /* Server handshake */ | |
108 | ++ if (SSL_connect(serverSession) < 0) { | |
109 | ++ Logger::logError("Error on SSL Connect."); | |
110 | ++ throw SSLConnectionError(); | |
111 | ++ } | |
112 | ++ cache->setNewSessionId(serverSession, SSL_get1_session(serverSession), | |
113 | ++ serverAddress.to_bytes().data(), | |
114 | ++ serverAddress.to_bytes().size()); | |
115 | ++ | |
116 | ++ /* Generate and set certificate */ | |
117 | ++ certman->getCertificateForTarget( | |
118 | ++ endpoint, wildcardOK, getServerCertificate(), &leaf, &chain); | |
119 | ++ useCertkey(clientSession, leaf, chain); | |
90 | 120 | } |
91 | 121 | |
92 | 122 | +/* Do not start TLS handshake: to support SNI */ |
@@ -96,7 +126,7 @@ index b9259ad..832adc7 100644 | ||
96 | 126 | ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); |
97 | 127 | SSL_CTX *serverCtx = SSL_CTX_new(SSLv23_client_method());; |
98 | 128 | SSL *serverSession = SSL_new(serverCtx);; |
99 | -@@ -112,15 +123,6 @@ void SSLBridge::handshakeWithServer() { | |
129 | +@@ -112,15 +143,6 @@ void SSLBridge::handshakeWithServer() { | |
100 | 130 | SSL_set_connect_state(serverSession); |
101 | 131 | SSL_set_fd(serverSession, serverSocket->native_handle()); |
102 | 132 | SSL_set_options(serverSession, SSL_OP_ALL); |
@@ -113,16 +143,23 @@ index b9259ad..832adc7 100644 | ||
113 | 143 | this->serverSession = serverSession; |
114 | 144 | } |
115 | 145 | diff --git a/SSLBridge.hpp b/SSLBridge.hpp |
116 | -index 753bd4e..d871c2f 100644 | |
146 | +index 753bd4e..82a44a2 100644 | |
117 | 147 | --- a/SSLBridge.hpp |
118 | 148 | +++ b/SSLBridge.hpp |
119 | -@@ -99,7 +99,8 @@ private: | |
149 | +@@ -98,10 +98,15 @@ private: | |
150 | + struct pollfd *pfds; | |
120 | 151 | std::optional<Lane> lanes[2]; |
121 | 152 | |
153 | ++ bool wildcardOK; | |
154 | ++ CertificateManager *certman; | |
122 | 155 | X509* getServerCertificate(); |
123 | 156 | - void buildClientContext(SSL_CTX *context, Certificate *leaf, std::list<Certificate*> *chain); |
124 | 157 | + void buildClientContext(SSL_CTX *context); |
125 | 158 | + void useCertkey(SSL *context, Certificate *leaf, std::list<Certificate*> *chain); |
159 | ++ void setupServerCert(); | |
126 | 160 | int forwardData(SSL *from, SSL *to); |
127 | 161 | void setServerName(); |
162 | ++ static int cert_cb(SSL *ssl, void *self); | |
163 | + | |
164 | + public: | |
128 | 165 |