|
Added
Link Here
|
| 1 |
#include <stdio.h> |
| 2 |
#include <stdlib.h> |
| 3 |
#include <string.h> |
| 4 |
#include <errno.h> |
| 5 |
|
| 6 |
#ifdef _WIN32 |
| 7 |
#include <direct.h> |
| 8 |
#else |
| 9 |
#include <unistd.h> |
| 10 |
#endif |
| 11 |
|
| 12 |
#include "tptpOpenSSL.h" |
| 13 |
#include "openSSLTypes.h" |
| 14 |
#include "tptp/tptpSSLProvider.h" |
| 15 |
#include "openSSLLog.h" |
| 16 |
|
| 17 |
/* Resolved OpenSSL functions */ |
| 18 |
static sslv23_server_method_t sslv23_server_method; |
| 19 |
static ssl_CTX_new_t ssl_CTX_new; |
| 20 |
static ssl_CTX_use_certificate_file_t ssl_CTX_use_certificate_file; |
| 21 |
static ssl_CTX_use_PrivateKey_file_t ssl_CTX_use_PrivateKey_file; |
| 22 |
static ssl_CTX_check_private_key_t ssl_CTX_check_private_key; |
| 23 |
static ssl_new_t ssl_new; |
| 24 |
static ssl_set_fd_t ssl_set_fd; |
| 25 |
static ssl_accept_t ssl_accept; |
| 26 |
static ssl_read_t ssl_read; |
| 27 |
static ssl_write_t ssl_write; |
| 28 |
static ssl_get_error_t ssl_get_error; |
| 29 |
static ssl_free_t ssl_free; |
| 30 |
static ssl_CTX_free_t ssl_CTX_free; |
| 31 |
static ssl_shutdown_t ssl_shutdown; |
| 32 |
|
| 33 |
static SOCKET serverSocket; |
| 34 |
static char* certFile = NULL; |
| 35 |
static char* keyFile = NULL; |
| 36 |
|
| 37 |
static log_service_t *logService; |
| 38 |
|
| 39 |
static int initKeys(); |
| 40 |
static int loadOpenSSLLibrary(); |
| 41 |
|
| 42 |
int sslInit(log_service_t *_logService, int port) { |
| 43 |
struct sockaddr_in saddr; |
| 44 |
int rc; |
| 45 |
|
| 46 |
logService = _logService; |
| 47 |
|
| 48 |
if (loadOpenSSLLibrary() < 0) { |
| 49 |
TPTP_LOG_ERROR_MSG(logService, "Error: unable to load tptpSSLProvider's openssl library.") ; |
| 50 |
return -1; |
| 51 |
} |
| 52 |
|
| 53 |
if (initKeys() < 0) { |
| 54 |
return -1; |
| 55 |
} |
| 56 |
|
| 57 |
/* create and initialize the server socket */ |
| 58 |
serverSocket = getTheSocket(port, &saddr); |
| 59 |
|
| 60 |
if (serverSocket < 0) { |
| 61 |
TPTP_LOG_ERROR_MSG1(logService, "Error: unable to create the server socket at port %d.", port) ; |
| 62 |
return -1; |
| 63 |
} |
| 64 |
else { |
| 65 |
rc = bindAndListen(serverSocket, (struct sockaddr*)&saddr) ; |
| 66 |
} |
| 67 |
|
| 68 |
TPTP_LOG_DEBUG_MSG1(logService, "Socket server is running at port number of %d.", port) ; |
| 69 |
|
| 70 |
return rc; |
| 71 |
} |
| 72 |
|
| 73 |
void* sslAccept() { |
| 74 |
ssl_socket_t ssl_socket; |
| 75 |
SOCKET clientSocket; |
| 76 |
|
| 77 |
clientSocket = acceptSocketConnection(serverSocket); |
| 78 |
if (isSocketValid(clientSocket) == 0) { |
| 79 |
TPTP_LOG_ERROR_MSG(logService, "Accept() receives invalid socket request.") ; |
| 80 |
return NULL; |
| 81 |
} |
| 82 |
|
| 83 |
setHandleInherited((HANDLE) clientSocket); |
| 84 |
|
| 85 |
/* set up the data block for each request */ |
| 86 |
ssl_socket = (ssl_socket_t) malloc(sizeof(ssl_socket_data_t)); |
| 87 |
ssl_socket->clientSocket = clientSocket; |
| 88 |
ssl_socket->secured = FALSE; |
| 89 |
|
| 90 |
return ssl_socket; |
| 91 |
} |
| 92 |
|
| 93 |
int sslHandshake(void* _ssl_socket) { |
| 94 |
ssl_socket_t ssl_socket = (ssl_socket_t) _ssl_socket; // to make compiler happy :) |
| 95 |
SSL_METHOD *meth; |
| 96 |
SSL_CTX* ctx; |
| 97 |
SSL* ssl; |
| 98 |
int err; |
| 99 |
|
| 100 |
meth = (*sslv23_server_method)(); |
| 101 |
|
| 102 |
ctx = (*ssl_CTX_new)(meth); |
| 103 |
if (!ctx) { |
| 104 |
TPTP_LOG_DEBUG_MSG(logService, "SSL: context error"); |
| 105 |
return -1; |
| 106 |
} |
| 107 |
|
| 108 |
if (certFile == NULL) { |
| 109 |
TPTP_LOG_DEBUG_MSG(logService, "SSL: no certificate file found"); |
| 110 |
return -1; |
| 111 |
} |
| 112 |
|
| 113 |
if ((*ssl_CTX_use_certificate_file)(ctx, certFile, SSL_FILETYPE_PEM) <= 0) { |
| 114 |
TPTP_LOG_DEBUG_MSG1(logService, "SSL: invalid certificate file %s", certFile); |
| 115 |
return -1; |
| 116 |
} |
| 117 |
|
| 118 |
if (keyFile == NULL) { |
| 119 |
TPTP_LOG_DEBUG_MSG(logService, "SSL: no key file found"); |
| 120 |
return -1; |
| 121 |
} |
| 122 |
|
| 123 |
if ((*ssl_CTX_use_PrivateKey_file)(ctx, keyFile, SSL_FILETYPE_PEM) <= 0) { |
| 124 |
TPTP_LOG_DEBUG_MSG1(logService, "SSL: invalid key file %s", keyFile); |
| 125 |
return -1; |
| 126 |
} |
| 127 |
|
| 128 |
if (!(*ssl_CTX_check_private_key)(ctx)) { |
| 129 |
TPTP_LOG_DEBUG_MSG2(logService, "SSL: Private key %s does not match the certificate public key %s", |
| 130 |
keyFile, certFile); |
| 131 |
return -1; |
| 132 |
} |
| 133 |
|
| 134 |
ssl = (*ssl_new)(ctx); |
| 135 |
if (ssl < 0) { |
| 136 |
TPTP_LOG_DEBUG_MSG(logService, "SSL.new error"); |
| 137 |
return -1; |
| 138 |
} |
| 139 |
|
| 140 |
(*ssl_set_fd)(ssl, ssl_socket->clientSocket); |
| 141 |
err = (*ssl_accept)(ssl); |
| 142 |
if (err < 0) { |
| 143 |
TPTP_LOG_DEBUG_MSG1(logService, "SSL: ssl_accept error %d", (*ssl_get_error)(ssl, err)); |
| 144 |
return -1; |
| 145 |
} |
| 146 |
|
| 147 |
ssl_socket->secured = TRUE; |
| 148 |
ssl_socket->sslCtx = ctx; |
| 149 |
ssl_socket->ssl = ssl; |
| 150 |
|
| 151 |
return 0; |
| 152 |
} |
| 153 |
|
| 154 |
int sslRead(void* _ssl_socket, char* buffer, int length) { |
| 155 |
ssl_socket_t ssl_socket = (ssl_socket_t) _ssl_socket; |
| 156 |
int rc, bytesRead; |
| 157 |
|
| 158 |
if (ssl_socket == NULL) return -1; |
| 159 |
|
| 160 |
if (ssl_socket->secured) { |
| 161 |
return (ssl_read == NULL) ? -1 : (*ssl_read)(ssl_socket->ssl, buffer, length); |
| 162 |
} |
| 163 |
else { |
| 164 |
rc = readFromSocket(ssl_socket->clientSocket, buffer, length, &bytesRead); |
| 165 |
return (rc < 0) ? -1 : bytesRead; |
| 166 |
} |
| 167 |
} |
| 168 |
|
| 169 |
int sslWrite(void* _ssl_socket, char* buffer, int length) { |
| 170 |
ssl_socket_t ssl_socket = (ssl_socket_t) _ssl_socket; |
| 171 |
if (ssl_socket == NULL) return -1; |
| 172 |
|
| 173 |
if (ssl_socket->secured) { |
| 174 |
return (ssl_write == NULL) ? -1 : (*ssl_write)(ssl_socket->ssl, buffer, length); |
| 175 |
} |
| 176 |
else { |
| 177 |
return writeToSocket(ssl_socket->clientSocket, buffer, length); |
| 178 |
} |
| 179 |
} |
| 180 |
|
| 181 |
int sslClose(void* _ssl_socket) { |
| 182 |
ssl_socket_t ssl_socket = (ssl_socket_t) _ssl_socket; |
| 183 |
if (ssl_socket == NULL) return -1; |
| 184 |
|
| 185 |
if (ssl_socket->ssl != NULL) { |
| 186 |
(*ssl_shutdown)(ssl_socket->ssl); |
| 187 |
} |
| 188 |
|
| 189 |
closeSocket(ssl_socket->clientSocket); |
| 190 |
|
| 191 |
if (ssl_socket->ssl != NULL) { |
| 192 |
(*ssl_free)(ssl_socket->ssl); |
| 193 |
ssl_socket->ssl = NULL; |
| 194 |
} |
| 195 |
|
| 196 |
if (ssl_socket->sslCtx != NULL) { |
| 197 |
(*ssl_CTX_free)(ssl_socket->sslCtx); |
| 198 |
ssl_socket->sslCtx = NULL; |
| 199 |
} |
| 200 |
|
| 201 |
free(ssl_socket); |
| 202 |
|
| 203 |
return 0; |
| 204 |
} |
| 205 |
|
| 206 |
int sslReset() { |
| 207 |
closeSocket(serverSocket); |
| 208 |
return 0; |
| 209 |
} |
| 210 |
|
| 211 |
int loadOpenSSLLibrary() { |
| 212 |
DLL_REFERENCE opensslLibrary; |
| 213 |
ssl_load_error_strings_t ssl_load_error_strings = NULL; |
| 214 |
ssl_library_init_t ssl_library_init = NULL; |
| 215 |
int rc; |
| 216 |
|
| 217 |
opensslLibrary = LOAD_LIBRARY(SSL_LIBRARY_NAME); |
| 218 |
if (opensslLibrary == NULL) { |
| 219 |
TPTP_LOG_ERROR_MSG(logService, "Unable to find openssl library") ; |
| 220 |
return -1; |
| 221 |
} |
| 222 |
|
| 223 |
ssl_load_error_strings = (ssl_load_error_strings_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_LOAD_ESTRINGS); |
| 224 |
ssl_library_init = (ssl_library_init_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_LIBRARY_INIT); |
| 225 |
sslv23_server_method = (sslv23_server_method_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSLV23_SERVER_METHOD); |
| 226 |
ssl_CTX_new = (ssl_CTX_new_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_CTX_NEW); |
| 227 |
ssl_CTX_use_certificate_file = (ssl_CTX_use_certificate_file_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_CTX_CERT_FILE); |
| 228 |
ssl_CTX_use_PrivateKey_file = (ssl_CTX_use_PrivateKey_file_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_CTX_KEY_FILE); |
| 229 |
ssl_CTX_check_private_key = (ssl_CTX_check_private_key_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_CTX_CHECK_KEY); |
| 230 |
ssl_new = (ssl_new_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_NEW); |
| 231 |
ssl_set_fd = (ssl_set_fd_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_SET_FD); |
| 232 |
ssl_accept = (ssl_accept_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_ACCEPT); |
| 233 |
ssl_read = (ssl_read_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_READ); |
| 234 |
ssl_write = (ssl_write_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_WRITE); |
| 235 |
ssl_get_error = (ssl_get_error_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_GET_ERROR); |
| 236 |
ssl_free = (ssl_free_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_FREE); |
| 237 |
ssl_CTX_free = (ssl_CTX_free_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_CTX_FREE); |
| 238 |
ssl_shutdown = (ssl_shutdown_t) RESOLVE_ENTRY_POINT(opensslLibrary, SSL_SHUTDOWN); |
| 239 |
|
| 240 |
/* Check to make sure we found everything */ |
| 241 |
if (ssl_load_error_strings && |
| 242 |
ssl_library_init && |
| 243 |
sslv23_server_method && |
| 244 |
ssl_CTX_new && |
| 245 |
ssl_CTX_use_certificate_file && |
| 246 |
ssl_CTX_use_PrivateKey_file && |
| 247 |
ssl_CTX_check_private_key && |
| 248 |
ssl_new && |
| 249 |
ssl_set_fd && |
| 250 |
ssl_accept && |
| 251 |
ssl_read && |
| 252 |
ssl_write && |
| 253 |
ssl_get_error && |
| 254 |
ssl_free && |
| 255 |
ssl_shutdown && |
| 256 |
ssl_CTX_free) { |
| 257 |
|
| 258 |
(*ssl_load_error_strings)(); |
| 259 |
(*ssl_library_init)(); |
| 260 |
|
| 261 |
rc = 0; |
| 262 |
} |
| 263 |
else { |
| 264 |
TPTP_LOG_ERROR_MSG(logService, "Unable to resolve openssl library"); |
| 265 |
rc = -1; |
| 266 |
} |
| 267 |
|
| 268 |
return rc; |
| 269 |
} |
| 270 |
|
| 271 |
int checkFile (char* fileName) { |
| 272 |
FILE *fp; |
| 273 |
|
| 274 |
if (fileName == NULL) return -1; |
| 275 |
|
| 276 |
fp = fopen(fileName, "r"); |
| 277 |
if (fp == NULL) { |
| 278 |
return -1; |
| 279 |
} |
| 280 |
|
| 281 |
fclose(fp); |
| 282 |
|
| 283 |
return 0; |
| 284 |
} |
| 285 |
|
| 286 |
int initKeys() { |
| 287 |
if (certFile == NULL) { |
| 288 |
TPTP_LOG_ERROR_MSG(logService, "SSL: no certificate file provided"); |
| 289 |
return -1; |
| 290 |
} |
| 291 |
|
| 292 |
if (checkFile(certFile) < 0) { |
| 293 |
TPTP_LOG_ERROR_MSG1(logService, "SSL: certificate file %s not found", certFile); |
| 294 |
return -1; |
| 295 |
} |
| 296 |
|
| 297 |
if (keyFile == NULL) { |
| 298 |
TPTP_LOG_ERROR_MSG(logService, "SSL: no key file provided"); |
| 299 |
return -1; |
| 300 |
} |
| 301 |
|
| 302 |
if (checkFile(keyFile) < 0) { |
| 303 |
TPTP_LOG_ERROR_MSG1(logService, "SSL: key file %s not found\n", keyFile); |
| 304 |
return -1; |
| 305 |
} |
| 306 |
|
| 307 |
return 0; |
| 308 |
} |
| 309 |
|
| 310 |
void sslSetValue(const char* name, const char* value) { |
| 311 |
if (!strcmp(CERTIFICATE_FILE_KEY,name)) { |
| 312 |
if (value == NULL) |
| 313 |
certFile = NULL; |
| 314 |
else { |
| 315 |
if (certFile != NULL) free(certFile); |
| 316 |
certFile = (char*) malloc(strlen(value)+1); |
| 317 |
strcpy(certFile, value); |
| 318 |
} |
| 319 |
} |
| 320 |
else if (!strcmp(KEYS_FILE_KEY,name)) { |
| 321 |
if (value == NULL) |
| 322 |
keyFile = NULL; |
| 323 |
else { |
| 324 |
if (keyFile != NULL) free(keyFile); |
| 325 |
keyFile = (char*) malloc(strlen(value)+1); |
| 326 |
strcpy(keyFile, value); |
| 327 |
} |
| 328 |
} |
| 329 |
} |
| 330 |
|
| 331 |
char* sslGetValue(const char* name) { |
| 332 |
if (!strcmp(CERTIFICATE_FILE_KEY,name)) return certFile; |
| 333 |
if (!strcmp(KEYS_FILE_KEY,name)) return keyFile; |
| 334 |
return NULL; |
| 335 |
} |
| 336 |
|
| 337 |
char* sslGetProviderName() { |
| 338 |
return VERSION_NUMBER; |
| 339 |
} |