Esempio n. 1
0
int SSL_CTX_build_cert_chain(SSL_CTX* ssl_ctx, X509** certs, int count)
{
    int i;

    for (i = count - 1; i >= 0; --i)
        if (!SSL_CTX_add_extra_chain_cert(ssl_ctx, certs[i]))
        {
            write_out(PRINT_ERROR, "Unable to build certificate chain.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            return 0;
        }
    
    return 1;
}
Esempio n. 2
0
void shutdown_ssl(SSL* ssl, int sockfd, BIO* rbio, BIO* wbio)
{
    int err;
    
    write_out(PRINT_INFO, "Attempting to gracefully shutdown TLS socket.");
    for (;;)
    {
        err = SSL_shutdown(ssl);

        if (err < 0)
        {
            err = SSL_get_error(ssl, err);
            
            switch (err)
            {
                case SSL_ERROR_WANT_WRITE:
                    put_bio_data(sockfd, rbio, 0, 0);
                    break;
                case SSL_ERROR_WANT_READ:
                    send_bio_data(sockfd, wbio, 0, 0);
                    if (put_bio_data(sockfd, rbio, 0, 0) <= 0)
                        goto for_break;
                    break;                
                default:
                    write_out(PRINT_WARNING, "Error in TLS shutdown!");
                    write_raise_level();
                    write_out(PRINT_ERROR, "TLS error: %d", SSL_get_error(ssl, err));
                    print_ssl_error_stack(PRINT_ERROR);
                    write_lower_level();
            }
        }
        else if (err == 1)
            break;
    }
for_break: ;
}
Esempio n. 3
0
//SSL_CTX* init_ssl_server_ctx(const SSL_METHOD* method, const char* server_cert, const char* server_priv_key, const char* dh_params, const char* ecdh_curve, const char* ecdsa_cert, const char* ecdsa_privkey, int check_client)
SSL_CTX* init_ssl_server_ctx(const SSL_METHOD* method, X509* server_cert, EVP_PKEY* server_priv_key, const char* dh_params, const char* ecdh_curve, X509* ecdsa_cert, EVP_PKEY* ecdsa_privkey, X509* root_cert)
{
    SSL_CTX* ssl_ctx = 0;
    DH* dh = 0;
    EC_KEY* ecdh = 0;
    FILE* param_file = 0;
    X509_STORE* x509_store;
    int nid;
    
    //make ssl context
    if (!(ssl_ctx = SSL_CTX_new(method)))
    {
        write_out(PRINT_ERROR, "Unable to initialize OpenSSL.");
        write_raise_level();
        print_ssl_error_stack(PRINT_ERROR);
        write_lower_level();
        
        goto error_die;
    }
    
    //disable renegotiation to ensure a fresh start
    SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_OFF);
    SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_TICKET);
    
    if (server_cert && server_priv_key)
    {
        //load rsa certs
        //if (SSL_CTX_use_certificate_file(ssl_ctx, server_cert, SSL_FILETYPE_PEM) != 1)
        if (SSL_CTX_use_certificate(ssl_ctx, server_cert) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load RSA certificate.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        if (SSL_CTX_use_PrivateKey(ssl_ctx, server_priv_key) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load RSA private key.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        if (!SSL_CTX_check_private_key(ssl_ctx))
        {
            write_out(PRINT_ERROR, "RSA Certificate and private key do not match!");
            
            goto error_die;
        }
    }
    
    if (dh_params)
    {    
        //load dh params
        param_file = fopen(dh_params, "rb");
        if (!param_file)
        {
            write_out(PRINT_ERROR, "DH Parameter file could not be read: %s", dh_params);
        }
        
        dh = PEM_read_DHparams(param_file, 0, 0, 0);
        if (!dh)
        {
            write_out(PRINT_ERROR, "DH Parameters could not be loaded!");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        fclose(param_file);
        param_file = 0;

        if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1)
        {
            write_out(PRINT_ERROR, "DH Parameters could not be set!");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        DH_free(dh);
        dh = 0;
    }
    
    if (ecdh_curve)
    {
        //load ecdh params
        if ((nid = OBJ_sn2nid(ecdh_curve)) == NID_undef)
        {
            write_out(PRINT_ERROR, "Unable to find elliptic curve %s.", ecdh_curve);
            goto error_die;
        }
        
        if ((ecdh = EC_KEY_new_by_curve_name(nid)) == 0)
        {
            write_out(PRINT_ERROR, "Unable to create elliptic curve %s.", ecdh_curve);
            goto error_die;
        }
        
        if (SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh) != 1)
        {
            write_out(PRINT_ERROR, "ECDH Parameters could not be set!");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        EC_KEY_free(ecdh);
        ecdh = 0;
    }
    
    if (ecdsa_cert && ecdsa_privkey)
    {
        //load ecdsa certs
        //if (SSL_CTX_use_certificate_file(ssl_ctx, ecdsa_cert, SSL_FILETYPE_PEM) != 1)
        if (SSL_CTX_use_certificate(ssl_ctx, ecdsa_cert) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load ECDSA certificate.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        //if (SSL_CTX_use_PrivateKey_file(ssl_ctx, ecdsa_privkey, SSL_FILETYPE_PEM) != 1)
        if (SSL_CTX_use_PrivateKey(ssl_ctx, ecdsa_privkey) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load ECDSA private key.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        if (!SSL_CTX_check_private_key(ssl_ctx))
        {
            write_out(PRINT_ERROR, "ECDSA Certificate and private key do not match!");
            
            goto error_die;
        }
    }

    //setup the root_cert for verification
    if (root_cert)
    {
        x509_store = SSL_CTX_get_cert_store(ssl_ctx);
        
        X509_STORE_add_cert(x509_store, root_cert);
    }
    
    return ssl_ctx;
    
error_die:
    if (ssl_ctx)
        SSL_CTX_free(ssl_ctx);
    
    if (param_file)
        fclose(param_file);
    
    if (dh)
        DH_free(dh);
    
    if (ecdh)
        EC_KEY_free(ecdh);
    
    return 0;
}
Esempio n. 4
0
int do_handshake(int sockfd, SSL* ssl, BIO* rbio, BIO* wbio, MUTATOR in_mut, void* in_state, MUTATOR out_mut, void* out_state)
{
    int err;

    SSL_set_accept_state(ssl);
    
    write_out(PRINT_INFO, "Starting TLS handshake...");
    write_raise_level();
    while (!SSL_is_init_finished(ssl))
    {
        //write_out(PRINT_INFO, "SSL_accept");
        err = SSL_accept(ssl);
        if (err <= 0)
        {
            err = SSL_get_error(ssl, err);
            switch (err)
            {
                case SSL_ERROR_WANT_READ:
                    //grab handshake info in the BIO and send it out to the client if there is any
                    if (!send_bio_data(sockfd, wbio, out_mut, out_state))
                    {
                        write_out(PRINT_ERROR, "TLS handshake error while sending data!");
                        write_lower_level();
                        return HANDSHAKE_UNSUCCESSFUL;
                    }
                    
                    if (!put_bio_data(sockfd, rbio, in_mut, in_state))
                    {
                        write_out(PRINT_ERROR, "TLS handshake error while recv'ing data!");
                        write_lower_level();
                        return HANDSHAKE_UNSUCCESSFUL;
                    }
                    
                    break;
                case SSL_ERROR_SSL:
                    if (ERR_peek_error() == 0x1408C095)
                    {
                        write_out(PRINT_ERROR, "Bad TLS finished digest.");
                        write_lower_level();
                        return HANDSHAKE_BAD_DIGEST;
                    }
                default:
                    write_out(PRINT_ERROR, "TLS accept error: %d", err);
                    print_ssl_error_stack(PRINT_ERROR);
                    write_lower_level();
                    
                    return HANDSHAKE_UNSUCCESSFUL;
            }
        }
    }
    
    //send the final encrypted handshake
    if (!send_bio_data(sockfd, wbio, out_mut, out_state))
    {
        write_out(PRINT_ERROR, "TLS handshake error while sending data!");
        write_lower_level();
        return 0;
    }
    
    write_out(PRINT_INFO, "TLS handshake complete.");
    write_lower_level();
    
    return HANDSHAKE_SUCCESSFUL;
}
Esempio n. 5
0
int irc_dcc_accept(irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback) {
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 1);

    if (!dcc)
        return 1;

    if (dcc->state != LIBIRC_STATE_INIT) {
        session->lasterror = LIBIRC_ERR_STATE;
        libirc_mutex_unlock(&session->mutex_dcc);
        return 1;
    }

    dcc->cb = callback;
    dcc->ctx = ctx;

    DBG_OK("going to socket_connect!");

    // Initiate the connect

    if (socket_connect(&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof (dcc->remote_addr))) {
        libirc_dcc_destroy_nolock(session, dccid);
        libirc_mutex_unlock(&session->mutex_dcc);
        session->lasterror = LIBIRC_ERR_CONNECT;
        return 1;
    }
    
#ifdef ENABLE_SSL
    if (dcc->ssl == 1) {
        DBG_OK("using ssl!");

        while (1) {
            int err = SSL_connect(dcc->ssl_ctx);
            if (err <= 0) {
                int ssl_err = SSL_get_error(dcc->ssl_ctx, err);
                if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
                    continue;
                } else {
                    print_ssl_error_stack();
                    session->lasterror = LIBIRC_ERR_CONNECT;
                    return 1;
                }
            }
            DBG_OK("ssl_connect succeded!");
            break;
        }
        
        const char *ciphers_used = "None";
        ciphers_used = SSL_get_cipher_name(dcc->ssl_ctx);
        logprintf(LOG_INFO, "using cipher suite: %s for dcc connection", ciphers_used);
    }
#endif

    DBG_OK("connect succeded2!");

    dcc->state = LIBIRC_STATE_CONNECTING;
#ifdef ENABLE_SSL
    if (dcc->ssl) {
        dcc->state = LIBIRC_STATE_CONNECTED;
    }
#endif
    libirc_mutex_unlock(&session->mutex_dcc);
    return 0;
}