Wireshark-dev: Re: [Wireshark-dev] ssl decryption in a dissector
From: Sebastiano Di Paola <sebastiano.dipaola@xxxxxxxxx>
Date: Wed, 31 Jul 2019 09:35:18 +0900


On Wed, 31 Jul 2019 at 07:43, Peter Wu <peter@xxxxxxxxxxxxx> wrote:
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()!

Thanks a lot Peter, I'm working on the latest development version :)
I will add the env variable in my development environment so I can spot this kind of issues. 

> 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

I will surely check out the code you pointed me to.
Thanks a lot!

 
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.

So this means that both should work right?

Have a nice day.
Sebastiano