Wireshark-dev: Re: [Wireshark-dev] ssl decryption in a dissector

From: Peter Wu <peter@xxxxxxxxxxxxx>
Date: Tue, 30 Jul 2019 23:42:56 +0100
Hi Sebastiano,

On Tue, Jul 30, 2019 at 09:31:40AM +0900, Sebastiano Di Paola wrote:
> Hello,
> I'm trying to write a new dissector.
> The protocol is over TLS so in order to do dissection I need to decrypt TLS
> (dumping the key setting SSLKEYLOGFILE variable).
> So inside the new dissector I'm writing I need first to call the ssl
> decryption and then starting parsing payload bytes.
> What is the right way to use the API?
> 
> I tried this...mimic the PROTOABBREV skeleton and then add ssl_dissector
> add in the proto_reg_handoff
> but it wil result in a crash with this error message
>  Main Warn QObject::setParent: Cannot set parent, new parent is in a
> different thread

What Wireshark version have you based your work on? It is recommended to
develop based on the latest development version (git master). You can
try to set environment variable WIRESHARK_ABORT_ON_DISSECTOR_BUG=1, that
should have printed this error:

    SSL appdata dissectors must register with register_dissector()!

> void
> proto_reg_handoff_newproto(void)
> {
>     dissector_handle_t  newproto_handle;
> 
>     /* Use create_dissector_handle() to indicate that dissect_PROTOABBREV()
>      * returns the number of bytes it dissected (or 0 if it thinks the
> packet
>      * does not belong to PROTONAME).
>      */
>     newproto_handle = create_dissector_handle(dissect_newproto,
>             proto_ newproto );
>      ssl_dissector_add(NEWPROTO_TCP_PORT, newproto_handle);
> }
> 
> 
> I could made it work if in the  void proto_register_newproto(void)
> I do these operations (not creating the handle dissector in
> the_reg_handoff_newproto)
> 
>  newproto_handle = register_dissector("newproto", dissect_newproto,
> proto_newproto);
> 
> and in the reg_handoff_newproto I just make the call ssl_dissector_add(...)
> and then when the callback dissect_newproto is called then in the tvb
> buffer I can see the decrypted bytes (provided I set for TLS the right file
> with the dumped key).
> 
> What is the proper way to achieve what I'm trying to do?

The second approach is correct. I would suggest having a look at how
existing dissectors do it. In commit v3.1.0rc0-1327-g1da2caa0e0
(https://github.com/wireshark/wireshark/commit/1da2caa0e0), TLS support
was added to an existing dissector:

 - Call ssl_dissector with a handle from register_protocol:
    ssl_dissector_add(your_tcp_port, your_proto_handle)
 - Since CoAP has an official IANA registration for ALPN[1],
   automatically recognize your decrypted application protocol even on
   non-standard ports:
    dissector_add_string("tls.alpn", "coap", coap_handle);

 [1]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids

As for why create_dissector_handle did not work, it does not add a name.
register_dissector does the same as create_dissector_handle, but
additionally adds a name, enabling things such as Decode As.
-- 
Kind regards,
Peter Wu
https://lekensteyn.nl