📄 certcget.c
字号:
HASHFUNCTION hashFunction;
const int maxLength = *certInfoLength;
int hashSize, issuerSerialDataSize, status;
/* Get the hash algorithm information and hash the cert to get the cert
ID if necessary */
getHashParameters( CRYPT_ALGO_SHA, &hashFunction, &hashSize );
if( !certInfoPtr->certHashSet )
{
hashFunction( NULL, certInfoPtr->certHash, certInfoPtr->certificate,
certInfoPtr->certificateSize, HASH_ALL );
certInfoPtr->certHashSet = TRUE;
}
assert( certInfoPtr->serialNumber != NULL );
/* Write the ESSCertID:
ESSCertID ::= SEQUENCE {
certHash OCTET STRING SIZE(20),
issuerSerial SEQUENCE {
issuer SEQUENCE { [4] EXPLICIT Name },
serial INTEGER
}
} */
issuerSerialDataSize = ( int ) \
sizeofObject( sizeofObject( certInfoPtr->issuerDNsize ) ) + \
sizeofInteger( certInfoPtr->serialNumber,
certInfoPtr->serialNumberLength );
*certInfoLength = ( int ) \
sizeofObject( sizeofObject( hashSize ) + \
sizeofObject( issuerSerialDataSize ) );
if( certInfo == NULL )
return( CRYPT_OK );
if( *certInfoLength > maxLength )
return( CRYPT_ERROR_OVERFLOW );
sMemOpen( &stream, certInfo, *certInfoLength );
writeSequence( &stream, sizeofObject( hashSize ) + \
sizeofObject( issuerSerialDataSize ) );
writeOctetString( &stream, certInfoPtr->certHash, hashSize, DEFAULT_TAG );
writeSequence( &stream, issuerSerialDataSize );
writeSequence( &stream, sizeofObject( certInfoPtr->issuerDNsize ) );
writeConstructed( &stream, certInfoPtr->issuerDNsize, 4 );
swrite( &stream, certInfoPtr->issuerDNptr, certInfoPtr->issuerDNsize );
status = writeInteger( &stream, certInfoPtr->serialNumber,
certInfoPtr->serialNumberLength, DEFAULT_TAG );
sMemDisconnect( &stream );
assert( cryptStatusOK( status ) );
return( status );
}
/* Encode PKI user information into the external format and return it */
static int getPkiUserInfo( CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType,
void *certInfo, int *certInfoLength )
{
char encUserInfo[ 128 ];
BYTE userInfo[ 128 ], *userInfoPtr = userInfo;
const int maxLength = *certInfoLength;
int userInfoLength = 128, status;
if( certInfoType == CRYPT_CERTINFO_PKIUSER_ID )
{
status = getCertAttributeComponent( certInfoPtr,
CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
userInfo, &userInfoLength );
assert( cryptStatusOK( status ) );
if( cryptStatusError( status ) )
return( status ); /* Should never happen */
}
else
userInfoPtr = ( certInfoType == CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD ) ? \
certInfoPtr->pkiIssuePW : certInfoPtr->pkiRevPW;
*certInfoLength = encodePKIUserValue( encUserInfo, userInfoPtr,
( certInfoType == CRYPT_CERTINFO_PKIUSER_ID ) ? 3 : 4 );
zeroise( userInfo, 128 );
if( certInfo == NULL )
return( CRYPT_OK );
if( *certInfoLength > maxLength )
return( CRYPT_ERROR_OVERFLOW );
memcpy( certInfo, encUserInfo, *certInfoLength );
zeroise( encUserInfo, 128 );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Get a Component *
* *
****************************************************************************/
/* Get a certificate component */
int getCertComponent( CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType,
void *certInfo, int *certInfoLength )
{
const int maxLength = ( certInfoLength != NULL ) ? *certInfoLength : 0;
void *data = NULL;
int *valuePtr = ( int * ) certInfo;
int dataLength = 0;
assert( ( certInfo == NULL && *certInfoLength == 0 ) || \
( certInfoLength == NULL ) || \
( *certInfoLength > 1 && *certInfoLength <= 32768 ) );
/* If it's a GeneralName or DN component, return it. These are
special-case attribute values, so they have to come before the
general attribute-handling code */
if( isGeneralNameSelectionComponent( certInfoType ) )
{
SELECTION_STATE savedState;
int status;
/* Determine whether the given component is present or not. This
has a somewhat odd status return since it returns the found/
notfound status in the return code as well as the returned value,
this mirrors the behaviour when reading extension-present
pseudo-attributes */
saveSelectionState( savedState, certInfoPtr );
status = selectGeneralName( certInfoPtr, certInfoType,
MAY_BE_ABSENT );
if( cryptStatusOK( status ) )
status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
MUST_BE_PRESENT );
*valuePtr = cryptStatusOK( status ) ? TRUE : FALSE;
restoreSelectionState( savedState, certInfoPtr );
return( status );
}
if( isGeneralNameComponent( certInfoType ) )
{
ATTRIBUTE_LIST *attributeListPtr;
int status;
/* Find the requested GeneralName component and return it to the
caller */
status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
MUST_BE_PRESENT );
if( cryptStatusError( status ) )
return( status );
attributeListPtr = findAttributeField( certInfoPtr->attributeCursor,
certInfoPtr->attributeCursor->fieldID,
certInfoType );
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
return( getCertAttributeComponentData( attributeListPtr, certInfo,
certInfoLength ) );
}
if( isDNComponent( certInfoType ) )
{
int status;
/* Find the requested DN component and return it to the caller */
status = selectDN( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
MUST_BE_PRESENT );
if( cryptStatusError( status ) )
return( status );
return( getDNComponentValue( *certInfoPtr->currentSelection.dnPtr,
certInfoType, certInfo, certInfoLength,
maxLength ) );
}
/* If it's standard cert or CMS attribute, return it */
if( ( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \
certInfoType <= CRYPT_CERTINFO_LAST_EXTENSION ) || \
( certInfoType >= CRYPT_CERTINFO_FIRST_CMS && \
certInfoType <= CRYPT_CERTINFO_LAST_CMS ) )
return( getCertAttributeComponent( certInfoPtr, certInfoType,
certInfo, certInfoLength ) );
/* If it's anything else, handle it specially */
switch( certInfoType )
{
case CRYPT_CERTINFO_SELFSIGNED:
*valuePtr = ( certInfoPtr->flags & CERT_FLAG_SELFSIGNED ) ? \
TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_CERTINFO_IMMUTABLE:
*valuePtr = ( certInfoPtr->certificate != NULL ) ? TRUE: FALSE;
return( CRYPT_OK );
case CRYPT_CERTINFO_XYZZY:
{
BYTE policyOID[ MAX_OID_SIZE ];
int policyOIDLength = MAX_OID_SIZE;
/* Check for the presence of the XYZZY policy OID */
if( cryptStatusOK( \
getCertAttributeComponent( certInfoPtr,
CRYPT_CERTINFO_CERTPOLICYID,
policyOID, &policyOIDLength ) ) && \
policyOIDLength == sizeofOID( OID_CRYPTLIB_XYZZYCERT ) && \
!memcmp( policyOID, OID_CRYPTLIB_XYZZYCERT, policyOIDLength ) )
*valuePtr = TRUE;
else
*valuePtr = FALSE;
return( CRYPT_OK );
}
case CRYPT_CERTINFO_CERTTYPE:
*valuePtr = certInfoPtr->type;
return( CRYPT_OK );
case CRYPT_CERTINFO_FINGERPRINT_MD5:
case CRYPT_CERTINFO_FINGERPRINT_SHA:
return( getCertHash( certInfoPtr, certInfoType, certInfo,
certInfoLength ) );
case CRYPT_CERTINFO_CURRENT_CERTIFICATE:
case CRYPT_CERTINFO_CURRENT_EXTENSION:
case CRYPT_CERTINFO_CURRENT_FIELD:
case CRYPT_CERTINFO_CURRENT_COMPONENT:
/* The current component and field are essentially the same
thing since a component is one of a set of entries in a
multivalued field, thus we only distinguish between
extensions and everything else */
if( certInfoPtr->attributeCursor == NULL )
return( CRYPT_ERROR_NOTINITED );
*valuePtr = ( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION ) ? \
certInfoPtr->attributeCursor->attributeID :
certInfoPtr->attributeCursor->fieldID;
return( CRYPT_OK );
case CRYPT_CERTINFO_TRUSTED_USAGE:
if( certInfoPtr->trustedUsage == CRYPT_ERROR )
return( CRYPT_ERROR_NOTFOUND );
*valuePtr = certInfoPtr->trustedUsage;
return( CRYPT_OK );
case CRYPT_CERTINFO_TRUSTED_IMPLICIT:
*valuePtr = cryptStatusOK( \
krnlSendMessage( certInfoPtr->ownerHandle,
IMESSAGE_SETATTRIBUTE,
&certInfoPtr->objectHandle,
CRYPT_IATTRIBUTE_CERT_CHECKTRUST ) ) ? \
TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_CERTINFO_SIGNATURELEVEL:
*valuePtr = certInfoPtr->signatureLevel;
return( CRYPT_OK );
case CRYPT_CERTINFO_VERSION:
*valuePtr = certInfoPtr->version;
return( CRYPT_OK );
case CRYPT_CERTINFO_SERIALNUMBER:
if( certInfoPtr->type == CRYPT_CERTTYPE_CRL )
{
const REVOCATION_INFO *revInfoPtr = \
( certInfoPtr->currentRevocation != NULL ) ? \
certInfoPtr->currentRevocation : certInfoPtr->revocations;
if( revInfoPtr != NULL )
{
data = revInfoPtr->dataPtr;
dataLength = revInfoPtr->dataLength;
}
}
else
{
data = certInfoPtr->serialNumber;
dataLength = certInfoPtr->serialNumberLength;
}
return( copyCertInfo( certInfo, certInfoLength, data,
dataLength ) );
case CRYPT_CERTINFO_ISSUERNAME:
*valuePtr = ( certInfoPtr->issuerName != NULL ) ? TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_CERTINFO_VALIDFROM:
case CRYPT_CERTINFO_THISUPDATE:
if( certInfoPtr->startTime > 0 )
{
data = &certInfoPtr->startTime;
dataLength = sizeof( time_t );
}
return( copyCertInfo( certInfo, certInfoLength, data,
dataLength ) );
case CRYPT_CERTINFO_VALIDTO:
case CRYPT_CERTINFO_NEXTUPDATE:
if( certInfoPtr->endTime > 0 )
{
data = &certInfoPtr->endTime;
dataLength = sizeof( time_t );
}
return( copyCertInfo( certInfo, certInfoLength, data,
dataLength ) );
case CRYPT_CERTINFO_SUBJECTNAME:
*valuePtr = ( certInfoPtr->subjectName != NULL ) ? TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_CERTINFO_ISSUERUNIQUEID:
return( copyCertInfo( certInfo, certInfoLength,
certInfoPtr->issuerUniqueID,
certInfoPtr->issuerUniqueIDlength ) );
case CRYPT_CERTINFO_SUBJECTUNIQUEID:
return( copyCertInfo( certInfo, certInfoLength,
certInfoPtr->subjectUniqueID,
certInfoPtr->subjectUniqueIDlength ) );
case CRYPT_CERTINFO_REVOCATIONDATE:
/* If there's a specific validity/revocation entry selected, get
its invalidity/revocation time, otherwise if there are
invalid/revoked certs present get the first cert's invalidity/
revocation time, otherwise get the default invalidity/
revocation time */
if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
data = ( certInfoPtr->currentValidity != NULL ) ? \
&certInfoPtr->currentValidity->invalidityTime : \
( certInfoPtr->validityInfo != NULL ) ? \
&certInfoPtr->validityInfo->invalidityTime : \
( certInfoPtr->revocationTime ) ? \
&certInfoPtr->revocationTime : NULL;
else
data = ( certInfoPtr->currentRevocation != NULL ) ? \
&certInfoPtr->currentRevocation->revocationTime : \
( certInfoPtr->revocations != NULL ) ? \
&certInfoPtr->revocations->revocationTime : \
( certInfoPtr->revocationTime ) ? \
&certInfoPtr->revocationTime : NULL;
if( data != NULL )
dataLength = sizeof( time_t );
return( copyCertInfo( certInfo, certInfoLength, data,
dataLength ) );
case CRYPT_CERTINFO_CERTSTATUS:
{
const VALIDITY_INFO *valInfoPtr = \
( certInfoPtr->currentValidity != NULL ) ? \
certInfoPtr->currentValidity : certInfoPtr->validityInfo;
if( valInfoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
*valuePtr = valInfoPtr->extStatus;
return( CRYPT_OK );
}
case CRYPT_CERTINFO_REVOCATIONSTATUS:
{
const REVOCATION_INFO *revInfoPtr = \
( certInfoPtr->currentRevocation != NULL ) ? \
certInfoPtr->currentRevocation : certInfoPtr->revocations;
if( revInfoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
*valuePtr = revInfoPtr->status;
return( CRYPT_OK );
}
case CRYPT_CERTINFO_DN:
{
STREAM stream;
int status;
/* Export the entire DN in string form */
status = selectDN( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
MUST_BE_PRESENT );
if( cryptStatusError( status ) )
return( status );
sMemOpen( &stream, certInfo, *certInfoLength );
status = writeDNstring( &stream,
*certInfoPtr->currentSelection.dnPtr );
if( cryptStatusOK( status ) )
*certInfoLength = stell( &stream );
sMemDisconnect( &stream );
return( status );
}
case CRYPT_CERTINFO_PKIUSER_ID:
case CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD:
case CRYPT_CERTINFO_PKIUSER_REVPASSWORD:
return( getPkiUserInfo( certInfoPtr, certInfoType, certInfo,
certInfoLength ) );
case CRYPT_IATTRIBUTE_CRLENTRY:
return( getCrlEntry( certInfoPtr, certInfo, certInfoLength ) );
case CRYPT_IATTRIBUTE_SUBJECT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -