⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 write.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
		
		if( cryptStatusError( requestEntrySize ) )
			return( requestEntrySize );
		requestInfoLength += requestEntrySize;
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	if( cryptStatusError( extensionSize ) )
		return( extensionSize );
	length = sizeofObject( requestInfoLength ) + \
			 ( ( extensionSize > 0 ) ? sizeofObject( extensionSize ) : 0 );

	/* Write the outer SEQUENCE wrapper */
	writeSequence( stream, length );

	/* Write the SEQUENCE OF request wrapper and the request information */
	status = writeSequence( stream, requestInfoLength );
	for( validityInfo = certValInfo->validityInfo, iterationCount = 0;
		 cryptStatusOK( status ) && validityInfo != NULL && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE; 
		 validityInfo = validityInfo->next, iterationCount++ )
		{
		status = writeRtcsRequestEntry( stream, validityInfo );
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	if( cryptStatusError( status ) || extensionSize <= 0 )
		return( status );

	/* Write the attributes */
	return( writeAttributes( stream, subjectCertInfoPtr->attributes,
							 CRYPT_CERTTYPE_RTCS_REQUEST, extensionSize ) );
	}

/* Write an RTCS response:

	RTCSResponse ::= SEQUENCE {
		SEQUENCE OF SEQUENCE {
			certHash	OCTET STRING SIZE(20),
			RESPONSEINFO
			}
		} */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeRtcsResponseInfo( INOUT STREAM *stream,
								  INOUT CERT_INFO *subjectCertInfoPtr,
								  STDC_UNUSED const CERT_INFO *issuerCertInfoPtr,
								  STDC_UNUSED \
									const CRYPT_CONTEXT iIssuerCryptContext )
	{
	CERT_VAL_INFO *certValInfo = subjectCertInfoPtr->cCertVal;
	VALIDITY_INFO *validityInfo;
	int length = 0, extensionSize, validityInfoLength = 0;
	int iterationCount, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );

	REQUIRES( issuerCertInfoPtr == NULL );
	REQUIRES( iIssuerCryptContext == CRYPT_UNUSED );

	/* RTCS can legitimately return an empty response if there's a problem
	   with the responder so we don't require that any responses be present
	   as for CRLs/OCSP */

	/* Perform any necessary pre-encoding steps */
	if( sIsNullStream( stream ) )
		{
		status = preEncodeCertificate( subjectCertInfoPtr, NULL,
									   PRE_SET_VALINFO, PRE_CHECK_NONE,
									   PRE_FLAG_NONE );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Determine how big the encoded RTCS response will be */
	for( validityInfo = certValInfo->validityInfo, iterationCount = 0;
		 validityInfo != NULL && iterationCount < FAILSAFE_ITERATIONS_LARGE; 
		 validityInfo = validityInfo->next, iterationCount++ )
		{
		const int responseEntrySize = \
			sizeofRtcsResponseEntry( validityInfo,
					certValInfo->responseType == RTCSRESPONSE_TYPE_EXTENDED );

		if( cryptStatusError( responseEntrySize ) )
			return( responseEntrySize );
		validityInfoLength += responseEntrySize;
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	if( cryptStatusError( extensionSize ) )
		return( extensionSize );
	length += sizeofObject( validityInfoLength ) + \
			  ( ( extensionSize > 0 ) ? sizeofObject( extensionSize ) : 0 );

	/* Write the SEQUENCE OF status information wrapper and the certificate 
	   status information */
	status = writeSequence( stream, validityInfoLength );
	for( validityInfo = certValInfo->validityInfo, iterationCount = 0;
		 cryptStatusOK( status ) && validityInfo != NULL && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE; 
		 validityInfo = validityInfo->next, iterationCount++ )
		{
		status = writeRtcsResponseEntry( stream, validityInfo,
					certValInfo->responseType == RTCSRESPONSE_TYPE_EXTENDED );
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	if( cryptStatusError( status ) || extensionSize <= 0 )
		return( status );

	/* Write the attributes */
	return( writeAttributes( stream, subjectCertInfoPtr->attributes,
							 CRYPT_CERTTYPE_RTCS_RESPONSE, extensionSize ) );
	}

/* Write an OCSP request:

	OCSPRequest ::= SEQUENCE {				-- Write, v1
		reqName		[1]	EXPLICIT [4] EXPLICIT DirectoryName OPTIONAL,
		reqList			SEQUENCE OF SEQUENCE {
						SEQUENCE {			-- certID
			hashAlgo	AlgorithmIdentifier,
			iNameHash	OCTET STRING,
			iKeyHash	OCTET STRING,
			serialNo	INTEGER
			} }
		}

	OCSPRequest ::= SEQUENCE {				-- Write, v2
		version		[0]	EXPLICIT INTEGER (1),
		reqName		[1]	EXPLICIT [4] EXPLICIT DirectoryName OPTIONAL,
		reqList			SEQUENCE OF SEQUENCE {
			certID	[2]	EXPLICIT OCTET STRING	-- Certificate hash
			}
		} */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeOcspRequestInfo( INOUT STREAM *stream, 
								 INOUT CERT_INFO *subjectCertInfoPtr,
								 IN_OPT const CERT_INFO *issuerCertInfoPtr,
								 IN_HANDLE_OPT \
									const CRYPT_CONTEXT iIssuerCryptContext )
	{
	CERT_REV_INFO *certRevInfo = subjectCertInfoPtr->cCertRev;
	REVOCATION_INFO *revocationInfo;
	int length, extensionSize, revocationInfoLength = 0;
	int iterationCount, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );
	assert( issuerCertInfoPtr == NULL || \
			isReadPtr( issuerCertInfoPtr, sizeof( CERT_INFO ) ) );

	REQUIRES( iIssuerCryptContext == CRYPT_UNUSED || \
			  isHandleRangeValid( iIssuerCryptContext ) );/* Not used here */

	/* Perform any necessary pre-encoding steps.  We should really update the
	   nonce when we write the data for real, but to do that we'd have to re-
	   calculate the extension information (via preEncodeCertifiate()) for
	   null-stream and real writes just because the one extension changes so
	   we calculate it when we do the dummy write instead.  This is safe
	   because the write process always performs a real write immediately
	   after the null-stream write */
	if( sIsNullStream( stream ) )
		{
		ATTRIBUTE_LIST *attributeListPtr;
		MESSAGE_DATA msgData;

		/* To ensure freshness we always use a new nonce when we write an
		   OCSP request.  We don't check for problems (which in any case,
		   could only occur if there's an out-of-memory error) because
		   there's not much that we can meaningfully do if the add fails */
		attributeListPtr = findAttributeField( subjectCertInfoPtr->attributes,
											   CRYPT_CERTINFO_OCSP_NONCE,
											   CRYPT_ATTRIBUTE_NONE );
		if( attributeListPtr != NULL )
			{
			setMessageData( &msgData, attributeListPtr->value, 16 );
			status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
									  IMESSAGE_GETATTRIBUTE_S, &msgData,
									  CRYPT_IATTRIBUTE_RANDOM_NONCE );
			attributeListPtr->valueLength = 16;
			}
		else
			{
			CRYPT_ATTRIBUTE_TYPE dummy1;
			CRYPT_ERRTYPE_TYPE dummy2;
			BYTE nonce[ CRYPT_MAX_HASHSIZE + 8 ];

			setMessageData( &msgData, nonce, 16 );
			status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
									  IMESSAGE_GETATTRIBUTE_S, &msgData,
									  CRYPT_IATTRIBUTE_RANDOM_NONCE );
			if( cryptStatusOK( status ) )
				{
				status = addAttributeField( &subjectCertInfoPtr->attributes,
											CRYPT_CERTINFO_OCSP_NONCE,
											CRYPT_ATTRIBUTE_NONE, nonce, 16,
											ATTR_FLAG_NONE, &dummy1, &dummy2 );
				}
			attributeListPtr = findAttributeField( subjectCertInfoPtr->attributes,
												   CRYPT_CERTINFO_OCSP_NONCE,
												   CRYPT_ATTRIBUTE_NONE );
			}
		if( cryptStatusError( status ) )
			return( status );
		if( attributeListPtr != NULL )
			{
			BYTE *noncePtr = attributeListPtr->value;

			/* Because of OCSP's inexplicable use of integers to encode the
			   nonce octet string we have to tweak the first byte to ensure
			   that the integer encoding works as a standard OCTET STRING */
			noncePtr[ 0 ] &= 0x7F;
			if( noncePtr[ 0 ] == 0 )
				noncePtr[ 0 ]++;
			}

		/* Perform the pre-encoding checks */
		if( issuerCertInfoPtr != NULL )
			{
			/* It's a signed request, there has to be an issuer DN present */
			status = preEncodeCertificate( subjectCertInfoPtr, 
										   issuerCertInfoPtr, PRE_SET_REVINFO, 
										   PRE_CHECK_ISSUERDN | \
												PRE_CHECK_REVENTRIES,
										   PRE_FLAG_DN_IN_ISSUERCERT );
			}
		else
			{
			status = preEncodeCertificate( subjectCertInfoPtr, NULL,
										   PRE_SET_REVINFO,  
										   PRE_CHECK_REVENTRIES, 
										   PRE_FLAG_NONE );
			}
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Determine how big the encoded OCSP request will be */
	for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
		 revocationInfo != NULL && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE;
		 revocationInfo = revocationInfo->next, iterationCount++ )
		{
		const int requestEntrySize = sizeofOcspRequestEntry( revocationInfo );

		if( cryptStatusError( requestEntrySize ) )
			return( requestEntrySize );
		revocationInfoLength += requestEntrySize;
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	if( cryptStatusError( extensionSize ) )
		return( extensionSize );
	length = ( ( subjectCertInfoPtr->version == 2 ) ? \
				 sizeofObject( sizeofShortInteger( CTAG_OR_VERSION ) ) : 0 ) + \
			 ( ( issuerCertInfoPtr != NULL ) ? \
				 sizeofObject( sizeofObject( issuerCertInfoPtr->subjectDNsize ) ) : 0 ) + \
			 sizeofObject( revocationInfoLength ) + \
			 ( ( extensionSize > 0 ) ? \
			   sizeofObject( sizeofObject( extensionSize ) ) : 0 );

	/* Write the outer SEQUENCE wrapper */
	writeSequence( stream, length );

	/* If we're using v2 identifiers, mark this as a v2 request */
	if( subjectCertInfoPtr->version == 2 )
		{
		writeConstructed( stream, sizeofShortInteger( 1 ), CTAG_OR_VERSION );
		writeShortInteger( stream, 1, DEFAULT_TAG );
		}

	/* If we're signing the request, write the issuer DN as a GeneralName */
	if( issuerCertInfoPtr != NULL )
		{
		writeConstructed( stream,
						  sizeofObject( issuerCertInfoPtr->subjectDNsize ), 1 );
		writeConstructed( stream, issuerCertInfoPtr->subjectDNsize, 4 );
		swrite( stream, issuerCertInfoPtr->subjectDNptr,
				issuerCertInfoPtr->subjectDNsize );
		}

	/* Write the SEQUENCE OF revocation information wrapper and the
	   revocation information */
	status = writeSequence( stream, revocationInfoLength );
	for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
		 cryptStatusOK( status ) && revocationInfo != NULL && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE;
		 revocationInfo = revocationInfo->next, iterationCount++ )
		{
		status = writeOcspRequestEntry( stream, revocationInfo );
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	if( cryptStatusError( status ) || extensionSize <= 0 )
		return( status );

	/* Write the attributes */
	return( writeAttributes( stream, subjectCertInfoPtr->attributes,
							 CRYPT_CERTTYPE_OCSP_REQUEST, extensionSize ) );
	}

