Okay.  SSLv3 is different from TLSv1.0.  And you really, really,
REALLY need to give the correct error.  Your original message said it
was alert number 10, not alert 21.

Alert 21 is not specified in SSLv3 (see
http://www.freesoft.org/CIE/Topics/ssl-draft/3-SPEC.HTM for the alert
definitions, section 7.4 and 7.4.2).  It is specified in TLSv1 (RFC
2246), though, and is decryption_failed.  See
ftp://ftp.rfc-editor.org/in-notes/rfc2246.txt for the specification.

If there is data available for SSL_read() to read on the socket,
select() will tell you.  You should not use SSL_pending for the task,
for the reason that David mentioned.  You should realize that it's
possible for SSL_read() to return 0 even in the event that there is
data available on the socket, and it's also possible for it to return
-1 with SSL_ERROR_WANT_WRITE -- a partial packet might have been
delivered, or it might just be a renegotiation with no user data
available.  Either way, you should structure your code to call
SSL_read() on any descriptor that select() says has pending data, and
only then if you actually have any application data in there should
you try to copy anything to the other side of the proxied pair.
Remove the call to SSL_pending() -- just let the library deal with its
internal bookkeeping, and make your code a little more naïve.

Remember, SSL_read() returns the number of bytes it read from the
stream.  If it's 0, then there's no user data, even if it did need to
do a renegotiation.  In that case, just continue; your select() loop
without trying to complete copying of a 0-length buffer.  And it can
return -1/SSL_ERROR_WANT_* at any time (if the auto-retry option isn't
set).

-Kyle H

On Fri, Oct 31, 2008 at 6:44 AM, Weber Antonio
<[EMAIL PROTECTED]> wrote:
> Hi,
>
> I watched the traffic. There I can see, that the client
> sends 'SSLv3: Encrypted Alert / Alert 21 (0x15)' so it seems that the
> client have a problem with a message it was sent to him.
>
> Thats right, it is the endpoint of the TLS connections but I use
> SSL_read() and SSL_write() allready.
> Because select does not help all the time I added SSL_pending as
> condition so only if there is not allready data pending I count
> on select. I found no better way to recognise that data is ready
> to read.
>
> Ah the alert 21 tells me decryption_failed (you allready mentioned it)
> as of rfc2246 right?
> This would mean that I forward something I got with a direct
> read() to a socket but I do not call read() directly.
>
> Greetings,
> Antonio
>
>
>> TLS defines alert number 10 to be "unexpected message" (RFC2246,
>> section 7.2 and 7.2.2).  It indicates a protocol error; as the RFC
>> says, "this alert should never be observed in communication between
>> proper implementations."  Which side is sending the alert, the proxy
>> or the peer?
>>
>> The way you described your original concept, it sounded like you were
>> making the proxy be the endpoint of the TLS connections.  If this is
>> the way it is done, it obligates the proxy to encrypt/decrypt both of
>> the connections for the entire lifetime of those connections. On
>> decrypted-read from one, perform an encrypted-write to the other.  It
>> is NOT okay to simply use an OS-level read() and write() to do this!
>> It is also NOT okay to simply use select() to figure out what must be
>> done!  (it can help, but it's not the be-all and end-all.)
>>
>> The proxy must handle each file descriptor (and its associated SSL
>> session) separately.  If select() indicates that there's data to read,
>> the function to be called is SSL_read().  This can return -1 and the
>> error state SSL_ERROR_WANT_WRITE, and if it does, you need to call
>> SSL_read() again with the same parameters.  When you go to write that
>> data, use SSL_write().  This can return -1 and the error state
>> SSL_ERROR_WANT_READ, and if it does, call SSL_write() again with the
>> same parameters.  OpenSSL will handle the underlying read() and
>> write() calls for you, but it must be allowed to do so.  Note that you
>> can bypass this need to retry yourself if you use SSL_set_mode (or if
>> you're using the SSL_CTX structures, SSL_CTX_set_mode) with
>> SSL_MODE_AUTO_RETRY.
>>
>> If the proxy is the endpoint of all TLS sessions, then what happens on
>> one session should not affect the other session that it's paired with
>> (since the proxy's peers aren't talking directly with each other, they
>> don't need to know about each other's implementations).
>>
>> And as for the reason you can't simply use read() and write()
>> directly: the session keys will be different, and the rolling HMAC key
>> will be different.  This will make the other endpoint give up with a
>> "decryption_failed" or "bad_record_mac" alert.  (I still can't figure
>> out why you'd be seeing an unexpected_message alert.)
>>
>> -Kyle H
>>
>> On Fri, Oct 31, 2008 at 4:04 AM, Weber Antonio
>> <[EMAIL PROTECTED]> wrote:
>> > Hi,
>> >
>> >
>> >> Yes, the code is prone to deadlock. The code implements the "I will not
>> >> start doing X until I finish doing Y" logic. This is known to cause
>> >> deadlocks in proxies, as one end or the other of the connection proxied
>> >> inevitably has an "I will not start doing Y until I finish doing X"
>> logic.
>> >>
>> >> You thus wind up with a proxy that could make forward progress in one
>> >> direction but refuses to because it cannot make forward progress in the
>> >> other direction.
>> >
>> > please tell me where the deadlock is.
>> > As far as I know a deadlock arise when one process locks a resource an
>> other
>> > process requests and vice versa.
>> > Perhaps I misinterpret the SSL_pending
>> >
>> > All I do is call select which tells me if I can read on the
>> sockets/filehandles.
>> > If I can read from one or both endpoints without blocking I read the
>> > data and send it to the other endpoint. Write should never block on
>> > sockets I think?
>> >
>> >> But that's not your problem. You're problem is that you are horribly
>> >> abusing SSL_pending. SSL data may be neither in the socket buffer nor
>> >> pending, and you ignore it. (For example, the SSL connection may have,
>> in
>> >> its buffer, an entire SSL protocol block. No data is pending, since the
>> >> first byte of the block has not been analyzed yet, and no data is
>> waiting
>> >> on the socket.)
>> >
>> > The question is how will I find out that there is data I can read.
>> > Calling select is not sufficent?
>> >
>> >> In general terms, a general-purpose proxy can never say "I could do X,
>> but
>> >> I won't do it *now*". You break this rule in two ways. One with
>> >> SSL_pending (which checks for one type of forward progress while
>> ignoring
>> >> another) and by blocking in one direction even when you could make
>> >> progress in the other.
>> >>
>> >> DS
>> >>
>> >
>> > Greetings,
>> > Antonio
>> >
>> ______________________________________________________________________
>> OpenSSL Project                                 http://www.openssl.org
>> User Support Mailing List                    openssl-users@openssl.org
>> Automated List Manager                           [EMAIL PROTECTED]
>
:��I"Ϯ��r�m����
(����Z+�K�+����1���x��h����[�z�(����Z+���f�y�������f���h��)z{,���

Reply via email to