Changeset 5ebff60 for lib/ssl_gnutls.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/ssl_gnutls.c
raf359b4 r5ebff60 1 1 /********************************************************************\ 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * … … 50 50 #define SSLDEBUG 0 51 51 52 struct scd 53 { 52 struct scd { 54 53 ssl_input_function func; 55 54 gpointer data; … … 59 58 char *hostname; 60 59 gboolean verify; 61 60 62 61 gnutls_session_t session; 63 62 }; … … 65 64 static GHashTable *session_cache; 66 65 67 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond);68 static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond);69 static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond);70 71 static void ssl_deinit( void);72 73 static void ssl_log( int level, const char *line)74 { 75 printf( "%d %s", level, line);76 } 77 78 void ssl_init( void)79 { 80 if ( initialized )66 static gboolean ssl_connected(gpointer data, gint source, b_input_condition cond); 67 static gboolean ssl_starttls_real(gpointer data, gint source, b_input_condition cond); 68 static gboolean ssl_handshake(gpointer data, gint source, b_input_condition cond); 69 70 static void ssl_deinit(void); 71 72 static void ssl_log(int level, const char *line) 73 { 74 printf("%d %s", level, line); 75 } 76 77 void ssl_init(void) 78 { 79 if (initialized) { 81 80 return; 82 81 } 82 83 83 gnutls_global_init(); 84 gnutls_certificate_allocate_credentials( &xcred ); 85 if( global.conf->cafile ) 86 { 87 gnutls_certificate_set_x509_trust_file( xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM ); 88 84 gnutls_certificate_allocate_credentials(&xcred); 85 if (global.conf->cafile) { 86 gnutls_certificate_set_x509_trust_file(xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM); 87 89 88 /* Not needed in GnuTLS 2.11+ (enabled by default there) so 90 89 don't do it (resets possible other defaults). */ 91 if( !gnutls_check_version( "2.11" ) ) 92 gnutls_certificate_set_verify_flags( xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT ); 90 if (!gnutls_check_version("2.11")) { 91 gnutls_certificate_set_verify_flags(xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); 92 } 93 93 } 94 94 initialized = TRUE; 95 96 gnutls_global_set_log_function( ssl_log);95 96 gnutls_global_set_log_function(ssl_log); 97 97 /* 98 98 gnutls_global_set_log_level( 3 ); 99 99 */ 100 101 session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free);102 103 atexit( ssl_deinit);104 } 105 106 static void ssl_deinit( void)100 101 session_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); 102 103 atexit(ssl_deinit); 104 } 105 106 static void ssl_deinit(void) 107 107 { 108 108 gnutls_global_deinit(); 109 gnutls_certificate_free_credentials( xcred);110 g_hash_table_destroy( session_cache);109 gnutls_certificate_free_credentials(xcred); 110 g_hash_table_destroy(session_cache); 111 111 session_cache = NULL; 112 112 } 113 113 114 void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data)115 { 116 struct scd *conn = g_new0( struct scd, 1);117 114 void *ssl_connect(char *host, int port, gboolean verify, ssl_input_function func, gpointer data) 115 { 116 struct scd *conn = g_new0(struct scd, 1); 117 118 118 conn->func = func; 119 119 conn->data = data; 120 120 conn->inpa = -1; 121 conn->hostname = g_strdup( host);121 conn->hostname = g_strdup(host); 122 122 conn->verify = verify && global.conf->cafile; 123 conn->fd = proxy_connect( host, port, ssl_connected, conn ); 124 125 if( conn->fd < 0 ) 126 { 127 g_free( conn ); 123 conn->fd = proxy_connect(host, port, ssl_connected, conn); 124 125 if (conn->fd < 0) { 126 g_free(conn); 128 127 return NULL; 129 128 } 130 129 131 130 return conn; 132 131 } 133 132 134 void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data)135 { 136 struct scd *conn = g_new0( struct scd, 1);137 133 void *ssl_starttls(int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data) 134 { 135 struct scd *conn = g_new0(struct scd, 1); 136 138 137 conn->fd = fd; 139 138 conn->func = func; 140 139 conn->data = data; 141 140 conn->inpa = -1; 142 conn->hostname = g_strdup( hostname);143 141 conn->hostname = g_strdup(hostname); 142 144 143 /* For now, SSL verification is globally enabled by setting the cafile 145 144 setting in bitlbee.conf. Commented out by default because probably … … 147 146 may not have the cert of their private Jabber server in it. */ 148 147 conn->verify = verify && global.conf->cafile; 149 148 150 149 /* This function should be called via a (short) timeout instead of 151 150 directly from here, because these SSL calls are *supposed* to be … … 153 152 (or *_connect, for examle) returns. Also, errors are reported via 154 153 the callback function, not via this function's return value. 155 154 156 155 In short, doing things like this makes the rest of the code a lot 157 156 simpler. */ 158 159 b_timeout_add( 1, ssl_starttls_real, conn);160 157 158 b_timeout_add(1, ssl_starttls_real, conn); 159 161 160 return conn; 162 161 } 163 162 164 static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond)163 static gboolean ssl_starttls_real(gpointer data, gint source, b_input_condition cond) 165 164 { 166 165 struct scd *conn = data; 167 168 return ssl_connected( conn, conn->fd, B_EV_IO_WRITE);169 } 170 171 static int verify_certificate_callback( gnutls_session_t session)166 167 return ssl_connected(conn, conn->fd, B_EV_IO_WRITE); 168 } 169 170 static int verify_certificate_callback(gnutls_session_t session) 172 171 { 173 172 unsigned int status; … … 178 177 gnutls_x509_crt_t cert; 179 178 struct scd *conn; 180 181 conn = gnutls_session_get_ptr( session);182 183 gnutlsret = gnutls_certificate_verify_peers2( session, &status);184 if ( gnutlsret < 0 )179 180 conn = gnutls_session_get_ptr(session); 181 182 gnutlsret = gnutls_certificate_verify_peers2(session, &status); 183 if (gnutlsret < 0) { 185 184 return VERIFY_CERT_ERROR; 186 187 if( status & GNUTLS_CERT_INVALID ) 185 } 186 187 if (status & GNUTLS_CERT_INVALID) { 188 188 verifyret |= VERIFY_CERT_INVALID; 189 190 if( status & GNUTLS_CERT_REVOKED ) 189 } 190 191 if (status & GNUTLS_CERT_REVOKED) { 191 192 verifyret |= VERIFY_CERT_REVOKED; 192 193 if( status & GNUTLS_CERT_SIGNER_NOT_FOUND ) 193 } 194 195 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 194 196 verifyret |= VERIFY_CERT_SIGNER_NOT_FOUND; 195 196 if( status & GNUTLS_CERT_SIGNER_NOT_CA ) 197 } 198 199 if (status & GNUTLS_CERT_SIGNER_NOT_CA) { 197 200 verifyret |= VERIFY_CERT_SIGNER_NOT_CA; 198 199 if( status & GNUTLS_CERT_INSECURE_ALGORITHM ) 201 } 202 203 if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { 200 204 verifyret |= VERIFY_CERT_INSECURE_ALGORITHM; 205 } 201 206 202 207 #ifdef GNUTLS_CERT_NOT_ACTIVATED 203 208 /* Amusingly, the GnuTLS function used above didn't check for expiry 204 209 until GnuTLS 2.8 or so. (See CVE-2009-1417) */ 205 if ( status & GNUTLS_CERT_NOT_ACTIVATED )210 if (status & GNUTLS_CERT_NOT_ACTIVATED) { 206 211 verifyret |= VERIFY_CERT_NOT_ACTIVATED; 207 208 if( status & GNUTLS_CERT_EXPIRED ) 212 } 213 214 if (status & GNUTLS_CERT_EXPIRED) { 209 215 verifyret |= VERIFY_CERT_EXPIRED; 216 } 210 217 #endif 211 218 212 if ( gnutls_certificate_type_get( session ) != GNUTLS_CRT_X509 || gnutls_x509_crt_init( &cert ) < 0 )219 if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509 || gnutls_x509_crt_init(&cert) < 0) { 213 220 return VERIFY_CERT_ERROR; 214 215 cert_list = gnutls_certificate_get_peers( session, &cert_list_size ); 216 if( cert_list == NULL || gnutls_x509_crt_import( cert, &cert_list[0], GNUTLS_X509_FMT_DER ) < 0 ) 221 } 222 223 cert_list = gnutls_certificate_get_peers(session, &cert_list_size); 224 if (cert_list == NULL || gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { 217 225 return VERIFY_CERT_ERROR; 218 219 if( !gnutls_x509_crt_check_hostname( cert, conn->hostname ) ) 220 {226 } 227 228 if (!gnutls_x509_crt_check_hostname(cert, conn->hostname)) { 221 229 verifyret |= VERIFY_CERT_INVALID; 222 230 verifyret |= VERIFY_CERT_WRONG_HOSTNAME; 223 231 } 224 232 225 gnutls_x509_crt_deinit( cert);233 gnutls_x509_crt_deinit(cert); 226 234 227 235 return verifyret; 228 236 } 229 237 230 struct ssl_session 231 { 238 struct ssl_session { 232 239 size_t size; 233 240 char data[]; 234 241 }; 235 242 236 static void ssl_cache_add( struct scd *conn)243 static void ssl_cache_add(struct scd *conn) 237 244 { 238 245 size_t data_size = 0; 239 246 struct ssl_session *data; 240 247 char *hostname; 241 242 if ( !conn->hostname ||243 gnutls_session_get_data( conn->session, NULL, &data_size ) != 0 )248 249 if (!conn->hostname || 250 gnutls_session_get_data(conn->session, NULL, &data_size) != 0) { 244 251 return; 245 246 data = g_malloc( sizeof( struct ssl_session ) + data_size ); 247 if( gnutls_session_get_data( conn->session, data->data, &data_size ) != 0 )248 {249 g_free( data);252 } 253 254 data = g_malloc(sizeof(struct ssl_session) + data_size); 255 if (gnutls_session_get_data(conn->session, data->data, &data_size) != 0) { 256 g_free(data); 250 257 return; 251 258 } 252 253 hostname = g_strdup( conn->hostname);254 g_hash_table_insert( session_cache, hostname, data);255 } 256 257 static void ssl_cache_resume( struct scd *conn)259 260 hostname = g_strdup(conn->hostname); 261 g_hash_table_insert(session_cache, hostname, data); 262 } 263 264 static void ssl_cache_resume(struct scd *conn) 258 265 { 259 266 struct ssl_session *data; 260 261 if( conn->hostname && 262 ( data = g_hash_table_lookup( session_cache, conn->hostname ) ) ) 263 { 264 gnutls_session_set_data( conn->session, data->data, data->size ); 265 g_hash_table_remove( session_cache, conn->hostname ); 266 } 267 } 268 269 char *ssl_verify_strerror( int code ) 270 { 271 GString *ret = g_string_new( "" ); 272 273 if( code & VERIFY_CERT_REVOKED ) 274 g_string_append( ret, "certificate has been revoked, " ); 275 if( code & VERIFY_CERT_SIGNER_NOT_FOUND ) 276 g_string_append( ret, "certificate hasn't got a known issuer, " ); 277 if( code & VERIFY_CERT_SIGNER_NOT_CA ) 278 g_string_append( ret, "certificate's issuer is not a CA, " ); 279 if( code & VERIFY_CERT_INSECURE_ALGORITHM ) 280 g_string_append( ret, "certificate uses an insecure algorithm, " ); 281 if( code & VERIFY_CERT_NOT_ACTIVATED ) 282 g_string_append( ret, "certificate has not been activated, " ); 283 if( code & VERIFY_CERT_EXPIRED ) 284 g_string_append( ret, "certificate has expired, " ); 285 if( code & VERIFY_CERT_WRONG_HOSTNAME ) 286 g_string_append( ret, "certificate hostname mismatch, " ); 287 288 if( ret->len == 0 ) 289 { 290 g_string_free( ret, TRUE ); 267 268 if (conn->hostname && 269 (data = g_hash_table_lookup(session_cache, conn->hostname))) { 270 gnutls_session_set_data(conn->session, data->data, data->size); 271 g_hash_table_remove(session_cache, conn->hostname); 272 } 273 } 274 275 char *ssl_verify_strerror(int code) 276 { 277 GString *ret = g_string_new(""); 278 279 if (code & VERIFY_CERT_REVOKED) { 280 g_string_append(ret, "certificate has been revoked, "); 281 } 282 if (code & VERIFY_CERT_SIGNER_NOT_FOUND) { 283 g_string_append(ret, "certificate hasn't got a known issuer, "); 284 } 285 if (code & VERIFY_CERT_SIGNER_NOT_CA) { 286 g_string_append(ret, "certificate's issuer is not a CA, "); 287 } 288 if (code & VERIFY_CERT_INSECURE_ALGORITHM) { 289 g_string_append(ret, "certificate uses an insecure algorithm, "); 290 } 291 if (code & VERIFY_CERT_NOT_ACTIVATED) { 292 g_string_append(ret, "certificate has not been activated, "); 293 } 294 if (code & VERIFY_CERT_EXPIRED) { 295 g_string_append(ret, "certificate has expired, "); 296 } 297 if (code & VERIFY_CERT_WRONG_HOSTNAME) { 298 g_string_append(ret, "certificate hostname mismatch, "); 299 } 300 301 if (ret->len == 0) { 302 g_string_free(ret, TRUE); 291 303 return NULL; 292 } 293 else 294 { 295 g_string_truncate( ret, ret->len - 2 ); 296 return g_string_free( ret, FALSE ); 297 } 298 } 299 300 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ) 304 } else { 305 g_string_truncate(ret, ret->len - 2); 306 return g_string_free(ret, FALSE); 307 } 308 } 309 310 static gboolean ssl_connected(gpointer data, gint source, b_input_condition cond) 301 311 { 302 312 struct scd *conn = data; 303 304 if( source == -1 ) 305 { 306 conn->func( conn->data, 0, NULL, cond ); 307 g_free( conn ); 313 314 if (source == -1) { 315 conn->func(conn->data, 0, NULL, cond); 316 g_free(conn); 308 317 return FALSE; 309 318 } 310 319 311 320 ssl_init(); 312 313 gnutls_init( &conn->session, GNUTLS_CLIENT);314 gnutls_session_set_ptr( conn->session, (void *) conn);321 322 gnutls_init(&conn->session, GNUTLS_CLIENT); 323 gnutls_session_set_ptr(conn->session, (void *) conn); 315 324 #if GNUTLS_VERSION_NUMBER < 0x020c00 316 gnutls_transport_set_lowat( conn->session, 0);325 gnutls_transport_set_lowat(conn->session, 0); 317 326 #endif 318 gnutls_set_default_priority( conn->session ); 319 gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, xcred ); 320 if( conn->hostname && !g_ascii_isdigit( conn->hostname[0] ) ) 321 gnutls_server_name_set( conn->session, GNUTLS_NAME_DNS, 322 conn->hostname, strlen( conn->hostname ) ); 323 324 sock_make_nonblocking( conn->fd ); 325 gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr_t) GNUTLS_STUPID_CAST conn->fd ); 326 327 ssl_cache_resume( conn ); 328 329 return ssl_handshake( data, source, cond ); 330 } 331 332 static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ) 327 gnutls_set_default_priority(conn->session); 328 gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, xcred); 329 if (conn->hostname && !g_ascii_isdigit(conn->hostname[0])) { 330 gnutls_server_name_set(conn->session, GNUTLS_NAME_DNS, 331 conn->hostname, strlen(conn->hostname)); 332 } 333 334 sock_make_nonblocking(conn->fd); 335 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) GNUTLS_STUPID_CAST conn->fd); 336 337 ssl_cache_resume(conn); 338 339 return ssl_handshake(data, source, cond); 340 } 341 342 static gboolean ssl_handshake(gpointer data, gint source, b_input_condition cond) 333 343 { 334 344 struct scd *conn = data; 335 345 int st, stver; 336 346 337 347 /* This function returns false, so avoid calling b_event_remove again */ 338 348 conn->inpa = -1; 339 340 if( ( st = gnutls_handshake( conn->session ) ) < 0 ) 341 { 342 if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED ) 343 { 344 conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), 345 ssl_handshake, data ); 349 350 if ((st = gnutls_handshake(conn->session)) < 0) { 351 if (st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED) { 352 conn->inpa = b_input_add(conn->fd, ssl_getdirection(conn), 353 ssl_handshake, data); 354 } else { 355 conn->func(conn->data, 0, NULL, cond); 356 357 gnutls_deinit(conn->session); 358 closesocket(conn->fd); 359 360 g_free(conn); 346 361 } 347 else 348 { 349 conn->func( conn->data, 0, NULL, cond ); 350 351 gnutls_deinit( conn->session ); 352 closesocket( conn->fd ); 353 354 g_free( conn ); 362 } else { 363 if (conn->verify && (stver = verify_certificate_callback(conn->session)) != 0) { 364 conn->func(conn->data, stver, NULL, cond); 365 366 gnutls_deinit(conn->session); 367 closesocket(conn->fd); 368 369 g_free(conn); 370 } else { 371 /* For now we can't handle non-blocking perfectly everywhere... */ 372 sock_make_blocking(conn->fd); 373 374 ssl_cache_add(conn); 375 conn->established = TRUE; 376 conn->func(conn->data, 0, conn, cond); 355 377 } 356 378 } 357 else 358 { 359 if( conn->verify && ( stver = verify_certificate_callback( conn->session ) ) != 0 ) 360 { 361 conn->func( conn->data, stver, NULL, cond ); 362 363 gnutls_deinit( conn->session ); 364 closesocket( conn->fd ); 365 366 g_free( conn ); 367 } 368 else 369 { 370 /* For now we can't handle non-blocking perfectly everywhere... */ 371 sock_make_blocking( conn->fd ); 372 373 ssl_cache_add( conn ); 374 conn->established = TRUE; 375 conn->func( conn->data, 0, conn, cond ); 376 } 377 } 378 379 379 380 return FALSE; 380 381 } 381 382 382 int ssl_read( void *conn, char *buf, int len)383 int ssl_read(void *conn, char *buf, int len) 383 384 { 384 385 int st; 385 386 if( !((struct scd*)conn)->established ) 387 { 386 387 if (!((struct scd*) conn)->established) { 388 388 ssl_errno = SSL_NOHANDSHAKE; 389 389 return -1; 390 390 } 391 392 st = gnutls_record_recv( ((struct scd*)conn)->session, buf, len);393 391 392 st = gnutls_record_recv(((struct scd*) conn)->session, buf, len); 393 394 394 ssl_errno = SSL_OK; 395 if ( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )395 if (st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED) { 396 396 ssl_errno = SSL_AGAIN; 397 398 if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st ); 399 397 } 398 399 if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0) { 400 len = write(2, buf, st); 401 } 402 400 403 return st; 401 404 } 402 405 403 int ssl_write( void *conn, const char *buf, int len)406 int ssl_write(void *conn, const char *buf, int len) 404 407 { 405 408 int st; 406 407 if( !((struct scd*)conn)->established ) 408 { 409 410 if (!((struct scd*) conn)->established) { 409 411 ssl_errno = SSL_NOHANDSHAKE; 410 412 return -1; 411 413 } 412 413 st = gnutls_record_send( ((struct scd*)conn)->session, buf, len);414 414 415 st = gnutls_record_send(((struct scd*) conn)->session, buf, len); 416 415 417 ssl_errno = SSL_OK; 416 if ( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )418 if (st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED) { 417 419 ssl_errno = SSL_AGAIN; 418 419 if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st ); 420 420 } 421 422 if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0) { 423 len = write(2, buf, st); 424 } 425 421 426 return st; 422 427 } 423 428 424 int ssl_pending( void *conn)425 { 426 if ( conn == NULL )429 int ssl_pending(void *conn) 430 { 431 if (conn == NULL) { 427 432 return 0; 428 429 if( !((struct scd*)conn)->established ) 430 {433 } 434 435 if (!((struct scd*) conn)->established) { 431 436 ssl_errno = SSL_NOHANDSHAKE; 432 437 return 0; … … 434 439 435 440 #if GNUTLS_VERSION_NUMBER >= 0x03000d && GNUTLS_VERSION_NUMBER <= 0x030012 436 if ( ssl_errno == SSL_AGAIN )441 if (ssl_errno == SSL_AGAIN) { 437 442 return 0; 443 } 438 444 #endif 439 440 return gnutls_record_check_pending( ((struct scd*)conn)->session) != 0;441 } 442 443 void ssl_disconnect( void *conn_)445 446 return gnutls_record_check_pending(((struct scd*) conn)->session) != 0; 447 } 448 449 void ssl_disconnect(void *conn_) 444 450 { 445 451 struct scd *conn = conn_; 446 447 if( conn->inpa != -1 ) 448 b_event_remove( conn->inpa ); 449 450 if( conn->established ) 451 gnutls_bye( conn->session, GNUTLS_SHUT_WR ); 452 453 closesocket( conn->fd ); 454 455 if( conn->session ) 456 gnutls_deinit( conn->session ); 457 g_free( conn->hostname ); 458 g_free( conn ); 459 } 460 461 int ssl_getfd( void *conn ) 462 { 463 return( ((struct scd*)conn)->fd ); 464 } 465 466 b_input_condition ssl_getdirection( void *conn ) 467 { 468 return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ? 469 B_EV_IO_WRITE : B_EV_IO_READ ); 470 } 471 472 size_t ssl_des3_encrypt( const unsigned char *key, size_t key_len, const unsigned char *input, 473 size_t input_len, const unsigned char *iv, unsigned char **res ) 452 453 if (conn->inpa != -1) { 454 b_event_remove(conn->inpa); 455 } 456 457 if (conn->established) { 458 gnutls_bye(conn->session, GNUTLS_SHUT_WR); 459 } 460 461 closesocket(conn->fd); 462 463 if (conn->session) { 464 gnutls_deinit(conn->session); 465 } 466 g_free(conn->hostname); 467 g_free(conn); 468 } 469 470 int ssl_getfd(void *conn) 471 { 472 return(((struct scd*) conn)->fd); 473 } 474 475 b_input_condition ssl_getdirection(void *conn) 476 { 477 return(gnutls_record_get_direction(((struct scd*) conn)->session) ? 478 B_EV_IO_WRITE : B_EV_IO_READ); 479 } 480 481 size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, 482 size_t input_len, const unsigned char *iv, unsigned char **res) 474 483 { 475 484 gcry_cipher_hd_t gcr; 476 485 gcry_error_t st; 477 486 478 487 ssl_init(); 479 480 *res = g_malloc( input_len);481 st = gcry_cipher_open( &gcr, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0) ||482 gcry_cipher_setkey( gcr, key, key_len) ||483 gcry_cipher_setiv( gcr, iv, 8) ||484 gcry_cipher_encrypt( gcr, *res, input_len, input, input_len);485 486 gcry_cipher_close( gcr);487 488 if ( st == 0 )488 489 *res = g_malloc(input_len); 490 st = gcry_cipher_open(&gcr, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0) || 491 gcry_cipher_setkey(gcr, key, key_len) || 492 gcry_cipher_setiv(gcr, iv, 8) || 493 gcry_cipher_encrypt(gcr, *res, input_len, input, input_len); 494 495 gcry_cipher_close(gcr); 496 497 if (st == 0) { 489 498 return input_len; 490 491 g_free( *res ); 499 } 500 501 g_free(*res); 492 502 return 0; 493 503 }
Note: See TracChangeset
for help on using the changeset viewer.