00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "precomp.h"
00030 #include "ssl_connection.h"
00031 #include "tcp_connection.h"
00032 #include "exception.h"
00033 #include "logger.h"
00034 #include <prerr.h>
00035
00037
00038
00039 CL_SSLConnection::CL_SSLConnection(CL_TCPConnection *connection, CL_PK11PasswordHandler *handler)
00040 : ssl_fd(0), connection(connection), password_handler(handler)
00041 {
00042 SECStatus result;
00043 PRFileDesc *model_fd = 0;
00044 PRFileDesc *socket_fd = create_prfd();
00045 PRFileDesc *ssl_fd = SSL_ImportFD(model_fd, socket_fd);
00046 if (ssl_fd == 0)
00047 throw CL_Exception(TEXT("Unable to import socket fd into a ssl fd"));
00048
00049
00050
00051
00052
00053
00054 CERTCertificate *cert;
00055 SECKEYPrivateKey *key;
00056 SSLKEAType kea_type = kt_rsa;
00057 result = SSL_ConfigSecureServer(ssl_fd, cert, key, kea_type);
00058 if (result != SECSuccess)
00059 throw CL_Exception(TEXT("SSL_ConfigSecureServer failed!"));
00060
00061
00062
00063
00064
00065
00066
00067 int res = SSL_SetPKCS11PinArg(ssl_fd, password_handler);
00068 if (res == -1)
00069 throw CL_Exception(TEXT("SSL_SetPKCS11PinArg failed!"));
00070
00071 result = SSL_AuthCertificateHook(ssl_fd, &CL_SSLConnection::auth_certificate, this);
00072 if (result != SECSuccess)
00073 throw CL_Exception(TEXT("SSL_AuthCertificateHook failed!"));
00074
00075 result = SSL_BadCertHook(ssl_fd, &CL_SSLConnection::bad_certificate, this);
00076 if (result != SECSuccess)
00077 throw CL_Exception(TEXT("SSL_BadCertHook failed!"));
00078
00079 result = SSL_GetClientAuthDataHook(ssl_fd, &CL_SSLConnection::get_client_auth_data, this);
00080 if (result != SECSuccess)
00081 throw CL_Exception(TEXT("SSL_GetClientAuthDataHook failed!"));
00082
00083 result = SSL_HandshakeCallback(ssl_fd, &CL_SSLConnection::handshake_completed, this);
00084 if (result != SECSuccess)
00085 throw CL_Exception(TEXT("SSL_HandshakeCallback failed!"));
00086
00087
00088
00089
00090
00091
00092 int as_server = 1;
00093 result = SSL_ResetHandshake(ssl_fd, as_server);
00094 if (result != SECSuccess)
00095 throw CL_Exception(TEXT("SSL_ResetHandshake failed!"));
00096 }
00097
00098 CL_SSLConnection::~CL_SSLConnection()
00099 {
00100 PR_Close(ssl_fd);
00101 }
00102
00104
00105
00107
00108
00110
00111
00112 PRIOMethods CL_SSLConnection::methods =
00113 {
00114 PR_DESC_SOCKET_TCP,
00115 &CL_SSLConnection::prfd_close,
00116 &CL_SSLConnection::prfd_read,
00117 &CL_SSLConnection::prfd_write,
00118 &CL_SSLConnection::prfd_available,
00119 &CL_SSLConnection::prfd_available64,
00120 &CL_SSLConnection::prfd_fsync,
00121 &CL_SSLConnection::prfd_seek,
00122 &CL_SSLConnection::prfd_seek64,
00123 &CL_SSLConnection::prfd_file_info,
00124 &CL_SSLConnection::prfd_file_info64,
00125 &CL_SSLConnection::prfd_writev,
00126 &CL_SSLConnection::prfd_connect,
00127 &CL_SSLConnection::prfd_accept,
00128 &CL_SSLConnection::prfd_bind,
00129 &CL_SSLConnection::prfd_listen,
00130 &CL_SSLConnection::prfd_shutdown,
00131 &CL_SSLConnection::prfd_recv,
00132 &CL_SSLConnection::prfd_send,
00133 &CL_SSLConnection::prfd_recvfrom,
00134 &CL_SSLConnection::prfd_sendto,
00135 &CL_SSLConnection::prfd_poll,
00136 &CL_SSLConnection::prfd_acceptread,
00137 &CL_SSLConnection::prfd_transmitfile,
00138 &CL_SSLConnection::prfd_getsockname,
00139 &CL_SSLConnection::prfd_getpeername,
00140 &CL_SSLConnection::prfd_reserved,
00141 &CL_SSLConnection::prfd_reserved,
00142 &CL_SSLConnection::prfd_getsockopt,
00143 &CL_SSLConnection::prfd_setsockopt,
00144 &CL_SSLConnection::prfd_sendfile,
00145 &CL_SSLConnection::prfd_connectcontinue,
00146 &CL_SSLConnection::prfd_reserved,
00147 &CL_SSLConnection::prfd_reserved,
00148 &CL_SSLConnection::prfd_reserved,
00149 &CL_SSLConnection::prfd_reserved
00150 };
00151
00152 PRFileDesc *CL_SSLConnection::create_prfd()
00153 {
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 PRFileDesc *fd = PR_CreateIOLayerStub(0, &methods);
00165 if (fd == 0)
00166 throw CL_Exception(TEXT("Unable to allocate memory for a PRFileDesc structure"));
00167 fd->secret = (PRFilePrivate *) this;
00168 return fd;
00169 }
00170
00171 SECStatus CL_SSLConnection::auth_certificate(void *arg, PRFileDesc *ssl_fd, PRBool check_sig, PRBool is_server)
00172 {
00173 CL_SSLConnection *self = (CL_SSLConnection *) arg;
00174 return SSL_AuthCertificate(CERT_GetDefaultCertDB(), ssl_fd, check_sig, is_server);
00175 }
00176
00177 SECStatus CL_SSLConnection::bad_certificate(void *arg, PRFileDesc *ssl_fd)
00178 {
00179 CL_SSLConnection *self = (CL_SSLConnection *) arg;
00180 return SECSuccess;
00181 }
00182
00183 SECStatus CL_SSLConnection::get_client_auth_data(
00184 void *arg,
00185 PRFileDesc *ssl_fd,
00186 CERTDistNames *ca_names,
00187 CERTCertificate **out_return_cert,
00188 SECKEYPrivateKey **out_return_key)
00189 {
00190 CL_SSLConnection *self = (CL_SSLConnection *) arg;
00191 return NSS_GetClientAuthData(0, ssl_fd, ca_names, out_return_cert, out_return_key);
00192 }
00193
00194 void CL_SSLConnection::handshake_completed(PRFileDesc *ssl_fd, void *arg)
00195 {
00196 CL_SSLConnection *self = (CL_SSLConnection *) arg;
00197 }
00198
00199 void CL_SSLConnection::prfd_dtor(PRFileDesc *fd)
00200 {
00201 }
00202
00203 PRStatus CL_SSLConnection::prfd_close(PRFileDesc *fd)
00204 {
00205 cl_log_event("ssl", "prfd_close called");
00206 return PR_SUCCESS;
00207 }
00208
00209 PRInt32 CL_SSLConnection::prfd_read(PRFileDesc *fd, void *buf, PRInt32 amount)
00210 {
00211 cl_log_event("ssl", "prfd_read called (%1)", amount);
00212 return -1;
00213 }
00214
00215 PRInt32 CL_SSLConnection::prfd_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
00216 {
00217 cl_log_event("ssl", "prfd_write called (%1)", amount);
00218 return -1;
00219 }
00220
00221 PRInt32 CL_SSLConnection::prfd_available(PRFileDesc *fd)
00222 {
00223 cl_log_event("ssl", "prfd_available called");
00224 return -1;
00225 }
00226
00227 PRInt64 CL_SSLConnection::prfd_available64(PRFileDesc *fd)
00228 {
00229 cl_log_event("ssl", "prfd_available64 called");
00230 return -1;
00231 }
00232
00233 PRStatus CL_SSLConnection::prfd_fsync(PRFileDesc *fd)
00234 {
00235 cl_log_event("ssl", "prfd_fsync called");
00236 return (PRStatus) PR_INVALID_METHOD_ERROR;
00237 }
00238
00239 PRInt32 CL_SSLConnection::prfd_seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
00240 {
00241 cl_log_event("ssl", "prfd_seek called");
00242 return -1;
00243 }
00244
00245 PRInt64 CL_SSLConnection::prfd_seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
00246 {
00247 cl_log_event("ssl", "prfd_seek64 called");
00248 return -1;
00249 }
00250
00251 PRStatus CL_SSLConnection::prfd_file_info(PRFileDesc *fd, PRFileInfo *info)
00252 {
00253 cl_log_event("ssl", "prfd_file_info called");
00254 return (PRStatus) PR_INVALID_METHOD_ERROR;
00255 }
00256
00257 PRStatus CL_SSLConnection::prfd_file_info64(PRFileDesc *fd, PRFileInfo64 *info64)
00258 {
00259 cl_log_event("ssl", "prfd_file_info64 called");
00260 return (PRStatus) PR_INVALID_METHOD_ERROR;
00261 }
00262
00263 PRInt32 CL_SSLConnection::prfd_writev(PRFileDesc *fd, const PRIOVec *iov, PRInt32 size, PRIntervalTime timeout)
00264 {
00265 cl_log_event("ssl", "prfd_writev called (%1)", size);
00266 return -1;
00267 }
00268
00269 PRStatus CL_SSLConnection::prfd_connect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
00270 {
00271 cl_log_event("ssl", "prfd_connect called");
00272 return (PRStatus) PR_INVALID_METHOD_ERROR;
00273 }
00274
00275 PRFileDesc *CL_SSLConnection::prfd_accept(PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
00276 {
00277 cl_log_event("ssl", "prfd_accept called");
00278 return 0;
00279 }
00280
00281 PRStatus CL_SSLConnection::prfd_bind(PRFileDesc *fd, const PRNetAddr *addr)
00282 {
00283 cl_log_event("ssl", "prfd_bind called");
00284 return (PRStatus) PR_INVALID_METHOD_ERROR;
00285 }
00286
00287 PRStatus CL_SSLConnection::prfd_listen(PRFileDesc *fd, PRIntn backlog)
00288 {
00289 cl_log_event("ssl", "prfd_listen called");
00290 return (PRStatus) PR_INVALID_METHOD_ERROR;
00291 }
00292
00293 PRStatus CL_SSLConnection::prfd_shutdown(PRFileDesc *fd, PRIntn how)
00294 {
00295 cl_log_event("ssl", "prfd_shutdown called");
00296 return (PRStatus) PR_INVALID_METHOD_ERROR;
00297 }
00298
00299 PRInt32 CL_SSLConnection::prfd_recv(
00300 PRFileDesc *fd,
00301 void *buf,
00302 PRInt32 amount,
00303 PRIntn flags,
00304 PRIntervalTime timeout)
00305 {
00306 cl_log_event("ssl", "prfd_recv called");
00307 return -1;
00308 }
00309
00310 PRInt32 CL_SSLConnection::prfd_send(
00311 PRFileDesc *fd,
00312 const void *buf,
00313 PRInt32 amount,
00314 PRIntn flags,
00315 PRIntervalTime timeout)
00316 {
00317 cl_log_event("ssl", "prfd_send called");
00318 return -1;
00319 }
00320
00321 PRInt32 CL_SSLConnection::prfd_recvfrom(
00322 PRFileDesc *fd,
00323 void *buf,
00324 PRInt32 amount,
00325 PRIntn flags,
00326 PRNetAddr *addr,
00327 PRIntervalTime timeout)
00328 {
00329 cl_log_event("ssl", "prfd_recvfrom called");
00330 return -1;
00331 }
00332
00333 PRInt32 CL_SSLConnection::prfd_sendto(
00334 PRFileDesc *fd,
00335 const void *buf,
00336 PRInt32 amount,
00337 PRIntn flags,
00338 const PRNetAddr *addr,
00339 PRIntervalTime timeout)
00340 {
00341 cl_log_event("ssl", "prfd_sendto called");
00342 return -1;
00343 }
00344
00345 PRInt16 CL_SSLConnection::prfd_poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
00346 {
00347 cl_log_event("ssl", "prfd_poll called (%1)", in_flags);
00348 return -1;
00349 }
00350
00351 PRInt32 CL_SSLConnection::prfd_acceptread(
00352 PRFileDesc *listen_sock,
00353 PRFileDesc **accepted_sock,
00354 PRNetAddr **peer_addr,
00355 void *buf,
00356 PRInt32 amount,
00357 PRIntervalTime timeout)
00358 {
00359 cl_log_event("ssl", "prfd_acceptread called");
00360 return -1;
00361 }
00362
00363 PRInt32 CL_SSLConnection::prfd_transmitfile(
00364 PRFileDesc *network_socket,
00365 PRFileDesc *source_file,
00366 const void *headers,
00367 PRInt32 hlen,
00368 PRTransmitFileFlags flags,
00369 PRIntervalTime timeout)
00370 {
00371 cl_log_event("ssl", "prfd_transmitfile called");
00372 return -1;
00373 }
00374
00375 PRStatus CL_SSLConnection::prfd_getsockname(PRFileDesc *fd, PRNetAddr *addr)
00376 {
00377 cl_log_event("ssl", "prfd_getsockname called");
00378 return (PRStatus) PR_INVALID_METHOD_ERROR;
00379 }
00380
00381 PRStatus CL_SSLConnection::prfd_getpeername(PRFileDesc *fd, PRNetAddr *addr)
00382 {
00383 cl_log_event("ssl", "prfd_getpeername called");
00384 return (PRStatus) PR_INVALID_METHOD_ERROR;
00385 }
00386
00387 PRStatus CL_SSLConnection::prfd_getsockopt(PRFileDesc *fd, PRSocketOptionData *data)
00388 {
00389 cl_log_event("ssl", "prfd_getsockopt called");
00390 return (PRStatus) PR_INVALID_METHOD_ERROR;
00391 }
00392
00393 PRStatus CL_SSLConnection::prfd_setsockopt(PRFileDesc *fd, const PRSocketOptionData *data)
00394 {
00395 cl_log_event("ssl", "prfd_setsockopt called");
00396 return (PRStatus) PR_INVALID_METHOD_ERROR;
00397 }
00398
00399 PRInt32 CL_SSLConnection::prfd_sendfile(
00400 PRFileDesc *network_socket,
00401 PRSendFileData *send_data,
00402 PRTransmitFileFlags flags,
00403 PRIntervalTime timeout)
00404 {
00405 cl_log_event("ssl", "prfd_sendfile called");
00406 return -1;
00407 }
00408
00409 PRStatus CL_SSLConnection::prfd_connectcontinue(PRFileDesc *fd, PRInt16 out_flags)
00410 {
00411 cl_log_event("ssl", "prfd_connectcontinue called");
00412 return (PRStatus) PR_INVALID_METHOD_ERROR;
00413 }
00414
00415 PRIntn CL_SSLConnection::prfd_reserved(PRFileDesc *fd)
00416 {
00417 cl_log_event("ssl", "prfd_reserved called");
00418 return -1;
00419 }