/* Write an OCSP response:

	OCSPResponse ::= SEQUENCE {
		version		[0]	EXPLICIT INTEGER (1),
		respID		[1]	EXPLICIT Name,
		producedAt		GeneralizedTime,
		responses		SEQUENCE OF Response
		exts		[1]	EXPLICIT Extensions OPTIONAL,
		} */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
static int writeOcspResponseInfo( INOUT STREAM *stream,
								  INOUT CERT_INFO *subjectCertInfoPtr,
								  const CERT_INFO *issuerCertInfoPtr,
								  IN_HANDLE \
									const CRYPT_CONTEXT iIssuerCryptContext )
	{
	CERT_REV_INFO *certRevInfo = subjectCertInfoPtr->cCertRev;
	REVOCATION_INFO *revocationInfo;
	int length = 0, extensionSize, revocationInfoLength = 0;
	int iterationCount, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );
	assert( isReadPtr( issuerCertInfoPtr, sizeof( CERT_INFO ) ) );

	REQUIRES( isHandleRangeValid( iIssuerCryptContext ) );/* Not used here */

	/* Perform any necessary pre-encoding steps */
	if( sIsNullStream( stream ) )
		{
		status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
									   PRE_SET_NONE, 
									   PRE_CHECK_ISSUERDN | \
											PRE_CHECK_REVENTRIES,
									   PRE_FLAG_DN_IN_ISSUERCERT );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Determine how big the encoded OCSP response will be */
	for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
		 revocationInfo != NULL && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE; 
		 revocationInfo = revocationInfo->next, iterationCount++ )
		{
		const int responseEntrySize = sizeofOcspResponseEntry( revocationInfo );

		if( cryptStatusError( responseEntrySize ) )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -