cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
rpc.h
Go to the documentation of this file.
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 */
46  COMMAND_GETKEY, /* Get/set/delete key */
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 */
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. Because of the change in arg handling
255  for returned data in RPC vs. direct calls (the RPC returns the data in
256  the return message, the direct call requires an extra parameter to specify
257  the location of the returned data) we also need a macro RETURN_VALUE() to
258  no-op out the extra parameter in case we're using the RPC form */
259 
260 #ifdef USE_RPCAPI
261  #define DISPATCH_COMMAND( function, command ) \
262  dispatchCommand( &command )
263  #define DISPATCH_COMMAND_DBX( function, command, dbmsInfo ) \
264  dispatchCommand( &command, ( dbmsInfo )->stateInfo, ( dbmsInfo )->dispatchFunction )
265  #define RETURN_VALUE( value ) 0
266 #else
267  #define DISPATCH_COMMAND( function, command ) \
268  function( NULL, &command )
269  #define DISPATCH_COMMAND_DBX( function, command, dbmsInfo ) \
270  function( ( dbmsInfo )->stateInfo, &command )
271  #define RETURN_VALUE( value ) value
272 #endif /* USE_RPCAPI */
273 
274 /* Check whether a decoded command header contains valid data for the
275  different RPC types */
276 
277 #define checkCommandInfo( cmd, length ) \
278  ( ( cmd )->type > COMMAND_NONE && \
279  ( cmd )->type < COMMAND_LAST && \
280  ( ( cmd )->flags == COMMAND_FLAG_NONE || \
281  ( cmd )->flags == COMMAND_FLAG_RET_NONE || \
282  ( cmd )->flags == COMMAND_FLAG_RET_LENGTH ) && \
283  ( cmd )->noArgs >= 1 && ( cmd )->noArgs <= MAX_ARGS && \
284  ( cmd )->noStrArgs >= 0 && ( cmd )->noStrArgs <= MAX_STRING_ARGS && \
285  ( cmd )->strArgLen[ 0 ] >= 0 && \
286  ( cmd )->strArgLen[ 1 ] >= 0 && \
287  ( length ) >= 0 && ( length ) <= RPC_IO_BUFSIZE )
288 
289 #define checkCommandConsistency( cmd, length ) \
290  ( ( ( cmd )->strArgLen[ 0 ] + ( cmd )->strArgLen[ 1 ] ) == \
291  ( length - ( COMMAND_WORDSIZE * ( ( cmd )->noArgs + ( cmd )->noStrArgs ) ) ) )
292 
293 #define dbxCheckCommandInfo( cmd, length ) \
294  ( ( cmd )->type > DBX_COMMAND_NONE && \
295  ( cmd )->type < DBX_COMMAND_LAST && \
296  ( cmd )->flags == COMMAND_FLAG_NONE && \
297  ( cmd )->noArgs >= 0 && ( cmd )->noArgs <= DBX_MAX_ARGS && \
298  ( cmd )->noStrArgs >= 0 && ( cmd )->noStrArgs <= DBX_MAX_STRING_ARGS && \
299  ( cmd )->strArgLen[ 0 ] >= 0 && \
300  ( cmd )->strArgLen[ 1 ] >= 0 && \
301  ( cmd )->strArgLen[ 2 ] >= 0 && \
302  ( length ) >= 0 && ( length ) <= DBX_IO_BUFSIZE )
303 
304 #define dbxCheckCommandConsistency( cmd, length ) \
305  ( ( ( cmd )->strArgLen[ 0 ] + ( cmd )->strArgLen[ 1 ] + ( cmd )->strArgLen[ 2 ] ) == \
306  ( length - ( COMMAND_WORDSIZE * ( ( cmd )->noArgs + ( cmd )->noStrArgs ) ) ) )
307 
308 /* The maximum size of a message fragment. Messages containing more data
309  than this are broken up into fragments. On systems with very restricted
310  amounts of memory we make the size rather small to limit the size of
311  the intermediate buffers used */
312 
313 #ifdef CONFIG_CONSERVE_MEMORY
314  #define MAX_FRAGMENT_SIZE 8192
315 #else
316  #define MAX_FRAGMENT_SIZE 32768
317 #endif /* CONSERVER_MEMORY */
318 
319 /* The size of the I/O buffer used to assemble messages. This is equal to
320  the maximum fragment size plus the maximum header size for commands that
321  require fragmentation (COMMAND_ENCRYPT/COMMAND_DECRYPT and
322  COMMAND_PUSHDATA/COMMAND_POPDATA). We define a separate version for
323  database RPC since this uses much smaller buffers */
324 
325 #define RPC_IO_BUFSIZE MAX_FRAGMENT_SIZE + 32
326 #define DBX_IO_BUFSIZE 4096
327 
328 #endif /* _RPC_DEFINED */