📄 cryptcfg.c
字号:
/****************************************************************************
* *
* cryptlib Configuration Routines *
* Copyright Peter Gutmann 1994-2002 *
* *
****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crypt.h"
#ifdef INC_ALL
#include "asn1.h"
#else
#include "keymgmt/asn1.h"
#endif /* Compiler-specific includes */
/* Prototypes for functions in certrust.c */
int setTrustedCert( void *certObject, const int certObjectLength );
CRYPT_CERTIFICATE getFirstTrustedCert( void **statePtr, int *stateIndex );
CRYPT_CERTIFICATE getNextTrustedCert( void **statePtr, int *stateIndex );
/****************************************************************************
* *
* Configuration Options *
* *
****************************************************************************/
/* Configuration option types */
typedef enum {
OPTION_NONE, /* Non-option */
OPTION_STRING, /* Literal string */
OPTION_NUMERIC, /* Numeric value */
OPTION_BOOLEAN /* Boolean flag */
} OPTION_TYPE;
/* The configuration options. These are broken up into two parts, the fixed
default values which are shared across all cryptlib operations and the
variable values which are variable for each user object.
Alongside the CRYPT_ATTRIBUTE_TYPE we store a persistant index value for
the option which always stays the same even if the attribute type changes,
this avoids the need to change the config file every time an attribute is
added or deleted */
typedef struct {
const CRYPT_ATTRIBUTE_TYPE option;/* Magic number for this option */
const OPTION_TYPE type; /* Option type */
const int index; /* Index value for this option */
const char FAR_BSS *strDefault; /* Default if it's a string option */
const int intDefault; /* Default if it's a numeric/boolean */
} FIXED_OPTION_INFO;
typedef struct {
char *strValue; /* Value if it's a string option */
int intValue; /* Value if it's a numeric/boolean */
BOOLEAN dirty; /* Whether option has been changed */
} OPTION_INFO;
static const FIXED_OPTION_INFO FAR_BSS fixedOptionInfo[] = {
/* Dummy entry for CRYPT_ATTRIBUTE_NONE */
{ CRYPT_ATTRIBUTE_NONE, 0 },
/* cryptlib information (read-only) */
{ CRYPT_OPTION_INFO_DESCRIPTION, OPTION_STRING, CRYPT_UNUSED, "cryptlib encryption library" },
{ CRYPT_OPTION_INFO_COPYRIGHT, OPTION_STRING, CRYPT_UNUSED, "Copyright Peter Gutmann, Eric Young, 1994-2001" },
{ CRYPT_OPTION_INFO_MAJORVERSION, OPTION_NUMERIC, CRYPT_UNUSED, NULL, 3 },
{ CRYPT_OPTION_INFO_MINORVERSION, OPTION_NUMERIC, CRYPT_UNUSED, NULL, 0 },
{ CRYPT_OPTION_INFO_STEPPING, OPTION_NUMERIC, CRYPT_UNUSED, NULL, 6 },
/* Context options, base = 0 */
/* Algorithm = Conventional encryption/hash/MAC options */
{ CRYPT_OPTION_ENCR_ALGO, OPTION_NUMERIC, 0, NULL, CRYPT_ALGO_3DES },
{ CRYPT_OPTION_ENCR_HASH, OPTION_NUMERIC, 1, NULL, CRYPT_ALGO_SHA },
{ CRYPT_OPTION_ENCR_MAC, OPTION_NUMERIC, 2, NULL, CRYPT_ALGO_HMAC_SHA },
/* Algorithm = PKC options */
{ CRYPT_OPTION_PKC_ALGO, OPTION_NUMERIC, 3, NULL, CRYPT_ALGO_RSA },
{ CRYPT_OPTION_PKC_KEYSIZE, OPTION_NUMERIC, 4, NULL, bitsToBytes( 1024 ) },
/* Algorithm = Signature options */
{ CRYPT_OPTION_SIG_ALGO, OPTION_NUMERIC, 5, NULL, CRYPT_ALGO_RSA },
{ CRYPT_OPTION_SIG_KEYSIZE, OPTION_NUMERIC, 6, NULL, bitsToBytes( 1024 ) },
/* Algorithm = Key derivation options */
{ CRYPT_OPTION_KEYING_ALGO, OPTION_NUMERIC, 7, NULL, CRYPT_ALGO_SHA },
{ CRYPT_OPTION_KEYING_ITERATIONS, OPTION_NUMERIC, 8, NULL, 500 },
/* Certificate options, base = 100 */
{ CRYPT_OPTION_CERT_CREATEV3CERT, OPTION_BOOLEAN, 100, NULL, TRUE },
{ CRYPT_OPTION_CERT_PKCS10ALT, OPTION_BOOLEAN, 101, NULL, FALSE },
{ CRYPT_OPTION_CERT_FIXEMAILADDRESS, OPTION_BOOLEAN, 102, NULL, TRUE },
{ CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES, OPTION_BOOLEAN, 103, NULL, FALSE },
{ CRYPT_OPTION_CERT_TRUSTCHAINROOT, OPTION_BOOLEAN, 104, NULL, FALSE },
{ CRYPT_OPTION_CERT_VALIDITY, OPTION_NUMERIC, 105, NULL, 365 },
{ CRYPT_OPTION_CERT_UPDATEINTERVAL, OPTION_NUMERIC, 106, NULL, 90 },
{ CRYPT_OPTION_CERT_ENCODE_VALIDITYNESTING, OPTION_BOOLEAN, 107, NULL, TRUE },
{ CRYPT_OPTION_CERT_DECODE_VALIDITYNESTING, OPTION_BOOLEAN, 108, NULL, FALSE },
{ CRYPT_OPTION_CERT_ENCODE_CRITICAL, OPTION_BOOLEAN, 109, NULL, TRUE },
{ CRYPT_OPTION_CERT_DECODE_CRITICAL, OPTION_BOOLEAN, 110, NULL, TRUE },
/* CMS options */
{ CRYPT_OPTION_CMS_DEFAULTATTRIBUTES, OPTION_BOOLEAN, 130, NULL, TRUE },
/* Keyset options, base = 200 */
/* Keyset = LDAP options */
{ CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS, OPTION_STRING, 200, "inetOrgPerson" },
{ CRYPT_OPTION_KEYS_LDAP_OBJECTTYPE, OPTION_NUMERIC, 210, NULL, CRYPT_CERTTYPE_NONE },
{ CRYPT_OPTION_KEYS_LDAP_FILTER, OPTION_STRING, 211, "(objectclass=*)" },
{ CRYPT_OPTION_KEYS_LDAP_CACERTNAME, OPTION_STRING, 212, "cACertificate;binary" },
{ CRYPT_OPTION_KEYS_LDAP_CERTNAME, OPTION_STRING, 213, "userCertificate;binary" },
{ CRYPT_OPTION_KEYS_LDAP_CRLNAME, OPTION_STRING, 214, "certificateRevocationList;binary" },
{ CRYPT_OPTION_KEYS_LDAP_EMAILNAME, OPTION_STRING, 215, "mail" },
/* Device options, base = 300 */
/* Device = PKCS #11 token options */
{ CRYPT_OPTION_DEVICE_PKCS11_DVR01, OPTION_STRING, 300, NULL },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR02, OPTION_STRING, 301, NULL },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR03, OPTION_STRING, 302, NULL },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR04, OPTION_STRING, 303, NULL },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR05, OPTION_STRING, 304, NULL },
{ CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY, OPTION_BOOLEAN, 305, NULL, FALSE },
/* Device = Hardware RNG options */
{ CRYPT_OPTION_DEVICE_SERIALRNG, OPTION_STRING, 310, NULL },
{ CRYPT_OPTION_DEVICE_SERIALRNG_PARAMS, OPTION_STRING, 311, NULL },
/* Session options, base = 400 */
/* Miscellaneous options, base = 500 */
{ CRYPT_OPTION_NET_SOCKS_SERVER, OPTION_STRING, 500, NULL },
{ CRYPT_OPTION_NET_SOCKS_USERNAME, OPTION_STRING, 501, NULL },
{ CRYPT_OPTION_NET_HTTP_PROXY, OPTION_STRING, 502, NULL },
{ CRYPT_OPTION_NET_CONNECTTIMEOUT, OPTION_NUMERIC, 503, NULL, 30 },
{ CRYPT_OPTION_NET_TIMEOUT, OPTION_NUMERIC, 504, NULL, 0 },
{ CRYPT_OPTION_MISC_ASYNCINIT, OPTION_BOOLEAN, 504, NULL, TRUE },
/* cryptlib state information. These are special-case options which
record state information rather than a static config value. The
config-option-changed status value is updated dynamically, being set
to TRUE if any config option is changed. Writing it to FALSE commits
the changes to disk. The self-test status value is initially set to
FALSE, writing it to TRUE triggers a self-test which remains at TRUE
if the test succeeds */
{ CRYPT_OPTION_CONFIGCHANGED, OPTION_BOOLEAN, CRYPT_UNUSED, NULL, FALSE },
{ CRYPT_OPTION_SELFTESTOK, OPTION_BOOLEAN, CRYPT_UNUSED, NULL, FALSE },
{ CRYPT_ATTRIBUTE_NONE, OPTION_NONE, CRYPT_UNUSED, NULL, 0 }
};
/* The last option which is written to disk. Further options beyond this one
are ephemeral and are never written to disk */
#define LAST_STORED_OPTION CRYPT_OPTION_MISC_ASYNCINIT
/* The size of the variable-length config data */
#define OPTION_INFO_SIZE ( sizeof( OPTION_INFO ) * \
CRYPT_OPTION_CONFIGCHANGED - CRYPT_OPTION_FIRST )
/****************************************************************************
* *
* Set/Query Library-wide Config Options *
* *
****************************************************************************/
/* Set the value of a numeric or string option */
int setOption( OPTION_INFO *optionList, const CRYPT_ATTRIBUTE_TYPE option,
const int value )
{
const FIXED_OPTION_INFO *fixedOptionInfoPtr;
OPTION_INFO *optionInfoPtr;
/* The update of the selt-test status is performed in two phases, when we
begin the self-test it's set to an undefined value, once the self-test
completes it's set to the test result. Since there's no way to
indicate an internal status update from an external attempt to do the
same thing, we disallow any attempt to update the value when it's in
the undefined state, and use a write of CRYPT_OPTION_LAST to indicate
an update of the self-test status */
if( option == CRYPT_OPTION_LAST )
{
assert( optionList[ CRYPT_OPTION_SELFTESTOK - \
CRYPT_OPTION_FIRST ].intValue == CRYPT_ERROR );
optionList[ CRYPT_OPTION_SELFTESTOK - \
CRYPT_OPTION_FIRST ].intValue = value;
return( CRYPT_OK );
}
/* Get a pointer to the option information and make sure everything is
OK */
assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
optionInfoPtr = &optionList[ option - CRYPT_OPTION_FIRST ];
fixedOptionInfoPtr = &fixedOptionInfo[ option - CRYPT_OPTION_FIRST ];
assert( fixedOptionInfoPtr->type == OPTION_NUMERIC || \
fixedOptionInfoPtr->type == OPTION_BOOLEAN );
/* If the value is the same as the current one, there's nothing to do */
if( optionInfoPtr->intValue == value )
return( CRYPT_OK );
/* If we're forcing a commit by returning the config.changed flag to its
ground state, write any changed options to disk */
if( option == CRYPT_OPTION_CONFIGCHANGED )
{
int i;
/* Make sure there's something to write. We do this to avoid problems
with programs which always try to update the config (whether it's
necessary or not), which can cause problems with media with limited
writeability */
for( i = 1; fixedOptionInfo[ i ].option != CRYPT_ATTRIBUTE_NONE; i++ )
if( optionList[ i ].dirty )
break;
if( fixedOptionInfo[ i ].option == CRYPT_ATTRIBUTE_NONE )
/* Nothing has been changed, there's nothing to write */
return( CRYPT_OK );
/* We don't do anything at this level to write the config data since
we currently have the user object locked and don't want to stall
all operations which depend on it while we're updating the config
data, so we tell the user object to perform the necessary
operations */
return( OK_SPECIAL );
}
/* If we're forcing a self-test by changing the value of the self-test
status, perform an algorithm self-test */
if( option == CRYPT_OPTION_SELFTESTOK )
{
/* The self-test can take some time to complete, and while it's
running we don't want to leave the user object locked since this
will block most other threads which eventually read some sort of
config option. To get around this problem we set the result
value to an undefined status and unlock the user object around the
call, then re-lock it and set its actual value via an update of
the pseudo-option CRYPT_OPTION_LAST once the self-test is done */
if( optionInfoPtr->intValue == CRYPT_ERROR )
return( CRYPT_ERROR_BUSY );
optionInfoPtr->intValue = CRYPT_ERROR;
return( OK_SPECIAL );
}
if( fixedOptionInfoPtr->type == OPTION_BOOLEAN )
/* Turn a generic zero/nonzero boolean into TRUE or FALSE */
optionInfoPtr->intValue = ( value ) ? TRUE : FALSE;
else
optionInfoPtr->intValue = value;
optionInfoPtr->dirty = TRUE;
/* Remember that the config options have been changed */
optionInfoPtr = \
&optionList[ CRYPT_OPTION_CONFIGCHANGED - CRYPT_OPTION_FIRST ];
optionInfoPtr->intValue = TRUE;
return( CRYPT_OK );
}
int setOptionString( OPTION_INFO *optionList,
const CRYPT_ATTRIBUTE_TYPE option, const char *value,
const int valueLength )
{
const FIXED_OPTION_INFO *fixedOptionInfoPtr;
OPTION_INFO *optionInfoPtr;
char *valuePtr;
/* Get a pointer to the option information and make sure everything is
OK */
assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
optionInfoPtr = &optionList[ option - CRYPT_OPTION_FIRST ];
fixedOptionInfoPtr = &fixedOptionInfo[ option - CRYPT_OPTION_FIRST ];
assert( fixedOptionInfoPtr->type == OPTION_STRING );
/* Try and allocate room for the new option */
if( ( valuePtr = malloc( valueLength + 1 ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memcpy( valuePtr, value, valueLength );
valuePtr[ valueLength ] = '\0';
/* If the new value isn't different from the current one, don't do
anything */
if( optionInfoPtr->strValue != NULL && \
!memcmp( optionInfoPtr->strValue, value, valueLength ) )
{
free( valuePtr );
return( CRYPT_OK );
}
/* If the string value which is currently set isn't the default setting,
clear and free it */
if( optionInfoPtr->strValue != fixedOptionInfoPtr->strDefault )
{
zeroise( optionInfoPtr->strValue, strlen( optionInfoPtr->strValue ) );
free( optionInfoPtr->strValue );
}
/* Set the value */
optionInfoPtr->strValue = valuePtr;
optionInfoPtr->dirty = TRUE;
/* Remember that the config options have been changed */
optionInfoPtr = \
&optionList[ CRYPT_OPTION_CONFIGCHANGED - CRYPT_OPTION_FIRST ];
optionInfoPtr->intValue = TRUE;
return( CRYPT_OK );
}
/* Query the value of a numeric or string option */
int getOption( OPTION_INFO *optionList, const CRYPT_ATTRIBUTE_TYPE option )
{
assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
assert( fixedOptionInfo[ option - \
CRYPT_OPTION_FIRST ].type == OPTION_NUMERIC || \
fixedOptionInfo[ option - \
CRYPT_OPTION_FIRST ].type == OPTION_BOOLEAN );
return( optionList[ option - CRYPT_OPTION_FIRST ].intValue );
}
char *getOptionString( OPTION_INFO *optionList,
const CRYPT_ATTRIBUTE_TYPE option )
{
assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
assert( fixedOptionInfo[ option - \
CRYPT_OPTION_FIRST ].type == OPTION_STRING );
return( optionList[ option - CRYPT_OPTION_FIRST ].strValue );
}
/* Initialise/clean up the config option handling */
int initOptions( OPTION_INFO **optionListPtr )
{
OPTION_INFO *optionList;
int i;
/* Perform a consistency check on the options */
FORALL( i, 1, CRYPT_OPTION_LAST - CRYPT_OPTION_FIRST,
fixedOptionInfo[ i ].option == i + CRYPT_OPTION_FIRST );
/* Allocate storage for the variable config data */
if( ( optionList = malloc( OPTION_INFO_SIZE ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memset( optionList, 0, OPTION_INFO_SIZE );
/* Walk through the config table setting up each option to contain
its default value */
for( i = 1; fixedOptionInfo[ i ].option != CRYPT_ATTRIBUTE_NONE; i++ )
if( fixedOptionInfo[ i ].type == OPTION_STRING )
optionList[ i ].strValue = \
( char * ) fixedOptionInfo[ i ].strDefault;
else
optionList[ i ].intValue = fixedOptionInfo[ i ].intDefault;
*optionListPtr = optionList;
return( CRYPT_OK );
}
void endOptions( OPTION_INFO *optionList )
{
int i;
/* Walk through the config table clearing and freeing each option */
for( i = 1; fixedOptionInfo[ i ].option != CRYPT_ATTRIBUTE_NONE; i++ )
{
const FIXED_OPTION_INFO *fixedOptionInfoPtr = &fixedOptionInfo[ i ];
OPTION_INFO *optionInfoPtr = &optionList[ i ];
if( fixedOptionInfoPtr->type == OPTION_STRING )
{
/* If the string value which is currently set isn't the default
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -