2016-09-06 12 views
1

私はopenssl(クライアントとサーバーとして)を使用するLinuxマルチプロセスプラットフォームで作業しています。セッションの再利用(セッションID付き)とEXTERNAL CACHEを実装する必要があります。複数のプロセスのセッション用外部キャッシュ

私は、同じSSL_CTXオブジェクトを使用する場合のみ、新しく通知されるためにopensslにコールバックを接続してSSL_SESSIONを取得することに成功しました。

私の問題は、SSL_CTXオブジェクトが決して同じではない場合にセッションオブジェクトを再利用する方法です。

Opensslはそのために構築されていないようです。 いくつかの言葉で、私はSSL_CTXに依存しないSSLセッション用の外部キャッシュを実装したいと思います。

さらにもう1つ:それを行ったオープンソースプロジェクトを知っていますか?私はmod_sslがそのように動作しているとは思いますが、それを確認する必要はありません。

ありがとうございました。

* EDIT *私は例として、いくつかのコードを書いた

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <sys/socket.h> 

#include <openssl/ssl.h> 
#include <openssl/err.h> 

static SSL_SESSION* sess_session = 0; 
static unsigned char* char_session; 
static long char_session_length; 

static int new_session_cb(struct ssl_st *ssl, SSL_SESSION *sessionX) 
{ 
    printf("!!! NEW SESSION CB !!!\n"); 

    char_session_length = i2d_SSL_SESSION(sessionX, &char_session); 
    printf("Session length: %ld bytes.\n",char_session_length); 
    sess_session = sessionX; 
    return 0; 
} 

static void remove_session_cb(struct ssl_ctx_st *ctx, SSL_SESSION *sess) 
{ 
    printf("!!! REMOVE SESSION CB !!!\n"); 
    return; 
} 

static SSL_SESSION *get_session_cb(struct ssl_st *ssl, const unsigned char *data, int len, int *copy) 
{ 
    printf("!!! GET SESSION CB !!!\n"); 

    /* allow the session to be freed automatically by openssl */ 
    *copy = 0; 

    SSL_SESSION* a; 
    const unsigned char* ptr = (const unsigned char *)malloc(char_session_length); 
    memcpy(ptr,char_session, char_session_length); 
    a = d2i_SSL_SESSION(NULL, &ptr, char_session_length); 
    free((void*)ptr); 
    return a; 
} 


int main(int argc, char **argv) 
{ 
    SSL    *ssl = NULL; 
    SSL_CTX   *ctx = NULL; 
    int     servfd = -1; 
    int     clntfd = -1; 
    struct sockaddr_in serv; 
    struct sockaddr_in clnt; 
    socklen_t   socksize; 
    char    buf[128]; 
    int     ret; 
    int     clean_disconnect; 

    /* Initialize OpenSSL. */ 
    SSL_library_init(); 
    SSL_load_error_strings(); 
    OpenSSL_add_all_algorithms(); 

    /* Setup the socket to listen for incoming connections. */ 
    memset(&serv, 0, sizeof(serv)); 
    serv.sin_family  = AF_INET; 
    serv.sin_addr.s_addr = htonl(INADDR_ANY); 
    serv.sin_port  = htons(4433); 
    servfd    = socket(AF_INET, SOCK_STREAM, 0); 
    if (servfd == -1) { 
     printf("Failed to create socket\n"); 
     return 0; 
    } 
    if (bind(servfd, (struct sockaddr *)&serv, sizeof(struct sockaddr)) != 0) { 
     printf("Failed to bind\n"); 
     goto cleanup; 
    } 

    if (listen(servfd, 512) != 0) { 
     printf("Failed to listen\n"); 
     goto cleanup; 
    } 
    /* Wait for and handle connections as they come in. */ 
    while (1) { 

     printf("Loop..\n"); 

     /* Generate an SSL server context. */ 
     ctx = SSL_CTX_new(SSLv23_server_method()); 
     if (ctx == NULL) { 
      printf("Failed to create SSL server context\n"); 
      goto cleanup; 
     } 

     /* Set some options and the session id. 
     * SSL_OP_NO_SSLv2: SSLv2 is insecure, disable it. 
     * SSL_OP_NO_TICKET: We don't want TLS tickets used because this is an SSL server caching example. 
     *     It should be fine to use tickets in addition to server side caching. 
     */ 
     SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET); 
     SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_NO_INTERNAL); 
     SSL_CTX_sess_set_new_cb(ctx, new_session_cb); 
     SSL_CTX_sess_set_remove_cb(ctx,remove_session_cb); 
     SSL_CTX_sess_set_get_cb(ctx, get_session_cb); 

     /* Load certificate. */ 
     if (SSL_CTX_use_certificate_file(ctx, "/XXXX/certs/www.site1.com.crt", SSL_FILETYPE_PEM) != 1) { 
      printf("Failed to load cert.pem\n"); 
      goto cleanup; 
     } 
     if (SSL_CTX_use_PrivateKey_file(ctx, "/XXXX/certs/www.site1.com.key.pem.insecure", SSL_FILETYPE_PEM) != 1) { 
      printf("Failed to load key.pem\n"); 
      goto cleanup; 
     } 
     if (!SSL_CTX_check_private_key(ctx)) { 
      printf("Failed to validate cert\n"); 
      goto cleanup; 
     } 

     socksize = sizeof(struct sockaddr_in); 
     clntfd = accept(servfd, (struct sockaddr *)&clnt, &socksize); 
     if (clntfd == -1) { 
      continue; 
     } 
     ssl = SSL_new(ctx); 
     SSL_set_fd(ssl, clntfd); 
     SSL_accept(ssl); 

     clean_disconnect = 1; 
     ret = SSL_read(ssl, buf, sizeof(buf)); 
     if (ret <= 0) { 
      switch (SSL_get_error(ssl, ret)) { 
       case SSL_ERROR_NONE: 
       case SSL_ERROR_ZERO_RETURN: 
        break; 
       default: 
        clean_disconnect = 0; 
        break; 
      } 
     } 
     if (clean_disconnect) { 
      SSL_shutdown(ssl); 
     } else { 
      SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 
     } 

     SSL_free(ssl); 
     close(clntfd); 
