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

📄 certwr.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
	{
	RESOURCE_DATA msgData;
	int payloadLength, pubKeyDataSize, extensionSize, status;
	int subjectDNsize = 0, timeSize = 0;

	assert( issuerCertInfoPtr == NULL );

	/* Make sure everything is in order */
	if( sIsNullStream( stream ) )
		{
		status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
									   CRYPT_CERTTYPE_REQUEST_CERT );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Determine how big the encoded certificate request will be */
	setResourceData( &msgData, NULL, 0 );
	status = krnlSendMessage( subjectCertInfoPtr->iCryptContext, 
							  RESOURCE_IMESSAGE_GETATTRIBUTE_S,
							  &msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
	if( cryptStatusError( status ) )
		return( status );
	pubKeyDataSize = msgData.length;
	if( subjectCertInfoPtr->subjectName != NULL )
		subjectCertInfoPtr->subjectDNsize = subjectDNsize = \
								sizeofDN( subjectCertInfoPtr->subjectName );
	if( subjectCertInfoPtr->startTime )
		timeSize = ( int ) sizeofObject( sizeofGeneralizedTime() );
	if( subjectCertInfoPtr->endTime )
		timeSize += ( int ) sizeofObject( sizeofGeneralizedTime() );
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	payloadLength = ( timeSize ? ( int ) sizeofObject( timeSize ) : 0 ) + \
					( subjectDNsize ? ( int ) sizeofObject( subjectDNsize ) : 0 ) + \
					pubKeyDataSize;
	if( extensionSize )
		payloadLength += ( int ) sizeofObject( extensionSize );

	/* Write the header, request ID, inner header, DN, and public key */
	writeSequence( stream, sizeofShortInteger( 0 ) + \
				   sizeofObject( payloadLength ) );
	writeShortInteger( stream, 0, DEFAULT_TAG );
	writeSequence( stream, payloadLength );
	if( timeSize )
		{
		writeConstructed( stream, timeSize, CTAG_CF_VALIDITY );
		if( subjectCertInfoPtr->startTime )
			{
			writeConstructed( stream, sizeofGeneralizedTime(), 0 );
			writeGeneralizedTime( stream, subjectCertInfoPtr->startTime, 
								  DEFAULT_TAG );
			}
		if( subjectCertInfoPtr->endTime )
			{
			writeConstructed( stream, sizeofGeneralizedTime(), 1 );
			writeGeneralizedTime( stream, subjectCertInfoPtr->endTime, 
								  DEFAULT_TAG );
			}
		}
	if( subjectDNsize )
		{
		writeConstructed( stream, subjectCertInfoPtr->subjectDNsize, 
						  CTAG_CF_SUBJECT );
		writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
		}
	if( !sIsNullStream( stream ) )
		{
		BYTE *dataPtr = sMemBufPtr( stream );

		setResourceData( &msgData, dataPtr, pubKeyDataSize );
		status = krnlSendMessage( subjectCertInfoPtr->iCryptContext, 
								  RESOURCE_IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
		if( cryptStatusError( status ) )
			return( status );
		
		/* Convert the SPKI SEQUENCE tag to the CRMF alternative */
		*dataPtr = MAKE_CTAG( CTAG_CF_PUBLICKEY );
		}
	sSkip( stream, pubKeyDataSize );

	/* Write the attributes */
	if( extensionSize )
		{
		writeConstructed( stream, extensionSize, CTAG_CF_EXTENSIONS );
		writeAttributes( stream, subjectCertInfoPtr->attributes,
						 CRYPT_CERTTYPE_REQUEST_CERT, extensionSize );
		}

	return( sGetStatus( stream ) );
	}

/* Write CMP revocation request information:

	RevDetails ::= SEQUENCE {
		certTemplate			SEQUENCE {
			serialNumber  [ 1 ]	INTEGER,
			issuer		  [ 3 ]	EXPLICIT Name,
			},
		crlEntryDetails			SET OF Attribute
		} */

int writeRevRequestInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
						 const CERT_INFO *issuerCertInfoPtr,
						 const CRYPT_CONTEXT iIssuerCryptContext )
	{
	int payloadLength, extensionSize, status;

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

	/* Make sure everything is in order */
	if( sIsNullStream( stream ) )
		{
		status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
									   CRYPT_CERTTYPE_REQUEST_REVOCATION );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Determine how big the encoded certificate request will be */
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	payloadLength = sizeofInteger( subjectCertInfoPtr->serialNumber,
								   subjectCertInfoPtr->serialNumberLength ) + \
					sizeofObject( subjectCertInfoPtr->issuerDNsize ) + \
					( extensionSize ? ( int ) sizeofObject( extensionSize ) : 0 );

	/* Write the header, inner header, serial number and issuer DN */
	writeSequence( stream, sizeofObject( payloadLength ) );
	writeSequence( stream, payloadLength );
	writeInteger( stream, subjectCertInfoPtr->serialNumber,
				  subjectCertInfoPtr->serialNumberLength,
				  CTAG_CF_SERIALNUMBER );
	writeConstructed( stream, subjectCertInfoPtr->issuerDNsize, 
					  CTAG_CF_ISSUER );
	swrite( stream, subjectCertInfoPtr->issuerDNptr,
			subjectCertInfoPtr->issuerDNsize );
	if( cryptStatusError( status ) )
		return( status );

	/* Write the attributes */
	if( extensionSize )
		{
		writeConstructed( stream, extensionSize, CTAG_CF_EXTENSIONS );
		writeAttributes( stream, subjectCertInfoPtr->attributes,
						 CRYPT_CERTTYPE_REQUEST_REVOCATION, extensionSize );
		}

	return( sGetStatus( stream ) );
	}

/* Write CRL information:

	CRLInfo ::= SEQUENCE {
		version					INTEGER DEFAULT(0),
		signature				AlgorithmIdentifier,
		issuer					Name,
		thisUpdate				UTCTime,
		nextUpdate				UTCTime OPTIONAL,
		revokedCertificates		SEQUENCE OF RevokedCerts,
		extensions		  [ 0 ]	Extensions OPTIONAL
		} */

int writeCRLInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
				  const CERT_INFO *issuerCertInfoPtr,
				  const CRYPT_CONTEXT iIssuerCryptContext )
	{
	REVOCATION_INFO *revocationInfo;
	int length, extensionSize, revocationInfoLength = 0, status;

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

	/* Determine how big the encoded CRL will be */
	subjectCertInfoPtr->version = \
					( subjectCertInfoPtr->attributes != NULL ) ? 2 : 1;
	for( revocationInfo = subjectCertInfoPtr->revocations;
		 revocationInfo != NULL; revocationInfo = revocationInfo->next )
		{
		if( revocationInfo->attributes != NULL )
			/* If there are per-entry extensions present it's a v2 CRL */
			subjectCertInfoPtr->version = 2;
		revocationInfoLength += sizeofCRLentry( revocationInfo );
		}
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	length = ( extensionSize ? sizeofShortInteger( X509VERSION_2 ) : 0 ) +
			 sizeofContextAlgoID( iIssuerCryptContext, CRYPT_ALGO_SHA,
								  ALGOID_FLAG_ALGOID_ONLY ) +
			 issuerCertInfoPtr->subjectDNsize + sizeofUTCTime() +
			 ( subjectCertInfoPtr->endTime ? sizeofUTCTime() : 0 ) +
			 ( int ) sizeofObject( revocationInfoLength ) +
			 ( extensionSize ? \
			   ( int ) sizeofObject( sizeofObject( extensionSize ) ) : 0 );

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

	/* If there are extensions present, mark this as a v2 CRL */
	if( extensionSize )
		writeShortInteger( stream, X509VERSION_2, DEFAULT_TAG );

	/* Write the signature algorithm identifier, issuer name, and CRL time */
	status = writeContextAlgoID( stream, iIssuerCryptContext, CRYPT_ALGO_SHA,
								 ALGOID_FLAG_ALGOID_ONLY );
	if( cryptStatusError( status ) )
		return( status );
	swrite( stream, issuerCertInfoPtr->subjectDNptr,
			issuerCertInfoPtr->subjectDNsize );
	writeUTCTime( stream, subjectCertInfoPtr->startTime, DEFAULT_TAG );
	if( subjectCertInfoPtr->endTime )
		writeUTCTime( stream, subjectCertInfoPtr->endTime, DEFAULT_TAG );

	/* Write the SEQUENCE OF revoked certificates wrapper and the revoked
	   certificate information */
	writeSequence( stream, revocationInfoLength );
	for( revocationInfo = subjectCertInfoPtr->revocations;
		 revocationInfo != NULL; revocationInfo = revocationInfo->next )
		writeCRLentry( stream, revocationInfo );

	/* Write the extensions if necessary */
	if( extensionSize )
		writeAttributes( stream, subjectCertInfoPtr->attributes,
						 CRYPT_CERTTYPE_CRL, extensionSize );

	return( sGetStatus( stream ) );
	}

