Exemplo n.º 1
0
/**
 * Initializes a ssl connection for server use.
 * @param pemfilename Filename for the key/cert file
 * @return An ssl connection, or NULL if an error occured.
 */
ssl_server_connection *init_ssl_server(char *pemfile, char *clientpemfile) {
        ASSERT(pemfile);
        if (!ssl_initialized)
                start_ssl();
        ssl_server_connection *ssl_server = new_ssl_server_connection(pemfile, clientpemfile);
        if (!(ssl_server->method = SSLv23_server_method())) {
                LogError("Cannot initialize the SSL method -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (!(ssl_server->ctx = SSL_CTX_new(ssl_server->method))) {
                LogError("Cannot initialize SSL server certificate handler -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_use_certificate_chain_file(ssl_server->ctx, pemfile) != 1) {
                LogError("Cannot initialize SSL server certificate -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) != 1) {
                LogError("Cannot initialize SSL server private key -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_check_private_key(ssl_server->ctx) != 1) {
                LogError("The private key doesn't match the certificate public key -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (SSL_CTX_set_cipher_list(ssl_server->ctx, CIPHER_LIST) != 1) {
                LogError("Error setting cipher list '%s' (no valid ciphers)\n", CIPHER_LIST);
                goto sslerror;
        }
        SSL_CTX_set_options(ssl_server->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); // Disable SSLv2 and SSLv3 for security reasons
        SSL_CTX_set_session_cache_mode(ssl_server->ctx, SSL_SESS_CACHE_OFF); // Disable session cache
        /*
         * We need this to force transmission of client certs
         */
        if (!verify_init(ssl_server)) {
                LogError("Verification engine was not properly initialized -- %s\n", SSLERROR);
                goto sslerror;
        }
        if (ssl_server->clientpemfile) {
                STACK_OF(X509_NAME) *stack = SSL_CTX_get_client_CA_list(ssl_server->ctx);
                LogInfo("Found %d client certificates\n", sk_X509_NAME_num(stack));
        }
        return ssl_server;
sslerror:
        delete_ssl_server_socket(ssl_server);
        return NULL;
}
Exemplo n.º 2
0
int context_init(SERVICE_OPTIONS *section) { /* init SSL context */
    /* create SSL context */
    if(section->option.client)
        section->ctx=SSL_CTX_new(section->client_method);
    else /* server mode */
        section->ctx=SSL_CTX_new(section->server_method);
    if(!section->ctx) {
        sslerror("SSL_CTX_new");
        return 1; /* FAILED */
    }
    SSL_CTX_set_ex_data(section->ctx, index_opt, section); /* for callbacks */

    /* load certificate and private key to be verified by the peer server */
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_VERSION_NUMBER>=0x0090809fL
    /* SSL_CTX_set_client_cert_engine() was introduced in OpenSSL 0.9.8i */
    if(section->option.client && section->engine) {
        if(SSL_CTX_set_client_cert_engine(section->ctx, section->engine))
            s_log(LOG_INFO, "Client certificate engine (%s) enabled",
                ENGINE_get_id(section->engine));
        else /* no client certificate functionality in this engine */
            sslerror("SSL_CTX_set_client_cert_engine"); /* ignore error */
    }
#endif
    if(auth_init(section))
        return 1; /* FAILED */

    /* initialize verification of the peer server certificate */
    if(verify_init(section))
        return 1; /* FAILED */

    /* initialize DH/ECDH server mode */
    if(!section->option.client) {
#ifndef OPENSSL_NO_TLSEXT
        SSL_CTX_set_tlsext_servername_arg(section->ctx, section);
        SSL_CTX_set_tlsext_servername_callback(section->ctx, servername_cb);
#endif /* OPENSSL_NO_TLSEXT */
#ifndef OPENSSL_NO_DH
        dh_init(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_DH */
#ifndef OPENSSL_NO_ECDH
        ecdh_init(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_ECDH */
    }

    /* setup session cache */
    if(!section->option.client) {
        unsigned servname_len=(unsigned)strlen(section->servname);
        if(servname_len>SSL_MAX_SSL_SESSION_ID_LENGTH)
            servname_len=SSL_MAX_SSL_SESSION_ID_LENGTH;
        if(!SSL_CTX_set_session_id_context(section->ctx,
                (unsigned char *)section->servname, servname_len)) {
            sslerror("SSL_CTX_set_session_id_context");
            return 1; /* FAILED */
        }
    }
#ifdef SSL_SESS_CACHE_NO_INTERNAL_STORE
    /* the default cache mode is just SSL_SESS_CACHE_SERVER */
    SSL_CTX_set_session_cache_mode(section->ctx,
        SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
    SSL_CTX_sess_set_cache_size(section->ctx, section->session_size);
    SSL_CTX_set_timeout(section->ctx, section->session_timeout);
    SSL_CTX_sess_set_new_cb(section->ctx, sess_new_cb);
    SSL_CTX_sess_set_get_cb(section->ctx, sess_get_cb);
    SSL_CTX_sess_set_remove_cb(section->ctx, sess_remove_cb);

    /* set info callback */
    SSL_CTX_set_info_callback(section->ctx, info_callback);

    /* ciphers, options, mode */
    if(section->cipher_list)
        if(!SSL_CTX_set_cipher_list(section->ctx, section->cipher_list)) {
            sslerror("SSL_CTX_set_cipher_list");
            return 1; /* FAILED */
        }
    SSL_CTX_set_options(section->ctx,
        (SSL_OPTIONS_TYPE)(section->ssl_options_set));
#if OPENSSL_VERSION_NUMBER>=0x009080dfL
    SSL_CTX_clear_options(section->ctx,
        (SSL_OPTIONS_TYPE)(section->ssl_options_clear));
    s_log(LOG_DEBUG, "SSL options: 0x%08lX (+0x%08lX, -0x%08lX)",
        SSL_CTX_get_options(section->ctx),
        section->ssl_options_set, section->ssl_options_clear);
#else /* OpenSSL older than 0.9.8m */
    s_log(LOG_DEBUG, "SSL options: 0x%08lX (+0x%08lX)",
        SSL_CTX_get_options(section->ctx),
        section->ssl_options_set);
#endif /* OpenSSL 0.9.8m or later */

    /* initialize OpenSSL CONF options */
    if(conf_init(section))
        return 1; /* FAILED */

#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
        SSL_MODE_RELEASE_BUFFERS);
#else
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
    return 0; /* OK */
}
Exemplo n.º 3
0
/**
 * Initializes a ssl connection for server use.
 * @param pemfilename Filename for the key/cert file
 * @return An ssl connection, or NULL if an error occured.
 */
ssl_server_connection *init_ssl_server(char *pemfile, char *clientpemfile) {
  SSL_METHOD *server_method = NULL;
  ssl_server_connection *ssl_server;

  ASSERT(pemfile);

  if (!ssl_initialized)
    start_ssl();

  ssl_server = new_ssl_server_connection(pemfile, clientpemfile);
#ifdef OPENSSL_FIPS
  if (FIPS_mode())
    server_method = TLSv1_server_method();
  else
#endif
    server_method = SSLv23_server_method();
  if (!(ssl_server->method = server_method)) {
    LogError("%s: Cannot initialize the SSL method -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (!(ssl_server->ctx = SSL_CTX_new(ssl_server->method))) {
    LogError("%s: Cannot initialize SSL server certificate handler -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (SSL_CTX_use_certificate_chain_file(ssl_server->ctx, pemfile) != 1) {
    LogError("%s: Cannot initialize SSL server certificate -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) != 1) {
    LogError("%s: Cannot initialize SSL server private key -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (SSL_CTX_check_private_key(ssl_server->ctx) != 1) {
    LogError("%s: The private key doesn't match the certificate public key -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  /* Disable session cache */
  SSL_CTX_set_session_cache_mode(ssl_server->ctx, SSL_SESS_CACHE_OFF);

  /*
   * We need this to force transmission of client certs
   */
  if (!verify_init(ssl_server)) {
    LogError("%s: Verification engine was not properly initialized -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  if (ssl_server->clientpemfile) {
    STACK_OF(X509_NAME) *stack = SSL_CTX_get_client_CA_list(ssl_server->ctx);
    LogInfo("%s: Found %d client certificates\n", prog, sk_X509_NAME_num(stack));
  }

  return ssl_server;

sslerror:
  delete_ssl_server_socket(ssl_server);
  return NULL;
}
Exemplo n.º 4
0
void context_init(void) { /* init SSL */
    int i;

#if SSLEAY_VERSION_NUMBER >= 0x00907000L
    /* Load all bundled ENGINEs into memory and make them visible */
    ENGINE_load_builtin_engines();
    /* Register all of them for every algorithm they collectively implement */
    ENGINE_register_all_complete();
#endif
    if(!init_prng())
        log(LOG_INFO, "PRNG seeded successfully");
    SSLeay_add_ssl_algorithms();
    SSL_load_error_strings();
    if(options.option.client) {
        ctx=SSL_CTX_new(SSLv3_client_method());
    } else { /* Server mode */
        ctx=SSL_CTX_new(SSLv23_server_method());
#ifndef NO_RSA
        SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
#endif /* NO_RSA */
        if(init_dh())
            log(LOG_WARNING, "Diffie-Hellman initialization failed");
    }
    if(options.ssl_options) {
        log(LOG_DEBUG, "Configuration SSL options: 0x%08lX",
            options.ssl_options);
        log(LOG_DEBUG, "SSL options set: 0x%08lX", 
            SSL_CTX_set_options(ctx, options.ssl_options));
    }
#if SSLEAY_VERSION_NUMBER >= 0x00906000L
    SSL_CTX_set_mode(ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif /* OpenSSL-0.9.6 */

    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
    SSL_CTX_set_timeout(ctx, options.session_timeout);
    if(options.option.cert) {
        if(!SSL_CTX_use_certificate_chain_file(ctx, options.cert)) {
            log(LOG_ERR, "Error reading certificate file: %s", options.cert);
            sslerror("SSL_CTX_use_certificate_chain_file");
            exit(1);
        }
        log(LOG_DEBUG, "Certificate: %s", options.cert);
        log(LOG_DEBUG, "Key file: %s", options.key);
#ifdef USE_WIN32
        SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
#endif
        for(i=0; i<3; i++) {
#ifdef NO_RSA
            if(SSL_CTX_use_PrivateKey_file(ctx, options.key,
                    SSL_FILETYPE_PEM))
#else /* NO_RSA */
            if(SSL_CTX_use_RSAPrivateKey_file(ctx, options.key,
                    SSL_FILETYPE_PEM))
#endif /* NO_RSA */
                break;
            if(i<2 && ERR_GET_REASON(ERR_peek_error())==EVP_R_BAD_DECRYPT) {
                sslerror_stack(); /* dump the error stack */
                log(LOG_ERR, "Wrong pass phrase: retrying");
                continue;
            }
#ifdef NO_RSA
            sslerror("SSL_CTX_use_PrivateKey_file");
#else /* NO_RSA */
            sslerror("SSL_CTX_use_RSAPrivateKey_file");
#endif /* NO_RSA */
            exit(1);
        }
        if(!SSL_CTX_check_private_key(ctx)) {
            sslerror("Private key does not match the certificate");
            exit(1);
        }
    }

    verify_init(); /* Initialize certificate verification */

    SSL_CTX_set_info_callback(ctx, info_callback);

    if(options.cipher_list) {
        if (!SSL_CTX_set_cipher_list(ctx, options.cipher_list)) {
            sslerror("SSL_CTX_set_cipher_list");
            exit(1);
        }
    }
}
Exemplo n.º 5
0
/**
 * Initializes a ssl connection for server use.
 * @param pemfilename Filename for the key/cert file
 * @return An ssl connection, or NULL if an error occured.
 */
ssl_server_connection *init_ssl_server (char *pemfile, char *clientpemfile) {

#ifdef HAVE_OPENSSL

    ssl_server_connection *ssl_server = new_ssl_server_connection(pemfile,
                                        clientpemfile);

    ASSERT(pemfile);

    if (!ssl_initilized) {

        start_ssl();

    }

    if ((ssl_server->method= SSLv23_server_method()) == NULL ) {

        handle_ssl_error("init_ssl_server()");
        log("%s: init_ssl_server (): Cannot initialize the SSL method!\n", prog);
        goto sslerror;

    }

    if ((ssl_server->ctx= SSL_CTX_new(ssl_server->method)) == NULL ) {

        handle_ssl_error("init_ssl_server()");
        log("%s: init_ssl_server (): Cannot initialize SSL server"
            " certificate handler!\n"
            , prog);
        goto sslerror;

    }

    if (SSL_CTX_use_certificate_file(ssl_server->ctx, pemfile,
                                     SSL_FILETYPE_PEM) <= 0) {

        handle_ssl_error("init_ssl_server()");
        log("%s: init_ssl_server(): Cannot initialize SSL server"
            " certificate!\n", prog);
        goto sslerror;

    }

    if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile,
                                    SSL_FILETYPE_PEM) <= 0) {

        handle_ssl_error("init_ssl_server()");
        log("%s: init_ssl_server(): Cannot initialize SSL server"
            " private key!\n", prog);
        goto sslerror;

    }

    if (!SSL_CTX_check_private_key(ssl_server->ctx)) {

        handle_ssl_error("init_ssl_server()");
        log("%s: init_ssl_server(): The private key does not match the"
            " certificate public key!\n", prog);
        goto sslerror;

    }

    /*
     * We need this to force transmission of client certs
     */
    if (!verify_init(ssl_server)) {

        handle_ssl_error("init_ssl_server()");
        log("%s: init_ssl_server(): Verification engine was not"
            " properly initilized!\n", prog);
        goto sslerror;

    }

    if (ssl_server->clientpemfile != NULL) {

        verify_info(ssl_server);

    }

    return ssl_server;

sslerror:

    cleanup_ssl_server_socket(ssl_server);
    return NULL;

#else

    return NULL;

#endif

}
Exemplo n.º 6
0
Arquivo: ctx.c Projeto: Jimdo/stunnel
int context_init(SERVICE_OPTIONS *section) { /* init SSL context */
    /* create SSL context */
    if(section->option.client)
        section->ctx=SSL_CTX_new(section->client_method);
    else /* server mode */
        section->ctx=SSL_CTX_new(section->server_method);
    if(!section->ctx) {
        sslerror("SSL_CTX_new");
        return 1; /* FAILED */
    }
    SSL_CTX_set_ex_data(section->ctx, opt_index, section); /* for callbacks */

    /* load certificate and private key to be verified by the peer server */
#ifdef HAVE_OSSL_ENGINE_H
    if(section->option.client && section->engine) {
        if(SSL_CTX_set_client_cert_engine(section->ctx, section->engine))
            s_log(LOG_INFO, "Client certificate engine (%s) enabled",
                ENGINE_get_id(section->engine));
        else /* no client certificate functionality in this engine */
            sslerror("SSL_CTX_set_client_cert_engine"); /* ignore error */
    }
#endif
    if(load_cert(section))
        return 1; /* FAILED */

    /* initialize verification of the peer server certificate */
    if(verify_init(section))
        return 1; /* FAILED */

    /* initialize DH/ECDH server mode */
    if(!section->option.client) {
#ifndef OPENSSL_NO_TLSEXT
        SSL_CTX_set_tlsext_servername_arg(section->ctx, section);
        SSL_CTX_set_tlsext_servername_callback(section->ctx, servername_cb);
#endif /* OPENSSL_NO_TLSEXT */
#ifndef OPENSSL_NO_DH
        init_dh(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_DH */
#ifndef OPENSSL_NO_ECDH
        init_ecdh(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_ECDH */
    }

    /* setup session cache */
    if(!section->option.client) {
        unsigned int servname_len=strlen(section->servname);
        if(servname_len>SSL_MAX_SSL_SESSION_ID_LENGTH)
            servname_len=SSL_MAX_SSL_SESSION_ID_LENGTH;
        if(!SSL_CTX_set_session_id_context(section->ctx,
                (unsigned char *)section->servname, servname_len)) {
            sslerror("SSL_CTX_set_session_id_context");
            return 1; /* FAILED */
        }
    }
    SSL_CTX_set_session_cache_mode(section->ctx, SSL_SESS_CACHE_BOTH);
    SSL_CTX_sess_set_cache_size(section->ctx, section->session_size);
    SSL_CTX_set_timeout(section->ctx, section->session_timeout);
    if(section->option.sessiond) {
        SSL_CTX_sess_set_new_cb(section->ctx, sess_new_cb);
        SSL_CTX_sess_set_get_cb(section->ctx, sess_get_cb);
        SSL_CTX_sess_set_remove_cb(section->ctx, sess_remove_cb);
    }

    /* set info callback */
    SSL_CTX_set_info_callback(section->ctx, info_callback);

    /* ciphers, options, mode */
    if(section->cipher_list)
        if(!SSL_CTX_set_cipher_list(section->ctx, section->cipher_list)) {
            sslerror("SSL_CTX_set_cipher_list");
            return 1; /* FAILED */
        }
    s_log(LOG_DEBUG, "SSL options set: 0x%08lX",
        SSL_CTX_set_options(section->ctx, section->ssl_options));
#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
        SSL_MODE_RELEASE_BUFFERS);
#else
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
    return 0; /* OK */
}