cleanup: 
     if (ctx != NULL) 
      SSL_CTX_free(ctx); 
    } 

    if (servfd != -1) 
     close(servfd); 

    return 0; 
} 

をそして、私はこのクラッシュました:あなたはPEM_write_bio_SSL_SESSIONPEM_read_bio_SSL_SESSIONSSL_get1_sessionを使用したい

Loop.. 
!!! NEW SESSION CB !!! 
Session length: 115 bytes. 
Clean Disconnect do shutdown... 
Loop.. 
!!! GET SESSION CB !!! 

Program received signal SIGSEGV, Segmentation fault. 
malloc_consolidate ([email protected]=0x7ffff79b1760 <main_arena>) at malloc.c:4151 
4151 malloc.c: No such file or directory. 
(gdb) bt 
#0 malloc_consolidate ([email protected]=0x7ffff79b1760 <main_arena>) at malloc.c:4151 
#1 0x00007ffff7672ce8 in _int_malloc (av=0x7ffff79b1760 <main_arena>, bytes=1056) at malloc.c:3423 
#2 0x00007ffff76756c0 in __GI___libc_malloc (bytes=1056) at malloc.c:2891 
#3 0x00000000004afa36 in CRYPTO_malloc (num=1056, file=0x5f893a "crypto/kdf/tls1_prf.c", line=40) at crypto/mem.c:92 
#4 0x00000000004afa69 in CRYPTO_zalloc (num=1056, file=0x5f893a "crypto/kdf/tls1_prf.c", line=40) at crypto/mem.c:100 
#5 0x00000000004adefd in pkey_tls1_prf_init (ctx=0x8badf0) at crypto/kdf/tls1_prf.c:40 
#6 0x00000000004a79be in int_ctx_new (pkey=0x0, e=0x0, id=1021) at crypto/evp/pmeth_lib.c:135 
#7 0x00000000004a7cca in EVP_PKEY_CTX_new_id (id=1021, e=0x0) at crypto/evp/pmeth_lib.c:220 
#8 0x000000000044d6e6 in tls1_PRF (s=0x8bb800, seed1=0x5f0c09, seed1_len=13, seed2=0x8baa10, seed2_len=32, seed3=0x8baa30, seed3_len=32, seed4=0x0, seed4_len=0, 
    seed5=0x0, seed5_len=0, sec=0x8cc0f8 "\324\f", <incomplete sequence \353>, slen=48, out=0x8bad90 "h\031\233\367\377\177", olen=88) at ssl/t1_enc.c:65 
#9 0x000000000044d945 in tls1_generate_key_block (s=0x8bb800, km=0x8bad90 "h\031\233\367\377\177", num=88) at ssl/t1_enc.c:94 
#10 0x000000000044e6de in tls1_setup_key_block (s=0x8bb800) at ssl/t1_enc.c:417 
#11 0x0000000000431a37 in ossl_statem_server_pre_work (s=0x8bb800, wst=WORK_MORE_A) at ssl/statem/statem_srvr.c:477 
#12 0x0000000000424d78 in write_state_machine (s=0x8bb800) at ssl/statem/statem.c:725 
#13 0x0000000000424658 in state_machine (s=0x8bb800, server=1) at ssl/statem/statem.c:394 
#14 0x0000000000424138 in ossl_statem_accept (s=0x8bb800) at ssl/statem/statem.c:175 
#15 0x000000000041ca46 in SSL_do_handshake (s=0x8bb800) at ssl/ssl_lib.c:3025 
#16 0x00000000004199ba in SSL_accept (s=0x8bb800) at ssl/ssl_lib.c:1457 
#17 0x00000000004034ee in main (argc=1, argv=0x7fffffffdf28) at ../src/openssl_server2.c:195 
(gdb) 

答えて

0

をし、 SSL_set_session。しかし、これは基本的なものです。

ここでは詳細について説明しているlinkです。わたしにはできる。ディスク上の秘密情報も暗号化できます。

ディスクに秘密を残すことが問題にならないかどうかによって異なります。

関連する問題