/* 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	-- Cert hash
			} 
		} */

int writeOCSPRequestInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
						  const CERT_INFO *issuerCertInfoPtr,
						  const CRYPT_CONTEXT iIssuerCryptContext )
	{
	REVOCATION_INFO *revocationInfo;
	int length, extensionSize, revocationInfoLength = 0, status;

	/* Make sure we've actually got some requests present to write */
	if( subjectCertInfoPtr->revocations == NULL )
		{
		setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_USERCERTIFICATE,
					  CRYPT_ERRTYPE_ATTR_ABSENT );
		return( CRYPT_ERROR_NOTINITED );
		}

	/* 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;
		BYTE nonce[ CRYPT_MAX_HASHSIZE ];

		/* 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 we can meaningfully do if the add fails */
		attributeListPtr = findAttributeField( subjectCertInfoPtr->attributes,
											   CRYPT_CERTINFO_OCSP_NONCE,
											   CRYPT_ATTRIBUTE_NONE );
		if( attributeListPtr != NULL )
			deleteAttributeField( &subjectCertInfoPtr->attributes,
								  &subjectCertInfoPtr->attributeCursor, 
								  attributeListPtr );
		getNonce( nonce, 16 );
		addAttributeField( &subjectCertInfoPtr->attributes, 
						   CRYPT_CERTINFO_OCSP_NONCE, CRYPT_ATTRIBUTE_NONE, 
						   nonce, 16, ATTR_FLAG_NONE, NULL, NULL );

		/* Perform the pre-encoding checks */
		status = preEncodeCertificate( subjectCertInfoPtr, NULL,
									   CRYPT_CERTTYPE_OCSP_REQUEST );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Determine how big the encoded OCSP request will be */
	for( revocationInfo = subjectCertInfoPtr->revocations;
		 revocationInfo != NULL; revocationInfo = revocationInfo->next )
		revocationInfoLength += sizeofOCSPentry( revocationInfo, TRUE );
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	length = ( ( subjectCertInfoPtr->version == 2 ) ? \
				( int ) sizeofObject( sizeofShortInteger( CTAG_OR_VERSION ) ) : 0 ) +
			 ( ( issuerCertInfoPtr != NULL ) ? \
				( int ) sizeofObject( sizeofObject( issuerCertInfoPtr->subjectDNsize ) ) : 0 ) +
			 ( int ) sizeofObject( revocationInfoLength ) +
			 ( extensionSize ? \
			   ( int ) 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 */
	writeSequence( stream, revocationInfoLength );
	for( revocationInfo = subjectCertInfoPtr->revocations;
		 revocationInfo != NULL; revocationInfo = revocationInfo->next )
		writeOCSPentry( stream, revocationInfo, 0, TRUE );

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

/* 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,
		} */

int writeOCSPResponseInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
						   const CERT_INFO *issuerCertInfoPtr,
						   const CRYPT_CONTEXT iIssuerCryptContext )
	{
	REVOCATION_INFO *revocationInfo;
	int length, extensionSize, revocationInfoLength = 0, status;

	/* Make sure we've actually got some requests present to write */
	if( subjectCertInfoPtr->revocations == NULL )
		{
		setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_USERCERTIFICATE,
					  CRYPT_ERRTYPE_ATTR_ABSENT );
		return( CRYPT_ERROR_NOTINITED );
		}

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

	/* Determine how big the encoded OCSP response will be */
	for( revocationInfo = subjectCertInfoPtr->revocations;
		 revocationInfo != NULL; revocationInfo = revocationInfo->next )
		revocationInfoLength += sizeofOCSPentry( revocationInfo, FALSE );
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	length = ( int ) sizeofObject( sizeofShortInteger( CTAG_OP_VERSION ) ) +
			 ( int ) sizeofObject( issuerCertInfoPtr->subjectDNsize ) +
			 sizeofGeneralizedTime() +
			 ( int ) sizeofObject( revocationInfoLength ) +
			 ( extensionSize ? \
			   ( int ) sizeofObject( sizeofObject( extensionSize ) ) : 0 );

	/* Write the outer SEQUENCE wrapper, mark this as a v2 response, and
	   write the issuer DN and producedAt time */
	writeSequence( stream, length );
	writeConstructed( stream, sizeofShortInteger( 1 ), CTAG_OP_VERSION );
	writeShortInteger( stream, 1, DEFAULT_TAG );
	writeConstructed( stream, issuerCertInfoPtr->subjectDNsize, 1 );
	swrite( stream, issuerCertInfoPtr->subjectDNptr,
			issuerCertInfoPtr->subjectDNsize );
	writeGeneralizedTime( stream, subjectCertInfoPtr->startTime, 
						  DEFAULT_TAG );

	/* Write the SEQUENCE OF revocation information wrapper and the 
	   revocation information */
	writeSequence( stream, revocationInfoLength );
	for( revocationInfo = subjectCertInfoPtr->revocations;
		 revocationInfo != NULL; revocationInfo = revocationInfo->next )
		writeOCSPentry( stream, revocationInfo, 
						subjectCertInfoPtr->startTime, FALSE );

	/* Write the attributes if necessary */
	if( extensionSize )
		writeAttributes( stream, subjectCertInfoPtr->attributes,
						 CRYPT_CERTTYPE_OCSP_RESPONSE, extensionSize );
		
	return( sGetStatus( stream ) );
	}

⌨️ 快捷键说明

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