certrd.c
来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 1,383 行 · 第 1/4 页
C
1,383 行
certInfoPtr->subjectDNsize;
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_SUBJECTNAME,
status ) );
return( CRYPT_OK );
}
static int readIssuerDN( STREAM *stream, CERT_INFO *certInfoPtr )
{
int status;
certInfoPtr->issuerDNptr = sMemBufPtr( stream );
certInfoPtr->issuerDNsize = ( int ) stell( stream );
status = readDN( stream, &certInfoPtr->issuerName );
certInfoPtr->issuerDNsize = ( int ) stell( stream ) - \
certInfoPtr->issuerDNsize;
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_ISSUERNAME,
status ) );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Read a Certificate Object *
* *
****************************************************************************/
/* Read the information in a certificate */
int readCertInfo( STREAM *stream, CERT_INFO *certInfoPtr )
{
int length, endPos, status;
/* Read the outer SEQUENCE and version number if it's present (these have
already been checked earlier on) */
readSequence( stream, &length );
endPos = ( int ) stell( stream ) + length;
if( peekTag( stream ) == MAKE_CTAG( CTAG_CE_VERSION ) )
{
long version;
readConstructed( stream, NULL, CTAG_CE_VERSION );
readShortInteger( stream, &version );
certInfoPtr->version = version + 1; /* Zero-based */
}
else
certInfoPtr->version = 1;
/* Read the serial number */
status = readSerialNumber( stream, &certInfoPtr->serialNumber,
&certInfoPtr->serialNumberLength, DEFAULT_TAG );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_SERIALNUMBER,
status ) );
/* Skip the signature algorithm information. This was included to avert
a somewhat obscure attack which isn't possible anyway because of the
way the signature data is encoded in PKCS #1 sigs (although it's still
possible for some of the ISO sig.types) so there's no need to record
it */
readUniversal( stream );
/* Read the issuer name, validity information, and subject name. We also
remember the position of the encoded subject name as an encoded blob
so we can copy it (complete with any encoding errors) to the issuer DN
field of any certs we sign */
status = readIssuerDN( stream, certInfoPtr );
if( cryptStatusError( status ) )
return( status );
status = readValidity( stream, &certInfoPtr->startTime,
&certInfoPtr->endTime, &certInfoPtr->errorLocus );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, certInfoPtr->errorLocus, status ) );
status = readSubjectDN( stream, certInfoPtr );
if( cryptStatusError( status ) )
return( status );
/* Check to see whether it's a self-signed cert */
if( certInfoPtr->issuerDNsize == certInfoPtr->subjectDNsize && \
!memcmp( certInfoPtr->issuerDNptr, certInfoPtr->subjectDNptr,
certInfoPtr->subjectDNsize ) )
certInfoPtr->flags |= CERT_FLAG_SELFSIGNED;
/* Read the public key information */
certInfoPtr->publicKeyInfo = sMemBufPtr( stream );
if( certInfoPtr->flags & CERT_FLAG_DATAONLY )
/* We're doing deferred handling of the public key, skip it for now */
status = readUniversal( stream );
else
status = readPublicKey( stream, &certInfoPtr->iCryptContext,
READKEY_OPTION_NONE, DEFAULT_TAG );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO,
status ) );
/* Read the issuer and subject unique ID's if there are any present */
if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( CTAG_CE_ISSUERUNIQUEID ) )
{
status = readUniqueID( stream, &certInfoPtr->issuerUniqueID,
&certInfoPtr->issuerUniqueIDlength );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_ISSUERUNIQUEID,
status ) );
}
if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( CTAG_CE_SUBJECTUNIQUEID ) )
{
status = readUniqueID( stream, &certInfoPtr->subjectUniqueID,
&certInfoPtr->subjectUniqueIDlength );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_SUBJECTUNIQUEID,
status ) );
}
/* Read the extensions if there are any present. Because some certs will
have broken encoding of lengths, we allow for a bit of slop for
software which gets the length encoding wrong by a few bytes */
if( stell( stream ) <= endPos - MIN_ATTRIBUTE_SIZE )
status = readAttributes( stream, &certInfoPtr->attributes,
CRYPT_CERTTYPE_CERTIFICATE, endPos - stell( stream ),
&certInfoPtr->errorLocus, &certInfoPtr->errorType );
/* Convert an email address in a DN into an altName if required */
if( cryptStatusOK( status ) )
{
int fixEmailAddress;
krnlSendMessage( certInfoPtr->ownerHandle,
RESOURCE_IMESSAGE_GETATTRIBUTE, &fixEmailAddress,
CRYPT_OPTION_CERT_FIXEMAILADDRESS );
if( fixEmailAddress )
status = convertEmailAddress( certInfoPtr );
}
return( status );
}
/* Read the information in an attribute certificate */
int readAttributeCertInfo( STREAM *stream, CERT_INFO *certInfoPtr )
{
int length, endPos, status;
/* Read the outer SEQUENCE and version number if it's present (these have
already been checked earlier on) */
readSequence( stream, &length );
endPos = ( int ) stell( stream ) + length;
if( peekTag( stream ) == BER_INTEGER )
readUniversal( stream );
/* Read the subject and issuer names */
if( peekTag( stream ) == MAKE_CTAG( CTAG_AC_BASECERTIFICATEID ) )
{
/* !!!!!!!!!!!! */
return( CRYPT_ERROR ); /* Not handled yet */
}
if( peekTag( stream ) == MAKE_CTAG( CTAG_AC_ENTITYNAME ) )
{
readConstructed( stream, NULL, CTAG_AC_ENTITYNAME );
status = readSubjectDN( stream, certInfoPtr );
if( cryptStatusError( status ) )
return( status );
}
status = readIssuerDN( stream, certInfoPtr );
if( cryptStatusError( status ) )
return( status );
/* Skip the signature algorithm information. This was included to avert
a somewhat obscure attack which isn't possible anyway because of the
way the signature data is encoded in PKCS #1 sigs (although it's still
possible for some of the ISO sig.types) so there's no need to record
it */
readUniversal( stream );
/* Read the serial number */
status = readSerialNumber( stream, &certInfoPtr->serialNumber,
&certInfoPtr->serialNumberLength, DEFAULT_TAG );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_SERIALNUMBER,
status ) );
/* Read the validity information */
status = readValidity( stream, &certInfoPtr->startTime,
&certInfoPtr->endTime, &certInfoPtr->errorLocus );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, certInfoPtr->errorLocus, status ) );
/* Skip the attributes for now since these aren't really defined yet */
readUniversal( stream );
/* Read the issuer unique ID if there's one present */
if( peekTag( stream ) == BER_BITSTRING )
{
status = readUniqueID( stream, &certInfoPtr->issuerUniqueID,
&certInfoPtr->issuerUniqueIDlength );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_ISSUERUNIQUEID,
status ) );
}
/* Read the extensions if there are any present. Because some certs will
have broken encoding of lengths, we allow for a bit of slop for
software which gets the length encoding wrong by a few bytes */
if( stell( stream ) <= endPos - MIN_ATTRIBUTE_SIZE )
status = readAttributes( stream, &certInfoPtr->attributes,
CRYPT_CERTTYPE_ATTRIBUTE_CERT, endPos - stell( stream ),
&certInfoPtr->errorLocus, &certInfoPtr->errorType );
return( status );
}
/* Read the information in a CRL:
CRLInfo ::= SEQUENCE {
version INTEGER DEFAULT(0),
signature AlgorithmIdentifier,
issuer Name,
thisUpdate UTCTime,
nextUpdate UTCTime OPTIONAL,
revokedCertificates SEQUENCE OF RevokedCerts,
extensions [ 0 ] Extensions OPTIONAL
} */
int readCRLInfo( STREAM *stream, CERT_INFO *certInfoPtr )
{
int length, endPos, status;
/* Read the outer SEQUENCE and version number if it's present (these have
already been checked earlier on) */
readSequence( stream, &length );
endPos = ( int ) stell( stream ) + length;
if( peekTag( stream ) == BER_INTEGER )
{
long version;
readShortInteger( stream, &version );
certInfoPtr->version = version + 1; /* Zero-based */
}
else
certInfoPtr->version = 1;
/* Skip the signature algorithm information. This was included to avert
a somewhat obscure attack which isn't possible anyway because of the
way the signature data is encoded in PKCS #1 sigs (although it's still
possible for some of the ISO sig.types) so there's no need to record
it */
readUniversal( stream );
/* Read the issuer name, update time, and optional next update time */
status = readIssuerDN( stream, certInfoPtr );
if( cryptStatusError( status ) )
return( status );
status = readUTCTime( stream, &certInfoPtr->startTime );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_THISUPDATE,
status ) );
if( peekTag( stream ) == BER_TIME_UTC )
{
status = readUTCTime( stream, &certInfoPtr->endTime );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_NEXTUPDATE,
status ) );
}
/* Read the SEQUENCE OF revoked certs and make the currently selected one
the start of the list */
status = readSequence( stream, &length );
while( !cryptStatusError( status ) && length > 16 )
{
const int innerStartPos = ( int ) stell( stream );
status = readCRLentry( stream, &certInfoPtr->revocations, certInfoPtr );
length -= ( int ) stell( stream ) - innerStartPos;
}
if( cryptStatusError( status ) )
/* The invalid attribute isn't quite a user certificate, but it's the
data which arose from a user certificate so it's the most
appropriate locus for the error */
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_USERCERTIFICATE,
status ) );
certInfoPtr->currentRevocation = certInfoPtr->revocations;
/* Read the extensions if there are any present. Because some CRL's will
have broken encoding of lengths, we allow for a bit of slop for
software which gets the length encoding wrong by a few bytes */
if( stell( stream ) <= endPos - MIN_ATTRIBUTE_SIZE )
status = readAttributes( stream, &certInfoPtr->attributes,
CRYPT_CERTTYPE_CRL, endPos - stell( stream ),
&certInfoPtr->errorLocus, &certInfoPtr->errorType );
/* Convert an email address in a DN into an altName if required */
if( cryptStatusOK( status ) )
{
int fixEmailAddress;
krnlSendMessage( certInfoPtr->ownerHandle,
RESOURCE_IMESSAGE_GETATTRIBUTE, &fixEmailAddress,
CRYPT_OPTION_CERT_FIXEMAILADDRESS );
if( fixEmailAddress )
status = convertEmailAddress( certInfoPtr );
}
return( status );
}
/* Read the information in a certification request */
int readCertRequestInfo( STREAM *stream, CERT_INFO *certInfoPtr )
{
int status;
/* Skip the outer SEQUENCE and version number if it's present (these have
already been checked earlier on) */
readSequence( stream, NULL );
readUniversal( stream );
/* Read the subject name and public key information */
status = readSubjectDN( stream, certInfoPtr );
if( cryptStatusError( status ) )
return( status );
certInfoPtr->publicKeyInfo = sMemBufPtr( stream );
if( certInfoPtr->flags & CERT_FLAG_DATAONLY )
/* We're doing deferred handling of the public key, skip it for now */
readUniversal( stream );
else
status = readPublicKey( stream, &certInfoPtr->iCryptContext,
READKEY_OPTION_NONE, DEFAULT_TAG );
if( cryptStatusError( status ) )
return( certErrorReturn( certInfoPtr, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO,
status ) );
/* Read the attributes */
if( peekTag( stream ) == MAKE_CTAG( CTAG_CR_ATTRIBUTES ) )
{
int length;
status = readConstructed( stream, &length, CTAG_CR_ATTRIBUTES );
if( cryptStatusOK( status ) && length >= MIN_ATTRIBUTE_SIZE )
status = readAttributes( stream, &certInfoPtr->attributes,
CRYPT_CERTTYPE_CERTREQUEST, length,
&certInfoPtr->errorLocus, &certInfoPtr->errorType );
}
/* Convert an email address in a DN into an altName if required */
if( cryptStatusOK( status ) )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?