FW: [jcifs] ASN.1

Tapperson Kevin Kevin.Tapperson at hcahealthcare.com
Fri Apr 22 13:10:43 GMT 2005


Mike,

May I suggest separating the encoding into two phases.  The first phase is
the actual encoding work; converting the objects into byte[]'s.  The second
phase is the construction of the ASN.1 data buffer.  Don't touch your
ASN1Buffer "dst" in the first phase.  Here's a pseudo code example (this may
not be entirely correct; it's pretty early), but the concept still works.  I
used this methodology when I wrote an LDAP proxy a couple years ago.  I have
attached some code from my LDAP proxy project as an example.  You can find
the LDAP RFC with all of its ASN.1 definitions at
http://www.faqs.org/rfcs/rfc2251.html.  If nothing else, the BERUtils class
that I wrote may help.  Rename example.zip.txt to example.zip.

    void encode( ASN1Buffer dst ) {
        //phase 1
        byte[] nameBytes = new byte[0];
        if (name != null) {
            //the encode method would return a byte[] consisting of { 0xA0,
length(name), name bytes... }
            nameBytes = name.encode();
        }
        byte[] oldBytes = new byte[0];
        if (old != null) {
            oldBytes = old.encode();
        }

        //phase 2
        dst.enc_intn( 0x60, 1 );
        dst.enc_length( nameBytes.length + oldBytes.length );
        if (name != null) { 
            dst.write(nameBytes);
        }
        if (oid != null) { 
            dst.write(oldBytes);
        }
    }

-----Original Message-----
From: jcifs-bounces+kevin.tapperson=hcahealthcare.com at lists.samba.org
[mailto:jcifs-bounces+kevin.tapperson=hcahealthcare.com at lists.samba.org]
On Behalf Of Michael B Allen
Sent: Friday, April 22, 2005 2:25 AM
To: jcifs at samba.org
Subject: [jcifs] ASN.1


I'm sort of just emailing this to myself for later but if anyone out
there's an ASN.1 expert let me share my pain... I need some limited ASN.1
/ DER code for SPNEGO. Decoding this stuff is pretty easy but I've been
thinking all night about how to *encode* it.

The problem is (assuming a little knowledge of DER encoding here) that you
can't encode an object until you know the size of it's payload and you
don't know the size of the payload until you encode it. Well obviously
that's not entirely true or it quite simply wouldn't be possible to do
this at all.  Rather what you must do is first traverse the entire tree
of objects from the leaves up just to add up the sizes. Then you can
recur again to encode everything.

What an inelegant pain in the ass. It's ironic that the standard is
so miserly about saving every little byte in encoding lengths because
doing so incurs this inefficent encoding requirement. And what's even
more inefficient are all the Java implementations out there that create
an Object for every tag. Arg. OOP is just a tool, and it's not the right
tool for decoding/encoding ASN.1!

Anyway, here's my pseudocode for how I think I'm going to handle this. I
think I have it figure'd out but any input or anecdotes about ASN.1,
SPNEGO, extended security, etc is welcome.

Mike

Record ::= SEQUENCE {
   name [0] Name OPTIONAL,
   oid  [1] OBJECT IDENTIFER
}

The above shoddy ASN.1 might be encoded/decoded in DER w/ something like:

class Record extends ASN1Object {

    private int size = -1;

	/* The idea here is that Name and OID are also ASN1Objects
	 * that have similar encode and decode methods. So we
	 * demonstrate recursion with one node.
     */
    Name name;
    OID oid;

    int size() {
        if (size > 0) return size;
        int n = 0;
        if (name != null) {
            int m = name.size();
            n += 1 + lenlen( m ) + m;
				/* lenlen computes the number of bytes
required
				 * to encode the length of the object
				 */
        }       
        if (oid != null)
            n += oid.size();
        return 1 + lenlen(n) + n;
    }

    void encode( ASN1Buffer dst ) { 
        dst.enc_intn( 0x60, 1 );
        dst.enc_length( size() );
        if (name != null) { 
            int n = name.size();
            dst.enc_intn( 0xA0, 1 );
            dst.enc_length( n );
            name.encode( dst );
        }
        if (oid != null) { 
            int n = oid.size();
            dst.enc_intn( 0xA1, 1 );
            dst.enc_length( n );
            oid.encode( dst );
        }
    }
    void decode( ASN1Buffer src ) {  /* decoding is easy */
        src.dec_intn( 1 );
        src.dec_length();
        for ( ;; ) {
            int tag = src.dec_intn( 1 ) & 0xF;
            src.dec_length();
            switch (tag) { 
                case 0: 
                    name = new Name(); 
                    name.decode( src );
                    break;  
                case 1: 
                    ...
            }       
        }       
    }
}

call() {
    Record r = new Record();
    r.name = new Name(); 
    r.name....set name members 
    r.oid = SPNEGO.MECHANISM_KERBEROS;
    r.encode( dst );

    OR to decode

    Record r = new Record();
    r.decode( src );
}

-- 
IRC - where men are men, women are men, and the boys are FBI agents.

-------------- next part --------------
PK    ñ>–2ïQ#    
   BERUtils.javaÕXmOÛHþ|‘øs|8Ù
¸	)‡AZh-U‰Ô
÷åćM²Ž7²×!”ÒßޝÝuü;qœpâ"$¯¼3ó<3óx_p'Spø—̈å2ëê™ÓË  ÏŽ?xŸ”Lì½F™U/â+ÌœÞõ|H§Üe~Ád)À„ðëÊ
;>§cˆÙ½Æ4xî†
	C¸ºþvË]/Ük¼ì5@üôlÈ	{×'
ˆÐ®?†ëîÇÞ'§ûÎaÿ¶xÙÿè8û6|øpqዼ8
âI`8ýÞa§sòça±—\Ÿƒ >ú‹ŒT
à†&ð‡€=
Ê]EÐTñP
¾°¶0ˆaÚjêµ
lJé#‚µ§*ª€›àÑhÇxò¥Ì$Œ<.
§$Ú?aA¹‘~©SP®ëùcä¯Ôó‡:õJHÚ1DüzD8Ìó¥”Ó÷`rþhÍ;-ÎÏÕ ±IàOGÓN?Ñ8ƒ¨2×ÕjÙÙ‰{€œ\9)
g2’5›fÖ6‡›‰«ggÐÉ!¤ÌšÅ9ë6©ÒҼؒoÆ¿VËgÌ
Éžw#Ï«ÛqNÆåš½Åùß±£­“âŽþ&À§Oi,c?&v
‘OçS:ät„h§"Ö>4A¯;g_è\-#fšvaeãp]–åY¥6ʧÞÇ\uí@;‘ÒÛ·áhó6^;ë‚V§Z±©òÔºß©.’^å²u<súϝ|„ÂK!_¡ß]~©]•†Ë-:&£6³ƒ¿‰Ñubð˜?V
Åà]ʉí^µ¢ 2%úKó¨¤	}JB]Ó7×Åqùþ»BŠÝîÅ¡Œ+Êc©Zÿ
DB‰ôI
MÖê$±.‹®Nbw°8#W\-¯ýhòö2¹¬%ä¶{‘`Ô
·”Ä¥þa³ÍlÀ˜G‰òºRã·ïR»V—4½Ý7J®_±m[fä{&ë´Ž‡úЩ?d#Š~øb–Á,–»aöºAøx¥]öä°Rv
~ï]
K×1
gk®a×z
\NµGIãWÞi
6ØÔ>)e©ÇÃâLkÍÄñ"#™E)AÌ~(k™mÎzi_–±´ÎÃWí®¼o•ª&e#™˜òî´iøXœò|QQ¡Òö ŒÖ&bÅk*u&¡6ø÷™B^ä{´I¾üÈf^
Nuª+jpŸcJ”‹ŒŠ§3ëFFç%eGÕ­”­Ë¢O`5¡ƒä5q¼%‘-”‘9ÜÉ`Ö˜r,Qh¤eï¡÷	×5XyÝJòè¹ÅŠ ýóí¿¬Ï NçË–¨|+ª°‰ÏyñIf¶rMÎúäËÐÞ8_å³å=iŠ
ÿŠÌoH-¡ysój×ùgqÔô†”Š'
âïPK    Ì>–2'~CE  é     Control.javaTßoÓ0~¯ÔÿáÈSª‹°
ª=Ðj“@cð2õÁMÔà%Á¾0*´ÿ
ÇIjÇIY
©õù»ï¾ûa‹‡²Pßù/ÎDÁ–{Â÷JñýM^Vô™ò‡Åt n>^ÿN±$Qä#‡=Ï餬6R¤J®5¬ŠœT!§“?Ó	˜Uª‚0%Ü‚ñyi¸Û—¸!›¢ÈsH• ‘r9 ô9¾rY¡•`QMÜøv: äJc»‰=å ôh§ŠG
^¶
U«½^"' žÁ,¯o¿š÷í
Ïbðè%æíBìk
àÓ‡ûµýÑÆ!ÇÇÆÔP¬}â†%¶PŸb¬•°á¢ã;w,Žgؘ0ƒ×ܽ
‚v
nËæüàw,¤íc-º’2¨h‰øç­÷uíC)âÄûâ
^&3w൲^AÄS²|ò
wc¥PW’F4
^!þ¬¸Ôq”°×ìíÅ+–$ç——oXÂ.Øyò.š
Wê"˜V~âno­EwÃì
™Z0ïe¤ÑýE©ñ´¸ÿËmR¥ò–·
 îjw¡†Ó8Ú|l€fƒ»K;¡Y¬‡¯º)ÞŸ«›žàê'Ö¼F­Îiå"ÇC©m‘†òB®B¯Z‘ÿ`ë§ñ¬6›È³âNH—Šö.
åŠÚ÷œõ^ž3ˆæ`];œÅ¯¾±®#§Â|PK    ?–2¹CZÞ   %     LDAPMessage.java
A‹Ã FïÿÃ
ÍEö
z(íe¡
ÞKÖH×%Á™¤”Òÿ^mÔÝM(+BÐoæÍ‹æÒ[Gð-G)2­X;'o;ƒT±bÆ{Vôé5
ä	ÉIE Z‰»íú°×ˆò¬YqgøÕ;KZ‘nÀt—)ýÜVó4 AÙŽœmVÐé+d^¾¦Î:~¦ñ?ìrªŒaÑ—A‘sOŸ{<2~ú±ÑšdÓl&!
¿Ip9!™ßÄSÕx=kÚ'¾Ä9MƒëþÕŒZÇ:ðâßãx®/³/Ù×+óðÞ)þ¨©ûýPK    ù>–2°§¬xÐ  —     PagedResultsControl.java}SMoÛ0=/@þçËd40
ìäÐv À‚¦Ý¥éA±9W›"yýï“e5þˆSÀ-êñ‘|$ŦІà7ßòDèäú@xe?ÌUQÒ’òÍt<ê¡æ?n÷)$´r—ãQQ®¥H!•ÜZXð
³{´¥${£-÷„*³ÎãÑëxô©0bË	A(‚Â9-Å?œ¶ì.ºP9¤Zÿèã€{B¬(ìèà‡'°ÖZ"WA"åRÐa]àO.KŒ^ŒÞYhÕV|­?ÕcË
ëðwx;„ÓÆoHUXsaa
wƒ÷¬M–äHȲ¸Í[)G<w,×·÷$¤MœköÀsV±w ¿€yè.÷_/ãæ¦Uß;§D•ÓKŸöÎ[O˜}SBûú.sEƒøº§}tÝ–‡·æ¥Å³™ûz=[=dÑÝ·«lÐZ—#d­úB`‰‚pUºàQ‰-Ë%,ño‰*E`^¦iÐם"¸ WæhÒßqÒu€Ø]Eñçh ë·ÞÜVòºf.‚`,>2ƒTÕÞˆ!ž0ÂŽêÆkyžè¸?АÅœe‰î©’¤µ
•
ðÆ°å8!Þ²ŠjW?βŠž£&C÷þPK    Ã>–2®Æ

6  ¥  
   Response.java¥UMÚ0½#ñæ˜)¢ê‘n%Xö€´ÕVôã²ÚƒIfYWÁŽì	ªö¿×!_vâ msAdÞ›yó&có]&Á/¶g—ÑâD8WŠžrÊrúF
Ùn6
u`«§‡cŒq)úÁu<ÊòMÊc`MŠÅqÊ´†5êL
€GB‘hx\ο~A­ÙÇ£ßã˜'S’0&LxÀÁ®„­–a	«ÐÅ£óUÐfeè½rÎXŠÙKž€6u[.H
½)yÐ`õØ+²16=¿´2
Û4ÜÁâaýƒxª#±Lp%¨¯Ä⫪§ªë
LN&ÉiÝ
~,)™êºü&çir_½\2bWI(¶ô6 ¿!JÏ/ÃYígñX#)9&—ëMEƒ‰¯ç*hIå¯à-Ÿa¶0k"ÅãJ˜ÜÁSo¨ÝV‘¯¥å}hì·xç@]Ó¤ŽŠÓãÇ©=§&Яs	V9í
xLÿÛn«¹Ó€
òÿ6BØD»ÉŠïa=ÏÇË*{O<Ø0YUàÁÜYVe­í*÷¸–ãìá«Tp>ŸMgæçSC«??à“É°óî&?e8ð±\lKŸùKÔª*xA؝CÛÌ‚Ç,åtȽ2E&œä\ßW¼áÄ%ü'KóR}&–Ù/åÿ‹ƒ­ñÏ::Ý÷‹V¾÷@<ëaƒÞ	÷%_7¢/A;]\ÏÚ¶ÕY¼öBÊ•(¹$›åúmsu75¢¡γ®&©IøPK     ñ>–2ïQ#    
 $              BERUtils.java
         Iï’:GÅIï’:GÅs_<N:GÅPK     Ì>–2'~CE  é   $          1  Control.java
         •\h:GÅ•\h:GÅÕšãc:GÅPK     ?–2¹CZÞ   %   $          a  LDAPMessage.java
         ‹À:GÅ‹À:GÅcíH:GÅPK     ù>–2°§¬xÐ  —   $          m  PagedResultsControl.java
         ©1}›:GÅ©1}›:GÅÿq
–:GÅPK     Ã>–2®Æ

6  ¥  
 $          s	  Response.java
         éXÌ]:GÅéXÌ]:GÅaSL:GÅPK      è  Ô    


More information about the jcifs mailing list