📄 trustmgr.c
字号:
/* Generate the checksum and hash of the cert object's subject name and
key ID */
status = dynCreate( &subjectDB, iCryptCert, CRYPT_IATTRIBUTE_SUBJECT );
if( cryptStatusError( status ) )
return( status );
status = dynCreate( &subjectKeyDB, iCryptCert,
CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER );
if( cryptStatusOK( status ) )
hasSKID = TRUE;
newElement->sCheck = checksumData( dynData( subjectDB ),
dynLength( subjectDB ) );
hashData( newElement->sHash, dynData( subjectDB ),
dynLength( subjectDB ) );
if( hasSKID )
{
newElement->kCheck = checksumData( dynData( subjectKeyDB ),
dynLength( subjectKeyDB ) );
hashData( newElement->kHash, dynData( subjectKeyDB ),
dynLength( subjectKeyDB ) );
dynDestroy( &subjectKeyDB );
}
else
{
newElement->kCheck = 0;
hashData( newElement->kHash, NULL, 0 );
}
dynDestroy( &subjectDB );
}
if( certObject != NULL || recreateCert )
{
DYNBUF certDB;
int objectLength = certObjectLength, status;
/* If we're using the data from an existing cert object, all we still
need is the encoded data */
if( recreateCert )
{
/* Get the encoded cert */
status = dynCreate( &certDB, iCryptCert,
CRYPT_CERTFORMAT_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
certObject = dynData( certDB );
objectLength = dynLength( certDB );
}
else
{
STREAM stream;
const BYTE *extensionPtr;
const void *subjectDNptr, *subjectKeyIDptr;
int subjectDNsize, subjectKeyIDsize;
int extensionSize = 0, i;
/* Parse the certificate to locate the start of the encoded
subject DN and cert extensions (if present) */
sMemConnect( &stream, certObject, certObjectLength );
readSequence( &stream, NULL ); /* Outer wrapper */
readSequence( &stream, NULL ); /* Inner wrapper */
if( peekTag( &stream ) == MAKE_CTAG( 0 ) )
readUniversal( &stream ); /* Version */
readUniversal( &stream ); /* Serial number */
readUniversal( &stream ); /* Sig.algo */
readUniversal( &stream ); /* Issuer DN */
readUniversal( &stream ); /* Validity */
subjectDNptr = sMemBufPtr( &stream );
readSequence( &stream, &subjectDNsize );
subjectDNsize = sizeofObject( subjectDNsize );
readUniversal( &stream ); /* Subject DN */
status = readUniversal( &stream );/* Public key */
if( cryptStatusOK( status ) && \
peekTag( &stream ) == MAKE_CTAG( 3 ) )
{
status = readConstructed( &stream, &extensionSize, 3 );
if( cryptStatusOK( status ) )
{
extensionPtr = sMemBufPtr( &stream );
sSkip( &stream, extensionSize );
}
}
if( cryptStatusOK( status ) ) /* Signature */
status = readUniversal( &stream );
sMemDisconnect( &stream );
if( cryptStatusError( status ) )
{
clFree( "addEntry", newElement );
assert( NOTREACHED );
return( CRYPT_ERROR_BADDATA );
}
/* Now look for the subjectKeyID in the extensions. It's easier
to do a pattern match than to try and parse the extensions */
subjectKeyIDptr = NULL;
subjectKeyIDsize = 0;
for( i = 0; i < extensionSize - 64; i++ )
{
/* Look for the OID. This potentially skips two bytes at a
time, but this is safe since the preceding bytes can never
contain either of these two values (they're 0x30, len) */
if( extensionPtr[ i++ ] != BER_OBJECT_IDENTIFIER || \
extensionPtr[ i++ ] != 3 )
continue;
if( memcmp( extensionPtr + i, "\x55\x1D\x0E", 3 ) )
continue;
i += 3;
/* We've found the OID (with 1.1e-12 error probability), skip
the critical flag if necessary */
if( extensionPtr[ i ] == BER_BOOLEAN )
i += 3;
/* Check for the OCTET STRING and a reasonable length */
if( extensionPtr[ i++ ] != BER_OCTETSTRING || \
extensionPtr[ i ] & 0x80 )
continue;
/* Extract the key ID */
if( i + extensionPtr[ i ] <= extensionSize )
{
subjectKeyIDsize = extensionPtr[ i++ ];
subjectKeyIDptr = extensionPtr + i;
}
}
/* Generate the checksum and hash of the encoded cert's subject
name and key ID */
newElement->sCheck = checksumData( subjectDNptr, subjectDNsize );
hashData( newElement->sHash, subjectDNptr, subjectDNsize );
newElement->kCheck = checksumData( subjectKeyIDptr, subjectKeyIDsize );
hashData( newElement->kHash, subjectKeyIDptr, subjectKeyIDsize );
}
/* Remember the trusted cert data for later use */
if( ( newElement->certObject = clAlloc( "addEntry",
objectLength ) ) == NULL )
{
clFree( "addEntry", newElement );
if( recreateCert )
dynDestroy( &certDB );
return( CRYPT_ERROR_MEMORY );
}
memcpy( newElement->certObject, certObject, objectLength );
newElement->certObjectLength = objectLength;
newElement->iCryptCert = CRYPT_ERROR;
/* Clean up */
if( recreateCert )
dynDestroy( &certDB );
}
else
{
/* The trusted key exists as a standard cert with a public-key
context attached, remember it for later */
krnlSendNotifier( iCryptCert, IMESSAGE_INCREFCOUNT );
newElement->iCryptCert = iCryptCert;
}
/* Add it to the list */
trustInfoEntry = newElement->sCheck & ( TRUSTINFO_SIZE - 1 );
if( trustInfoIndex[ trustInfoEntry ] == NULL )
trustInfoIndex[ trustInfoEntry ] = newElement;
else
{
TRUST_INFO *trustInfoCursor;
/* Add the new element to the end of the list */
for( trustInfoCursor = trustInfoIndex[ trustInfoEntry ];
trustInfoCursor->next != NULL;
trustInfoCursor = trustInfoCursor->next );
trustInfoCursor->next = newElement;
}
return( CRYPT_OK );
}
int addTrustEntry( void *trustInfoPtr, const CRYPT_CERTIFICATE iCryptCert,
const void *certObject, const int certObjectLength,
const BOOLEAN addSingleCert )
{
BOOLEAN seenNonDuplicate = FALSE;
int status;
assert( ( isHandleRangeValid( iCryptCert ) && certObject == NULL ) || \
( iCryptCert == CRYPT_UNUSED && certObject != NULL ) );
/* If we're adding encoded cert data, we can add it directly */
if( certObject != NULL )
return( addEntry( trustInfoPtr, CRYPT_UNUSED, certObject,
certObjectLength ) );
/* Add the cert/each cert in the trust list */
status = krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_TRUE, CRYPT_IATTRIBUTE_LOCKED );
if( cryptStatusError( status ) )
return( status );
if( !addSingleCert )
/* It's a trust list, move to the start of the list */
krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_CURSORFIRST,
CRYPT_CERTINFO_CURRENT_CERTIFICATE );
do
{
/* Add the certificate info if it's not already present */
if( findTrustEntry( trustInfoPtr, iCryptCert, FALSE ) == NULL )
{
seenNonDuplicate = TRUE;
status = addEntry( trustInfoPtr, iCryptCert, NULL, 0 );
}
}
while( cryptStatusOK( status ) && !addSingleCert && \
krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_CURSORNEXT,
CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK );
krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
if( cryptStatusOK( status ) && !seenNonDuplicate )
/* There were no new certs to add present, return an inited error */
status = CRYPT_ERROR_INITED;
return( status );
}
void deleteTrustEntry( void *trustInfoPtr, void *trustEntry )
{
TRUST_INFO **trustInfoIndex = ( TRUST_INFO ** ) trustInfoPtr;
TRUST_INFO *entryToDelete = ( TRUST_INFO * ) trustEntry, *prevInfoPtr;
const int trustInfoEntry = entryToDelete->sCheck & ( TRUSTINFO_SIZE - 1 );
assert( trustInfoIndex[ trustInfoEntry ] != NULL );
/* Unlink the trust info index */
prevInfoPtr = trustInfoIndex[ trustInfoEntry ];
if( prevInfoPtr == entryToDelete )
/* Unlink from the start of the list */
trustInfoIndex[ trustInfoEntry ] = entryToDelete->next;
else
{
/* Unlink from the middle/end of the list */
while( prevInfoPtr->next != entryToDelete )
prevInfoPtr = prevInfoPtr->next;
prevInfoPtr->next = entryToDelete->next;
}
/* Free the trust info entry */
if( entryToDelete->iCryptCert != CRYPT_ERROR )
krnlSendNotifier( entryToDelete->iCryptCert, IMESSAGE_DECREFCOUNT );
if( entryToDelete->certObject != NULL )
{
zeroise( entryToDelete->certObject, entryToDelete->certObjectLength );
clFree( "deleteTrustEntry", entryToDelete->certObject );
}
memset( entryToDelete, 0, sizeof( TRUST_INFO ) );
clFree( "deleteTrustEntry", entryToDelete );
}
/****************************************************************************
* *
* Init/Shut down Trusted Cert Info *
* *
****************************************************************************/
/* Initialise and shut down the trust information */
int initTrustInfo( void **trustInfoPtrPtr )
{
TRUST_INFO *trustInfoIndex;
/* Initialise the trust information table */
if( ( trustInfoIndex = \
clAlloc( "initTrustInfo", TRUSTINFO_SIZE * \
sizeof( TRUST_INFO * ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memset( trustInfoIndex, 0, TRUSTINFO_SIZE * sizeof( TRUST_INFO * ) );
*trustInfoPtrPtr = trustInfoIndex;
return( CRYPT_OK );
}
void endTrustInfo( void *trustInfoPtr )
{
TRUST_INFO **trustInfoIndex = ( TRUST_INFO ** ) trustInfoPtr;
int i;
if( trustInfoIndex == NULL )
return;
/* Destroy the chain of items at each table position */
for( i = 0; i < TRUSTINFO_SIZE; i++ )
{
TRUST_INFO *trustInfoCursor = trustInfoIndex[ i ];
/* Destroy any items in the list */
while( trustInfoCursor != NULL )
{
TRUST_INFO *itemToFree = trustInfoCursor;
trustInfoCursor = trustInfoCursor->next;
deleteTrustEntry( trustInfoIndex, itemToFree );
}
}
memset( trustInfoIndex, 0, TRUSTINFO_SIZE * sizeof( TRUST_INFO * ) );
clFree( "endTrustInfo", trustInfoIndex );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -