示例#1
0
BOOL netconn_secure_connect( netconn_t *conn )
{
#ifdef SONAME_LIBSSL
    X509 *cert;
    long res;

    ctx = pSSL_CTX_new( method );
    if (!pSSL_CTX_set_default_verify_paths( ctx ))
    {
        ERR("SSL_CTX_set_default_verify_paths failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
        set_last_error( ERROR_OUTOFMEMORY );
        return FALSE;
    }
    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_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)
    {
        ERR("SSL_connect failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
        set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
        goto fail;
    }
    if (!(cert = pSSL_get_peer_certificate( conn->ssl_conn )))
    {
        ERR("No certificate for server: %s\n", pERR_error_string( pERR_get_error(), 0 ));
        set_last_error( ERROR_WINHTTP_SECURE_CHANNEL_ERROR );
        goto fail;
    }
    if ((res = pSSL_get_verify_result( conn->ssl_conn )) != X509_V_OK)
    {
        /* FIXME: we should set an error and return, but we only print an error at the moment */
        ERR("couldn't verify server certificate (%ld)\n", res);
    }
    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;
}
示例#2
0
文件: net.c 项目: mikekap/wine
const void *netconn_get_certificate( netconn_t *conn )
{
#ifdef SONAME_LIBSSL
    X509 *cert;
    const CERT_CONTEXT *ret;

    if (!conn->secure) return NULL;

    if (!(cert = pSSL_get_peer_certificate( conn->ssl_conn ))) return NULL;
    ret = X509_to_cert_context( cert );
    return ret;
#else
    return NULL;
#endif
}
示例#3
0
LPCVOID NETCON_GetCert(netconn_t *connection)
{
#ifdef SONAME_LIBSSL
    X509* cert;
    LPCVOID r = NULL;

    if (!connection->ssl_s)
        return NULL;

    cert = pSSL_get_peer_certificate(connection->ssl_s);
    r = X509_to_cert_context(cert);
    return r;
#else
    return NULL;
#endif
}
示例#4
0
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection)
{
#ifdef SONAME_LIBSSL
    X509* cert;
    unsigned char* buffer,*p;
    INT len;
    BOOL malloced = FALSE;
    LPCVOID r = NULL;

    if (!connection->useSSL)
        return NULL;

    cert = pSSL_get_peer_certificate(connection->ssl_s);
    p = NULL;
    len = pi2d_X509(cert,&p);
    /*
     * SSL 0.9.7 and above malloc the buffer if it is null. 
     * however earlier version do not and so we would need to alloc the buffer.
     *
     * see the i2d_X509 man page for more details.
     */
    if (!p)
    {
        buffer = HeapAlloc(GetProcessHeap(),0,len);
        p = buffer;
        len = pi2d_X509(cert,&p);
    }
    else
    {
        buffer = p;
        malloced = TRUE;
    }

    r = CertCreateCertificateContext(X509_ASN_ENCODING,buffer,len);

    if (malloced)
        free(buffer);
    else
        HeapFree(GetProcessHeap(),0,buffer);

    return r;
#else
    return NULL;
#endif
}
示例#5
0
const void *netconn_get_certificate( netconn_t *conn )
{
#ifdef SONAME_LIBSSL
    X509 *cert;
    unsigned char *buffer, *p;
    int len;
    BOOL malloc = FALSE;
    const CERT_CONTEXT *ret;

    if (!conn->secure) return NULL;

    if (!(cert = pSSL_get_peer_certificate( conn->ssl_conn ))) return NULL;
    p = NULL;
    if ((len = pi2d_X509( cert, &p )) < 0) return NULL;
    /*
     * SSL 0.9.7 and above malloc the buffer if it is null.
     * however earlier version do not and so we would need to alloc the buffer.
     *
     * see the i2d_X509 man page for more details.
     */
    if (!p)
    {
        if (!(buffer = heap_alloc( len ))) return NULL;
        p = buffer;
        len = pi2d_X509( cert, &p );
    }
    else
    {
        buffer = p;
        malloc = TRUE;
    }

    ret = CertCreateCertificateContext( X509_ASN_ENCODING, buffer, len );

    if (malloc) free( buffer );
    else heap_free( buffer );

    return ret;
#else
    return NULL;
#endif
}
示例#6
0
/******************************************************************************
 * NETCON_secure_connect
 * Initiates a secure connection over an existing plaintext connection.
 */
BOOL NETCON_secure_connect(WININET_NETCONNECTION *connection, LPCWSTR hostname)
{
#ifdef SONAME_LIBSSL
    long verify_res;
    X509 *cert;
    int len;
    char *hostname_unix;

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

    ctx = pSSL_CTX_new(meth);
    if (!pSSL_CTX_set_default_verify_paths(ctx))
    {
        ERR("SSL_CTX_set_default_verify_paths failed: %s\n",
            pERR_error_string(pERR_get_error(), 0));
        INTERNET_SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }
    connection->ssl_s = pSSL_new(ctx);
    if (!connection->ssl_s)
    {
        ERR("SSL_new failed: %s\n",
            pERR_error_string(pERR_get_error(), 0));
        INTERNET_SetLastError(ERROR_OUTOFMEMORY);
        goto fail;
    }

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

    if (pSSL_connect(connection->ssl_s) <= 0)
    {
        ERR("SSL_connect failed: %s\n",
            pERR_error_string(pERR_get_error(), 0));
        INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
        goto fail;
    }
    cert = pSSL_get_peer_certificate(connection->ssl_s);
    if (!cert)
    {
        ERR("no certificate for server %s\n", debugstr_w(hostname));
        /* FIXME: is this the best error? */
        INTERNET_SetLastError(ERROR_INTERNET_INVALID_CA);
        goto fail;
    }
    verify_res = pSSL_get_verify_result(connection->ssl_s);
    if (verify_res != X509_V_OK)
    {
        ERR("couldn't verify the security of the connection, %ld\n", verify_res);
        /* FIXME: we should set an error and return, but we only warn at
         * the moment */
    }

    len = WideCharToMultiByte(CP_UNIXCP, 0, hostname, -1, NULL, 0, NULL, NULL);
    hostname_unix = HeapAlloc(GetProcessHeap(), 0, len);
    if (!hostname_unix)
    {
        INTERNET_SetLastError(ERROR_OUTOFMEMORY);
        goto fail;
    }
    WideCharToMultiByte(CP_UNIXCP, 0, hostname, -1, hostname_unix, len, NULL, NULL);

    if (!check_hostname(cert, hostname_unix))
    {
        HeapFree(GetProcessHeap(), 0, hostname_unix);
        INTERNET_SetLastError(ERROR_INTERNET_SEC_CERT_CN_INVALID);
        goto fail;
    }

    HeapFree(GetProcessHeap(), 0, hostname_unix);
    connection->useSSL = TRUE;
    return TRUE;

fail:
    if (connection->ssl_s)
    {
        pSSL_shutdown(connection->ssl_s);
        pSSL_free(connection->ssl_s);
        connection->ssl_s = NULL;
    }
#endif
    return FALSE;
}