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