From 3949f61cb6a890cbf6cfa08ee285276921f544cb Mon Sep 17 00:00:00 2001 Message-Id: <3949f61cb6a890cbf6cfa08ee285276921f544cb.1715461842.git.mdw@distorted.org.uk> From: Mark Wooding Date: Mon, 10 Jul 2017 11:12:11 +0100 Subject: [PATCH] wireshark/: Replace ancient dissector with a new one written in Lua. Organization: Straylight/Edgeware From: Mark Wooding This is mostly a good thing. + It work with both Wireshark 1.11 and 2. The old C code would have to choose between the two, and I couldn't easily tell how shiny a version of Wireshark I'd be pinning my colours to. + It actually dissects the TrIPE protocol as it currently is, including all of the group element encodings and bulk crypto transforms. + It'll be relatively easy to /keep/ the new dissector up-to-date relative to protocol changes. - It won't run as quickly -- but Lua has a reputation for being quite quick, and I'm not expecting to stress it very much. In theory, I'd be able to put this in an architecture-independent package, which would greatly shorten cross-build times. Alas, the plugin directory encodes the architecture name, so it'll have to be built separately for each architecture anyway. Lots of changes: * Eliminate the old `packet-tripe.c' dissector. Add the new one. Get the build system to install it in the right place. * Include a (rather shoddy) script for running `tripe' and capturing the conversation with `tshark', so I can test the dissector against it; and some small example captures. This might even turn into a proper test at some point, but for now it's just something I can do by hand. * Hack the `configure' script not to need all of the C compile-time machinery for building Wireshark plugins. --- configure.ac | 22 +- debian/control | 2 +- debian/rules | 3 - wireshark/Makefile.am | 9 +- wireshark/cap | Bin 9610 -> 4120 bytes wireshark/cap.dh | Bin 0 -> 3216 bytes wireshark/cap.ec | Bin 0 -> 1552 bytes wireshark/cap.x25519 | Bin 0 -> 1380 bytes wireshark/cap.x448 | Bin 0 -> 1740 bytes wireshark/capture-session | 77 +++++ wireshark/keyring | 4 + wireshark/packet-tripe.c | 479 ------------------------------- wireshark/tripe.lua | 582 ++++++++++++++++++++++++++++++++++++++ 13 files changed, 670 insertions(+), 508 deletions(-) create mode 100644 wireshark/cap.dh create mode 100644 wireshark/cap.ec create mode 100644 wireshark/cap.x25519 create mode 100644 wireshark/cap.x448 create mode 100755 wireshark/capture-session create mode 100644 wireshark/keyring delete mode 100644 wireshark/packet-tripe.c create mode 100644 wireshark/tripe.lua diff --git a/configure.ac b/configure.ac index f3b75ea2..33ce67dd 100644 --- a/configure.ac +++ b/configure.ac @@ -210,17 +210,7 @@ AC_ARG_WITH([wireshark], esac], [wantshark=yes mustshark=no]) -case "$wantshark" in - yes) - PKG_CHECK_MODULES([WIRESHARK], [wireshark >= 1.12.1], - [haveshark=yes], [haveshark=no]) - ;; - *) - haveshark=no - ;; -esac - -case "$haveshark,$wireshark_plugindir" in +case "$wantshark,$wireshark_plugindir" in yes,unknown) AC_CACHE_CHECK([where to put Wireshark plugins], [mdw_cv_wireshark_plugin_dir], [ @@ -249,11 +239,9 @@ case "$haveshark,$wireshark_plugindir" in ;; esac ;; -esac - -dnl If we're still interested, find Glib. -case "$haveshark" in - yes) AM_PATH_GLIB_2_0([2.4.0], [], [haveshark=false], [gmodule]) ;; + no,*) + haveshark=no + ;; esac case "$haveshark,$needshark" in @@ -261,8 +249,6 @@ case "$haveshark,$needshark" in AC_MSG_ERROR([failed to configure Wireshark plugin]) ;; yes,*) - WIRESHARK_CFLAGS="$GLIB_CFLAGS $WIRESHARK_CFLAGS" - AC_SUBST(WIRESHARK_CFLAGS) AC_SUBST(wireshark_plugindir) ;; esac diff --git a/debian/control b/debian/control index 24047590..17a7451a 100644 --- a/debian/control +++ b/debian/control @@ -56,7 +56,7 @@ Description: Trivial IP Encryption: a simple virtual private network Package: tripe-wireshark Architecture: any -Depends: wireshark-common (= ${tripe:Wireshark-Version}), ${shlibs:Depends} +Depends: wireshark-common (= ${tripe:Wireshark-Version}) Description: Trivial IP Encryption: a simple virtual private network TrIPE is a simple VPN protocol. It uses cryptography to ensure secrecy and authenticity of packets it sends and receives. diff --git a/debian/rules b/debian/rules index 01625b27..b45a6be5 100755 --- a/debian/rules +++ b/debian/rules @@ -28,9 +28,6 @@ dh-gencontrol-hook:: sed -n 's/^Version: */tripe:Wireshark-Version=/p' \ >> debian/tripe-wireshark.substvars -OVERRIDES += shlibdeps -dh_shlibdeps_OPTS += -Xwireshark/plugins - ###-------------------------------------------------------------------------- ### The startup script and related machinery. diff --git a/wireshark/Makefile.am b/wireshark/Makefile.am index 6342178e..36866dd6 100644 --- a/wireshark/Makefile.am +++ b/wireshark/Makefile.am @@ -28,12 +28,7 @@ include $(top_srcdir)/vars.am ###-------------------------------------------------------------------------- ### Wireshark plugin. -AM_CFLAGS += $(WIRESHARK_CFLAGS) -LIBS = - -wireshark_plugin_LTLIBRARIES = tripe.la - -tripe_la_LDFLAGS = -module -avoid-version -tripe_la_SOURCES = packet-tripe.c +wireshark_plugin_DATA = tripe.lua +EXTRA_DIST += tripe.lua ###----- That's all, folks -------------------------------------------------- diff --git a/wireshark/cap b/wireshark/cap index 1bd4c454b606bc13f57b07daff600cf7e979bb95..8e5cdc665c49e53825a2f631108c3ba1d62604eb 100644 GIT binary patch literal 4120 zcmbuC2{@E%8^>QUWDA+BVbEBcQTC#kn39r|Xi}CeH4HN*Te4=S#g;8n3L#r0PMGKr zNw$=-q-^IKa+D=y>3g54&pDG$-}PPJeO>qU-0#f$-1qPQ+|NAozFfS#TpkbvndmBu zvB2Zk@5TxVLi>qso<1mb>^AHcj2gzy)j?AoVuQ3HLr+(Vy&VOmU`eDpo;httbx}mA zVpXx4D1|*l57Z$?FVqn?7dNuE8_J1Fc13x9yHJGFL!cI@bM*TN!5P;;2*{gc=e7m@ zj1&Hr6CSytbr9s~KtWN+R1cK;7A^Qoo_}D1Z)fCVheum*0h?}a8&YN66Ma2627bsK z+TPIw3DN8KSFVNd5VRE?q7Uf{V4LqqJXV99g>RH^6q3l_iiYo&_MdIs7l}?V?JfF9 z5M)8@W#k3)o=hXbsyG?2B zd4BF)H?@&gQ~Ls{yaji85)2VM$_Q|Xd&=C#l3-J;H%cHqe%>C ziHT!cx0(p&_5W?%9AdgFX>pH&!`hO_GPymZb{3Dpgc`qW=Y2pOCv z^gmJy(~Wj`nS9T)c{V#tJd?HGuN%;x*UBfk3pyU_HR@5$q24~$;@yXJCJxDsx~1uA zco45KbOZhRVAI0}^z*gNeWm$p z{Lfsz`H(aye=T336Nhu@Y)hI;ihaA)f}SfSt&O>n=|WTWyQg(JIr`Jm@LBA8u>rG( zx&lY;G1d*N-*r$8Hn4u#>T=?(|=F+** z0{I1aGK)^2SG4_tXYOd4;lja*QBu?x|DAu0iMhV4yK28?{e`D0VG5TIzXGQPXfQOZ0j!cb6t%R@MtcWile}OMdU%hN3rH#Xk^?$uMw#X-a#c zsk=OqIf!k-mFt~cthEeK5ztG_OX+yFrSQ}f{BYTDU*ZV&CqWP1lveR4pB&Z3m-Z_B zl$8fpbMhCgstndvX4X60(B`(RviO@;3-a&WpEcG~jbK)`XO^l8xkbwM_3W=-aC7Vq z--Ew0#;>R0*}fDdo_I3byfInQN>2Ot>F~T{O4dy>P4scssoE|lhm6$6%jtPTgk)! zzF6?kKAlSw{O9d_?K*UjG@X!o+i02A8+(xxsgxKsjm$)QNzwAhdro{Xp3b8^A62TmzpM~0#aavj4zMSiUKdg`0M!~EUp5|n{l#Y?>0 zJ#0H+cOxRe%|}^Cug>w~Pj%F2J%09!e$+7fANc2UZjWo;f7w$@a}aeh4H zxACVsURchp=vdv4CwQPE>Kb!DM*X2cS8UHjP^4V?hl-umbW zRUWaG^HpdmjY~%~Y@(+(z3@V6Hm`Y2r?K$1rRVy!^qfD&E(i~%yFa+NO2)t2>F5MyA0!*bpT~Tnn0xySgJnE3X!!7P;xQ zSYhd1+SS*TwCE%5q0_c^3oe#EqQ>V~HdM;;r56855$;Xs54aF>y}tQYmIyu1xxFm5 zgWURC@8r7PS`XHN+}dNeru%argr7a|Afx<_^Z}=q5XvZA zerSk7o}2o47ndgqGDt!SVb=O8tYht5@lz2f?W@dW$D{uC3-W`v@vMJLb2o==jh1sR#E%lyjrnKcAlp8yNlIVCshn_Zeuh z&^b!(T+HEHoo+3GUzM_89f-uBxA8XqHa3T8!Y>qS<88%nbk=?0cV@Pm z^$`=GBJ)4h3x#U}(}(qi*7?cU!!htx`i>}OfO<+XO!{!?Xjz`wNFMP&7h?5AO}irX zP6WWS*&CGe%X>F0N1(%9sNJgQ8QSuz-u)-^a(%5Hq)G)y3Z-lxY=l54Bu1^B#sVYJ(G$1Us;|hY^r|v5YVav=K5Od%AfzQqQ0$RI(S* v!O;PA@+`{X+e`WyXf5O3G-8_|>-RXiNJf|qj)lIZg5SQ^eviHlpvJ!eBQY5? literal 9610 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 X~nnOVgvgJ0qyY*cnu&b literal 0 HcmV?d00001 diff --git a/wireshark/cap.ec b/wireshark/cap.ec new file mode 100644 index 0000000000000000000000000000000000000000..a9ecf1df81ee5984ff04b28e5a553d522b1e457d GIT binary patch literal 1552 zcmd<$<>e}2U|{gI(UxKa(*L1=nL(JrCo`|KLcv7OQqMrwST`{@#mt0(g~5Wsr8Ku7 zIk7-NBRsPxwKyZOC|gs(NY6;mOhLmvvqT{%wM-#2FFP;4JWnC5C_h)B6vEL28qWZ- z3uI3Qlx6^$$OMEr`3wx4Kp9S;I5&eL14C&_fkHukQHg?yk+FffLVl3~Ld3$@#1g2E z2ZtMhQegAhfOGm=;9ziNU@){0c3^N2WLaJhbRY;Xb>4HA zLH3`4DoCj#XI<{*I?H>Ueay;N#Z9%q=7P+h05u3?zV@OMCxG5y0AXYRHb2oq9Bh6u z%=|rfmpU`}{!0*GP?+QFGQHZ3@yEXNwpF`o8adT3fC(1|{5Euq0H+ zkwIZ+tZ&VwyBRO*3dCnj?@>9pPp>TAt-JC2)WytaW^g8NxpwiUU5M|TbBd21Dr>qd zu9>kRKrq8t?6KwAtLIm?1T!W?VU@h%w8o7JhBaY-tED#guicuIxM0PfZN{4x zf&BsUj|wQU00GE9%q)LTvH_SA!>wggF+|I>@CtV zJLMbVs&*P(K6IGjO^`Up#g6{8m!>LA{#{RuRlCE>n+?*UtHgx=^gO(%ZqWTvqQZ zyBTsDRNb<@DwCFN&G%xK$vx6;X27a<=2>mGk^?XM{8Gm`M}PN-fx-q9M&Jwuq(EV0 zWW4^=10WlOkpVc2E?LNd!{|3GjKFce@83mXLjEHZpWI!SzG)vRN?iVXrJc?7w0f(`}L{CXsxM&$x%MV)J1u|ylovJ)BkMcx*T`()@7rsf{j;<|Cgs1TzO-3 z+3O_Zn*$%Tc4j@vo3SeDUPb1s7$>gmtFQAv<<9as{w+|aFXv#Hv5D%8b)M4uC#Qn^ z4f1~j$TlDV`TxkGO{e04Y!F5UVE+eN$b-{-HO&9uG-CTNKxAtH*WX>49g^9dmXTM! zyCtoZQ#vNJdTs+Y7Qk1!@t<{`2<^ zpK<~6K^Pf;?KiVf0NXzmWzj2VXuN&8B})~&tYVcVQ|hb%_~VQDpn{c$}h`INlj5ms#HjU6wXWx91I|}=b44) YFhkjAb{NlL0kYYlX0Za<$N*#q00$N5JOBUy literal 0 HcmV?d00001 diff --git a/wireshark/cap.x25519 b/wireshark/cap.x25519 new file mode 100644 index 0000000000000000000000000000000000000000..6b65c111007905ab4f1e581ab60811c17fcf932a GIT binary patch literal 1380 zcmd<$<>e}2U|{gI(UxKa(*L1=nL(JrCo`|KLcv7OQqMrwST`{@#mt0(g~5Wsr8Ku7 zIk7-NBRsPxwKyZOC|gs(NY6;mOhLmvvqT{%wM-#2FFP;4JWnC5C_h)B6vEL28qWZ- z3uI3Qlx6^$$OMEr`3wx4Kp9S;I5&eL14C&_fkHukQHg@7g|VrnLVl3~Ld4kE*b=CY z2ZtMhQegAhfOGmT zAp6fi6{OUn@}&89F@OKt2c~1F&7SR@=aK?SR<@_Dkl!8o}^Kv9=t_W`Y7s+;2P2^irSsE1+6? zpN)jYswvA&7w*!qTP0Xrqr6wj;MqRUR@aInw{K3+y}d>7i3*?Og`#x zUVWCeXp8l;sfo)g^$h{iNSvgR4JZo2HYg}#pekXiYpZ}{rv#!2h!ESHN;kWv}{Fx_HqCWPOf}B=! zT5Qk7zTXQ2)oxjq-LmF=eCX2DiT?I`KKHI@bvvT&w{0ELd+kXKfN|rbGaO} zr9w40_VC$HT%Tme#`?2V|GW2Y$L9`jua!om88b8hRe{1c1&BcaWPi_{GdwOpHV7jF zu>EFMyTSJVg4quaU!{Mh3?C-6hb{?Ds;o7-6q}s=N)V`(Q9F5QjXTI}Rv?Du-B-b^ z49V@w#Tgl77@YG<^GZ^SiWLfq^2;()Qd1O?Diu;71s)Rv2Lnj0esza9Gn9R%ZMirL Qkj)Nt7%PyC3_x}O0D=yh>i_@% literal 0 HcmV?d00001 diff --git a/wireshark/cap.x448 b/wireshark/cap.x448 new file mode 100644 index 0000000000000000000000000000000000000000..0dd5d94163bca2eb79177bb7a4c24d0262d75b5d GIT binary patch literal 1740 zcmd<$<>e}2U|{gI(UxKa(*L1=nL(JrCo`|KLcv7OQqMrwST`{@#mt0(g~5Wsr8Ku7 zIk7-NBRsPxwKyZOC|gs(NY6;mOhLmvvqT{%wM-#2FFP;4JWnC5C_h)B6vEL28qWZ- z3uI3Qlx6^$$OMEr`3wx4Kp9S;I5&eL14C&_fkHukQHg?yfq{vELVl3~T*TPK*wP%R zjt7Sufl^@e*?@Echyw(br_PJ~-Err;J&+B;$bf^vm4U%9_nrfTgW$Q_^*{%L@SKdc zSO(dD2C5*X0lrnXoRhbiG9{lASs7xT2R0XEehbtfkojpWtv`~1d=N$kVDm$BAArr@ z3Nybgc1{L^S@ulyc zZJHw!bNtntT>UcJMIkp{y^)#+wj1PzKTyj+ZqQuC`|~!C55mX*?1r zot_%+l{m~Dle$RA(A90{il4PM^~=AAov%~uG@d89XYJ|L>f7`lZELNY`+WO0iz%C% zvRx)Vo9B~xqDUiJ$l~k4@ONjY?7MfBzeKg&w>D{!!;GI`KZE@40ZL3j0P?&0x>G;Z zfqW1~1|YvPO6EQR`Tgu$nBPI+&&c{;LWtb(zhybE;*-vK-6Li*jw@Mf8&6x){j%2j z6Q6tP^{I_TdwSkXH{PolCTsRMYaZW1nML*%v*Te}W_?v? zRpyS#tqgtfNb=r!X2I8CAg^}J6n$lP^Kx#l{mDs|<&wSfukK#dz5V&Cz!HIgs}m02 zowewp(^mUUO-s-4a!CFT^PSOmIP385vKQd+1BGJ*QaBz<-uKHK$OmC$01ijZ+-Kl$ zM9C+NqW?97DGd)w)6%v{lKkQ2;h_@6s~e+C%)z-La!FZu=ehaHd(;E?UT(R-J2%-s zoGU4O$2Dh`uFG0&w=S&?Kil&{V%58g8S7kYq<{8uSL#2BXPjfEaxC4rBJ^DTq7NZ& zBVEKSrk+=PlToER&)JYm?mT=l@S zvhUr!YaUQ5(W}bMKw0xe>2C!fsw@ z{wb&1+t0YRNcF+K&!Ok5zecG&b=FaS0(KY3eJN0ffZWHIb?KK2kPpJh0PH@q+!tW? zoq@RzTy`k^Gi4|eHu|f7GmYtc*!v*cRRy4MXUuPjv%d^7n-z$2poYB)W@T7%%2Jw< zL59IOzcjBTwWwI3peVmAGbJ@eA*oU!1yZpvF>o+|)Jn+kNHas(zCe8}KsGznELI>J I8G!5n0Mwsh0ssI2 literal 0 HcmV?d00001 diff --git a/wireshark/capture-session b/wireshark/capture-session new file mode 100755 index 00000000..4b5d81ac --- /dev/null +++ b/wireshark/capture-session @@ -0,0 +1,77 @@ +#! /bin/sh -e +### +### A simple script for capturing TrIPE sessions, for testing the Wireshark +### dissector. + +ty=${1?ty} param=${2-$ty} +tripe=${TRIPE-tripe} +rm -rf captmp +mkdir captmp +cd captmp + +cp ../keyring . +for i in alice bob; do + key add -eforever -a$ty -t$i -pparam-$param tripe +done +cp keyring keyring.pub + +for i in alice bob; do + mkfifo $i.in $i.out + TRIPE_SLIPIF=/usr/bin/tripe-uslip \ + $tripe -d. -as.$i -F -nslip -t$i -p0 <$i.in >$i.out 2>$i.err& +done +exec 3>alice.in 4bob.in 6&$in + while read tag tail; do + : "$tag $tail" + case $tag in + INFO) echo $tail ;; + FAIL) echo >&2 "command \`$*' failed: $tail"; exit 10 ;; + OK) break ;; + esac + done <&$out +} + +await () { + who=$1 + eval out=\$${who}_out + while read tag kind rest; do + : "$tag $kind $rest" + case $tag,$kind in + NOTE,KXDONE) break ;; + esac + done <&$out +} + +docmd alice watch n-tw +docmd bob watch n-tw + +p_alice=$(docmd alice port) +p_bob=$(docmd bob port) + +tshark -ilo -f"udp port $p_alice or udp port $p_bob" \ + -w../cap.$param& shark=$! +pause + +docmd alice add -cork bob 127.0.0.1 $p_bob +c=$(docmd bob getchal) +docmd alice greet bob $c +docmd bob add alice 127.0.0.1 $p_alice +await alice& walice=$! +await bob& wbob=$! +wait $walice +wait $wbob + +echo ping | tripe-uslip -p bob +x=$(tripe-uslip -g alice) + +pause + +exec 3>&- 4>&- 5>&- 6>&- +kill $shark +wait diff --git a/wireshark/keyring b/wireshark/keyring new file mode 100644 index 00000000..84b6133e --- /dev/null +++ b/wireshark/keyring @@ -0,0 +1,4 @@ +86249683:tripe-param:param-ec struct:[curve=string,shared:nist%2dp256] forever forever hash=sha256&kx-group=ec&cipher=rijndael-cbc&bulk=iiv +fae23925:tripe-param:param-x25519 string,shared:%2e forever forever hash=sha256&kx-group=x25519&cipher=salsa20&bulk=naclbox +a0fafc6b:tripe-param:param-dh struct:[p=integer,shared:635937223373484887991140560420669529960468634418212194527199243018802509220923645480563049852948379631872315326364181219863391536284352632127476573990043945919830000350264391397346335414535975554209931971547284463207275833747975949070870172306582775948778222246682185331862354083029804303222690541851195763223409045953191584611635790362191424339883737168342809190665629632289528654983812904611647818546832860081714363504512892885600580448186423533085059295328609139522690627823102925150246378111221377628009667319528150747320084312110336288028683700603719073769314245952464113622780032073817850603131463761017417455806035107984621889773217138911836476354442521466189648565925624512100087534918369360007697883847802211797655614684090408428715299537509886614640500137409891381649298835563011151796284848165977247286439820050405175697064122759870661294968492275655767983096727976056361878300352234381528837008128941375285251387,g=integer,shared:293025651734044707050351995205142657657141955131408425452312245943331353163428637443799381119408990271553007202915223601376791534187122912295000993316207089139736477148501917083144416322685925261624358336253378688806309805096283386698409139605996997308008266491782991490291726095895573563845937760385377670846794792328581579165150512160132493375389995617711312966986681865792948443127326586291576561351005982500369077653940283008076332825908419690031303502192009860824429031526378047535596212801179578879818504990773143072529887215206211778546705082334239130823956177702608427222251531070457604183947814624087379251368161182770323100074409926426428526795865215674068539423364010352920515052672366811052717283396264950182005583498061313136436293898863077084485762289185337928869086731032780517039420605615746259170222257438835029958473402842467194409561307509136616954789698181252705567549441508247668319257495617674881793988,q=integer,shared:89271282791461757245617785540129155142212959423277129581512553253419075634703] forever forever hash=sha256&kx-group=dh&cipher=twofish-cbc&bulk=v0 +8f879aef:tripe-param:param-x448 string,shared:%2e forever forever mgf=shake256-xof&hash=shake256&kx-group=x448&cipher=chacha20&bulk=naclbox diff --git a/wireshark/packet-tripe.c b/wireshark/packet-tripe.c deleted file mode 100644 index 28bfc83e..00000000 --- a/wireshark/packet-tripe.c +++ /dev/null @@ -1,479 +0,0 @@ -/* -*-c-*- - * - * TrIPE protocol dissector for Wireshark - * - * (c) 2003 Straylight/Edgeware - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of Trivial IP Encryption (TrIPE). - * - * TrIPE is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * TrIPE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with TrIPE; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "config.h" - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include "protocol.h" - -/*----- Static variables --------------------------------------------------*/ - -static int proto_tripe = -1; - -static guint hashsz = 20, tagsz = 10, ivsz = 8; - -typedef struct hfmp { - int hf, hf_len, hf_val, tt; -} hfmp; -typedef struct hfge { - int hf, hf_len, hf_val, hfx_len, hfx_val, hfy_len, hfy_val, tt; -} hfge; - -static int hf_tripe_cat = -1; -static int hf_tripe_packet_type = -1; -static int hf_tripe_ct = -1; -static int hf_tripe_ct_seq = -1; -static int hf_tripe_ct_iv = -1; -static int hf_tripe_ct_ct = -1; -static int hf_tripe_ct_tag = -1; -static int hf_tripe_misc_type = -1; -static int hf_tripe_misc_payload = -1; -static int hf_tripe_kx_type = -1; -static hfge hf_tripe_kx_mychal = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int hf_tripe_kx_mycookie = -1; -static int hf_tripe_kx_yourcookie = -1; -static hfmp hf_tripe_kx_check = { -1, -1, -1, -1 }; -static int hf_tripe_huh = -1; - -static int tt_tripe = -1; -static int tt_tripe_ct = -1; - -G_MODULE_EXPORT const gchar version[] = VERSION; - -/*----- Main code ---------------------------------------------------------*/ - -static void prefcb(void) { } - -static gint gethash(proto_tree *tt, int hf, tvbuff_t *b, gint off) -{ - proto_tree_add_item(tt, hf, b, off, hashsz, FALSE); - return (off + hashsz); -} - -static gint getmp(proto_tree *tt, const hfmp *hf, tvbuff_t *b, gint off) -{ - guint16 len = tvb_get_ntohs(b, off); - proto_item *ti = proto_tree_add_item(tt, hf->hf, b, off, len + 2, FALSE); - tt = proto_item_add_subtree(ti, hf->tt); - proto_tree_add_item(tt, hf->hf_len, b, off, 2, FALSE); - proto_tree_add_item(tt, hf->hf_val, b, off + 2, len, FALSE); - return (off + 2 + len); -} - -static gint getge(proto_tree *tt, const hfge *hf, tvbuff_t *b, gint off) -{ - guint16 len = tvb_get_ntohs(b, off), len2; - guint r; - proto_item *ti; - r = tvb_length_remaining(b, off); - if (r < 4 + len || - (len2 = tvb_get_ntohs(b, off + 2 + len), r < 4 + len + len2)) { - ti = proto_tree_add_item(tt, hf->hf, b, off, len + 2, FALSE); - tt = proto_item_add_subtree(ti, hf->tt); - proto_tree_add_item(tt, hf->hf_len, b, off, 2, FALSE); - proto_tree_add_item(tt, hf->hf_val, b, off + 2, len, FALSE); - r = off + len + 2; - } else { - ti = proto_tree_add_item(tt, hf->hf, b, off, len + len2 + 4, FALSE); - tt = proto_item_add_subtree(ti, hf->tt); - proto_tree_add_item(tt, hf->hfx_len, b, off, 2, FALSE); - proto_tree_add_item(tt, hf->hfx_val, b, off + 2, len, FALSE); - proto_tree_add_item(tt, hf->hfy_len, b, off + 2 + len, 2, FALSE); - proto_tree_add_item(tt, hf->hfy_val, b, off + 4 + len, len2, FALSE); - r = off + len + len2 + 4; - } - return (r); -} - -static void dissect_tripe(tvbuff_t *b, packet_info *p, proto_tree *t) -{ - proto_item *ti; - proto_tree *tt; - guint8 ty; - gint off = 0; - guint32 seq; - - /* --- Initialize the summary cells --- */ - - col_set_str(p->cinfo, COL_PROTOCOL, "TrIPE"); - col_clear(p->cinfo, COL_INFO); - ty = tvb_get_guint8(b, 0); - col_clear(p->cinfo, COL_INFO); - switch (ty & MSG_CATMASK) { - case MSG_PACKET: - switch (ty & MSG_TYPEMASK) { - case 0: - col_set_str(p->cinfo, COL_INFO, "Packet data"); - break; - default: - col_add_fstr(p->cinfo, COL_INFO, - "Packet data, unknown type code %u", - ty & MSG_TYPEMASK); - break; - } - break; - case MSG_KEYEXCH: - switch (ty & MSG_TYPEMASK) { - case KX_PRECHAL: - col_set_str(p->cinfo, COL_INFO, "Key exchange, prechallenge"); - break; - case KX_CHAL: - col_set_str(p->cinfo, COL_INFO, "Key exchange, challenge"); - break; - case KX_REPLY: - col_set_str(p->cinfo, COL_INFO, "Key exchange, reply"); - break; - case KX_SWITCH: - col_set_str(p->cinfo, COL_INFO, "Key exchange, switch request"); - break; - case KX_SWITCHOK: - col_set_str(p->cinfo, COL_INFO, "Key exchange, switch response"); - break; - default: - col_add_fstr(p->cinfo, COL_INFO, - "Key exchange, unknown type code %u", - ty & MSG_TYPEMASK); - break; - } - break; - case MSG_MISC: - switch (ty & MSG_TYPEMASK) { - case MISC_NOP: - col_set_str(p->cinfo, COL_INFO, "Miscellaneous, no-operation"); - break; - case MISC_PING: - col_set_str(p->cinfo, COL_INFO, "Miscellaneous, transport ping"); - break; - case MISC_PONG: - col_set_str(p->cinfo, COL_INFO, - "Miscellaneous, transport ping reply"); - break; - case MISC_EPING: - col_set_str(p->cinfo, COL_INFO, "Miscellaneous, encrypted ping"); - break; - case MISC_EPONG: - col_set_str(p->cinfo, COL_INFO, - "Miscellaneous, encrypted ping reply"); - break; - case MISC_GREET: - col_set_str(p->cinfo, COL_INFO, - "Miscellaneous, greeting"); - break; - default: - col_add_fstr(p->cinfo, COL_INFO, - "Miscellaneous, unknown type code %u", - ty & MSG_TYPEMASK); - break; - } - break; - default: - col_add_fstr(p->cinfo, COL_INFO, - "Unknown category code %u, unknown type code %u", - ty & MSG_CATMASK, ty & MSG_TYPEMASK); - break; - } - - /* --- Fill in the tree --- */ - - if (t) { - ti = proto_tree_add_item(t, proto_tripe, b, 0, -1, FALSE); - tt = proto_item_add_subtree(ti, tt_tripe); - - proto_tree_add_item(tt, hf_tripe_cat, b, 0, 1, FALSE); - - off = 1; - switch (ty & MSG_CATMASK) { - case MSG_PACKET: - proto_tree_add_item(tt, hf_tripe_packet_type, b, 0, 1, FALSE); - switch (ty & MSG_TYPEMASK) { - case 0: - goto ct; - default: - goto huh; - } - break; - case MSG_KEYEXCH: - proto_tree_add_item(tt, hf_tripe_kx_type, b, 0, 1, FALSE); - switch (ty & MSG_TYPEMASK) { - case KX_PRECHAL: - off = getge(tt, &hf_tripe_kx_mychal, b, off); - goto tail; - case KX_CHAL: - off = getge(tt, &hf_tripe_kx_mychal, b, off); - off = gethash(tt, hf_tripe_kx_yourcookie, b, off); - off = getmp(tt, &hf_tripe_kx_check, b, off); - goto tail; - case KX_REPLY: - off = getge(tt, &hf_tripe_kx_mychal, b, off); - off = gethash(tt, hf_tripe_kx_yourcookie, b, off); - off = getmp(tt, &hf_tripe_kx_check, b, off); - goto ct; - case KX_SWITCH: - off = gethash(tt, hf_tripe_kx_mycookie, b, off); - off = gethash(tt, hf_tripe_kx_yourcookie, b, off); - goto ct; - case KX_SWITCHOK: - goto ct; - default: - goto huh; - } - break; - case MSG_MISC: - proto_tree_add_item(tt, hf_tripe_misc_type, b, 0, 1, FALSE); - switch (ty & MSG_TYPEMASK) { - case MISC_NOP: - case MISC_PING: - case MISC_PONG: - case MISC_GREET: - proto_tree_add_item(tt, hf_tripe_misc_payload, - b, off, -1, FALSE); - goto done; - case MISC_EPING: - case MISC_EPONG: - goto ct; - default: - goto huh; - } - break; - default: - goto huh; - } - tail: - if (tvb_offset_exists(b, off)) - goto huh; - goto done; - huh: - proto_tree_add_item(tt, hf_tripe_huh, b, off, -1, FALSE); - goto done; - ct: - ti = proto_tree_add_item(tt, hf_tripe_ct, b, off, -1, FALSE); - seq = tvb_get_ntohl(b, off + tagsz); - proto_item_set_text(ti, "Encrypted ciphertext (sequence number %lu)", - (unsigned long)seq); - tt = proto_item_add_subtree(ti, tt_tripe_ct); - if (tagsz) { - proto_tree_add_item(tt, hf_tripe_ct_tag, b, off, tagsz, FALSE); - off += tagsz; - } - proto_tree_add_item(tt, hf_tripe_ct_seq, b, off, 4, FALSE); - off += 4; - if (ivsz) { - proto_tree_add_item(tt, hf_tripe_ct_iv, b, off, ivsz, FALSE); - off += ivsz; - } - proto_tree_add_item(ti, hf_tripe_ct_ct, b, off, -1, FALSE); - goto done; - done:; - } -} - -void proto_register_tripe(void) -{ - module_t *mod; - - static value_string vs_kxtype[] = { - { KX_PRECHAL, "KX_PRECHAL (prechallenge)" }, - { KX_CHAL, "KX_CHAL (challenge)" }, - { KX_REPLY, "KX_REPLY (reply)" }, - { KX_SWITCH, "KX_SWITCH (switch request)" }, - { KX_SWITCHOK, "KX_SWITCHOK (switch response)" }, - { 0, 0 } - }; - - static hf_register_info hfs[] = { - { &hf_tripe_cat, { - "Message category", "tripe.cat", - FT_UINT8, BASE_HEX, 0, MSG_CATMASK - } }, - { &hf_tripe_packet_type, { - "Packet message type", "tripe.packet.type", - FT_UINT8, BASE_HEX, 0, MSG_TYPEMASK, - "This is the TrIPE packet type subcode." - } }, - { &hf_tripe_ct, { - "Encrypted ciphertext", "tripe.ct", - FT_BYTES, BASE_NONE, 0, 0, - "This is an encrypted message." - } }, - { &hf_tripe_ct_seq, { - "Ciphertext sequence number", "tripe.ct.seq", - FT_UINT32, BASE_DEC, 0, 0, - "This is the unique sequence number for the ciphertext." - } }, - { &hf_tripe_ct_iv, { - "Ciphertext initialization vector", "tripe.ct.iv", - FT_BYTES, BASE_NONE, 0, 0, - "This is the initialization vector used for the actual encryption." - } }, - { &hf_tripe_ct_ct, { - "Actual encrypted data", "tripe.ct.ct", - FT_BYTES, BASE_NONE, 0, 0, - "This is the encrypted message. Reading it ought to be hard." - } }, - { &hf_tripe_ct_tag, { - "Message authentication code", "tripe.ct.tag", - FT_BYTES, BASE_NONE, 0, 0, - "This is the message authentication code tag for the ciphertext." - } }, - { &hf_tripe_misc_type, { - "Miscellaneous message type", "tripe.misc.type", - FT_UINT8, BASE_HEX, 0, MSG_TYPEMASK, - "This is the TrIPE miscellaneous message type subcode." - } }, - { &hf_tripe_misc_payload, { - "Miscellaneous message payload", "tripe.misc.payload", - FT_BYTES, BASE_NONE, 0, 0, - "This is the miscellaneous message payload." - } }, - { &hf_tripe_kx_type, { - "Key-exchange message type", "tripe.kx.type", - FT_UINT8, BASE_HEX, vs_kxtype, MSG_TYPEMASK, - "This is the TrIPE key-exchange type subcode." - } }, - { &hf_tripe_kx_mychal.hf, { - "Sender's challenge data", "tripe.kx.mychal", - FT_BYTES, BASE_NONE, 0, 0, - "This is the sender's challenge." - } }, - { &hf_tripe_kx_mychal.hf_len, { - "Challenge length", "tripe.kx.mychal.len", - FT_UINT16, BASE_DEC, 0, 0, - "This is the length of the sender's challenge." - } }, - { &hf_tripe_kx_mychal.hf_val, { - "Challenge", "tripe.kx.mychal.val", - FT_BYTES, BASE_NONE, 0, 0, - "This is the value of the sender's challenge." - } }, - { &hf_tripe_kx_mychal.hfx_len, { - "Challenge x length", "tripe.kx.mychal.x.len", - FT_UINT16, BASE_DEC, 0, 0, - "This is the length of the sender's challenge x-coordinate." - } }, - { &hf_tripe_kx_mychal.hfx_val, { - "Challenge x value", "tripe.kx.mychal.x.val", - FT_BYTES, BASE_NONE, 0, 0, - "This is the value of the sender's challenge x-coordinate." - } }, - { &hf_tripe_kx_mychal.hfy_len, { - "Challenge y length", "tripe.kx.mychal.y.len", - FT_UINT16, BASE_DEC, 0, 0, - "This is the length of the sender's challenge x-coordinate." - } }, - { &hf_tripe_kx_mychal.hfy_val, { - "Challenge y value", "tripe.kx.mychal.y.val", - FT_BYTES, BASE_NONE, 0, 0, - "This is the value of the sender's challenge x-coordinate." - } }, - { &hf_tripe_kx_mycookie, { - "Sender's hashed cookie", "tripe.kx.mycookie", - FT_BYTES, BASE_NONE, 0, 0, - "This is the hash of the sender's challenge." - } }, - { &hf_tripe_kx_yourcookie, { - "Recipient's hashed cookie", "tripe.kx.yourcookie", - FT_BYTES, BASE_NONE, 0, 0, - "This is the hash of the recipient's challenge." - } }, - { &hf_tripe_kx_check.hf, { - "Challenge check-value", "tripe.kx.check", - FT_BYTES, BASE_NONE, 0, 0, - "This is an encrypted check-value which proves that the sender " - "knows the answer to the challenge, and that it is therefore honest." - } }, - { &hf_tripe_kx_check.hf_len, { - "Check-value length", "tripe.kx.check.len", - FT_UINT16, BASE_DEC, 0, 0, - "This is the length of the encrypted check-value." - } }, - { &hf_tripe_kx_check.hf_val, { - "Check-value data", "tripe.kx.check.val", - FT_BYTES, BASE_NONE, 0, 0, - "This is the actual encrypted check-value." - } }, - { &hf_tripe_huh, { - "Unknown data", "tripe.huh", - FT_BYTES, BASE_NONE, 0, 0, - "I don't know what's meant to appear here." - } }, - }; - - static gint *tts[] = { - &tt_tripe, - &tt_tripe_ct, - &hf_tripe_kx_mychal.tt, - &hf_tripe_kx_check.tt, - }; - - proto_tripe = proto_register_protocol("TrIPE", "TrIPE", "tripe"); - proto_register_field_array(proto_tripe, hfs, array_length(hfs)); - proto_register_subtree_array(tts, array_length(tts)); - - mod = prefs_register_protocol(proto_tripe, prefcb); - prefs_register_uint_preference(mod, "hashsz", "Hash length", - "hash function output length (in octets)", - 10, &hashsz); - prefs_register_uint_preference(mod, "tagsz", "MAC tag length", - "MAC tag length (in octets)", 10, &tagsz); - prefs_register_uint_preference(mod, "ivsz", "IV length", - "block cipher initialization vector length" - " (in octets)", - 10, &ivsz); -} - -void proto_reg_handoff_tripe(void) -{ - dissector_handle_t dh; - - dh = create_dissector_handle(dissect_tripe, proto_tripe); - dissector_add_uint("udp.port", TRIPE_PORT, dh); -} - -G_MODULE_EXPORT void plugin_reg_handoff(void) -{ - proto_reg_handoff_tripe(); -} - -G_MODULE_EXPORT void plugin_register(void) -{ - if (proto_tripe == -1) - proto_register_tripe(); -} - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/wireshark/tripe.lua b/wireshark/tripe.lua new file mode 100644 index 00000000..fcc948d2 --- /dev/null +++ b/wireshark/tripe.lua @@ -0,0 +1,582 @@ +--- -*-lua-*- +--- +--- Wireshark protocol dissector for TrIPE +--- +--- (c) 2017 Straylight/Edgeware +--- + +-------- Licensing notice --------------------------------------------------- +--- +--- This file is part of Trivial IP Encryption (TrIPE). +--- +--- TrIPE is free software; you can redistribute it and/or modify +--- it under the terms of the GNU General Public License as published by +--- the Free Software Foundation; either version 2 of the License, or +--- (at your option) any later version. +--- +--- TrIPE is distributed in the hope that it will be useful, +--- but WITHOUT ANY WARRANTY; without even the implied warranty of +--- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +--- GNU General Public License for more details. +--- +--- You should have received a copy of the GNU General Public License +--- along with TrIPE; if not, write to the Free Software Foundation, +--- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +local tripe = Proto("tripe", "TrIPE VPN") + +----------------------------------------------------------------------------- +--- Configuration handling. + +local CONFIG = { + -- Information about the configuration variables. This table, when it's + -- set up, maps the internal names, which are used to refer to + -- configuration variables in the rest of this code, to a little structure: + -- + -- * `var' names the variable, and is the usual key for lookups; + -- + -- * `name' is the label used in the dialogue box; + -- + -- * `type' is the type of variable, currently either `enum' or `int'; + -- + -- * `descr' is a longer (but generally fairly useless) description for + -- use in a tooltip; + -- + -- * `allowed' is a sequence of allowed values for an `enum' variable; + -- and + -- + -- * `min' and `max' are the limits on permitted values for an `int' + -- variable (and may be omitted). + -- + -- More slots are added at runtime: + -- + -- * `map' is a table mapping string values to their integer indices, as + -- stored in Wireshark's preferences database. + -- + -- Initially, though, the table is given as a sequence, so that the + -- preferences can be populated in a consistent (and approximately logical) + -- order. + + { var = "bulk", name = "Bulk transform", + type = "enum", allowed = { "v0", "iiv", "naclbox" }, + descr = "Bulk cryptographic transform", default = "v0" }, + { var = "hashsz", name = "Hash length", type = "int", min = 0, + descr = "Hash length (bytes)", default = 20 }, + { var = "tagsz", name = "Tag length", type = "int", min = 0, + descr = "Authentication tag length (bytes)", default = 10 }, + { var = "ivsz", name = "IV length", type = "int", min = 0, + descr = "Initialization vector length (bytes)", default = 8 }, + { var = "kx", name = "Key-exchange group", + type = "enum", allowed = { "dh", "ec", "x25519", "x448" }, + descr = "Key-exchange group type", default = "dh" }, + { var = "scsz", name = "Scalar length", type = "int", min = 1, + descr = "Scalar field-element length (bytes)", default = 32 }, +} + +local C = { } -- The working values of the configuration variables. + +local function set_config(k, v) + -- Set configuration variable K to the value V. + -- + -- K is a string naming the variable to set. V is the new value, which may + -- be a string or a number. + -- + -- For `int' variables, V is converted to a number if necessary, and then + -- checked against the permitted bounds. + -- + -- For `enum' variables, things are more complicated. If V is a string, + -- it's checked against the permitted values. If V is a number, it's + -- converted back into the corresponding string. + + local info = CONFIG[k] + + if info == nil then error("unknown config key `" .. k .. "'") end + + if info.type == "enum" then + if type(v) == "number" then + local t = info.allowed[v] + if t == nil then + error(string.format("bad index %d for `%s'", n, k)) + end + v = t + else + if info.map[v] == nil then + error(string.format("bad value `%s' for `%s'", v, k)) + end + end + + elseif info.type == "int" then + local n = tonumber(v) + if n == nil then error("bad number `" .. v .. "'") end + if n ~= math.floor(n) then + error("value `" .. v .. "' is not an integer") + end + if (info.min ~= nil and n < info.min) or + (info.max ~= nil and n > info.max) + then + error(string.format("value %d out of range for `%s'", n, k)) + end + v = n + end + + C[k] = v +end + +-- Set up the configuration information. Configure preferences objects on +-- the dissector. For `enum' variables, build the `map' slots. +for i, v in ipairs(CONFIG) do + local k = v.var + CONFIG[k] = v + if v.type == "enum" then + local tab = { } + v.map = { } + for i, t in pairs(v.allowed) do + v.map[t] = i + tab[i] = { i, t, i } + end + tripe.prefs[k] = Pref.enum(v.name, v.map[v.default], v.descr, tab) + elseif v.type == "int" then + tripe.prefs[k] = Pref.uint(v.name, v.default, v.descr) + end +end + +local function prefs_changed() + -- Notice that the preferences have been changed and update `C'. + + for k, _ in pairs(CONFIG) do + if type(k) == "string" then set_config(k, tripe.prefs[k]) end + end +end +tripe.prefs_changed = prefs_changed + +-- Populate the configuration table from the stored preferences or their +-- default values. +prefs_changed() + +-- Now work through arguments passed in on the command line. Annoyingly, +-- while one can set preferences on the Wireshark command line, these are +-- done /before/ Lua scripts are loaded, so the silly thing thinks the +-- preference slots don't exist. So we have to do it a different way. +for _, arg in ipairs({...}) do + local k, v = arg:match("(.+)=(.+)") + if k == nil or v == nil then error("bad option syntax `" .. arg .. "'") end + se_config(k, v) +end + +----------------------------------------------------------------------------- +--- Protocol dissection primitives. + +local PF = { } -- The table of protocol fields, filled in later. + +-- The `dissect_*' functions follow a common protocol. They parse a thing +-- from a packet buffer BUF, of size SZ, starting from POS, and store +-- interesting things in a given TREE; when they're done, they return the +-- updated index where the next interesting thing might be. As a result, +-- it's usually a simple matter to parse a packet by invoking the appropriate +-- primitive dissectors in the right order. + +local function dissect_wtf(buf, tree, pos, sz) + -- If POS is not at the end of the buffer, note that there's unexpected + -- stuff in the packet. + + if pos < sz then tree:add(PF["tripe.wtf"], buf(pos, sz - pos)) end + return sz +end + +-- Dissect a ciphertext of some particular kind. +local dissect_ct = { } +function dissect_ct.naclbox(buf, tree, pos, sz) + tree:add(PF["tripe.ciphertext.tag"], buf(pos, 16)); pos = pos + 16 + tree:add(PF["tripe.ciphertext.seq"], buf(pos, 4)); pos = pos + 4 + tree:add(PF["tripe.ciphertext.body"], buf(pos, sz - pos)) +end +function dissect_ct.iiv(buf, tree, pos, sz) + tree:add(PF["tripe.ciphertext.tag"], buf(pos, C.tagsz)); pos = pos + C.tagsz + tree:add(PF["tripe.ciphertext.seq"], buf(pos, 4)); pos = pos + 4 + tree:add(PF["tripe.ciphertext.body"], buf(pos, sz - pos)) +end +function dissect_ct.v0(buf, tree, pos, sz) + tree:add(PF["tripe.ciphertext.tag"], buf(pos, C.tagsz)); pos = pos + C.tagsz + tree:add(PF["tripe.ciphertext.seq"], buf(pos, 4)); pos = pos + 4 + tree:add(PF["tripe.ciphertext.iv"], buf(pos, C.ivsz)); pos = pos + C.ivsz + tree:add(PF["tripe.ciphertext.body"], buf(pos, sz - pos)) +end + +local function dissect_ciphertext(buf, tree, label, pos, sz) + -- Dissect a ciphertext, making the whole thing be a little subtree with + -- the given LABEL. + + local t = tree:add(PF[label], buf(pos, sz - pos)) + dissect_ct[C.bulk](buf, t, pos, sz) + return pos +end + +local function dissect_packet(buf, tree, pos, sz) + return dissect_ciphertext(buf, tree, "tripe.packet.payload", pos, sz) +end + +-- Dissect a group element of some particular kind. +local dissect_ge = { } +function dissect_ge.dh(buf, tree, pos, sz) + tree:add(PF["tripe.dh.len"], buf(pos, 2)) + xsz = buf(pos, 2):uint(); pos = pos + 2 + tree:add(PF["tripe.dh.x"], buf(pos, xsz)); pos = pos + xsz + return pos +end +function dissect_ge.ec(buf, tree, pos, sz) + tree:add(PF["tripe.ec.xlen"], buf(pos, 2)) + xsz = buf(pos, 2):uint(); pos = pos + 2 + tree:add(PF["tripe.ec.x"], buf(pos, xsz)); pos = pos + xsz + tree:add(PF["tripe.ec.ylen"], buf(pos, 2)) + ysz = buf(pos, 2):uint(); pos = pos + 2 + tree:add(PF["tripe.ec.y"], buf(pos, ysz)); pos = pos + ysz + return pos +end +function dissect_ge.x25519(buf, tree, pos, sz) + tree:add(PF["tripe.x25519.x"], buf(pos, 32)) + return pos + 32 +end +function dissect_ge.x448(buf, tree, pos, sz) + tree:add(PF["tripe.x448.x"], buf(pos, 56)) + return pos + 56 +end + +local function dissect_my_challenge(buf, tree, pos, sz) + -- We don't know how long the group element is going to be. We can set the + -- length later, but (at least in older versions) it doesn't work so well + -- to increase the length, so make it large to start out, and shrink it + -- later. + local t = tree:add(PF["tripe.keyexch.mychal"], buf(pos, sz - pos)) + local q = dissect_ge[C.kx](buf, t, pos, sz) + t:set_len(q - pos) + return q +end + +local function dissect_my_cookie(buf, tree, pos, sz) + tree:add(PF["tripe.keyexch.mycookie"], buf(pos, C.hashsz)) + return pos + C.hashsz +end + +local function dissect_your_cookie(buf, tree, pos, sz) + tree:add(PF["tripe.keyexch.yourcookie"], buf(pos, C.hashsz)) + return pos + C.hashsz +end + +local kx_scsz = { x25519 = 32, x448 = 56 } -- Hardwired scalar sizes. +local function dissect_check(buf, tree, pos, sz) + local scsz = kx_scsz[C.kx] or C.scsz + tree:add(PF["tripe.keyexch.check"], buf(pos, scsz)) + return pos + scsz +end + +local function dissect_reply(buf, tree, pos, sz) + return dissect_ciphertext(buf, tree, "tripe.keyexch.reply", pos, sz) +end + +local function dissect_switch(buf, tree, pos, sz) + return dissect_ciphertext(buf, tree, "tripe.keyexch.switch", pos, sz) +end + +local function dissect_switchok(buf, tree, pos, sz) + return dissect_ciphertext(buf, tree, "tripe.keyexch.switchok", pos, sz) +end + +local function dissect_misc_payload(buf, tree, pos, sz) + tree:add(PF["tripe.misc.payload"], buf(pos, sz - pos)) + return sz +end + +local function dissect_misc_ciphertext(buf, tree, pos, sz) + return dissect_ciphertext(buf, tree, "tripe.misc.ciphertext", pos, sz) +end + +----------------------------------------------------------------------------- +--- The protocol information table. + +local PKTINFO = { + -- This is the main table which describes the protocol. The top level maps + -- category codes to structures: + -- + -- * `label' is the category code's symbolic name; + -- + -- * `subtype' is the field name for the subtype code; + -- + -- * `info' is a prefix for the information column display; and + -- + -- * `sub' is a table describing the individual subtypes. + -- + -- The subtype table similarly maps subtype codes to structures: + -- + -- * `label' is the subtype code's symbolic name; + -- + -- * `info' is the suffix for the information column display; and + -- + -- * `dissect' is a sequence of primitive dissectors to run in order to + -- parse the rest of the packet. + + [0] = { + label = "MSG_PACKET", subtype = "tripe.packet.type", + info = "Packet data", + sub = { + [0] = { label = "PACKET_IP", info = "encapsulated IP datagram", + dissect = { dissect_packet} } + } + }, + + [1] = { + label = "MSG_KEYEXCH", subtype = "tripe.keyexch.type", + info = "Key exchange", + sub = { + [0] = { label = "KX_PRECHAL", info = "pre-challenge", + dissect = { dissect_my_challenge, + dissect_wtf } }, + [1] = { label = "KX_CHAL", info = "challenge", + dissect = { dissect_my_challenge, + dissect_your_cookie, + dissect_check, + dissect_wtf } }, + [2] = { label = "KX_REPLY", info = "reply", + dissect = { dissect_my_challenge, + dissect_your_cookie, + dissect_check, + dissect_reply } }, + [3] = { label = "KX_SWITCH", info = "switch", + dissect = { dissect_my_cookie, + dissect_your_cookie, + dissect_switch } }, + [4] = { label = "KX_SWITCHOK", info = "switch-ok", + dissect = { dissect_switchok } }, + } + }, + + [2] = { + label = "MSG_MISC", subtype = "tripe.misc.type", + info = "Miscellaneous", + sub = { + [0] = { label = "MISC_NOP", info = "no-operation (keepalive)", + dissect = { dissect_misc_payload } }, + [1] = { label = "MISC_PING", info = "transport-level ping", + dissect = { dissect_misc_payload } }, + [2] = { label = "MISC_PONG", info = "transport-level ping reply", + dissect = { dissect_misc_payload } }, + [3] = { label = "MISC_EPING", info = "crypto-level ping", + dissect = { dissect_misc_ciphertext } }, + [4] = { label = "MISC_EPONG", info = "crypto-level ping reply", + dissect = { dissect_misc_ciphertext } }, + [5] = { label = "MISC_GREET", info = "greeting", + dissect = { dissect_misc_payload } }, + } + } +} + +do + -- Work through the master table and build `cattab' and `subtab' tables, + -- mapping category and subtype codes to their symbolic names for + -- presentation. The `subtab' is a two-level table, needing two layers of + -- indexing. + local cattab = { } + local subtab = { } + for i, v in pairs(PKTINFO) do + cattab[i] = v.label + if v.sub ~= nil then + subtab[i] = { } + for j, w in pairs(v.sub) do + subtab[i][j] = w.label + end + end + end + + local ftab = { + -- The protocol fields. This table maps the field names to structures + -- used to build the fields, which are then stored in `PF' (declared way + -- above): + -- + -- * `name' is the field name to show in the dissector tree view; + -- + -- * `type' is the field type; + -- + -- * `base' is a tweak describing how the field should be formatted; + -- + -- * `mask' is used to single out a piece of a larger bitfield; and + -- + -- * `tab' names a mapping table used to convert numerical values to + -- symbolic names. + + ["tripe.type"] = { + name = "Message type", type = ftypes.UINT8, base = base.HEX + }, + ["tripe.cat"] = { + name = "Message category", type = ftypes.UINT8, base = base.DEC, + mask = 0xf0, tab = cattab + }, + ["tripe.packet.type"] = { + name = "Packet subcode", type = ftypes.UINT8, base = base.DEC, + mask = 0x0f, tab = subtab[0] + }, + ["tripe.packet.payload"] = { + name = "Encrypted packet", type = ftypes.NONE + }, + ["tripe.keyexch.type"] = { + name = "Key-exchange subcode", type = ftypes.UINT8, base = base.DEC, + mask = 0x0f, tab = subtab[1] + }, + ["tripe.keyexch.mychal"] = { + name = "Sender's challenge R = r P", type = ftypes.NONE + }, + ["tripe.keyexch.mycookie"] = { + name = "Hash of recipient's challenge = H(R, ...)", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.keyexch.yourcookie"] = { + name = "Hash of sender's challenge = H(R', ...)", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.keyexch.reply"] = { + name = "Encrypted reply = k R'", type = ftypes.NONE + }, + ["tripe.keyexch.switch"] = { + name = "Encrypted reply and switch request = k R', H(...)", + type = ftypes.NONE + }, + ["tripe.keyexch.switchok"] = { + name = "Encrypted switch confirmation = H(...)", type = ftypes.NONE + }, + ["tripe.misc.type"] = { + name = "Miscellenaous subcode", type = ftypes.UINT8, base = base.DEC, + mask = 0x0f, tab = subtab[2] + }, + ["tripe.misc.payload"] = { + name = "Miscellaneous payload", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.misc.ciphertext"] = { + name = "Miscellaneous encrypted payload", type = ftypes.NONE + }, + ["tripe.wtf"] = { + name = "Unexpected trailing data", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.keyexch.check"] = { + name = "Sender's challenge check value = r XOR H(r K', ...)", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.ciphertext.seq"] = { + name = "Sequence number", type = ftypes.UINT32, base = base.DEC + }, + ["tripe.ciphertext.iv"] = { + name = "Initialization vector", type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.ciphertext.tag"] = { + name = "Authentication tag", type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.ciphertext.body"] = { + name = "Encrypted data", type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.dh.len"] = { + name = "DH group element length", + type = ftypes.UINT16, base = base.DEC + }, + ["tripe.dh.x"] = { + name = "DH group element value", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.ec.xlen"] = { + name = "Elliptic curve x-coordinate length", + type = ftypes.UINT16, base = base.DEC + }, + ["tripe.ec.x"] = { + name = "Elliptic curve x-coordinate value", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.ec.ylen"] = { + name = "Elliptic curve y-coordinate length", + type = ftypes.UINT16, base = base.DEC + }, + ["tripe.ec.y"] = { + name = "Elliptic curve y-coordinate value", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.x25519.x"] = { + name = "X25519 x-coordinate", + type = ftypes.BYTES, base = base.SPACE + }, + ["tripe.x448.x"] = { + name = "X448 x-coordinate", + type = ftypes.BYTES, base = base.SPACE + }, + } + + -- Convert this table into the protocol fields, and populate `PF'. + local ff = { } + local i = 1 + + -- Figure out whether we can use `none' fields (see below). + -- probe for this easily + local use_none_p = rawget(ProtoField, 'none') ~= nil + for abbr, args in pairs(ftab) do + + -- An annoying hack. Older versions of Wireshark don't allow setting + -- fields with type `none', which is a shame because they're ideal as + -- internal tree nodes. + ty = args.type + b = args.base + if ty == ftypes.NONE and not use_none_p then + ty = ftypes.BYTES + b = base.SPACE + end + + -- Go make the field. + local f = ProtoField.new(args.name, abbr, ty, + args.tab, b, args.mask, args.descr) + PF[abbr] = f + ff[i] = f; i = i + 1 + end + tripe.fields = PF +end + +----------------------------------------------------------------------------- +--- The main dissector. + +function tripe.dissector(buf, pinfo, tree) + + -- Fill in the obvious stuff. + pinfo.cols.protocol = "TrIPE" + + local sz = buf:reported_length_remaining() + local sub = tree:add(tripe, buf(0, sz), "TrIPE packet") + local p = 1 + + -- Decode the packet type octet. + local tycode = buf(0, 1):uint() + local ty = sub:add(PF["tripe.type"], buf(0, 1)) + ty:add(PF["tripe.cat"], buf(0, 1)) + local cat = bit.rshift(bit.band(tycode, 0xf0), 4) + local subty = bit.band(tycode, 0x0f) + local info = PKTINFO[cat] + + -- Dispatch using the master protocol table. + if info == nil then + pinfo.cols.info = string.format("Unknown category code %u, " .. + "unknown type code %u", + cat, subty) + else + ty:add(PF[info.subtype], buf(0, 1)) + local subinfo = info.sub[subty] + if subinfo == nil then + pinfo.cols.info = string.format("%s, unknown type code %u", + info.info, subty) + else + pinfo.cols.info = string.format("%s, %s", info.info, subinfo.info) + p = 1 + for _, d in ipairs(subinfo.dissect) do p = d(buf, sub, p, sz) end + end + end + + -- Return the final position we reached. + return p +end + +-- We're done. Register the dissector. +DissectorTable.get("udp.port"):add(4070, tripe) + +-------- That's all, folks -------------------------------------------------- -- [mdw]