opensslshiy流程:
1.初始化; SSLv23_client_method();创建SSL上下文环境 SSL_CTX_new ()
2.创建socket,connect;校验证书;
3.socket绑定SSL:SSL_new,SSL_connect;
4.校验服务器证书;
5.SSL_write,SSL_read;
6.释放资源 SSL_shutdown等;
view source
print?
001 openssl
002 //author:jordan.sg QQ:87895224
003 //2012.7
004 //初始化部分
005 SSL_library_init();
006 SSL_load_error_strings();
007 SSLeay_add_ssl_algorithms();
008
009 //校验服务器
010 bool CWorker::verifyServer(APP_SERVER *ptserver)
011 {
012 /* Following two steps are optional and not required for
013 data exchange to be successful. */
014
015 /* Set for server verification*/
016 SSL_CTX_set_verify(ptserver->psslctx,SSL_VERIFY_PEER,NULL);
017
018 /* Get the cipher – opt */
019 #ifdef _DEBUG
020 LogExt(LOG_LOG_LEVEL,”SSL connection using %s\n”, SSL_get_cipher(ptserver->ssl));
021 #endif
022 /* Get server’s certificate (note: beware of dynamic allocation) – opt */
023
024 ptserver->server_cert = SSL_get_peer_certificate (ptserver->ssl);
025 if (!ptserver->server_cert)
026 {
027 writelogimmediatly(“[exception]SSL_get_peer_certificate \n”);
028 setallthreadexitflag();
029 return false;
030 }
031 #ifdef _DEBUG
032 LogExt(LOG_LOG_LEVEL,”Server certificate:\n”);
033 #endif
034 char* str = X509_NAME_oneline (X509_get_subject_name (ptserver->server_cert),0,0);
035 if (!str)
036 {
037 writelogimmediatly(“[exception]X509_NAME_oneline\n”);
038 setallthreadexitflag();
039 return false;
040 }
041
042 #ifdef _DEBUG
043 LogExt(LOG_LOG_LEVEL,”\t subject: %s\n”, str);
044 //subject: /C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
045 //issuer: /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority – L1C
046 #endif
047
048 OPENSSL_free (str);
049
050 str = X509_NAME_oneline (X509_get_issuer_name(ptserver->server_cert),0,0);
051 if (!str)
052 {
053 writelogimmediatly(“[exception]X509_NAME_oneline.\n”);
054 setallthreadexitflag();
055 return false;
056 }
057
058 #ifdef _DEBUG
059 LogExt(LOG_LOG_LEVEL,”\t issuer: %s\n”, str);
060 #endif
061
062 OPENSSL_free (str);
063
064 /* We could do all sorts of certificate verification stuff here before
065 deallocating the certificate. */
066
067 X509_free (ptserver->server_cert);
068
069 return true;
070 }
071 //本机校验
072 bool CWorker::caVerify(APP_SERVER *ptserver)
073 {
074 /* define HOME to be dir for key and certificate files… */
075 //#define HOME “/certs/”
076 /* Make these what you want for certificate & key files */
077 #define CERT_FILE ptserver->pemfile / HOME “1024ccert.pem”
078 #define KEY_FILE ptserver->pemfile
079
080 /*Cipher list to be used*/
081 #define CIPHER_LIST “AES128-SHA”
082
083 /*Trusted CAs location*/
084 #define CA_FILE ptserver->pemfile ”/certs/1024ccert.pem”
085 #define CA_DIR NULL
086
087 /*Set cipher list*/
088 if (SSL_CTX_set_cipher_list(ptserver->psslctx,CIPHER_LIST) <= 0)
089 {
090 writelogimmediatly(“[exception][CWorker][SSL]Error setting the cipher list.\n”);
091 setallthreadexitflag();
092 return false ;
093 }
094
095 /*Indicate the certificate file to be used*/
096
097 string pathfile=getExePath();
098 pathfile+=”\\”;
099 pathfile+=ptserver->pemfile;
100 if (SSL_CTX_use_certificate_file(ptserver->psslctx, pathfile.c_str(), SSL_FILETYPE_PEM) <= 0)
101 {
102
103 string errstr(“[err][SSL]Error setting the certificate file”);
104 const char * pc=ERR_reason_error_string(ERR_get_error());
105 errstr.append(pc?pc:”!\n”);
106 errstr.append(“\n”);
107 writelogimmediatly(errstr.c_str() );
108
109 setallthreadexitflag();
110 return false;
111 }
112
113
114 /*Load the password for the Private Key*/
115 SSL_CTX_set_default_passwd_cb_userdata(ptserver->psslctx, (void*)g_cfg.pem_psw.c_str());
116
117 pathfile=getExePath();
118 pathfile+= “\\”;
119 pathfile+=KEY_FILE;
120 /*Indicate the key file to be used*/
121 if (SSL_CTX_use_PrivateKey_file(ptserver->psslctx, pathfile.c_str(), SSL_FILETYPE_PEM) <= 0)
122 {
123 writelogimmediatly(“[exception][CWorker][SSL]Error setting the key file.\n”);
124 setallthreadexitflag();
125 return false;
126 }
127
128 /*Make sure the key and certificate file match*/
129 if (SSL_CTX_check_private_key(ptserver->psslctx) == 0) {
130 writelogimmediatly(“[log][CWorker][SSL]Private key does not match the certificate public key\n”);
131 setallthreadexitflag();
132 return false;
133 }
134
135 /* Set the list of trusted CAs based on the file and/or directory provided*/
136 pathfile=getExePath();
137 pathfile+= “\\”;
138 pathfile+=CA_FILE;
139 if(SSL_CTX_load_verify_locations(ptserver->psslctx, pathfile.c_str(), CA_DIR)<1) {
140 writelogimmediatly(“[log][CWorker][SSL]Error setting verify location\n”);
141 setallthreadexitflag();
142 return false;
143 }
144
145 return true;
146
147 }
148 //连接到苹果的服务器
149 bool CWorker::connectToServer(const char *hostname,int port,APP_SERVER *ptserver)
150 {
151 #ifdef _DEBUG
152 writelogimmediatly(“connectToServer start\n”);
153 #endif
154
155 //set client using SSL version
156 ptserver->meth = (SSL_METHOD *)SSLv23_client_method();
157
158
159 //创建SSL上下文环境
160 ptserver->psslctx = SSL_CTX_new (ptserver->meth);
161 if(!ptserver->psslctx)
162 {
163 writelogimmediatly(“[err]SSL_CTX_new: NULL\n”);
164 //LogExt(LOG_LOG_LEVEL,”Error: %s\n”, ERR_reason_error_string(ERR_get_error()));
165 return false;
166 }
167
168 caVerify(ptserver);
169 /* ———————————————– */
170 /* Create a socket and connect to server using normal socket calls. */
171
172 ptserver->sd = socket (AF_INET, SOCK_STREAM, 0);
173 if(SOCKET_ERROR == ptserver->sd)
174 {
175 writelogimmediatly(“[err][connectToServer]socket\n”);
176 return false;
177 }
178
179 if(!nonblock_connect(ptserver->sd,ptserver->sa,hostname,port))
180 {
181 return false;
182 }
183
184 /* ———————————————– */
185 /* Now we have TCP conncetion. Start SSL negotiation. */
186 ptserver->ssl = SSL_new (ptserver->psslctx);
187 if(!ptserver->ssl)
188 {
189 string errstr(“[err][SSL_new]“);
190 const char * pc=ERR_reason_error_string(ERR_get_error());
191 errstr.append(pc?pc:”fail!\n”);
192 writelogimmediatly(errstr.c_str() );
193 return false;
194 }
195 SSL_set_fd (ptserver->ssl, ptserver->sd);
196 SSL_set_mode(ptserver->ssl, SSL_MODE_AUTO_RETRY);
197
198 #ifdef NONEBLOCK_SOCKET
199
200 CONN_RE:
201
202 ptserver->err = SSL_connect (ptserver->ssl);
203 if(1 == ptserver->err)
204 {
205 #ifdef _DEBUG
206 LogExt(LOG_LOG_LEVEL,”The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been established.\n”);
207 #endif
208 }
209 else if(-1 == ptserver->err)
210 {
211 ptserver->err = SSL_get_error(ptserver->ssl,ptserver->err);
212 if (SSL_ERROR_WANT_READ==ptserver->err || SSL_ERROR_WANT_WRITE==ptserver->err)
213 {
214 goto CONN_RE;
215 }
216 string errstr(“[err][SSL_connect]fail!\n”);
217 writelogimmediatly(errstr.c_str() );
218 return false;
219 }
220
221 #else
222
223 ptserver->err = SSL_connect (ptserver->ssl);
224 if(1 == ptserver->err)
225 {
226 LogExt(LOG_LOG_LEVEL,”The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been established.\n”);
227 }
228 else if(-1 == ptserver->err)
229 {
230 string errstr(“[err][SSL_connect]“);
231 const char * pc=ERR_reason_error_string(ERR_get_error());
232 errstr.append(pc?pc:”fail!\n”);
233 writelogimmediatly(errstr.c_str() );
234 return false;
235 }
236 #endif
237 // 检查证书是否有效
238 //20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate
239 // the issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found.
240
241 int ret_ssl=0;
242 if(X509_V_OK != ( ret_ssl=SSL_get_verify_result(ptserver->ssl)))
243 {
244 LogExt(LOG_LOG_LEVEL,”SSL_get_verify_result =>%d\n”,ret_ssl);
245 }
246
247 return true;
248 }
249
250 //连接到Feedback沙盒测试服务器
251 bool CWorker::connectToFeedbackSandBoxServer()
252 {
253 bool ret = connectToServer(g_cfg.feedback_sandbox_www.c_str(),g_cfg.feedback_sandbox_port,&this->feed);
254 if (ret)
255 {
256 verifyServer(&this->feed);
257 }
258
259 return ret;
260 }
261
262 //读取Feedback
263 void CWorker::getFeedback()
264 {
265 bool ret = false;
266 if ( IsSandBox())
267 {
268 ret = connectToFeedbackSandBoxServer();
269 }
270 else
271 {
272 ret = connectToFeedbackServer();
273 }
274
275 //读feedback
276 if (ret)
277 {
278 readFeedbackSub();
279 }
280
281 stopSSLFeed();
282 }
283 //发送推送信息
284 void CWorker::sendtoAPNs()
285 {
286 bool ret = false;
287 if ( IsSandBox())
288 {
289 ret = connectToAPNsSandBox();
290 }
291 else
292 {
293 ret = connectToAPNs();
294 }
295
296 if (ret)
297 {
298 //找到开始的一条信息,开始的一个设备
299 string current_info_id(“”);//send_id char12
300 UINT current_device_id=0;
301 string current_device_token(“”);
302
303 StartSend(current_info_id,current_device_token,¤t_device_id);
304 if (!current_info_id.empty() && !current_device_token.empty() )
305 {
306 batchSendtoApns(current_info_id,current_device_token,current_device_id);
307 }
308
309 //
310
311 }
312 stopSSLApns();
313
314 }
315
316 void CWorker::stopSSLFeed()
317 {
318
319 if (feed.ssl)
320 {
321 SSL_shutdown (feed.ssl); /* send SSL/TLS close_notify */
322
323 close (feed.sd);
324 SSL_free (feed.ssl);
325 SSL_CTX_free (feed.psslctx);
326 }
327 feed.ssl=NULL;
328
329
330 }
opensslshiy流程:
1.初始化;SSLv23_client_method();创建SSL上下文环境 SSL_CTX_new ()
2.创建socket,connect;校验证书;
3.socket绑定SSL:SSL_new,SSL_connect;
4.校验服务器证书;
5.SSL_write,SSL_read;
6.释放资源 SSL_shutdown等;
006 | SSL_load_error_strings(); |
007 | SSLeay_add_ssl_algorithms(); |
010 | bool CWorker::verifyServer(APP_SERVER *ptserver) |
016 | SSL_CTX_set_verify(ptserver->psslctx,SSL_VERIFY_PEER,NULL); |
020 | LogExt(LOG_LOG_LEVEL, "SSL connection using %s\n" , SSL_get_cipher(ptserver->ssl)); |
024 | ptserver->server_cert = SSL_get_peer_certificate (ptserver->ssl); |
025 | if (!ptserver->server_cert) |
027 | writelogimmediatly( "[exception]SSL_get_peer_certificate \n" ); |
028 | setallthreadexitflag(); |
032 | LogExt(LOG_LOG_LEVEL, "Server certificate:\n" ); |
034 | char * str = X509_NAME_oneline (X509_get_subject_name (ptserver->server_cert),0,0); |
037 | writelogimmediatly( "[exception]X509_NAME_oneline\n" ); |
038 | setallthreadexitflag(); |
043 | LogExt(LOG_LOG_LEVEL, "\t subject: %s\n" , str); |
050 | str = X509_NAME_oneline (X509_get_issuer_name(ptserver->server_cert),0,0); |
053 | writelogimmediatly( "[exception]X509_NAME_oneline.\n" ); |
054 | setallthreadexitflag(); |
059 | LogExt(LOG_LOG_LEVEL, "\t issuer: %s\n" , str); |
067 | X509_free (ptserver->server_cert); |
072 | bool CWorker::caVerify(APP_SERVER *ptserver) |
077 | #define CERT_FILE ptserver->pemfile / HOME "1024ccert.pem" |
078 | #define KEY_FILE ptserver->pemfile |
081 | #define CIPHER_LIST "AES128-SHA" |
084 | #define CA_FILE ptserver->pemfile "/certs/1024ccert.pem" |
088 | if (SSL_CTX_set_cipher_list(ptserver->psslctx,CIPHER_LIST) <= 0) |
090 | writelogimmediatly( "[exception][CWorker][SSL]Error setting the cipher list.\n" ); |
091 | setallthreadexitflag(); |
097 | string pathfile=getExePath(); |
099 | pathfile+=ptserver->pemfile; |
100 | if (SSL_CTX_use_certificate_file(ptserver->psslctx, pathfile.c_str(), SSL_FILETYPE_PEM) <= 0) |
103 | string errstr( "[err][SSL]Error setting the certificate file" ); |
104 | const char * pc=ERR_reason_error_string(ERR_get_error()); |
105 | errstr.append(pc?pc: "!\n" ); |
107 | writelogimmediatly(errstr.c_str() ); |
109 | setallthreadexitflag(); |
115 | SSL_CTX_set_default_passwd_cb_userdata(ptserver->psslctx, ( void *)g_cfg.pem_psw.c_str()); |
117 | pathfile=getExePath(); |
121 | if (SSL_CTX_use_PrivateKey_file(ptserver->psslctx, pathfile.c_str(), SSL_FILETYPE_PEM) <= 0) |
123 | writelogimmediatly( "[exception][CWorker][SSL]Error setting the key file.\n" ); |
124 | setallthreadexitflag(); |
129 | if (SSL_CTX_check_private_key(ptserver->psslctx) == 0) { |
130 | writelogimmediatly( "[log][CWorker][SSL]Private key does not match the certificate public key\n" ); |
131 | setallthreadexitflag(); |
136 | pathfile=getExePath(); |
139 | if (SSL_CTX_load_verify_locations(ptserver->psslctx, pathfile.c_str(), CA_DIR)<1) { |
140 | writelogimmediatly( "[log][CWorker][SSL]Error setting verify location\n" ); |
141 | setallthreadexitflag(); |
149 | bool CWorker::connectToServer( const char *hostname, int port,APP_SERVER *ptserver) |
152 | writelogimmediatly( "connectToServer start\n" ); |
156 | ptserver->meth = (SSL_METHOD *)SSLv23_client_method(); |
160 | ptserver->psslctx = SSL_CTX_new (ptserver->meth); |
161 | if (!ptserver->psslctx) |
163 | writelogimmediatly( "[err]SSL_CTX_new: NULL\n" ); |
172 | ptserver->sd = socket (AF_INET, SOCK_STREAM, 0); |
173 | if (SOCKET_ERROR == ptserver->sd) |
175 | writelogimmediatly( "[err][connectToServer]socket\n" ); |
179 | if (!nonblock_connect(ptserver->sd,ptserver->sa,hostname,port)) |
186 | ptserver->ssl = SSL_new (ptserver->psslctx); |
189 | string errstr( "[err][SSL_new]" ); |
190 | const char * pc=ERR_reason_error_string(ERR_get_error()); |
191 | errstr.append(pc?pc: "fail!\n" ); |
192 | writelogimmediatly(errstr.c_str() ); |
195 | SSL_set_fd (ptserver->ssl, ptserver->sd); |
196 | SSL_set_mode(ptserver->ssl, SSL_MODE_AUTO_RETRY); |
198 | #ifdef NONEBLOCK_SOCKET |
202 | ptserver->err = SSL_connect (ptserver->ssl); |
203 | if (1 == ptserver->err) |
206 | LogExt(LOG_LOG_LEVEL, "The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been established.\n" ); |
209 | else if (-1 == ptserver->err) |
211 | ptserver->err = SSL_get_error(ptserver->ssl,ptserver->err); |
212 | if (SSL_ERROR_WANT_READ==ptserver->err || SSL_ERROR_WANT_WRITE==ptserver->err) |
216 | string errstr( "[err][SSL_connect]fail!\n" ); |
217 | writelogimmediatly(errstr.c_str() ); |
223 | ptserver->err = SSL_connect (ptserver->ssl); |
224 | if (1 == ptserver->err) |
226 | LogExt(LOG_LOG_LEVEL, "The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been established.\n" ); |
228 | else if (-1 == ptserver->err) |
230 | string errstr( "[err][SSL_connect]" ); |
231 | const char * pc=ERR_reason_error_string(ERR_get_error()); |
232 | errstr.append(pc?pc: "fail!\n" ); |
233 | writelogimmediatly(errstr.c_str() ); |
242 | if (X509_V_OK != ( ret_ssl=SSL_get_verify_result(ptserver->ssl))) |
244 | LogExt(LOG_LOG_LEVEL, "SSL_get_verify_result =>%d\n" ,ret_ssl); |
251 | bool CWorker::connectToFeedbackSandBoxServer() |
253 | bool ret = connectToServer(g_cfg.feedback_sandbox_www.c_str(),g_cfg.feedback_sandbox_port,& this ->feed); |
256 | verifyServer(& this ->feed); |
263 | void CWorker::getFeedback() |
268 | ret = connectToFeedbackSandBoxServer(); |
272 | ret = connectToFeedbackServer(); |
284 | void CWorker::sendtoAPNs() |
289 | ret = connectToAPNsSandBox(); |
293 | ret = connectToAPNs(); |
299 | string current_info_id( "" ); |
300 | UINT current_device_id=0; |
301 | string current_device_token( "" ); |
303 | StartSend(current_info_id,current_device_token,¤t_device_id); |
304 | if (!current_info_id.empty() && !current_device_token.empty() ) |
306 | batchSendtoApns(current_info_id,current_device_token,current_device_id); |
316 | void CWorker::stopSSLFeed() |
321 | SSL_shutdown (feed.ssl); |
325 | SSL_CTX_free (feed.psslctx); |