Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ssl_connection.cpp

Go to the documentation of this file.
00001 /*
00002 **  ClanLib SDK
00003 **  Copyright (c) 1997-2005 The ClanLib Team
00004 **
00005 **  This software is provided 'as-is', without any express or implied
00006 **  warranty.  In no event will the authors be held liable for any damages
00007 **  arising from the use of this software.
00008 **
00009 **  Permission is granted to anyone to use this software for any purpose,
00010 **  including commercial applications, and to alter it and redistribute it
00011 **  freely, subject to the following restrictions:
00012 **
00013 **  1. The origin of this software must not be misrepresented; you must not
00014 **     claim that you wrote the original software. If you use this software
00015 **     in a product, an acknowledgment in the product documentation would be
00016 **     appreciated but is not required.
00017 **  2. Altered source versions must be plainly marked as such, and must not be
00018 **     misrepresented as being the original software.
00019 **  3. This notice may not be removed or altered from any source distribution.
00020 **
00021 **  Note: Some of the libraries ClanLib link to may have additional
00022 **  requirements or restrictions.
00023 **
00024 **  File Author(s):
00025 **
00026 **    Magnus Norddahl
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 // CL_SSLConnection Construction:
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         // PRStatus status = PR_SetSocketOption(ssl_fd, option_data);
00049         // SECStatus result = SSL_OptionSet(ssl_fd, option, on);
00050         // if (result != SECSuccess)
00051         //      throw CL_Exception(TEXT("SSL_OptionSet failed!"));
00052                 
00053         // Server:
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         // Client:
00062 //      int res = SSL_SetURL(ssl_fd, hostname);
00063 //      if (res == -1)
00064 //              throw CL_Exception(TEXT("SSL_SetURL failed!"));
00065 
00066         // Client and server:
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 //      result = SSL_CipherPrefSet(ssl_fd, cipher, enabled);
00088 //      if (result != SECSuccess)
00089 //              throw CL_Exception(TEXT("SSL_CipherPrefSet failed!"));
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 // CL_SSLConnection Attributes:
00105 
00107 // CL_SSLConnection Operations:
00108 
00110 // CL_SSLConnection Implementation:
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, // reserved_fn_6
00141         &CL_SSLConnection::prfd_reserved, // reserved_fn_5
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, // reserved_fn_3
00147         &CL_SSLConnection::prfd_reserved, // reserved_fn_2
00148         &CL_SSLConnection::prfd_reserved, // reserved_fn_1
00149         &CL_SSLConnection::prfd_reserved  // reserved_fn_0
00150 };
00151 
00152 PRFileDesc *CL_SSLConnection::create_prfd()
00153 {
00154 /*
00155         PRFileDesc *fd = (PRFileDesc *) PR_Malloc(sizeof(PRFileDesc));
00156         if (fd == 0)
00157                 throw CL_Exception(TEXT("Unable to allocate memory for a PRFileDesc structure"));
00158         memset(fd, 0, sizeof(PRFileDesc));
00159         fd->methods = methods;
00160         fd->secret = (PRFilePrivate *) this;
00161         fd->dtor = &CL_SSLConnection::prfd_dtor;
00162         fd->identity = 0;
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, /*PRShutdownHow*/ 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 }

Generated on Sat Feb 19 22:51:16 2005 for npcore by  doxygen 1.4.1