📄 keyset.h
字号:
/****************************************************************************
* *
* cryptlib Keyset Interface Header File *
* Copyright Peter Gutmann 1996-2005 *
* *
****************************************************************************/
#ifndef _KEYSET_DEFINED
#define _KEYSET_DEFINED
/* Various include files needed by the DBMS libraries */
#include <time.h>
#ifndef _STREAM_DEFINED
#if defined( INC_ALL )
#include "stream.h"
#else
#include "io/stream.h"
#endif /* Compiler-specific includes */
#endif /* _STREAM_DEFINED */
/****************************************************************************
* *
* Database Keyset Headers *
* *
****************************************************************************/
/* Handle ODBC support. This gets rather complex, with all sorts of special-
case handling of headers and types required across different systems */
#ifdef USE_ODBC
/* As part of the ever-changing way of identifying Win32, Microsoft changed
the predefined constant from WIN32 to _WIN32 in VC++ 2.1. However the
ODBC header files still expect to find WIN32 and if this isn't defined
will use the default (i.e. C) calling convention instead of the Pascal
convention which is actually used by the ODBC functions. This means that
both the caller and the callee clean up the stack so that for each ODBC
call the stack creeps upwards by a few bytes until eventually the local
variables and/or return address get trashed. This problem is usually
hidden by the fact that something else defines WIN32 so everything works
OK, but the October 1997 development platform upgrade changes this so
that compiling the code after this update is installed breaks things. To
avoid this problem, we define WIN32 if it isn't defined, which ensures
that the ODBC header files work properly */
#if defined( __WIN32__ ) && !defined( WIN32 )
#define WIN32
#endif /* __WIN32__ && !WIN32 */
#ifdef __WINDOWS__
/* Borland have their own weird place to put ODBC headers */
#if defined( __BORLANDC__ )
#include <mfc/sqltypes.h>
#else
/* UnixODBC defines its own version of various Windows types, if we're
building under Windows we have to disable this. The UnixODBC headers
have a guard ALLREADY_HAVE_WINDOWS_TYPE (sic) but this is all-or-
nothing, disabling the defining of Windows *and* SQL types. Defining
the guard value fixes most compile problems but in order to build it
the commented-out typedefs also need to be defined. These are
already defined in the standard (Windows) sqltypes.h so their use
needs to be manually enabled for UnixODBC under Windows, which is
unlikely to occur given that it's a Unix-only driver */
#define ALLREADY_HAVE_WINDOWS_TYPE
#if 0
typedef signed short RETCODE;
typedef short int SWORD;
typedef long int SDWORD;
typedef signed char SQLSCHAR;
typedef HWND SQLHWND;
#endif /* 0 */
#include <sql.h>
#include <sqlext.h>
#endif /* Compiler-specific include locations */
#else
#include <sql.h>
#include <sqlext.h>
#endif /* Windows vs.everything else */
#endif /* USE_ODBC */
#ifdef USE_DATABASE
#error Need to add database backend-specific includes
#endif /* USE_DATABASE */
/****************************************************************************
* *
* Keyset Types and Constants *
* *
****************************************************************************/
/* The maximum size of a certificate in binary and base64-encoded form */
#define MAX_CERT_SIZE 2048
#define MAX_ENCODED_CERT_SIZE ( MAX_CERT_SIZE * 4 ) / 3
/* Keyset information flags */
#define KEYSET_OPEN 0x01 /* Keyset is open */
#define KEYSET_EMPTY 0x02 /* Keyset is empty */
#define KEYSET_DIRTY 0x04 /* Keyset data has been changed */
#define KEYSET_STREAM_OPEN 0x08 /* Underlying file stream is open */
/* The precise type of the key file that we're working with. This is used
for type checking to make sure we don't try to find private keys in a
collection of certificates or whatever */
typedef enum {
KEYSET_SUBTYPE_NONE, /* Unknown */
KEYSET_SUBTYPE_PGP_PUBLIC, /* PGP public keyring */
KEYSET_SUBTYPE_PGP_PRIVATE, /* PGP private keyring */
KEYSET_SUBTYPE_PKCS12, /* PKCS #12 key mess */
KEYSET_SUBTYPE_PKCS15, /* PKCS #15 keys */
KEYSET_SUBTYPE_LAST /* Last valid keyset subtype */
} KEYSET_SUBTYPE;
/* When we perform a DBMS transaction there are several variations on the
basic operation type. The following values tell performQuery() and
performUpdate() which type of operation to perform */
typedef enum {
DBMS_QUERY_NONE, /* No DBMS query */
DBMS_QUERY_NORMAL, /* Standard data fetch */
DBMS_QUERY_CHECK, /* Check-type fetch, don't fetch data */
DBMS_QUERY_START, /* Begin an ongoing query */
DBMS_QUERY_CONTINUE, /* Continue an ongoing query */
DBMS_QUERY_CANCEL, /* Cancel ongoing query */
DBMS_QUERY_LAST /* Last valid DBMS query type */
} DBMS_QUERY_TYPE;
typedef enum {
DBMS_UPDATE_NONE, /* No DBMS update */
DBMS_UPDATE_NORMAL, /* Standard update */
DBMS_UPDATE_BEGIN, /* Begin a transaction */
DBMS_UPDATE_CONTINUE, /* Continue an ongoing transaction */
DBMS_UPDATE_COMMIT, /* Commit a transaction */
DBMS_UPDATE_ABORT, /* Abort a transaction */
DBMS_UPDATE_LAST /* Last valid DBMS update type */
} DBMS_UPDATE_TYPE;
/* To optimise database accesses we use prepared queries that are prepared
once and then re-used whenever a new result set is required. The following
values are used to refer to the prepared query types */
typedef enum {
DBMS_CACHEDQUERY_NONE, /* No cached query */
DBMS_CACHEDQUERY_CERTID, /* Query on certificate ID */
DBMS_CACHEDQUERY_ISSUERID, /* Query on issuer ID */
DBMS_CACHEDQUERY_NAMEID, /* Query in name ID */
DBMS_CACHEDQUERY_URI, /* Query on URI */
DBMS_CACHEDQUERY_LAST /* Last valid cached query type */
} DBMS_CACHEDQUERY_TYPE;
#define NO_CACHED_QUERIES 5
/****************************************************************************
* *
* Keyset Structures *
* *
****************************************************************************/
/* Database state information maintained by the database back-end specific
code. This storage is logically distinct from the keyset object storage,
and may in fact be physically distinct if the back-end is accessed via an
RPC mechanism */
typedef struct {
/* DBMS status information */
BOOLEAN needsUpdate; /* Whether data remains to be committed */
BOOLEAN hasBinaryBlobs; /* Whether back-end supports binary blobs */
/* Error information returned by the back-end. This is copied over to
the keyset object as required */
ERROR_INFO errorInfo;
/* Database-specific information */
#ifdef USE_ODBC
/* ODBC access information */
SQLHENV hEnv; /* Environment handle */
SQLHDBC hDbc; /* Connection handle */
ARRAY_FIXED( NO_CACHED_QUERIES ) \
SQLHSTMT hStmt[ NO_CACHED_QUERIES + 8 ];/* Statement handles */
ARRAY_FIXED( NO_CACHED_QUERIES ) \
BOOLEAN hStmtPrepared[ NO_CACHED_QUERIES + 8 ];/* Whether stmt is prepared on handle */
BOOLEAN transactIsDestructive; /* Whether commit/rollback destroys prep'd queries */
SQLSMALLINT blobType; /* SQL type of blob data type */
BUFFER( CRYPT_MAX_TEXTSIZE, blobNameLength ) \
char blobName[ CRYPT_MAX_TEXTSIZE + 8 ];/* Name of blob data type */
int blobNameLength; /* Length of blob data type name */
SQLINTEGER dateTimeNameColSize; /* Back-end specific size of datetime column */
BUFFER( CRYPT_MAX_TEXTSIZE, dateTimeNameLength ) \
char dateTimeName[ CRYPT_MAX_TEXTSIZE + 8 ];/* Name of datetime data type */
int dateTimeNameLength; /* Length of datetime data type name */
BOOLEAN needLongLength; /* Back-end needs blob length at bind.time */
int backendType; /* Back-end type if special handling is req'd */
#endif /* USE_ODBC */
#ifdef USE_DATABASE
#error Need to add database backend-specific state variables
#endif /* USE_DATABASE */
#ifdef USE_TCP
STREAM stream; /* Network I/O stream */
#endif /* USE_TCP */
} DBMS_STATE_INFO;
/* The internal fields in a keyset that hold data for the various keyset
types */
typedef enum { KEYSET_NONE, KEYSET_FILE, KEYSET_DBMS, KEYSET_LDAP,
KEYSET_HTTP } KEYSET_TYPE;
struct KI; /* Forward declaration for argument to function pointers */
typedef struct {
/* The I/O stream and file name */
STREAM stream; /* I/O stream for key file */
char fileName[ MAX_PATH_LENGTH + 8 ];/* Name of key file */
} FILE_INFO;
typedef struct DI {
/* DBMS status information */
int flags; /* General status flags */
/* For database types that can use binary blobs we need to bind the
locations of variables and use placeholders in the SQL text rather
than passing the data as part of the SQL command. We can't leave this
on the stack since it can be referenced by the back-end an arbitrary
amount of time after we initiate the update, so we copy it to the
following staging area before we pass control to the database
back-end */
char boundData[ MAX_ENCODED_CERT_SIZE + 8 ];
/* The data being sent to the back-end can be communicated over a variety
of channels. If we're using the RPC API, there's a single dispatch
function through which all data is communicated via the RPC mechanism.
If we're not using the RPC API, there are a set of function pointers,
one for each back-end access type. In addition the state information
storage contains the state data needed for the communications
channel */
#ifdef USE_RPCAPI
void ( *dispatchFunction )( void *stateInfo, BYTE *buffer );
#else
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
int ( *openDatabaseBackend )( INOUT DBMS_STATE_INFO *dbmsStateInfo,
IN_BUFFER( nameLen ) const char *name,
IN_LENGTH_NAME const int nameLen,
IN_ENUM_OPT( CRYPT_KEYOPT ) \
const CRYPT_KEYOPT_TYPE options,
OUT_FLAGS_Z( DBMS_FEATURE ) int *featureFlags );
STDC_NONNULL_ARG( ( 1 ) ) \
void ( *closeDatabaseBackend )( INOUT DBMS_STATE_INFO *dbmsStateInfo );
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int ( *performUpdateBackend )( INOUT DBMS_STATE_INFO *dbmsStateInfo,
IN_BUFFER_OPT( commandLength ) \
const char *command,
IN_LENGTH_SHORT_Z const int commandLength,
IN_ARRAY_OPT( BOUND_DATA_MAXITEMS ) \
const void *boundData,
IN_ENUM( DBMS_UPDATE ) \
const DBMS_UPDATE_TYPE updateType );
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int ( *performQueryBackend )( INOUT DBMS_STATE_INFO *dbmsStateInfo,
IN_BUFFER_OPT( commandLength ) \
const char *command,
IN_LENGTH_SHORT_Z const int commandLength,
OUT_BUFFER_OPT( dataMaxLength, *dataLength ) \
char *data,
IN_LENGTH_SHORT_Z const int dataMaxLength,
OUT_LENGTH_SHORT_Z int *dataLength,
IN_OPT const void *boundData,
IN_ENUM_OPT( DBMS_CACHEDQUERY ) \
const DBMS_CACHEDQUERY_TYPE queryEntry,
IN_ENUM( DBMS_QUERY ) \
const DBMS_QUERY_TYPE queryType );
#endif /* !USE_RPCAPI */
void *stateInfo;
/* Database back-end access functions. These use the dispatch function/
function pointers above to communicate with the back-end */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
int ( *openDatabaseFunction )( INOUT struct DI *dbmsInfo,
IN_BUFFER( nameLen ) const char *name,
IN_LENGTH_NAME const int nameLen,
IN_ENUM_OPT( CRYPT_KEYOPT ) \
const CRYPT_KEYOPT_TYPE options,
OUT_FLAGS_Z( DBMS ) int *featureFlags );
STDC_NONNULL_ARG( ( 1 ) ) \
void ( *closeDatabaseFunction )( INOUT struct DI *dbmsInfo );
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int ( *performUpdateFunction )( INOUT struct DI *dbmsInfo,
IN_STRING_OPT const char *command,
IN_OPT const void *boundData,
IN_ENUM( DBMS_UPDATE ) \
const DBMS_UPDATE_TYPE updateType );
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int ( *performStaticUpdateFunction )( INOUT struct DI *dbmsInfo,
IN_STRING const char *command );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -