dbxpk15.c
来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 1,715 行 · 第 1/5 页
C
1,715 行
if( commonAttributeSize )
writeCharacterString( &stream, ( BYTE * ) pkcs15info->label,
pkcs15info->labelLength, BER_STRING_UTF8 );
writeSequence( &stream, commonCertAttributeSize );
writeOctetString( &stream, pkcs15info->iD, pkcs15info->iDlength,
DEFAULT_TAG );
if( isCA )
writeBoolean( &stream, TRUE, DEFAULT_TAG );
if( trustedUsage != CRYPT_UNUSED )
{
writeConstructed( &stream, trustedUsageSize, CTAG_CA_TRUSTED_USAGE );
writeBitString( &stream, trustedUsage, DEFAULT_TAG );
}
writeConstructed( &stream, keyIdentifierDataSize, CTAG_CA_IDENTIFIERS );
writeSequence( &stream,
sizeofShortInteger( PKCS15_KEYID_SUBJECTKEYIDENTIFIER ) +
sizeofObject( pkcs15info->keyIDlength ) );
writeShortInteger( &stream, PKCS15_KEYID_SUBJECTKEYIDENTIFIER,
DEFAULT_TAG );
writeOctetString( &stream, pkcs15info->keyID,
pkcs15info->keyIDlength, DEFAULT_TAG );
writeSequence( &stream,
sizeofShortInteger( PKCS15_KEYID_ISSUERANDSERIALNUMBERHASH ) +
sizeofObject( pkcs15info->iAndSIDlength ) );
writeShortInteger( &stream, PKCS15_KEYID_ISSUERANDSERIALNUMBERHASH,
DEFAULT_TAG );
writeOctetString( &stream, pkcs15info->iAndSID,
pkcs15info->iAndSIDlength, DEFAULT_TAG );
writeSequence( &stream,
sizeofShortInteger( PKCS15_KEYID_ISSUERNAMEHASH ) +
sizeofObject( pkcs15info->issuerNameIDlength ) );
writeShortInteger( &stream, PKCS15_KEYID_ISSUERNAMEHASH, DEFAULT_TAG );
writeOctetString( &stream, pkcs15info->issuerNameID,
pkcs15info->issuerNameIDlength, DEFAULT_TAG );
writeSequence( &stream,
sizeofShortInteger( PKCS15_KEYID_SUBJECTNAMEHASH ) +
sizeofObject( pkcs15info->subjectNameIDlength ) );
writeShortInteger( &stream, PKCS15_KEYID_SUBJECTNAMEHASH, DEFAULT_TAG );
writeOctetString( &stream, pkcs15info->subjectNameID,
pkcs15info->subjectNameIDlength, DEFAULT_TAG );
if( pkcs15info->pgp2KeyIDlength )
{
writeSequence( &stream,
sizeofShortInteger( PKCS15_KEYID_PGP2 ) +
sizeofObject( pkcs15info->pgp2KeyIDlength ) );
writeShortInteger( &stream, PKCS15_KEYID_PGP2, DEFAULT_TAG );
writeOctetString( &stream, pkcs15info->pgp2KeyID,
pkcs15info->pgp2KeyIDlength, DEFAULT_TAG );
}
writeSequence( &stream,
sizeofShortInteger( PKCS15_KEYID_OPENPGP ) +
sizeofObject( pkcs15info->openPGPKeyIDlength ) );
writeShortInteger( &stream, PKCS15_KEYID_OPENPGP, DEFAULT_TAG );
writeOctetString( &stream, pkcs15info->openPGPKeyID,
pkcs15info->openPGPKeyIDlength, DEFAULT_TAG );
if( trustedImplicit )
writeBoolean( &stream, TRUE, CTAG_CA_TRUSTED_IMPLICIT );
writeGeneralizedTime( &stream, pkcs15info->validFrom, DEFAULT_TAG );
writeGeneralizedTime( &stream, pkcs15info->validTo, CTAG_CA_VALIDTO );
*certAttributeSize = ( int ) stell( &stream );
assert( sStatusOK( &stream ) );
sMemDisconnect( &stream );
return( CRYPT_OK );
}
/****************************************************************************
* *
* PKCS #15 Init/Shutdown Functions *
* *
****************************************************************************/
/* Write the multiple layers of wrapping needed for individual objects */
static void writeObjectWrapper( STREAM *stream, const int length,
const int tag )
{
#if 0 /* pcg 28/6/00 Changed for another interp.of ASN.1 rules */
writeConstructed( stream, ( int ) sizeofObject( \
sizeofObject( \
sizeofObject( length ) ) ),
tag );
writeSequence( stream, ( int ) sizeofObject( \
sizeofObject( length ) ) );
writeConstructed( stream, ( int ) sizeofObject( length ),
CTAG_OV_DIRECT );
writeSequence( stream, length );
#else
writeConstructed( stream, ( int ) sizeofObject( length ), tag );
writeConstructed( stream, length, CTAG_OV_DIRECT );
#endif /* 0 */
}
/* Write a data item */
static int sizeofDataItem( const PKCS15_INFO *pkcs15infoPtr )
{
const int dataSize = \
( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
pkcs15infoPtr->dataDataSize : \
( int ) sizeofObject( pkcs15infoPtr->dataDataSize );
const int labelSize = \
( pkcs15infoPtr->labelLength ) ? \
( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;
return( ( int ) \
sizeofObject( \
sizeofObject( labelSize ) + \
sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
sizeofObject( \
sizeofObject( \
sizeofOID( OID_CRYPTLIB_CONFIGDATA ) + dataSize ) ) ) );
}
static void writeDataItem( STREAM *stream, const PKCS15_INFO *pkcs15infoPtr )
{
const BYTE *oid = \
( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA ) ? \
OID_CRYPTLIB_CONFIGDATA : \
( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX ) ? \
OID_CRYPTLIB_USERINDEX : OID_CRYPTLIB_USERINFO;
const int labelSize = \
( pkcs15infoPtr->labelLength ) ? \
( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;
const int contentSize = sizeofOID( oid ) + \
( ( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
pkcs15infoPtr->dataDataSize : \
( int ) sizeofObject( pkcs15infoPtr->dataDataSize ) );
assert( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX || \
pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO );
writeConstructed( stream, \
( int ) sizeofObject( labelSize ) + \
( int ) sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
( int ) sizeofObject( sizeofObject( contentSize ) ),
CTAG_DO_OIDDO );
writeSequence( stream, labelSize );
if( labelSize )
writeCharacterString( stream, ( BYTE * ) pkcs15infoPtr->label,
pkcs15infoPtr->labelLength, BER_STRING_UTF8 );
writeSequence( stream, sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) );
writeOID( stream, OID_CRYPTLIB_CONTENTTYPE );
writeConstructed( stream, ( int ) sizeofObject( contentSize ),
CTAG_OB_TYPEATTR );
writeSequence( stream, contentSize );
writeOID( stream, oid );
if( pkcs15infoPtr->dataType != CRYPT_IATTRIBUTE_USERINFO )
/* UserInfo is a straight object, the others are SEQUENCEs of
objects */
writeSequence( stream, pkcs15infoPtr->dataDataSize );
swrite( stream, pkcs15infoPtr->dataData, pkcs15infoPtr->dataDataSize );
}
/* Flush a PKCS #15 collection to a stream */
static int pkcs15Flush( STREAM *stream, const PKCS15_INFO *pkcs15info )
{
int pubKeySize = 0, privKeySize = 0, certSize = 0, dataSize = 0;
int objectsSize = 0, i;
/* Determine the overall size of the objects */
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
switch( pkcs15info[ i ].type )
{
case PKCS15_SUBTYPE_NONE:
break;
case PKCS15_SUBTYPE_NORMAL:
pubKeySize += pkcs15info[ i ].pubKeyDataSize;
privKeySize += pkcs15info[ i ].privKeyDataSize;
/* Drop through */
case PKCS15_SUBTYPE_CERT:
certSize += pkcs15info[ i ].certDataSize;
break;
case PKCS15_SUBTYPE_SECRETKEY:
assert( NOTREACHED );
break;
case PKCS15_SUBTYPE_DATA:
dataSize += sizeofDataItem( &pkcs15info[ i ] );
break;
default:
assert( NOTREACHED );
}
/* Determine how much data there is to write. If there's no data
present, let the caller know that the keyset is empty */
#if 0 /* pcg 28/6/00 Changed for another interp.of ASN.1 rules */
objectsSize = \
( pubKeySize ? \
( int ) sizeofObject( sizeofObject( \
sizeofObject( \
sizeofObject( pubKeySize ) ) ) ) : 0 ) +
( privKeySize ? \
( int ) sizeofObject( sizeofObject( \
sizeofObject( \
sizeofObject( privKeySize ) ) ) ) : 0 ) +
( certSize ? \
( int ) sizeofObject( sizeofObject( \
sizeofObject( \
sizeofObject( certSize ) ) ) ) : 0 ) +
( dataSize ? \
( int ) sizeofObject( sizeofObject( \
sizeofObject( \
sizeofObject( dataSize ) ) ) ) : 0 );
#else
objectsSize = \
( pubKeySize ? \
( int ) sizeofObject( sizeofObject( pubKeySize ) ) : 0 ) +
( privKeySize ? \
( int ) sizeofObject( sizeofObject( privKeySize ) ) : 0 ) +
( certSize ? \
( int ) sizeofObject( sizeofObject( certSize ) ) : 0 ) +
( dataSize ? \
( int ) sizeofObject( sizeofObject( dataSize ) ) : 0 );
#endif /* 0 */
if( !objectsSize )
return( OK_SPECIAL );
/* Write the header information and each public key, private key, and
cert */
writeCMSheader( stream, OID_PKCS15_CONTENTTYPE,
sizeofShortInteger( 0 ) + sizeofObject( objectsSize ),
FALSE );
writeShortInteger( stream, 0, DEFAULT_TAG );
writeSequence( stream, objectsSize );
if( privKeySize )
{
writeObjectWrapper( stream, privKeySize, PKCS15_OBJECT_PRIVKEY );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( pkcs15info[ i ].privKeyDataSize )
swrite( stream, pkcs15info[ i ].privKeyData,
pkcs15info[ i ].privKeyDataSize );
}
if( pubKeySize )
{
writeObjectWrapper( stream, pubKeySize, PKCS15_OBJECT_PUBKEY );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( pkcs15info[ i ].pubKeyDataSize )
swrite( stream, pkcs15info[ i ].pubKeyData,
pkcs15info[ i ].pubKeyDataSize );
}
if( certSize )
{
writeObjectWrapper( stream, certSize, PKCS15_OBJECT_CERT );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( ( pkcs15info[ i ].type == PKCS15_SUBTYPE_NORMAL && \
pkcs15info[ i ].certDataSize ) || \
( pkcs15info[ i ].type == PKCS15_SUBTYPE_CERT ) )
swrite( stream, pkcs15info[ i ].certData,
pkcs15info[ i ].certDataSize );
}
if( dataSize )
{
writeObjectWrapper( stream, dataSize, PKCS15_OBJECT_DATA );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( pkcs15info[ i ].dataDataSize )
writeDataItem( stream, &pkcs15info[ i ] );
}
return( sflush( stream ) );
}
/* A PKCS #15 keyset can contain multiple keys and whatnot, so when we open
it we scan it and record various pieces of information about it which we
can use later when we need to access it */
static int initFunction( KEYSET_INFO *keysetInfo, const char *name,
const char *arg1, const CRYPT_KEYOPT_TYPE options )
{
PKCS15_INFO *pkcs15info, pkcs15objectInfo;
STREAM *stream = &keysetInfo->keysetFile.stream;
long outerEndPos;
int status;
assert( name == NULL ); assert( arg1 == NULL );
/* Allocate the PKCS #15 object info */
if( ( pkcs15info = malloc( sizeof( PKCS15_INFO ) * \
MAX_PKCS15_OBJECTS ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memset( pkcs15info, 0, sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS );
keysetInfo->keyData = pkcs15info;
keysetInfo->keyDataSize = sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS;
/* If this is a newly-created keyset, there's nothing left to do */
if( options == CRYPT_KEYOPT_CREATE )
return( CRYPT_OK );
/* Skip the outer header, optional keyManagementInfo, and inner header */
status = readCMSheader( stream, keyFileOIDselection, &outerEndPos, FALSE );
if( !cryptStatusError( status ) && outerEndPos < 16 )
/* Make sure the length is sensible, problems can occur if the
indefinite encoding is used */
status = CRYPT_ERROR_BADDATA;
outerEndPos += stell( stream ) - sizeofShortInteger( 0 );
if( !cryptStatusError( status ) && peekTag( stream ) == MAKE_CTAG( 0 ) )
status = readUniversal( stream );
if( !cryptStatusError( status ) )
status = readSequence( stream, NULL );
if( cryptStatusError( status ) )
{
free( keysetInfo->keyData );
keysetInfo->keyDataSize = 0;
return( status );
}
/* Scan all the objects in the file. We allow a bit of slop to handle
incorrect length encodings (16 bytes = roughly min.object size) */
while( !cryptStatusError( status ) && stell( stream ) < outerEndPos - 16 )
{
const PKCS15_OBJECT_TYPE type = EXTRACT_CTAG( readTag( stream ) );
int innerEndPos;
/* Read the [n] [0] wrapper to find out what we're dealing with */
if( type < 0 || type >= PKCS15_OBJECT_LAST )
{
status = CRYPT_ERROR_BADDATA;
break;
}
readShortLength( stream );
status = readConstructed( stream, &innerEndPos, CTAG_OV_DIRECT );
if( cryptStatusError( status ) )
break;
innerEndPos += stell( stream );
/* Scan all objects of this type, again allowing for slop */
while( stell( stream ) < innerEndPos - 16 )
{
PKCS15_INFO *pkcs15infoPtr;
void *objectData;
const int startPos = ( int ) stell( stream );
int objectLength;
/* Read the current object. We can't use getObjectLength() here
because we're reading from a file rather than a memory stream */
readTag( stream );
objectLength = readShortLength( stream );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?