Revision | 69e46c295fe2c9351894a375eb6c444b773b6f19 (tree) |
---|---|
Zeit | 2021-11-21 21:41:17 |
Autor | dyknon <dyknon@user...> |
Commiter | dyknon |
squash patch
@@ -1,57 +0,0 @@ | ||
1 | -From: dyknon <dyknon@users.osdn.me> | |
2 | -Date: Sat, 20 Nov 2021 20:49:46 +0900 | |
3 | -Subject: 4debug | |
4 | - | |
5 | ---- | |
6 | - certificate/AuthorityCertificateManager.cpp | 31 +++++++++++++++++++++++++++++ | |
7 | - 1 file changed, 31 insertions(+) | |
8 | - | |
9 | -diff --git a/certificate/AuthorityCertificateManager.cpp b/certificate/AuthorityCertificateManager.cpp | |
10 | -index d89dafb..4f3afa0 100644 | |
11 | ---- a/certificate/AuthorityCertificateManager.cpp | |
12 | -+++ b/certificate/AuthorityCertificateManager.cpp | |
13 | -@@ -19,6 +19,8 @@ | |
14 | - | |
15 | - #include "AuthorityCertificateManager.hpp" | |
16 | - | |
17 | -+#include <stdlib.h> | |
18 | -+#include <stdio.h> | |
19 | - | |
20 | - AuthorityCertificateManager::AuthorityCertificateManager(std::string &file, std::string &chain) { | |
21 | - path certPath(file); | |
22 | -@@ -133,6 +135,35 @@ void AuthorityCertificateManager::getCertificateForTarget(boost::asio::ip::tcp:: | |
23 | - | |
24 | - X509_sign(request, authority->getKey(), EVP_sha256()); | |
25 | - | |
26 | -+ char buf[80]; | |
27 | -+ std::string tmp_tmp("dyncert_"); | |
28 | -+ if(!X509_NAME_oneline(serverName, buf, sizeof(buf))){ | |
29 | -+ throw "TODO"; | |
30 | -+ } | |
31 | -+ std::string cert_id(buf); | |
32 | -+ std::replace_if(cert_id.begin(), cert_id.end(), | |
33 | -+ [](char c){ | |
34 | -+ return !('0' <= c && c <= '9' | |
35 | -+ || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' | |
36 | -+ || c == '.' || c == '-'); | |
37 | -+ }, | |
38 | -+ '_'); | |
39 | -+ tmp_tmp += cert_id; | |
40 | -+ tmp_tmp += "_XXXXXX"; | |
41 | -+ int cert_fd = mkstemp(tmp_tmp.data()); | |
42 | -+ if(cert_fd < 0){ | |
43 | -+ throw "TODO"; | |
44 | -+ } | |
45 | -+ FILE *cert_f = fdopen(cert_fd, "w"); | |
46 | -+ if(!cert_f){ | |
47 | -+ throw "TODO"; | |
48 | -+ } | |
49 | -+ if(!PEM_write_X509(cert_f, request)){ | |
50 | -+ unsigned long err = ERR_get_error(); | |
51 | -+ throw "TODO"; | |
52 | -+ } | |
53 | -+ fclose(cert_f); | |
54 | -+ | |
55 | - Certificate *leaf = new Certificate(); | |
56 | - leaf->setCert(request); | |
57 | - leaf->setKey(this->leafPair); |
@@ -1,165 +0,0 @@ | ||
1 | -From: dyknon <dyknon@users.osdn.me> | |
2 | -Date: Sun, 21 Nov 2021 18:48:30 +0900 | |
3 | -Subject: Add SNI support | |
4 | - | |
5 | ---- | |
6 | - SSLBridge.cpp | 84 +++++++++++++++++++++++++++++++++++++---------------------- | |
7 | - SSLBridge.hpp | 7 ++++- | |
8 | - 2 files changed, 59 insertions(+), 32 deletions(-) | |
9 | - | |
10 | -diff --git a/SSLBridge.cpp b/SSLBridge.cpp | |
11 | -index b9259ad..93f2b7c 100644 | |
12 | ---- a/SSLBridge.cpp | |
13 | -+++ b/SSLBridge.cpp | |
14 | -@@ -26,15 +26,13 @@ X509* SSLBridge::getServerCertificate() { | |
15 | - return SSL_get_peer_certificate(serverSession); | |
16 | - } | |
17 | - | |
18 | --void SSLBridge::buildClientContext(SSL_CTX *context, Certificate *leaf, std::list<Certificate*> *chain) { | |
19 | -+void SSLBridge::useCertkey( | |
20 | -+ SSL *ssl, Certificate *leaf, std::list<Certificate*> *chain | |
21 | -+){ | |
22 | -+ SSL_use_certificate(ssl, leaf->getCert()); | |
23 | -+ SSL_use_PrivateKey(ssl, leaf->getKey()); | |
24 | - | |
25 | -- SSL_CTX_sess_set_new_cb(context, &SessionCache::setNewSessionIdTramp); | |
26 | -- SSL_CTX_sess_set_get_cb(context, &SessionCache::getSessionIdTramp); | |
27 | -- | |
28 | -- SSL_CTX_use_certificate(context, leaf->getCert()); | |
29 | -- SSL_CTX_use_PrivateKey(context, leaf->getKey()); | |
30 | -- | |
31 | -- if (SSL_CTX_check_private_key(context) == 0) { | |
32 | -+ if (SSL_check_private_key(ssl) == 0) { | |
33 | - std::cerr << "*** Assertion Failed - Generated PrivateKey Doesn't Work." << std::endl; | |
34 | - throw SSLConnectionError(); | |
35 | - } | |
36 | -@@ -43,12 +41,13 @@ void SSLBridge::buildClientContext(SSL_CTX *context, Certificate *leaf, std::lis | |
37 | - std::list<Certificate*>::iterator end = chain->end(); | |
38 | - | |
39 | - for (;i != end; i++) { | |
40 | -- SSL_CTX_add_extra_chain_cert(context, (*i)->getCert()); | |
41 | -+ SSL_add1_chain_cert(ssl, (*i)->getCert()); | |
42 | - } | |
43 | -+} | |
44 | - | |
45 | -- // if (chain != NULL) | |
46 | -- // SSL_CTX_add_extra_chain_cert(context, chain->getCert()); | |
47 | -- | |
48 | -+void SSLBridge::buildClientContext(SSL_CTX *context) { | |
49 | -+ SSL_CTX_sess_set_new_cb(context, &SessionCache::setNewSessionIdTramp); | |
50 | -+ SSL_CTX_sess_set_get_cb(context, &SessionCache::getSessionIdTramp); | |
51 | - SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY); | |
52 | - } | |
53 | - | |
54 | -@@ -70,32 +69,64 @@ void SSLBridge::setServerName() { | |
55 | - free(serverNameStr); | |
56 | - } | |
57 | - | |
58 | -+int SSLBridge::cert_cb(SSL *ssl, void *self){ | |
59 | -+ ((SSLBridge *)self)->setupServerCert(); | |
60 | -+ return 1; | |
61 | -+} | |
62 | -+ | |
63 | - void SSLBridge::handshakeWithClient(CertificateManager &manager, bool wildcardOK) { | |
64 | -- Certificate *leaf; | |
65 | -- std::list<Certificate*> *chain; | |
66 | -+ ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); | |
67 | -+ this->wildcardOK = wildcardOK; | |
68 | -+ this->certman = &manager; | |
69 | -+ | |
70 | -+ /* Client handhake */ | |
71 | - | |
72 | -- ip::tcp::endpoint endpoint = getRemoteEndpoint(); | |
73 | -- manager.getCertificateForTarget(endpoint, wildcardOK, getServerCertificate(), &leaf, &chain); | |
74 | -- | |
75 | -- setServerName(); | |
76 | -- | |
77 | - SSL_CTX *clientContext = SSL_CTX_new(SSLv23_server_method()); | |
78 | -- buildClientContext(clientContext, leaf, chain); | |
79 | -+ buildClientContext(clientContext); | |
80 | -+ SSL_CTX_set_cert_cb(clientContext, SSLBridge::cert_cb, this); | |
81 | - | |
82 | - SSL *clientSession = SSL_new(clientContext); | |
83 | -+ this->clientSession = clientSession; | |
84 | - SSL_set_fd(clientSession, clientSocket->native_handle()); | |
85 | - | |
86 | - if (SSL_accept(clientSession) == 0) { | |
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); | |
120 | - } | |
121 | - | |
122 | -+/* Do not start TLS handshake: to support SNI */ | |
123 | - void SSLBridge::handshakeWithServer() { | |
124 | - int bogus; | |
125 | -- | |
126 | - ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); | |
127 | - SSL_CTX *serverCtx = SSL_CTX_new(SSLv23_client_method());; | |
128 | - SSL *serverSession = SSL_new(serverCtx);; | |
129 | -@@ -112,15 +143,6 @@ void SSLBridge::handshakeWithServer() { | |
130 | - SSL_set_connect_state(serverSession); | |
131 | - SSL_set_fd(serverSession, serverSocket->native_handle()); | |
132 | - SSL_set_options(serverSession, SSL_OP_ALL); | |
133 | -- | |
134 | -- if (SSL_connect(serverSession) < 0) { | |
135 | -- Logger::logError("Error on SSL Connect."); | |
136 | -- throw SSLConnectionError(); | |
137 | -- } | |
138 | -- | |
139 | -- cache->setNewSessionId(serverSession, SSL_get1_session(serverSession), | |
140 | -- serverAddress.to_bytes().data(), | |
141 | -- serverAddress.to_bytes().size()); | |
142 | - | |
143 | - this->serverSession = serverSession; | |
144 | - } | |
145 | -diff --git a/SSLBridge.hpp b/SSLBridge.hpp | |
146 | -index 753bd4e..82a44a2 100644 | |
147 | ---- a/SSLBridge.hpp | |
148 | -+++ b/SSLBridge.hpp | |
149 | -@@ -98,10 +98,15 @@ private: | |
150 | - struct pollfd *pfds; | |
151 | - std::optional<Lane> lanes[2]; | |
152 | - | |
153 | -+ bool wildcardOK; | |
154 | -+ CertificateManager *certman; | |
155 | - X509* getServerCertificate(); | |
156 | -- void buildClientContext(SSL_CTX *context, Certificate *leaf, std::list<Certificate*> *chain); | |
157 | -+ void buildClientContext(SSL_CTX *context); | |
158 | -+ void useCertkey(SSL *context, Certificate *leaf, std::list<Certificate*> *chain); | |
159 | -+ void setupServerCert(); | |
160 | - int forwardData(SSL *from, SSL *to); | |
161 | - void setServerName(); | |
162 | -+ static int cert_cb(SSL *ssl, void *self); | |
163 | - | |
164 | - public: | |
165 | - |
@@ -3,16 +3,16 @@ Date: Sat, 20 Nov 2021 18:09:30 +0900 | ||
3 | 3 | Subject: all fixs |
4 | 4 | |
5 | 5 | --- |
6 | - HTTPSBridge.cpp | 32 ++---- | |
6 | + HTTPSBridge.cpp | 32 ++-- | |
7 | 7 | HTTPSBridge.hpp | 3 +- |
8 | 8 | Logger.cpp | 4 +- |
9 | 9 | Logger.hpp | 4 +- |
10 | - SSLBridge.cpp | 159 +++++++++++++++++++++------- | |
11 | - SSLBridge.hpp | 30 +++++- | |
10 | + SSLBridge.cpp | 243 +++++++++++++++++++--------- | |
11 | + SSLBridge.hpp | 37 ++++- | |
12 | 12 | UpdateManager.cpp | 2 +- |
13 | - certificate/AuthorityCertificateManager.cpp | 78 ++++++++++++-- | |
13 | + certificate/AuthorityCertificateManager.cpp | 78 ++++++++- | |
14 | 14 | certificate/AuthorityCertificateManager.hpp | 2 +- |
15 | - 9 files changed, 233 insertions(+), 81 deletions(-) | |
15 | + 9 files changed, 292 insertions(+), 113 deletions(-) | |
16 | 16 | |
17 | 17 | diff --git a/HTTPSBridge.cpp b/HTTPSBridge.cpp |
18 | 18 | index 79e2458..6dc1e87 100644 |
@@ -106,10 +106,139 @@ index a6ee1d0..8fd04b9 100644 | ||
106 | 106 | static void logError(std::string error); |
107 | 107 | static void logUpdateRequest(std::string &product, std::string &version, |
108 | 108 | diff --git a/SSLBridge.cpp b/SSLBridge.cpp |
109 | -index 4cb3e0f..b9259ad 100644 | |
109 | +index 4cb3e0f..93f2b7c 100644 | |
110 | 110 | --- a/SSLBridge.cpp |
111 | 111 | +++ b/SSLBridge.cpp |
112 | -@@ -126,62 +126,139 @@ void SSLBridge::handshakeWithServer() { | |
112 | +@@ -26,15 +26,13 @@ X509* SSLBridge::getServerCertificate() { | |
113 | + return SSL_get_peer_certificate(serverSession); | |
114 | + } | |
115 | + | |
116 | +-void SSLBridge::buildClientContext(SSL_CTX *context, Certificate *leaf, std::list<Certificate*> *chain) { | |
117 | ++void SSLBridge::useCertkey( | |
118 | ++ SSL *ssl, Certificate *leaf, std::list<Certificate*> *chain | |
119 | ++){ | |
120 | ++ SSL_use_certificate(ssl, leaf->getCert()); | |
121 | ++ SSL_use_PrivateKey(ssl, leaf->getKey()); | |
122 | + | |
123 | +- SSL_CTX_sess_set_new_cb(context, &SessionCache::setNewSessionIdTramp); | |
124 | +- SSL_CTX_sess_set_get_cb(context, &SessionCache::getSessionIdTramp); | |
125 | +- | |
126 | +- SSL_CTX_use_certificate(context, leaf->getCert()); | |
127 | +- SSL_CTX_use_PrivateKey(context, leaf->getKey()); | |
128 | +- | |
129 | +- if (SSL_CTX_check_private_key(context) == 0) { | |
130 | ++ if (SSL_check_private_key(ssl) == 0) { | |
131 | + std::cerr << "*** Assertion Failed - Generated PrivateKey Doesn't Work." << std::endl; | |
132 | + throw SSLConnectionError(); | |
133 | + } | |
134 | +@@ -43,12 +41,13 @@ void SSLBridge::buildClientContext(SSL_CTX *context, Certificate *leaf, std::lis | |
135 | + std::list<Certificate*>::iterator end = chain->end(); | |
136 | + | |
137 | + for (;i != end; i++) { | |
138 | +- SSL_CTX_add_extra_chain_cert(context, (*i)->getCert()); | |
139 | ++ SSL_add1_chain_cert(ssl, (*i)->getCert()); | |
140 | + } | |
141 | ++} | |
142 | + | |
143 | +- // if (chain != NULL) | |
144 | +- // SSL_CTX_add_extra_chain_cert(context, chain->getCert()); | |
145 | +- | |
146 | ++void SSLBridge::buildClientContext(SSL_CTX *context) { | |
147 | ++ SSL_CTX_sess_set_new_cb(context, &SessionCache::setNewSessionIdTramp); | |
148 | ++ SSL_CTX_sess_set_get_cb(context, &SessionCache::getSessionIdTramp); | |
149 | + SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY); | |
150 | + } | |
151 | + | |
152 | +@@ -70,32 +69,64 @@ void SSLBridge::setServerName() { | |
153 | + free(serverNameStr); | |
154 | + } | |
155 | + | |
156 | ++int SSLBridge::cert_cb(SSL *ssl, void *self){ | |
157 | ++ ((SSLBridge *)self)->setupServerCert(); | |
158 | ++ return 1; | |
159 | ++} | |
160 | ++ | |
161 | + void SSLBridge::handshakeWithClient(CertificateManager &manager, bool wildcardOK) { | |
162 | +- Certificate *leaf; | |
163 | +- std::list<Certificate*> *chain; | |
164 | ++ ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); | |
165 | ++ this->wildcardOK = wildcardOK; | |
166 | ++ this->certman = &manager; | |
167 | ++ | |
168 | ++ /* Client handhake */ | |
169 | + | |
170 | +- ip::tcp::endpoint endpoint = getRemoteEndpoint(); | |
171 | +- manager.getCertificateForTarget(endpoint, wildcardOK, getServerCertificate(), &leaf, &chain); | |
172 | +- | |
173 | +- setServerName(); | |
174 | +- | |
175 | + SSL_CTX *clientContext = SSL_CTX_new(SSLv23_server_method()); | |
176 | +- buildClientContext(clientContext, leaf, chain); | |
177 | ++ buildClientContext(clientContext); | |
178 | ++ SSL_CTX_set_cert_cb(clientContext, SSLBridge::cert_cb, this); | |
179 | + | |
180 | + SSL *clientSession = SSL_new(clientContext); | |
181 | ++ this->clientSession = clientSession; | |
182 | + SSL_set_fd(clientSession, clientSocket->native_handle()); | |
183 | + | |
184 | + if (SSL_accept(clientSession) == 0) { | |
185 | + Logger::logError("SSL Accept Failed!"); | |
186 | + throw SSLConnectionError(); | |
187 | + } | |
188 | ++ setServerName(); | |
189 | ++} | |
190 | + | |
191 | +- this->clientSession = clientSession; | |
192 | ++void SSLBridge::setupServerCert(){ | |
193 | ++ ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); | |
194 | ++ ip::tcp::endpoint endpoint = getRemoteEndpoint(); | |
195 | ++ Certificate *leaf; | |
196 | ++ std::list<Certificate*> *chain; | |
197 | ++ | |
198 | ++ /* handle SNI */ | |
199 | ++ int sntype = SSL_get_servername_type(clientSession); | |
200 | ++ if(sntype == TLSEXT_NAMETYPE_host_name){ | |
201 | ++ const char *sname = SSL_get_servername(clientSession, sntype); | |
202 | ++ SSL_set_tlsext_host_name(serverSession, sname); | |
203 | ++ } | |
204 | ++ | |
205 | ++ /* Server handshake */ | |
206 | ++ if (SSL_connect(serverSession) < 0) { | |
207 | ++ Logger::logError("Error on SSL Connect."); | |
208 | ++ throw SSLConnectionError(); | |
209 | ++ } | |
210 | ++ cache->setNewSessionId(serverSession, SSL_get1_session(serverSession), | |
211 | ++ serverAddress.to_bytes().data(), | |
212 | ++ serverAddress.to_bytes().size()); | |
213 | ++ | |
214 | ++ /* Generate and set certificate */ | |
215 | ++ certman->getCertificateForTarget( | |
216 | ++ endpoint, wildcardOK, getServerCertificate(), &leaf, &chain); | |
217 | ++ useCertkey(clientSession, leaf, chain); | |
218 | + } | |
219 | + | |
220 | ++/* Do not start TLS handshake: to support SNI */ | |
221 | + void SSLBridge::handshakeWithServer() { | |
222 | + int bogus; | |
223 | +- | |
224 | + ip::address_v4 serverAddress = serverSocket->remote_endpoint().address().to_v4(); | |
225 | + SSL_CTX *serverCtx = SSL_CTX_new(SSLv23_client_method());; | |
226 | + SSL *serverSession = SSL_new(serverCtx);; | |
227 | +@@ -112,76 +143,144 @@ void SSLBridge::handshakeWithServer() { | |
228 | + SSL_set_connect_state(serverSession); | |
229 | + SSL_set_fd(serverSession, serverSocket->native_handle()); | |
230 | + SSL_set_options(serverSession, SSL_OP_ALL); | |
231 | +- | |
232 | +- if (SSL_connect(serverSession) < 0) { | |
233 | +- Logger::logError("Error on SSL Connect."); | |
234 | +- throw SSLConnectionError(); | |
235 | +- } | |
236 | +- | |
237 | +- cache->setNewSessionId(serverSession, SSL_get1_session(serverSession), | |
238 | +- serverAddress.to_bytes().data(), | |
239 | +- serverAddress.to_bytes().size()); | |
240 | + | |
241 | + this->serverSession = serverSession; | |
113 | 242 | } |
114 | 243 | |
115 | 244 | void SSLBridge::shuttleData() { |
@@ -291,7 +420,7 @@ index 4cb3e0f..b9259ad 100644 | ||
291 | 420 | |
292 | 421 | void SSLBridge::close() { |
293 | 422 | diff --git a/SSLBridge.hpp b/SSLBridge.hpp |
294 | -index 0feb9c0..753bd4e 100644 | |
423 | +index 0feb9c0..82a44a2 100644 | |
295 | 424 | --- a/SSLBridge.hpp |
296 | 425 | +++ b/SSLBridge.hpp |
297 | 426 | @@ -36,6 +36,9 @@ |
@@ -331,7 +460,7 @@ index 0feb9c0..753bd4e 100644 | ||
331 | 460 | |
332 | 461 | protected: |
333 | 462 | boost::shared_ptr<ip::tcp::socket> clientSocket; |
334 | -@@ -67,17 +90,18 @@ protected: | |
463 | +@@ -67,17 +90,23 @@ protected: | |
335 | 464 | |
336 | 465 | virtual ip::tcp::endpoint getRemoteEndpoint(); |
337 | 466 | virtual bool readFromClient(); |
@@ -343,13 +472,19 @@ index 0feb9c0..753bd4e 100644 | ||
343 | 472 | + struct pollfd *pfds; |
344 | 473 | + std::optional<Lane> lanes[2]; |
345 | 474 | + |
475 | ++ bool wildcardOK; | |
476 | ++ CertificateManager *certman; | |
346 | 477 | X509* getServerCertificate(); |
347 | - void buildClientContext(SSL_CTX *context, Certificate *leaf, std::list<Certificate*> *chain); | |
478 | +- void buildClientContext(SSL_CTX *context, Certificate *leaf, std::list<Certificate*> *chain); | |
348 | 479 | - int isAvailable(int revents); |
349 | 480 | - int isClosed(int revents); |
481 | ++ void buildClientContext(SSL_CTX *context); | |
482 | ++ void useCertkey(SSL *context, Certificate *leaf, std::list<Certificate*> *chain); | |
483 | ++ void setupServerCert(); | |
350 | 484 | int forwardData(SSL *from, SSL *to); |
351 | 485 | void setServerName(); |
352 | 486 | - bool readFromServer(); |
487 | ++ static int cert_cb(SSL *ssl, void *self); | |
353 | 488 | |
354 | 489 | public: |
355 | 490 |
@@ -6,5 +6,3 @@ boost-1.67.patch | ||
6 | 6 | Fix-FTBFS-with-Boost-1.71.patch |
7 | 7 | fix_FTBFS_boost174.patch |
8 | 8 | all-fixs.patch |
9 | -4debug.patch | |
10 | -Add-SNI-support.patch |