Beispiel #1
0
BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname )
{
#ifdef SONAME_LIBSSL
    if (!(conn->ssl_conn = pSSL_new( ctx )))
    {
        ERR("SSL_new failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
        set_last_error( ERROR_OUTOFMEMORY );
        goto fail;
    }
    if (!pSSL_set_ex_data( conn->ssl_conn, hostname_idx, hostname ))
    {
        ERR("SSL_set_ex_data failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
        set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
        goto fail;
    }
    if (!pSSL_set_ex_data( conn->ssl_conn, conn_idx, conn ))
    {
        ERR("SSL_set_ex_data failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
        set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
        return FALSE;
    }
    if (!pSSL_set_fd( conn->ssl_conn, conn->socket ))
    {
        ERR("SSL_set_fd failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
        set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
        goto fail;
    }
    if (pSSL_connect( conn->ssl_conn ) <= 0)
    {
        DWORD err;

        err = (DWORD_PTR)pSSL_get_ex_data( conn->ssl_conn, error_idx );
        if (!err) err = ERROR_WINHTTP_SECURE_CHANNEL_ERROR;
        ERR("couldn't verify server certificate (%d)\n", err);
        set_last_error( err );
        goto fail;
    }
    TRACE("established SSL connection\n");
    conn->secure = TRUE;
    return TRUE;

fail:
    if (conn->ssl_conn)
    {
        pSSL_shutdown( conn->ssl_conn );
        pSSL_free( conn->ssl_conn );
        conn->ssl_conn = NULL;
    }
#endif
    return FALSE;
}
Beispiel #2
0
/******************************************************************************
 * NETCON_secure_connect
 * Initiates a secure connection over an existing plaintext connection.
 */
DWORD NETCON_secure_connect(netconn_t *connection)
{
    DWORD res = ERROR_NOT_SUPPORTED;
#ifdef SONAME_LIBSSL
    void *ssl_s;

    /* can't connect if we are already connected */
    if (connection->ssl_s)
    {
        ERR("already connected\n");
        return ERROR_INTERNET_CANNOT_CONNECT;
    }

    ssl_s = pSSL_new(ctx);
    if (!ssl_s)
    {
        ERR("SSL_new failed: %s\n",
            pERR_error_string(pERR_get_error(), 0));
        return ERROR_OUTOFMEMORY;
    }

    if (!pSSL_set_fd(ssl_s, connection->socketFD))
    {
        ERR("SSL_set_fd failed: %s\n",
            pERR_error_string(pERR_get_error(), 0));
        res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
        goto fail;
    }

    if (!pSSL_set_ex_data(ssl_s, conn_idx, connection))
    {
        ERR("SSL_set_ex_data failed: %s\n",
            pERR_error_string(pERR_get_error(), 0));
        res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
        goto fail;
    }
    if (pSSL_connect(ssl_s) <= 0)
    {
        res = (DWORD_PTR)pSSL_get_ex_data(ssl_s, error_idx);
        if (!res)
            res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
        ERR("SSL_connect failed: %d\n", res);
        goto fail;
    }

    connection->ssl_s = ssl_s;
    return ERROR_SUCCESS;

fail:
    if (ssl_s)
    {
        pSSL_shutdown(ssl_s);
        pSSL_free(ssl_s);
    }
#endif
    return res;
}
Beispiel #3
0
static int netconn_secure_verify( int preverify_ok, X509_STORE_CTX *ctx )
{
    SSL *ssl;
    WCHAR *server;
    BOOL ret = FALSE;
    netconn_t *conn;

    ssl = pX509_STORE_CTX_get_ex_data( ctx, pSSL_get_ex_data_X509_STORE_CTX_idx() );
    server = pSSL_get_ex_data( ssl, hostname_idx );
    conn = pSSL_get_ex_data( ssl, conn_idx );
    if (preverify_ok)
    {
        HCERTSTORE store = CertOpenStore( CERT_STORE_PROV_MEMORY, 0, 0,
         CERT_STORE_CREATE_NEW_FLAG, NULL );

        if (store)
        {
            X509 *cert;
            int i;
            PCCERT_CONTEXT endCert = NULL;

            ret = TRUE;
            for (i = 0; ret && i < psk_num((struct stack_st *)ctx->chain); i++)
            {
                PCCERT_CONTEXT context;

                cert = (X509 *)psk_value((struct stack_st *)ctx->chain, i);
                if ((context = X509_to_cert_context( cert )))
                {
                    if (i == 0)
                        ret = CertAddCertificateContextToStore( store, context,
                            CERT_STORE_ADD_ALWAYS, &endCert );
                    else
                        ret = CertAddCertificateContextToStore( store, context,
                            CERT_STORE_ADD_ALWAYS, NULL );
                    CertFreeCertificateContext( context );
                }
            }
            if (!endCert) ret = FALSE;
            if (ret)
            {
                DWORD_PTR err = netconn_verify_cert( endCert, store, server,
                                                     conn->security_flags );

                if (err)
                {
                    pSSL_set_ex_data( ssl, error_idx, (void *)err );
                    ret = FALSE;
                }
            }
            CertFreeCertificateContext( endCert );
            CertCloseStore( store, 0 );
        }
    }
    return ret;
}