# Hessian 2.0 Security

Caucho Technology Inc.

              P.O. Box 9001
              La Jolla
              CA
              92038
              USA

            ferg@caucho.com

Caucho Technology Inc.

              P.O. Box 9001
              La Jolla
              CA
              92038
              USA

            emil@caucho.com

# Design Goals

Unlike older binary protocols, Hessian is both self-describing, compact, and portable across languages. The wire protocol for web services should be invisible to application writers, it should not require external schema or IDL.
The Hessian protocol has the following design goals:
It must not require external IDL or schema definitions, i.e. the protocol should be invisible to application code.
It must be language-independent.
It must be simple so it can be effectively tested and implemented.
It must be as fast as possible.
It must be as compact as possible.
It must support Unicode strings.
It must support 8-bit binary data (i.e. without encoding or using attachments.)
It must support encryption, compression, signature, and transaction context envelopes.

# Hessian Grammar

Envelope/Messaging/RPC Grammar
# Envelope for encryption/headers envelope ::= 'E' x02 x00 env-chunk* 'z'

# header, body, footer env-chunk ::= int (string object)* binary int (string object)*

# Envelope

Envelope Grammar
envelope ::= E x02 x00 m b1 b0 <method-string> env-chunk* z

env-chunk ::= int (string object)* binary int (string object)*
A Hessian envelope wraps a Hessian message, adding headers and footers and possibly compressing or encrypting the wrapped message. The envelope type is identified by a method string, e.g. "com.caucho.hessian.io.Deflation" or "com.caucho.hessian.security.X509Encryption".
Some envelopes may chunk the data, providing multiple header/footer chunks. For example, a signature envelope might chunk a large streaming message to reduce the amount of buffering required to validate the signatures.

## Envelope examples

Identity Envelope
E x02 x00 m x00 x08 Identity # "Identity" envelope does nothing to the body x90 # no headers B x00 x0a # binary wrapped body (12 bytes) p x02 x00 # wrapped message x05 hello # "hello" z # end of wrapped message x90 # no footers z # end of envelope
Chunked Identity Envelope
E x02 x00 m x00 x08 Identity # "Identity" envelope does nothing to the body x90 # no headers B x00 x0c # binary header for wrapped body (10 bytes) p x02 x00 # wrapped message x07 hello, # "hello, " z # end of wrapped message x90 # no footers

x90 # no headers B x00 x08 # binary wrapped body (10 bytes) p x02 x00 # wrapped message x05 world # world z x90 # no footers z # end of envelope
Compression Envelope
E x02 x00 m x00 x09 Deflation # "Deflation" envelope compresses the body x90 # no headers B x00 x0a # binary wrapped body (32 bytes) x78 x9c x4b... # compressed message x90 # no footers z # end of envelope

# Bytecode map

Hessian is organized as a bytecode protocol. A Hessian implementation is essentially a big switch statement on the initial bytecode.
Bytecode Encoding
x00 - x1f # utf-8 string length 0-32 x20 - x2f # binary data length 0-16 x30 - x37 # reserved x38 - x3f # long from -x40000 to x3ffff x40 - x41 # reserved x42 # 8-bit binary data final chunk ('B') x43 # reserved ('C' streaming call) x44 # 64-bit IEEE encoded double ('D') x45 # reserved ('E' envelope) x46 # boolean false ('F') x47 # reserved x48 # reserved ('H' header) x49 # 32-bit signed integer ('I') x4a # reference to 1-256th map/list x4b # reference to 1-65536th map/list x4c # 64-bit signed long integer ('L') x4d # map with optional type ('M') x4e # null ('N') x4f # object definition ('O') x50 # reserved ('P' streaming message/post) x51 # reserved x52 # reference to map/list - integer ('R') x53 # utf-8 string final chunk ('S') x54 # boolean true ('T') x55 # reserved x56 # list/vector ('V') x57 # reserved x58 # utf-8 xml final chunk ('X') x59 - x62 # reserved x62 # 8-bit binary data non-final chunk ('b') x63 # reserved ('c' call for RPC) x64 # UTC time encoded as 64-bit long milliseconds since # epoch ('d') x65 # reserved x66 # reserved ('f' for fault for RPC) x67 # double 0.0 x68 # double 1.0 x69 # double represented as byte (-128.0 to 127.0) x6a # double represented as short (-32768.0 to 327676.0) x6b # double represented as float x6c # list/vector length ('l') x6d # reserved ('m' method for RPC call) x6e # list/vector compact length x6f # object instance ('o') x70 # reserved ('p' - message/post) x71 # reserved x72 # reserved ('r' reply for message/RPC) x73 # utf-8 string non-final chunk ('s') x74 # map/list type ('t') x75 # type-ref x76 # compact vector ('v') x77 # long encoded as 32-bit int x78 # utf-8 XML non-final chunk ('x') x79 # reserved x7a # list/map terminator ('z') x7b - x7f # reserved x80 - xbf # one-byte compact int (-x10 to x3f, x90 is 0) xc0 - xcf # two-byte compact int (-x800 to x3ff) xd0 - xd7 # three-byte compact int (-x40000 to x3ffff)