📄 cryptapi.c
字号:
do
{
COMMAND_INFO cmdResult = { 0 };
const int fragmentLength = min( dataLength, MAX_FRAGMENT_SIZE );
int status;
/* Write the fixed and variable-length message fields to the buffer */
putMessageType( buffer, sentCmd.type, 0, sentCmd.noArgs,
sentCmd.noStrArgs );
if( sentCmd.type == COMMAND_POPDATA )
{
putMessageLength( buffer + COMMAND_WORDSIZE,
( COMMAND_WORDSIZE * 2 ) );
}
else
{
putMessageLength( buffer + COMMAND_WORDSIZE,
( COMMAND_WORDSIZE * 2 ) + fragmentLength );
}
putMessageWord( buffer + COMMAND_FIXED_DATA_SIZE,
sentCmd.arg[ 0 ] );
putMessageWord( payloadStartPtr, fragmentLength );
if( sentCmd.type != COMMAND_POPDATA )
memcpy( payloadStartPtr + COMMAND_WORDSIZE, payloadPtr,
fragmentLength );
/* Process as much data as we can and read the server's message
header */
serverTransact( buffer );
memcpy( header, buffer, COMMAND_FIXED_DATA_SIZE );
/* Process the fixed message header and make sure it's valid */
getMessageType( header, cmdResult.type, cmdResult.flags,
cmdResult.noArgs, cmdResult.noStrArgs );
resultLength = getMessageLength( header + COMMAND_WORDSIZE );
if( !checkCommandInfo( &cmdResult, resultLength ) || \
cmdResult.type != COMMAND_RESULT || \
cmdResult.flags != COMMAND_FLAG_NONE )
{
assert( NOTREACHED );
return( CRYPT_ERROR );
}
if( cmdResult.noArgs != 1 || cmdResult.noStrArgs )
{
/* Make sure the parameters are valid for a non-error return */
if( sentCmd.type == COMMAND_PUSHDATA )
{
if( cmdResult.noArgs != 2 || cmdResult.noStrArgs )
{
assert( NOTREACHED );
return( CRYPT_ERROR );
}
}
else
if( cmdResult.noArgs != 1 || cmdResult.noStrArgs != 1 )
{
assert( NOTREACHED );
return( CRYPT_ERROR );
}
}
/* Process the fixed message header and make sure it's valid */
bufPtr = buffer + COMMAND_FIXED_DATA_SIZE;
status = getMessageWord( bufPtr );
if( cryptStatusError( status ) )
{
/* The push data command is a special case since it returns a
bytes copied value even if an error occurs */
if( sentCmd.type == COMMAND_PUSHDATA )
{
const long bytesCopied = \
getMessageWord( bufPtr + COMMAND_WORDSIZE );
if( bytesCopied < 0 )
{
assert( NOTREACHED );
return( CRYPT_ERROR );
}
cmdResult.arg[ 0 ] = cmd->arg[ 0 ] + bytesCopied;
cmdResult.noArgs = 1;
}
*cmd = cmdResult;
return( status );
}
assert( cryptStatusOK( status ) );
/* Read the rest of the server's message */
resultLength = getMessageWord( bufPtr + COMMAND_WORDSIZE );
if( isPushPop )
{
/* It's a variable-length transformation, we have to return a
non-negative number of bytes */
if( resultLength <= 0 )
{
if( resultLength == 0 )
/* We've run out of data, return to the caller */
break;
assert( NOTREACHED );
return( CRYPT_ERROR );
}
if( cmd->type == COMMAND_PUSHDATA )
cmd->arg[ 0 ] += resultLength;
else
cmd->strArgLen[ 0 ] += resultLength;
if( sentCmd.type == COMMAND_POPDATA )
{
memcpy( payloadPtr, payloadStartPtr + COMMAND_WORDSIZE,
resultLength );
/* If we got less than what we asked for, there's nothing
more available, exit */
if( resultLength < fragmentLength )
dataLength = resultLength;
}
}
else
{
/* It's an encrypt/decrypt, the result must be a 1:1
transformation unless it's a hash, in which case nothing is
returned */
if( resultLength )
{
if( resultLength != fragmentLength )
{
assert( NOTREACHED );
return( CRYPT_ERROR );
}
memcpy( payloadPtr, payloadStartPtr + COMMAND_WORDSIZE,
resultLength );
}
else
/* If no data was returned, it was a hash, set a pseudo-
result length which is the same size as the amount of
data fed in */
resultLength = fragmentLength;
}
/* Move on to the next fragment */
payloadPtr += resultLength;
dataLength -= resultLength;
}
while( dataLength > 0 );
return( CRYPT_OK );
}
#endif /* USE_RPCAPI */
/****************************************************************************
* *
* Client-side Translation Handling *
* *
****************************************************************************/
/* When the cryptlib client is using a different character set, we need to
map from the internal to the external character set. The following
function checks for attribute values that contain text strings. In
addition the functions cryptGetPrivateKey(), cryptAddPrivateKey(), and
cryptLogin() use text strings that need to be mapped to the internal
character set */
#if defined( EBCDIC_CHARS ) || defined( UNICODE_CHARS )
static BOOLEAN needsTranslation( const CRYPT_ATTRIBUTE_TYPE attribute )
{
if( attribute < CRYPT_CTXINFO_LAST )
{
if( attribute < CRYPT_OPTION_LAST )
return( ( attribute == CRYPT_ATTRIBUTE_INT_ERRORMESSAGE || \
attribute == CRYPT_OPTION_INFO_DESCRIPTION || \
attribute == CRYPT_OPTION_INFO_COPYRIGHT || \
attribute == CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS || \
attribute == CRYPT_OPTION_KEYS_LDAP_FILTER || \
attribute == CRYPT_OPTION_KEYS_LDAP_CACERTNAME || \
attribute == CRYPT_OPTION_KEYS_LDAP_CERTNAME || \
attribute == CRYPT_OPTION_KEYS_LDAP_CRLNAME || \
attribute == CRYPT_OPTION_KEYS_LDAP_EMAILNAME ) ? \
TRUE : FALSE );
return( ( attribute == CRYPT_CTXINFO_NAME_ALGO || \
attribute == CRYPT_CTXINFO_NAME_MODE || \
attribute == CRYPT_CTXINFO_KEYING_VALUE || \
attribute == CRYPT_CTXINFO_LABEL ) ? \
TRUE : FALSE );
}
if( attribute <= CRYPT_CERTINFO_LAST_NAME )
{
if( attribute < CRYPT_CERTINFO_FIRST_NAME )
return( ( attribute == CRYPT_CERTINFO_DN || \
attribute == CRYPT_CERTINFO_PKIUSER_ID || \
attribute == CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD || \
attribute == CRYPT_CERTINFO_PKIUSER_REVPASSWORD ) ? \
TRUE : FALSE );
return( ( attribute == CRYPT_CERTINFO_COUNTRYNAME || \
attribute == CRYPT_CERTINFO_STATEORPROVINCENAME || \
attribute == CRYPT_CERTINFO_LOCALITYNAME || \
attribute == CRYPT_CERTINFO_ORGANIZATIONNAME || \
attribute == CRYPT_CERTINFO_ORGANIZATIONALUNITNAME || \
attribute == CRYPT_CERTINFO_COMMONNAME || \
attribute == CRYPT_CERTINFO_OTHERNAME_TYPEID || \
attribute == CRYPT_CERTINFO_RFC822NAME || \
attribute == CRYPT_CERTINFO_DNSNAME || \
attribute == CRYPT_CERTINFO_EDIPARTYNAME_NAMEASSIGNER || \
attribute == CRYPT_CERTINFO_EDIPARTYNAME_PARTYNAME || \
attribute == CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER ) ? \
TRUE : FALSE );
}
if( attribute <= CRYPT_CERTINFO_LAST_EXTENSION )
{
return( ( attribute == CRYPT_CERTINFO_SIGG_PROCURE_COUNTRY || \
attribute == CRYPT_CERTINFO_SIGG_PROCURE_TYPEOFSUBSTITUTION || \
attribute == CRYPT_CERTINFO_SIGG_MONETARY_CURRENCY || \
attribute == CRYPT_CERTINFO_SIGG_RESTRICTION || \
attribute == CRYPT_CERTINFO_SUBJECTDIR_TYPE || \
attribute == CRYPT_CERTINFO_CERTPOLICYID || \
attribute == CRYPT_CERTINFO_CERTPOLICY_CPSURI || \
attribute == CRYPT_CERTINFO_CERTPOLICY_ORGANIZATION || \
attribute == CRYPT_CERTINFO_CERTPOLICY_EXPLICITTEXT || \
attribute == CRYPT_CERTINFO_ISSUERDOMAINPOLICY || \
attribute == CRYPT_CERTINFO_SUBJECTDOMAINPOLICY || \
attribute == CRYPT_CERTINFO_SET_MERID || \
attribute == CRYPT_CERTINFO_SET_MERACQUIRERBIN || \
attribute == CRYPT_CERTINFO_SET_MERCHANTLANGUAGE || \
attribute == CRYPT_CERTINFO_SET_MERCHANTNAME || \
attribute == CRYPT_CERTINFO_SET_MERCHANTCITY || \
attribute == CRYPT_CERTINFO_SET_MERCHANTSTATEPROVINCE || \
attribute == CRYPT_CERTINFO_SET_MERCHANTPOSTALCODE || \
attribute == CRYPT_CERTINFO_SET_MERCHANTCOUNTRYNAME || \
attribute == CRYPT_CERTINFO_SET_MERCOUNTRY || \
attribute == CRYPT_CERTINFO_SET_MERAUTHFLAG ) ? \
TRUE : FALSE );
}
if( attribute <= CRYPT_CERTINFO_LAST_CMS )
return( ( attribute == CRYPT_CERTINFO_CMS_SECLABEL_POLICY || \
attribute == CRYPT_CERTINFO_CMS_SECLABEL_PRIVACYMARK || \
attribute == CRYPT_CERTINFO_CMS_SECLABEL_CATTYPE || \
attribute == CRYPT_CERTINFO_CMS_SECLABEL_CATVALUE || \
attribute == CRYPT_CERTINFO_CMS_CONTENTHINT_DESCRIPTION || \
attribute == CRYPT_CERTINFO_CMS_EQVLABEL_POLICY || \
attribute == CRYPT_CERTINFO_CMS_EQVLABEL_PRIVACYMARK || \
attribute == CRYPT_CERTINFO_CMS_EQVLABEL_CATTYPE || \
attribute == CRYPT_CERTINFO_CMS_EQVLABEL_CATVALUE || \
attribute == CRYPT_CERTINFO_CMS_SIGNINGCERT_POLICIES || \
attribute == CRYPT_CERTINFO_CMS_SPCOPUSINFO_NAME || \
attribute == CRYPT_CERTINFO_CMS_SPCOPUSINFO_URL || \
attribute == CRYPT_CERTINFO_CMS_SPCAGENCYURL ) ? \
TRUE : FALSE );
if( attribute < CRYPT_KEYINFO_LAST )
return( ( attribute == CRYPT_KEYINFO_QUERY || \
attribute == CRYPT_KEYINFO_QUERY_REQUESTS ) ? \
TRUE : FALSE );
if( attribute < CRYPT_DEVINFO_LAST )
return( ( attribute == CRYPT_DEVINFO_INITIALISE || \
attribute == CRYPT_DEVINFO_AUTHENT_USER || \
attribute == CRYPT_DEVINFO_AUTHENT_SUPERVISOR || \
attribute == CRYPT_DEVINFO_SET_AUTHENT_USER || \
attribute == CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR || \
attribute == CRYPT_DEVINFO_ZEROISE || \
attribute == CRYPT_DEVINFO_LABEL ) ? \
TRUE : FALSE );
if( attribute < CRYPT_ENVINFO_LAST )
return( ( attribute == CRYPT_ENVINFO_PASSWORD || \
attribute == CRYPT_ENVINFO_RECIPIENT || \
attribute == CRYPT_ENVINFO_PRIVATEKEY_LABEL ) ? \
TRUE : FALSE );
if( attribute < CRYPT_SESSINFO_LAST )
return( ( attribute == CRYPT_SESSINFO_USERNAME || \
attribute == CRYPT_SESSINFO_PASSWORD || \
attribute == CRYPT_SESSINFO_SERVER_NAME || \
attribute == CRYPT_SESSINFO_CLIENT_NAME ) ? \
TRUE : FALSE );
return( ( attribute == CRYPT_USERINFO_PASSWORD ) ? TRUE : FALSE );
}
#ifdef EBCDIC_CHARS
#define nativeStrlen( string ) strlen( string )
#define nativeToCryptlibString( dest, src, length ) \
ebcdicToAscii( dest, src, length )
#define cryptlibToNativeString( dest, src, length ) \
asciiToEbcdic( dest, src, length )
#else
#define nativeStrlen( string ) wcslen( string )
#define nativeToCryptlibString( dest, src, length ) \
unicodeToAscii( dest, src, length )
#define cryptlibToNativeString( dest, src, length ) \
asciiToUnicode( dest, src, length )
#endif /* EBCDIC vs. Unicode translation */
#endif /* EBCDIC_CHARS || UNICODE_CHARS */
/****************************************************************************
* *
* Utility Functions *
* *
****************************************************************************/
/* Some functions take null-terminated strings as parameters, since these
can be ASCII or Unicode strings depending on the environment we need to
define a situation-specific get-string-length function to handle them */
#ifdef nativeStrlen
#define strParamLen nativeStrlen
#else
#define strParamLen strlen
#endif /* System-specific string parameter length functions */
/* Internal parameter errors are reported in terms of the parameter type (eg
invalid object, invalid attribute), but externally they're reported in
terms of parameter numbers. Before we return error values to the caller,
we have to map them from the internal representation to the position they
occur in in the function parameter list. The following function takes a
list of parameter types and maps the returned parameter type error to a
parameter position error */
typedef enum {
ARG_D, /* Dummy placeholder */
ARG_O, /* Object */
ARG_V, /* Value (attribute) */
ARG_N, /* Numeric arg */
ARG_S, /* String arg */
ARG_LAST
} ERRORMAP;
static int mapError( const ERRORMAP *errorMap, const int status )
{
ERRORMAP type;
int count = 0, i;
/* If it's not an internal parameter error, let it out */
if( !cryptArgError( status ) )
{
assert( status <= 0 && status >= CRYPT_ENVELOPE_RESOURCE );
return( status );
}
/* Map the parameter error to a position error */
switch( status )
{
case CRYPT_ARGERROR_OBJECT:
type = ARG_O;
break;
case CRYPT_ARGERROR_VALUE:
type = ARG_V;
break;
case CRYPT_ARGERROR_NUM1:
case CRYPT_ARGERROR_NUM2:
type = ARG_N;
count = CRYPT_ARGERROR_NUM1 - status;
break;
case CRYPT_ARGERROR_STR1:
case CRYPT_ARGERROR_STR2:
type = ARG_S;
count = CRYPT_ARGERROR_STR1 - status;
break;
default:
assert( NOTREACHED );
}
for( i = 0; errorMap[ i ] != ARG_LAST; i++ )
if( errorMap[ i ] == type && !count-- )
return( CRYPT_ERROR_PARAM1 - i );
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/****************************************************************************
* *
* Create/Destroy Objects *
* *
****************************************************************************/
/* A flag to record whether the external API initialisation function has
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -