[ https://issues.apache.org/jira/browse/PROTON-171?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Philip Harvey reassigned PROTON-171: ------------------------------------ Assignee: Ken Giusti > after connection close, proton-c SSL decryption fails when left-over bytes > passed to input() > -------------------------------------------------------------------------------------------- > > Key: PROTON-171 > URL: https://issues.apache.org/jira/browse/PROTON-171 > Project: Qpid Proton > Issue Type: Bug > Components: proton-c > Reporter: Philip Harvey > Assignee: Ken Giusti > > We've been working on the Java SSL implementation and are seeing a test fail > against proton-c but that works against proton-j. We believe this is due to > a bug in proton-c. > One of the scenarios we wanted to cover in our testing was the case where the > Transport input method leaves "left-overs", e.g. when you call server.input() > with 100 bytes of input, but it only accepts 20, as indicated by its return > value. > For example, we expect this to happen if the preceding client.output() call > is told to write to a buffer sized such that its output contains a trailing > *fragment* of an SSL packet, which input() won't be able to decipher. > We therefore modified the pump method in proton/tests/proton_tests/ssl.py to > handle this case. In its loop, it now captures the bytes "left over" after > calling input(), and prepends them to the input() invocation in the next > iteration. The buffer size is now a parameter so individual tests can > exercise the packet fragmenting behaviour described above. > We made the following change: > ------- > diff --git a/tests/proton_tests/ssl.py b/tests/proton_tests/ssl.py > index 8567b1b..237c3da 100644 > --- a/tests/proton_tests/ssl.py > +++ b/tests/proton_tests/ssl.py > @@ -43,13 +43,32 @@ class SslTest(common.Test): > self.t_client = None > self.t_server = None > > - def _pump(self): > + def _pump(self, buffer_size=1024): > + """ > + Make the transport send up to buffer_size bytes (this will be the > AMQP > + header and open frame) returning a buffer containing the bytes > + sent. Transport is stateful so this will return 0 when it has > + no more frames to send. > + TODO this function is duplicated in sasl.py. Should be moved to a > common place. > + """ > + out_client_leftover_by_server = "" > + out_server_leftover_by_client = "" > + i=0 > while True: > - out_client = self.t_client.output(1024) > - out_server = self.t_server.output(1024) > - if out_client: self.t_server.input(out_client) > - if out_server: self.t_client.input(out_server) > + > + out_client = out_client_leftover_by_server + > self.t_client.output(buffer_size) > + out_server = out_server_leftover_by_client + > self.t_server.output(buffer_size) > + > + if out_client: > + number_server_consumed = self.t_server.input(out_client) > + out_client_leftover_by_server = > out_client[number_server_consumed:] # if it consumed everything then this is > empty > + > + if out_server: > + number_client_consumed = self.t_client.input(out_server) > + out_server_leftover_by_client = > out_server[number_client_consumed:] # if it consumed everything then this is > empty > + > if not out_client and not out_server: break > + i=i+1 > > def _testpath(self, file): > """ Set the full path to the certificate,keyfile, etc. for the test. > ------- > Several ssl tests now fail when run against proton-c, all with the same > error. This surprised us because we hadn't started playing with the buffer > size yet - we were still using the default of 1024. > For example, test_server_authentication gives this output: > ------- > proton_tests.ssl.SslTest.test_server_authentication > .........................................................................[0xa2ca208:0] > ERROR[-2] SSL Failure: error:1408F119:SSL > routines:SSL3_GET_RECORD:decryption failed or bad record mac > fail > Error during test: Traceback (most recent call last): > File "./tests/proton-test", line 331, in run > phase() > File "/home/phil/dev/proton/tests/proton_tests/ssl.py", line 166, in > test_server_authentication > self._pump() > File "/home/phil/dev/proton/tests/proton_tests/ssl.py", line 63, in _pump > number_server_consumed = self.t_server.input(out_client) > File "/home/phil/dev/proton/proton-c/bindings/python/proton.py", line > 2141, in input > return self._check(n) > File "/home/phil/dev/proton/proton-c/bindings/python/proton.py", line > 2115, in _check > raise exc("[%s]: %s" % (err, > pn_error_text(pn_transport_error(self._trans)))) > TransportException: [-2]: SSL Failure: error:1408F119:SSL > routines:SSL3_GET_RECORD:decryption failed or bad record mac > Totals: 1 tests, 0 passed, 0 skipped, 0 ignored, 1 failed > ------- > The first pump() call in this test works fine; the failure we see is when > it's invoked again after closing the connection. > The problem is that the previous t_server.input call didn't accept *any* of > the bytes given to it. On the next t_server.input call, these bytes are > prepended to the newly-produced ones from t_client.output, which seems > reasonable to us, but this produces the error above. -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira