ffead.server.doc
SSLHandler.cpp
1 /*
2  Copyright 2009-2012, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 /*
17  * SSLHandler.cpp
18  *
19  * Created on: 20-Jun-2012
20  * Author: sumeetc
21  */
22 
23 #include "SSLHandler.h"
24 
25 SSLHandler::SSLHandler() {
26  logger = Logger::getLogger("SSLHandler");
27 }
28 
29 SSLHandler::~SSLHandler() {
30  // TODO Auto-generated destructor stub
31 }
32 
33 char* SSLHandler::pass = NULL;
34 BIO* SSLHandler::bio_err = NULL;
35 
36 int SSLHandler::s_server_session_id_context = 1;
37 int SSLHandler::s_server_auth_session_id_context = 2;
38 Logger SSLHandler::logger;
39 
40 /*The password code is not thread safe*/
41 int SSLHandler::password_cb(char *buf,int num, int rwflag,void *userdata)
42  {
43  if(num<(int)(strlen(pass)+1))
44  return(0);
45 
46  strcpy(buf,pass);
47  return(strlen(pass));
48  }
49 
50 void SSLHandler::load_dh_params(SSL_CTX *ctx,char *file)
51 {
52  DH *ret=0;
53  BIO *bio;
54 
55  if ((bio=BIO_new_file(file,"r")) == NULL)
56  logger << "Couldn't open DH file" << endl;
57 
58  ret=PEM_read_bio_DHparams(bio,NULL,NULL,
59  NULL);
60  BIO_free(bio);
61  if(SSL_CTX_set_tmp_dh(ctx,ret)<0)
62  logger << "Couldn't set DH parameters" << endl;
63  }
64 
65 void SSLHandler::sigpipe_handle(int x){
66 }
67 
68 SSL_CTX *SSLHandler::initialize_ctx(char *keyfile,char *password, string ca_list)
69  {
70  SSL_METHOD *meth;
71  SSL_CTX *ctx;
72 
73  if(!bio_err){
74  /* Global system initialization*/
75  SSL_library_init();
76  SSL_load_error_strings();
77 
78  /* An error write context */
79  bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
80  }
81 
82  /* Set up a SIGPIPE handler */
83  signal(SIGPIPE,sigpipe_handle);
84 
85  /* Create our context*/
86  meth=(SSL_METHOD*)SSLv23_method();
87  ctx=SSL_CTX_new(meth);
88 
89  /* Load our keys and certificates*/
90  if(!(SSL_CTX_use_certificate_chain_file(ctx,
91  keyfile)))
92  logger << "Can't read certificate file" << endl;
93 
94  pass=password;
95  SSL_CTX_set_default_passwd_cb(ctx,
96  password_cb);
97  if(!(SSL_CTX_use_PrivateKey_file(ctx,
98  keyfile,SSL_FILETYPE_PEM)))
99  logger << "Can't read key file" << endl;
100 
101  /* Load the CAs we trust*/
102  if(!(SSL_CTX_load_verify_locations(ctx,
103  ca_list.c_str(),0)))
104  logger << "Can't read CA list" << endl;
105 #if (OPENSSL_VERSION_NUMBER < 0x00905100L)
106  SSL_CTX_set_verify_depth(ctx,1);
107 #endif
108 
109  return ctx;
110  }
111 
112 void SSLHandler::destroy_ctx(SSL_CTX *ctx)
113  {
114  SSL_CTX_free(ctx);
115  }
116 
117 void SSLHandler::error_occurred(char *error,int fd,SSL *ssl)
118 {
119  //logger << error << endl;
120  close(fd);
121  int r=SSL_shutdown(ssl);
122  if(!r){
123  /* If we called SSL_shutdown() first then
124  we always get return value of '0'. In
125  this case, try again, but first send a
126  TCP FIN to trigger the other side's
127  close_notify*/
128  shutdown(fd,1);
129  r=SSL_shutdown(ssl);
130  }
131  switch(r){
132  case 1:
133  break; /* Success */
134  case 0:
135  case -1:
136  default:
137  logger << "Socket shutdown failed" << endl;
138  break;
139  }
140  SSL_free(ssl);
141 }
142 
143 void SSLHandler::closeSSL(int fd,SSL *ssl,BIO* bio)
144 {
145  //BIO_free(bio);
146  int r=SSL_shutdown(ssl);
147  if(!r){
148  /* If we called SSL_shutdown() first then
149  we always get return value of '0'. In
150  this case, try again, but first send a
151  TCP FIN to trigger the other side's
152  close_notify*/
153  shutdown(fd,1);
154  r=SSL_shutdown(ssl);
155  }
156  switch(r){
157  case 1:
158  break; /* Success */
159  case 0:
160  case -1:
161  default:
162  logger << "Socket shutdown failed" << endl;
163  break;
164  }
165  SSL_free(ssl);
166 }