Module: wine
Branch: master
Commit: 13a349540ae0230f83466c04e003209656a889c0
URL: https://source.winehq.org/git/wine.git/?a=commit;h=13a349540ae0230f83466c04…
Author: Zebediah Figura <zfigura(a)codeweavers.com>
Date: Thu Jul 22 00:21:06 2021 -0500
cryptnet: Check only the first successfully retrieved CRL in verify_cert_revocation_from_dist_points_ext().
>From RFC 5280 § 4.2.1.13:
If the DistributionPointName contains multiple values, each name
describes a different mechanism to obtain the same CRL. For example,
the same CRL could be available for retrieval through both LDAP and
HTTP.
Steam attempts to validate a certificate containing what are apparently two
different mirrored URLs to the same 20 MB CRL, which currently takes over 400ms
to parse in Wine. According to my reading of the RFC, we should only need to
parse one of them, cutting the time in half.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/cryptnet/cryptnet_main.c | 111 ++++++++++++++++++++++--------------------
1 file changed, 58 insertions(+), 53 deletions(-)
diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c
index f4088021a0e..b1e2829d881 100644
--- a/dlls/cryptnet/cryptnet_main.c
+++ b/dlls/cryptnet/cryptnet_main.c
@@ -1528,66 +1528,71 @@ static DWORD verify_cert_revocation_with_crl_online(const CERT_CONTEXT *cert,
return ERROR_SUCCESS;
}
+/* Try to retrieve a CRL from any one of the specified distribution points. */
+static const CRL_CONTEXT *retrieve_crl_from_dist_points(const CRYPT_URL_ARRAY *array,
+ DWORD verify_flags, DWORD timeout)
+{
+ DWORD retrieve_flags = 0;
+ const CRL_CONTEXT *crl;
+ DWORD i;
+
+ if (verify_flags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION)
+ retrieve_flags |= CRYPT_CACHE_ONLY_RETRIEVAL;
+
+ /* Yes, this is a weird algorithm, but the documentation for
+ * CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT specifies this, and
+ * tests seem to bear it out for CertVerifyRevocation() as well. */
+ if (verify_flags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG)
+ timeout /= 2;
+
+ for (i = 0; i < array->cUrl; ++i)
+ {
+ if (CryptRetrieveObjectByUrlW(array->rgwszUrl[i], CONTEXT_OID_CRL, retrieve_flags,
+ timeout, (void **)&crl, NULL, NULL, NULL, NULL))
+ return crl;
+
+ /* We don't check the current time here. This may result in less
+ * accurate timeouts, but this too seems to be true of Windows. */
+ if ((verify_flags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG) && GetLastError() == ERROR_TIMEOUT)
+ timeout /= 2;
+ }
+
+ return NULL;
+}
+
static DWORD verify_cert_revocation_from_dist_points_ext(const CRYPT_DATA_BLOB *value, const CERT_CONTEXT *cert,
- FILETIME *pTime, DWORD dwFlags, const CERT_REVOCATION_PARA *pRevPara, CERT_REVOCATION_STATUS *pRevStatus)
+ FILETIME *time, DWORD flags, const CERT_REVOCATION_PARA *params, CERT_REVOCATION_STATUS *status)
{
- DWORD error = ERROR_SUCCESS, cbUrlArray;
+ DWORD url_array_size, error;
+ CRYPT_URL_ARRAY *url_array;
+ const CRL_CONTEXT *crl;
+ DWORD timeout = 0;
+
+ if (!CRYPT_GetUrlFromCRLDistPointsExt(value, NULL, &url_array_size, NULL, NULL))
+ return GetLastError();
+
+ if (!(url_array = CryptMemAlloc(url_array_size)))
+ return ERROR_OUTOFMEMORY;
- if (CRYPT_GetUrlFromCRLDistPointsExt(value, NULL, &cbUrlArray, NULL, NULL))
+ if (!CRYPT_GetUrlFromCRLDistPointsExt(value, url_array, &url_array_size, NULL, NULL))
{
- CRYPT_URL_ARRAY *urlArray = CryptMemAlloc(cbUrlArray);
+ CryptMemFree(url_array);
+ return GetLastError();
+ }
- if (urlArray)
- {
- DWORD j, retrievalFlags = 0, timeout = 0;
- BOOL ret;
-
- ret = CRYPT_GetUrlFromCRLDistPointsExt(value, urlArray,
- &cbUrlArray, NULL, NULL);
- if (dwFlags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION)
- retrievalFlags |= CRYPT_CACHE_ONLY_RETRIEVAL;
-
- if (pRevPara && pRevPara->cbSize >= RTL_SIZEOF_THROUGH_FIELD(CERT_REVOCATION_PARA, dwUrlRetrievalTimeout))
- timeout = pRevPara->dwUrlRetrievalTimeout;
-
- /* Yes, this is a weird algorithm, but the documentation for
- * CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT specifies this, and
- * tests seem to bear it out for CertVerifyRevocation() as well. */
- if (dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG)
- timeout /= 2;
-
- if (!ret)
- error = GetLastError();
- /* continue looping if one was offline; break if revoked or timed out */
- for (j = 0; (!error || error == CRYPT_E_REVOCATION_OFFLINE) && j < urlArray->cUrl; j++)
- {
- PCCRL_CONTEXT crl;
+ if (params && params->cbSize >= RTL_SIZEOF_THROUGH_FIELD(CERT_REVOCATION_PARA, dwUrlRetrievalTimeout))
+ timeout = params->dwUrlRetrievalTimeout;
- ret = CryptRetrieveObjectByUrlW(urlArray->rgwszUrl[j],
- CONTEXT_OID_CRL, retrievalFlags, timeout, (void **)&crl,
- NULL, NULL, NULL, NULL);
- if (ret)
- {
- error = verify_cert_revocation_with_crl_online(cert, crl, pTime, pRevStatus);
- CertFreeCRLContext(crl);
- }
- else
- {
- /* We don't check the current time here. This may result in
- * less accurate timeouts, but this too seems to be true of
- * Windows. */
- if ((dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG) && GetLastError() == ERROR_TIMEOUT)
- timeout /= 2;
- error = CRYPT_E_REVOCATION_OFFLINE;
- }
- }
- CryptMemFree(urlArray);
- }
- else
- error = ERROR_OUTOFMEMORY;
+ if (!(crl = retrieve_crl_from_dist_points(url_array, flags, timeout)))
+ {
+ CryptMemFree(url_array);
+ return CRYPT_E_REVOCATION_OFFLINE;
}
- else
- error = GetLastError();
+
+ error = verify_cert_revocation_with_crl_online(cert, crl, time, status);
+
+ CertFreeCRLContext(crl);
+ CryptMemFree(url_array);
return error;
}
Module: wine
Branch: master
Commit: 3a9d51bf36d9ced4792d4b5f731a2de6a370da7d
URL: https://source.winehq.org/git/wine.git/?a=commit;h=3a9d51bf36d9ced4792d4b5f…
Author: Zebediah Figura <zfigura(a)codeweavers.com>
Date: Thu Jul 22 00:21:05 2021 -0500
cryptnet: Respect the timeout also if CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG is not set.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/cryptnet/cryptnet_main.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c
index 565302957d6..f4088021a0e 100644
--- a/dlls/cryptnet/cryptnet_main.c
+++ b/dlls/cryptnet/cryptnet_main.c
@@ -1547,8 +1547,7 @@ static DWORD verify_cert_revocation_from_dist_points_ext(const CRYPT_DATA_BLOB *
if (dwFlags & CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION)
retrievalFlags |= CRYPT_CACHE_ONLY_RETRIEVAL;
- if ((dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG) && pRevPara
- && pRevPara->cbSize >= RTL_SIZEOF_THROUGH_FIELD(CERT_REVOCATION_PARA, dwUrlRetrievalTimeout))
+ if (pRevPara && pRevPara->cbSize >= RTL_SIZEOF_THROUGH_FIELD(CERT_REVOCATION_PARA, dwUrlRetrievalTimeout))
timeout = pRevPara->dwUrlRetrievalTimeout;
/* Yes, this is a weird algorithm, but the documentation for
@@ -1577,7 +1576,7 @@ static DWORD verify_cert_revocation_from_dist_points_ext(const CRYPT_DATA_BLOB *
/* We don't check the current time here. This may result in
* less accurate timeouts, but this too seems to be true of
* Windows. */
- if (GetLastError() == ERROR_TIMEOUT)
+ if ((dwFlags & CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG) && GetLastError() == ERROR_TIMEOUT)
timeout /= 2;
error = CRYPT_E_REVOCATION_OFFLINE;
}
Module: wine
Branch: master
Commit: ddf3b93ac184a7e707b13f2793d450e40c2b85f7
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ddf3b93ac184a7e707b13f27…
Author: Zebediah Figura <zfigura(a)codeweavers.com>
Date: Thu Jul 22 00:19:03 2021 -0500
winegstreamer: Don't try to convert duration from byte length.
This effectively reverts 613446d018b792b10d067314831901437b4ff6e5.
Duration and convert queries, in general, appear to be handled by the first
upstream element that knows how. If two different elements respond to each
query, we may treat the byte duration of the whole file as if it were the
duration of a single stream, or treat an undecoded byte duration as if it were a
decoded byte duration.
The aforementioned commit was written in order to ensure that we receive a valid
duration for test.mp3 in quartz_test.exe, and is obviated by the previous
patches which retry duration queries until successful (or EOS).
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51126
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/winegstreamer/wg_parser.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index eb53ac8efce..cd12a23d0c8 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -1525,7 +1525,7 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
for (i = 0; i < parser->stream_count; ++i)
{
struct wg_parser_stream *stream = parser->streams[i];
- gint64 duration, byte_length;
+ gint64 duration;
while (!stream->has_caps && !parser->error)
pthread_cond_wait(&parser->init_cond, &parser->mutex);
@@ -1567,18 +1567,6 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
break;
}
- GST_INFO("Failed to query time duration; trying to convert from byte length.\n");
-
- /* To accurately get a duration for the stream, we want to only
- * consider the length of that stream. Hence, query for the pad
- * duration, instead of using the file duration. */
- if (gst_pad_query_duration(stream->their_src, GST_FORMAT_BYTES, &byte_length)
- && gst_pad_query_convert(stream->their_src, GST_FORMAT_BYTES, byte_length,
- GST_FORMAT_TIME, &duration))
- {
- stream->duration = duration / 100;
- break;
- }
if (stream->eos)
{
stream->duration = 0;