📄 comp_get.c
字号:
return( status );
*certInfoLength = textOidLength;
if( certInfo == NULL )
return( CRYPT_OK );
return( attributeCopyParams( certInfo, certInfoMaxLength,
certInfoLength, textOID,
textOidLength ) );
}
/* If it's a basic data value, copy it over as an integer */
if( attributeListPtr->valueLength <= 0 )
{
*( ( int * ) certInfo ) = ( int ) attributeListPtr->intValue;
return( CRYPT_OK );
}
ENSURES( certInfoLength != NULL );
/* It's a more complex data type, copy it across */
return( attributeCopyParams( certInfo, certInfoMaxLength, certInfoLength,
attributeListPtr->value,
attributeListPtr->valueLength ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int getCertAttributeComponent( const CERT_INFO *certInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
OUT_BUFFER_OPT( certInfoMaxLength, certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
ATTRIBUTE_LIST *attributeListPtr;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( certInfoType > CRYPT_ATTRIBUTE_NONE && \
certInfoType < CRYPT_ATTRIBUTE_LAST );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
/* Try and find this attribute in the attribute list */
if( isRevocationEntryComponent( certInfoType ) )
{
/* If it's an RTCS per-entry attribute get the attribute from the
currently selected entry */
if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST || \
certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
{
CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;
if( certValInfo->currentValidity == NULL )
return( CRYPT_ERROR_NOTFOUND );
attributeListPtr = findAttributeFieldEx( \
certValInfo->currentValidity->attributes, certInfoType );
}
else
{
CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;
/* It's a CRL or OCSP per-entry attribute get the attribute
from the currently selected entry */
if( certRevInfo->currentRevocation == NULL )
return( CRYPT_ERROR_NOTFOUND );
attributeListPtr = findAttributeFieldEx( \
certRevInfo->currentRevocation->attributes, certInfoType );
if( attributeListPtr == NULL && \
certInfoType == CRYPT_CERTINFO_CRLREASON )
{
/* Revocation reason codes are actually a single range of
values spread across two different extensions so if we
don't find the value as a straight cRLReason we try again
for a cRLExtReason. If we've been specifically asked for
a cRLExtReason we don't go the other way because the
caller (presumably) specifically wants the extended
reason code */
attributeListPtr = findAttributeFieldEx( \
certRevInfo->currentRevocation->attributes,
CRYPT_CERTINFO_CRLEXTREASON );
}
}
}
else
{
attributeListPtr = findAttributeFieldEx( certInfoPtr->attributes,
certInfoType );
}
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* If this is a non-present field in a present attribute with a default
value for the field, return that */
if( isDefaultFieldValue( attributeListPtr ) )
{
const int value = getDefaultFieldValue( certInfoType );
if( cryptStatusError( value ) )
return( value );
*( ( int * ) certInfo ) = value;
return( CRYPT_OK );
}
/* If this is a non-present field in a present attribute which denotes
an entire (constructed) attribute, return a boolean indicating its
presence */
if( isCompleteAttribute( attributeListPtr ) )
{
*( ( int * ) certInfo ) = TRUE;
return( CRYPT_OK );
}
return( getCertAttributeComponentData( attributeListPtr, certInfo,
certInfoMaxLength,
certInfoLength ) );
}
/* Get the hash of a certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int getCertHash( INOUT CERT_INFO *certInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
OUT_BUFFER_OPT( certInfoMaxLength, \
certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
const CRYPT_ALGO_TYPE cryptAlgo = \
( certInfoType == CRYPT_CERTINFO_FINGERPRINT_MD5 ) ? \
CRYPT_ALGO_MD5 : CRYPT_ALGO_SHA1;
HASHFUNCTION_ATOMIC hashFunctionAtomic;
BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ];
int hashSize;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( certInfoType == CRYPT_CERTINFO_FINGERPRINT_MD5 || \
certInfoType == CRYPT_CERTINFO_FINGERPRINT_SHA );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
/* Get the hash algorithm information */
getHashAtomicParameters( cryptAlgo, &hashFunctionAtomic, &hashSize );
*certInfoLength = hashSize;
if( certInfo == NULL )
return( CRYPT_OK );
if( hashSize > certInfoMaxLength )
return( CRYPT_ERROR_OVERFLOW );
ENSURES( certInfoPtr->certificate != NULL );
/* Write the hash (fingerprint) to the output */
if( cryptAlgo == CRYPT_ALGO_SHA1 && certInfoPtr->certHashSet )
{
/* If we've got a cached hash present return that instead of re-
hashing the certificate */
memcpy( certInfo, certInfoPtr->certHash, KEYID_SIZE );
return( CRYPT_OK );
}
hashFunctionAtomic( hash, CRYPT_MAX_HASHSIZE, certInfoPtr->certificate,
certInfoPtr->certificateSize );
memcpy( certInfo, hash, hashSize );
if( cryptAlgo == CRYPT_ALGO_SHA1 )
{
/* Remember the hash/fingerprint/oobCertID/certHash/thumbprint/
whatever for later since this is reused frequently */
memcpy( certInfoPtr->certHash, hash, hashSize );
certInfoPtr->certHashSet = TRUE;
}
return( CRYPT_OK );
}
/* Get a single CRL entry */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getCrlEntry( INOUT CERT_INFO *certInfoPtr,
OUT_BUFFER_OPT( certInfoMaxLength, \
certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;
STREAM stream;
WRITECERT_FUNCTION writeCertFunction;
int crlEntrySize = DUMMY_INIT, status;
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
REQUIRES( certInfoPtr->type == CRYPT_CERTTYPE_CRL );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
if( certRevInfo->currentRevocation == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* Determine how big the encoded CRL entry will be. Doing it directly
in this manner is somewhat ugly but the only other way to do it would
be to pseudo-sign the certificate object in order to write the data,
which doesn't work for CRL entries where we could end up pseudo-
signing it multiple times */
writeCertFunction = getCertWriteFunction( certInfoPtr->type );
ENSURES( writeCertFunction != NULL );
sMemNullOpen( &stream );
status = writeCertFunction( &stream, certInfoPtr, NULL, CRYPT_UNUSED );
if( cryptStatusOK( status ) )
crlEntrySize = stell( &stream );
sMemClose( &stream );
if( cryptStatusError( status ) )
return( status );
/* Write the encoded single CRL entry */
*certInfoLength = crlEntrySize;
if( certInfo == NULL )
return( CRYPT_OK );
if( crlEntrySize > certInfoMaxLength )
return( CRYPT_ERROR_OVERFLOW );
sMemOpen( &stream, certInfo, crlEntrySize );
status = writeCertFunction( &stream, certInfoPtr, NULL, CRYPT_UNUSED );
sMemDisconnect( &stream );
return( status );
}
/* Get the issuerAndSerialNumber for a certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getIAndS( const CERT_INFO *certInfoPtr,
OUT_BUFFER_OPT( certInfoMaxLength, \
certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
STREAM stream;
void *serialNumber;
int serialNumberLength, status;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
if( certInfoPtr->type == CRYPT_CERTTYPE_CRL )
{
REVOCATION_INFO *crlInfoPtr = certInfoPtr->cCertRev->currentRevocation;
/* If it's a CRL, use the serial number of the currently selected
CRL entry */
REQUIRES( crlInfoPtr != NULL );
serialNumber = crlInfoPtr->idPtr;
serialNumberLength = crlInfoPtr->idLength;
}
else
{
serialNumber = certInfoPtr->cCertCert->serialNumber;
serialNumberLength = certInfoPtr->cCertCert->serialNumberLength;
}
ENSURES( serialNumber != NULL );
*certInfoLength = ( int ) \
sizeofObject( certInfoPtr->issuerDNsize + \
sizeofInteger( serialNumber, serialNumberLength ) );
if( certInfo == NULL )
return( CRYPT_OK );
if( *certInfoLength > certInfoMaxLength )
return( CRYPT_ERROR_OVERFLOW );
sMemOpen( &stream, certInfo, *certInfoLength );
writeSequence( &stream, certInfoPtr->issuerDNsize + \
sizeofInteger( serialNumber, serialNumberLength ) );
swrite( &stream, certInfoPtr->issuerDNptr, certInfoPtr->issuerDNsize );
status = writeInteger( &stream, serialNumber, serialNumberLength,
DEFAULT_TAG );
sMemDisconnect( &stream );
return( status );
}
/* Get the certificate holder's name, usually the commonName but if that's
not present some commonName-equivalent */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \
static int extractDnComponent( IN_BUFFER( encodedDnLength ) \
const char *encodedDn,
IN_LENGTH_SHORT const int encodedDnLength,
IN_BUFFER( componentNameLength ) \
const char *componentName,
IN_LENGTH_SHORT const int componentNameLength,
OUT_LENGTH_SHORT_Z int *startOffset,
OUT_LENGTH_SHORT_Z int *length )
{
int startPos, endPos;
assert( isReadPtr( encodedDn, encodedDnLength ) );
assert( isReadPtr( componentName, componentNameLength ) );
assert( isWritePtr( startOffset, sizeof( int ) ) );
assert( isWritePtr( length, sizeof( int ) ) );
REQUIRES( encodedDnLength > 0 && \
encodedDnLength < MAX_INTLENGTH_SHORT );
REQUIRES( componentNameLength > 0 && \
componentNameLength < MAX_INTLENGTH_SHORT );
/* Clear return value */
*startOffset = *length = 0;
/* Try and find the component name in the encoded DN string */
startPos = strFindStr( encodedDn, encodedDnLength,
componentName, componentNameLength );
if( startPos < 0 )
return( -1 );
startPos += componentNameLength; /* Skip type indicator */
/* Extract the component value */
for( endPos = startPos; endPos < encodedDnLength && \
encodedDn[ endPos ] != ',' && \
encodedDn[ endPos ] != '+'; endPos++ );
if( encodedDn[ endPos ] == '+' && \
encodedDn[ endPos - 1 ] == ' ' )
endPos--; /* Strip trailing space */
*startOffset = startPos;
*length = endPos - startPos;
return( CRYPT_OK );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 4 ) ) \
static int getNameFromDN( OUT_BUFFER_OPT( nameMaxLength, *nameLength ) void *name,
IN_LENGTH_SHORT_Z const int nameMaxLength,
OUT_LENGTH_SHORT_Z int *nameLength,
IN_BUFFER( encodedDnLength ) const char *encodedDn,
IN_LENGTH_SHORT const int encodedDnLength )
{
int startPos, length, status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -