secur32: Better deal with the lack of gnutls_mac_get_key_size().

Henri Verbeet hverbeet at gmail.com
Wed Mar 25 06:56:01 CDT 2009


2009/3/25 Francois Gouget <fgouget at codeweavers.com>:
> The only reason why the compilation fails with older versions of GnuTLS
> (down to 2.0.2) is because we use typeof(gnutls_mac_get_key_size). But
> if we define the function pointer prototype ourselves, then compilation
> works just fine.
>
> While I was at it I made a missing gnutls_mac_get_key_size function
> non-fatal and dealt with its absence in schan_QueryContextAttributesW().
> Let me know if that does not make sense (maybe that function is
> systematically used?). If so, then dropping just that part of the patch
> would maintain the status quo, while allowing Wine compiled with an
> older library to keep working with the newer ones which is pretty
> pratical for Debian 4.0 and FreeBSD 7.0.
>
SECPKG_ATTR_STREAM_SIZES is used to determine the buffer sizes passed
to EncryptMessage() and DecryptMessage(), so it probably doesn't help
much to return SEC_E_UNSUPPORTED_FUNCTION for that one. There are only
a couple of MAC algorithms though, so it shouldn't be too hard to
implement in the same way as schannel_get_cipher_block_size(), with
the difference that an unknown algorithm would be more fatal (though
we can limit the algorithms it'll try with
gnutls_set_default_priority()).

A bigger problem is that when gnutls_record_recv() returns
GNUTLS_E_AGAIN because we received an incomplete message, secur32
expects the entire buffer plus the extra data to be resent, while
gnutls only expects the extra data. We could hack around this by
keeping track of how much data we read into the current record and
skipping that much on the next call to DecryptMessage() for the same
session. This would work in general because in the typical case you're
working with a stream, not random records.
The proper way to fix that would be to discard the data we already
read for the current record though. GnuTLS has function to do that
called _gnutls_io_clear_read_buffer(), but that's an internal
function, so I'd need to send a patch to gnutls to expose that,
probably as a function called something like gnutls_record_reset(). I
haven't gotten around to actually doing this, but the implication
would be that we'd need to either use a *very* recent version of
gnutls, or use the internal _gnutls_io_clear_read_buffer() function,
neither of which would be very nice.



More information about the wine-patches mailing list