Wireshark-dev: Re: [Wireshark-dev] Keeping decryption state of dissector in sync

From: Stephen Fisher <steve@xxxxxxxxxxxxxxxxxx>
Date: Fri, 29 Apr 2011 14:24:00 -0600
On Fri, Apr 29, 2011 at 06:59:45PM +0400, Max wrote:

> For now I use "global" conversation state for dissection if the packet 
> has no proto data associated with it, otherwise I use state from 
> associated data which stores the state before first packet dissection 
> was done. Am I right doing such things?

That would work, although I typically use the pinfo->fd->flags.visited 
boolean flag (there is a macro called PINFO_FD_VISITED(pinfo) for this) 
to see if my dissector has already dissected this packet.  If it has 
already dissected it, then that implies that the per packet data 
(should) be there already.

> 1) Whether decryption and decompression should be done every time the 
> dissector is called? Or there is way to figure out that it was already 
> done?

It's probably easiest to decrypt every time you dissect a packet.  
Unless you need to obtain information from the decrypted packet for 
future packets (thus needing to decrypt every single packet), you can 
put it inside a if(tree) check to only decrypt when that packet is being 
looked at and build the proto tree then.

> 2) How to run dissector on the decrypted tvbuff? Should it be done 
> manually or Wireshark does this itself?
>     If I should run it manually than how to get the encrypted tvbuff 
> on the subsequent calls of the protocol dissector?

I've done this before on a private dissector, but don't have the source 
handy to recall how I did it.  Take a look at other dissectors such as 
packet-snmp.c that include "#ifdef HAVE_LIBGCRYPT" for ideas.  Basically 
you would probably create a new tvbuff and then run the dissection 
routines such as proto_tree_add_item() on that tvbuff not the original 
from the packet.

> 3) If it is supposed that decryption is done every time the dissector 
> is called, how then should I keep the decryption cipher context?
>     Cloning and storing cipher context for every packet may cost a lot 
> of memory, and AFAIK libgcrypt doesn't provide any means
>     to clone the context (cipher handle).

Is each packet encrypted independently of the others or is it a running 
stream?