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 + -
显示快捷键?