1 /****************************************************************************
2 *																			*
3 *							cryptlib RPC Header File						*
4 *						Copyright Peter Gutmann 1997-2001					*
5 *																			*
6 ****************************************************************************/
7 
8 #ifndef _RPC_DEFINED
9 
10 #define _RPC_DEFINED
11 
12 /* Each message when encoded looks as follows:
13 
14 	type			: 8
15 	flags			: 8
16 	noArgs			: 8
17 	noStringArgs	: 8
18 	length			: 32
19 	arg * 0..n		: 32 * n
20 	stringArg * 0..n: 32 + data * n
21 
22    The fixed header consists of a 32-bit type+format information value and
23    length (to allow the entire message to be read using only two read calls)
24    followed by 1 - MAX_ARGS integer args and 0 - MAX_STRING_ARGS variable-
25    length data args.  The protocol is completely stateless, the client sends
26    COMMAND_xxx requests to the server and the server responds with
27    COMMAND_RESULT messages */
28 
29 /* cryptlib API commands */
30 
31 typedef enum {
32 	COMMAND_NONE,				/* No command type */
33 	COMMAND_RESULT,				/* Result from server */
34 	COMMAND_SERVERQUERY,		/* Get info on server */
35 	COMMAND_CREATEOBJECT,		/* Create an object */
36 	COMMAND_CREATEOBJECT_INDIRECT,	/* Create an object indirectly */
37 	COMMAND_EXPORTOBJECT,		/* Export object in encoded form */
38 	COMMAND_DESTROYOBJECT,		/* Destroy an object */
39 	COMMAND_QUERYCAPABILITY,	/* Query capabilities */
40 	COMMAND_GENKEY,				/* Generate key */
41 	COMMAND_ENCRYPT,			/* Encrypt/sign/hash */
42 	COMMAND_DECRYPT,			/* Decrypt/sig check/hash */
43 	COMMAND_GETATTRIBUTE,		/* Get/set/delete attribute */
44 	COMMAND_SETATTRIBUTE,
45 	COMMAND_DELETEATTRIBUTE,
46 	COMMAND_GETKEY,				/* Get/set/delete key */
47 	COMMAND_SETKEY,
48 	COMMAND_DELETEKEY,
49 	COMMAND_PUSHDATA,
50 	COMMAND_POPDATA,
51 	COMMAND_FLUSHDATA,			/* Push/pop/flush data */
52 	COMMAND_CERTSIGN,			/* Sign certificate */
53 	COMMAND_CERTCHECK,			/* Check signature on certificate */
54 	COMMAND_CERTMGMT,			/* CA cert management operation */
55 	COMMAND_LAST				/* Last command type */
56 	} COMMAND_TYPE;
57 
58 /* Database shim commands */
59 
60 typedef enum {
61 	DBX_COMMAND_NONE,			/* No command type */
62 	DBX_COMMAND_RESULT,			/* Result from server (== COMAND_RESULT) */
63 	DBX_COMMAND_OPEN,			/* Open session with database */
64 	DBX_COMMAND_CLOSE,			/* Close session with database */
65 	DBX_COMMAND_QUERY,			/* Perform data fetch/check */
66 	DBX_COMMAND_UPDATE,			/* Perform data update */
67 	DBX_COMMAND_GETERRORINFO,	/* Sent if another command fails */
68 	DBX_COMMAND_LAST			/* Last command type */
69 	} DBX_COMMAND_TYPE;
70 
71 /* The command formats are as follows (arguments in square brackets are
72    implied arguments whose values are supplied at the C function level but
73    that aren't passed over the wire, this is used to handle reads of string
74    values):
75 
76 	COMMAND_SERVERQUERY
77 		<none>						word: status
78 									word: protocol version
79 									word: max.fragment size
80 	COMMAND_CREATEOBJECT
81 		word: handle				word: status
82 		word: object type			word: new handle
83 		word(s) | str(s): params
84 	COMMAND_CREATEOBJECT_INDIRECT
85 		word: handle				word: status
86 		word: object type			word: new handle
87 		str : encoded object data
88 	COMMAND_EXPORTOBJECT
89 		word: handle				word: status
90 		word(s): params				word: str_length | str: data
91 	COMMAND_DESTROYOBJECT
92 		word: handle				word: status
93 	COMMAND_QUERYCAPABILITY
94 		word: handle				word: status
95 		word: algo					word: str_length | str : data
96 		word: mode
97 		[str: return buffer]
98 	COMMAND_GENKEY
99 		word: handle				word: status
100 		word: is_async (optional)
101 	COMMAND_ENCRYPT
102 		word: handle				word: status
103 		str : data					str : data
104 	COMMAND_DECRYPT
105 		word: handle				word: status
106 		str : data					str : data
107 	COMMAND_GETATTRIBUTE
108 		word: handle				word: status
109 		word: attribute type		word: value | word: str_length | str: data
110 		word: get_str_data (optional)
111 		[str: return buffer for str_data]
112 	COMMAND_SETATTRIBUTE
113 		word: handle				word: status
114 		word: attribute type
115 		word: value | str : value
116 	COMMAND_DELETEATTRIBUTE
117 		word: handle				word: status
118 		word: attribute type
119 	COMMAND_GETKEY
120 		word: handle				word: status
121 		word: itemType				word: handle
122 		word: key ID type
123 		str : key ID (optional)
124 		str : password (optional)
125 	COMMAND_SETKEY
126 		word: handle				word: status
127 		word: key handle
128 		word: caItemType (optional)
129 		str : password (optional)
130 	COMMAND_DELETEKEY
131 		word: handle				word: status
132 		word: key ID type
133 		word: caItemType (optional)
134 		str : key ID
135 	COMMAND_PUSHDATA
136 		word: handle				word: status
137 		str : data					word: length
138 	COMMAND_POPDATA
139 		word: handle				word: status
140 		word: length				str : data
141 		[str: return buffer]
142 	COMMAND_CERTSIGN
143 		word: handle				word: status
144 		word: sig.key handle
145 	COMMAND_CERTCHECK
146 		word: handle				word: status
147 		word: check key handle
148 	COMMAND_CERTMGMT
149 		word: handle				word: status
150 		word: caKey					word: new cert (optional)
151 		word: certRequest
152 
153 	DBX_COMMAND_OPEN:
154 		word: options				word: status
155 		str : name					word: featureFlags
156 	DBX_COMMAND_CLOSE
157 		<none>
158 	DBX_COMMAND_UPDATE:
159 		word: type					word: status
160 		str : command
161 		str : date (optional)
162 		str : data (optional)
163 	DBX_COMMAND_QUERY:
164 		word: type					word: status
165 		word: query entry (opt.)	str : data
166 		str : command
167 		str : date (optional)
168 		str : data (optional)
169 		[str: return buffer]
170 	DBX_COMMAND_GETERRORINFO
171 		<none>						word: errorCode
172 									str : errorMessage */
173 
174 /* The maximum number of integer and string args, and the amount of space to
175    allocate in the COMMAND_INFO to store all possible args */
176 
177 #define MAX_ARGS				4
178 #define MAX_STRING_ARGS			2
179 #define DBX_MAX_ARGS			2
180 #define DBX_MAX_STRING_ARGS		3
181 #define ALLOC_MAX_ARGS			MAX_ARGS
182 #define ALLOC_MAX_STRING_ARGS	DBX_MAX_STRING_ARGS
183 
184 /* The possible command flags */
185 
186 #define COMMAND_FLAG_NONE		0x00	/* No command flag */
187 #define COMMAND_FLAG_RET_NONE	0x01	/* Don't return any data */
188 #define COMMAND_FLAG_RET_LENGTH	0x02	/* Return only length of string arg */
189 
190 /* The size of an integer as encoded in a message, the size of the fixed-
191    length fields, and the offsets of the data fields in the message */
192 
193 #define COMMAND_WORDSIZE		4
194 #define COMMAND_FIXED_DATA_SIZE	( COMMAND_WORDSIZE * 2 )
195 #define COMMAND_WORD1_OFFSET	COMMAND_FIXED_DATA_SIZE
196 #define COMMAND_WORD2_OFFSET	( COMMAND_FIXED_DATA_SIZE + COMMAND_WORDSIZE )
197 #define COMMAND_WORD3_OFFSET	( COMMAND_FIXED_DATA_SIZE + ( COMMAND_WORDSIZE * 2 ) )
198 #define COMMAND_WORD4_OFFSET	( COMMAND_FIXED_DATA_SIZE + ( COMMAND_WORDSIZE * 3 ) )
199 
200 /* Macros to encode/decode a message type value */
201 
202 #define putMessageType( buffer, type, flags, noInt, noString ) \
203 		{ \
204 		buffer[ 0 ] = ( BYTE ) ( type & 0xFF ); \
205 		buffer[ 1 ] = ( BYTE ) ( flags & 0xFF ); \
206 		buffer[ 2 ] = noInt; \
207 		buffer[ 3 ] = noString; \
208 		}
209 #define getMessageType( buffer, type, flags, noInt, noString ) \
210 		type = buffer[ 0 ]; flags = buffer[ 1 ]; \
211 		noInt = buffer[ 2 ]; noString = buffer[ 3 ]
212 
213 /* Macros to encode/decode an integer value and a length */
214 
215 #define putMessageWord( buffer, word ) \
216 		{ \
217 		( buffer )[ 0 ] = ( BYTE ) ( ( ( word ) >> 24 ) & 0xFF ); \
218 		( buffer )[ 1 ] = ( BYTE ) ( ( ( word ) >> 16 ) & 0xFF ); \
219 		( buffer )[ 2 ] = ( BYTE ) ( ( ( word ) >> 8 ) & 0xFF ); \
220 		( buffer )[ 3 ] = ( BYTE ) ( ( word ) & 0xFF ); \
221 		}
222 #define getMessageWord( buffer ) \
223 		( ( ( ( long ) ( buffer )[ 0 ] ) << 24 ) | \
224 		  ( ( ( long ) ( buffer )[ 1 ] ) << 16 ) | \
225 		  ( ( ( long ) ( buffer )[ 2 ] ) << 8 ) | \
226 			  ( long ) ( buffer )[ 3 ] )
227 
228 #define getMessageLength	getMessageWord
229 #define putMessageLength	putMessageWord
230 
231 /* A structure to contain the command elements */
232 
233 typedef struct {
234 	COMMAND_TYPE type;					/* Command type */
235 	int flags;							/* Command flags */
236 	int noArgs, noStrArgs;				/* Number of int, string args */
237 	int arg[ ALLOC_MAX_ARGS ];			/* Integer arguments */
238 	void *strArg[ ALLOC_MAX_STRING_ARGS ];	/* String args */
239 	int strArgLen[ ALLOC_MAX_STRING_ARGS ];
240 	} COMMAND_INFO;
241 
242 /* Function pointers for a generic dispatch function that dispatches the
243    marshalled data to a receiver, and command handlers that process each
244    command type */
245 
246 typedef void ( *DISPATCH_FUNCTION )( void *stateInfo, BYTE *buffer );
247 typedef int ( *COMMAND_HANDLER )( void *stateInfo, COMMAND_INFO *cmd );
248 
249 /* The full RPC interface (with marshalling and everything) provides complete
250    isolation of input and output, however it resuls in a slight performance
251    decrease due to copying, and can't handle large objects atomically due to
252    limits on message size (this specifically applies to mega-CRLs).  Because
253    of this, we also allow a direct interface that just forwards the data
254    without marshalling/unmarshalling.
255 
256    Because of the change in arg handling for returned data in RPC vs. direct
257    calls (the RPC returns the data in the return message, the direct call
258    requires an extra parameter to specify the location of the returned data)
259    we also need a macro RETURN_VALUE() to no-op out the extra parameter in
260    case we're using the RPC form */
261 
262 #ifdef USE_RPCAPI
263   #define DISPATCH_COMMAND( function, command ) \
264 		  dispatchCommand( &command )
265   #define DISPATCH_COMMAND_DBX( function, command, dbmsInfo ) \
266 		  dispatchCommand( &command, ( dbmsInfo )->stateInfo, ( dbmsInfo )->dispatchFunction )
267   #define RETURN_VALUE( value )		0
268 #else
269   #define DISPATCH_COMMAND( function, command ) \
270 		  function( &command )
271   #define DISPATCH_COMMAND_DBX( function, command, dbmsInfo ) \
272 		  function( ( dbmsInfo )->stateInfo, &command )
273   #define RETURN_VALUE( value )		value
274 #endif /* USE_RPCAPI */
275 
276 /* Check whether a decoded command header contains valid data for the
277    different RPC types */
278 
279 #define checkCommandInfo( cmd, length ) \
280 		( ( cmd )->type > COMMAND_NONE && \
281 		  ( cmd )->type < COMMAND_LAST && \
282 		  ( ( cmd )->flags == COMMAND_FLAG_NONE || \
283 		    ( cmd )->flags == COMMAND_FLAG_RET_NONE || \
284 			( cmd )->flags == COMMAND_FLAG_RET_LENGTH ) && \
285 		  ( cmd )->noArgs >= 1 && ( cmd )->noArgs <= MAX_ARGS && \
286 		  ( cmd )->noStrArgs >= 0 && ( cmd )->noStrArgs <= MAX_STRING_ARGS && \
287 		  ( cmd )->strArgLen[ 0 ] >= 0 && \
288 		  ( cmd )->strArgLen[ 1 ] >= 0 && \
289 		  ( length ) >= 0 && ( length ) <= RPC_IO_BUFSIZE )
290 
291 #define checkCommandConsistency( cmd, length ) \
292 		( ( ( cmd )->strArgLen[ 0 ] + ( cmd )->strArgLen[ 1 ] ) == \
293 			( length - ( COMMAND_WORDSIZE * ( ( cmd )->noArgs + ( cmd )->noStrArgs ) ) ) )
294 
295 #define dbxCheckCommandInfo( cmd, length ) \
296 		( ( cmd )->type > DBX_COMMAND_NONE && \
297 		  ( cmd )->type < DBX_COMMAND_LAST && \
298 		  ( cmd )->flags == COMMAND_FLAG_NONE && \
299 		  ( cmd )->noArgs >= 0 && ( cmd )->noArgs <= DBX_MAX_ARGS && \
300 		  ( cmd )->noStrArgs >= 0 && ( cmd )->noStrArgs <= DBX_MAX_STRING_ARGS && \
301 		  ( cmd )->strArgLen[ 0 ] >= 0 && \
302 		  ( cmd )->strArgLen[ 1 ] >= 0 && \
303 		  ( cmd )->strArgLen[ 2 ] >= 0 && \
304 		  ( length ) >= 0 && ( length ) <= DBX_IO_BUFSIZE )
305 
306 #define dbxCheckCommandConsistency( cmd, length ) \
307 		( ( ( cmd )->strArgLen[ 0 ] + ( cmd )->strArgLen[ 1 ] + ( cmd )->strArgLen[ 2 ] ) == \
308 			( length - ( COMMAND_WORDSIZE * ( ( cmd )->noArgs + ( cmd )->noStrArgs ) ) ) )
309 
310 /* The maximum size of a message fragment.  Messages containing more data
311    than this are broken up into fragments.  On systems with very restricted
312    amounts of memory we make the size rather small to limit the size of
313    the intermediate buffers used */
314 
315 #ifdef CONFIG_CONSERVE_MEMORY
316   #define MAX_FRAGMENT_SIZE		8192
317 #else
318   #define MAX_FRAGMENT_SIZE		32768
319 #endif /* CONSERVER_MEMORY */
320 
321 /* The size of the I/O buffer used to assemble messages.  This is equal to
322    the maximum fragment size plus the maximum header size for commands that
323    require fragmentation (COMMAND_ENCRYPT/COMMAND_DECRYPT and
324    COMMAND_PUSHDATA/COMMAND_POPDATA).  We define a separate version for
325    database RPC since this uses much smaller buffers */
326 
327 #define RPC_IO_BUFSIZE			MAX_FRAGMENT_SIZE + 32
328 #define DBX_IO_BUFSIZE			4096
329 
330 #endif /* _RPC_DEFINED */
331