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

📄 certwr.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
		certID			CertID,
		extensions	[0]	EXPLICIT Extensions OPTIONAL
		}

	Entry ::= SEQUENCE {				-- Response
		certID			CertID,
		certStatus		CHOICE { [0] ..., [1] ..., [2] ... }, 
		thisUpdate		GeneralizedTime, 
		extensions	[1]	EXPLICIT Extensions OPTIONAL 
		} 

	CertID ::=	SEQUENCE {
		hashAlgo		AlgorithmIdentifier,
		iNameHash		OCTET STRING,	-- Hash of issuerName
		iKeyHash		OCTET STRING,	-- Hash of issuer SPKI w/o tag+len
		serialNo		INTEGER
					}
	or	iAndSerial	[0]	EXPLICIT IssuerAndSerialNumber
	or	certificate	[1]	EXPLICIT Certificate
	or	certHash	[2]	EXPLICIT OCTET STRING */

static int sizeofOCSPentry( REVOCATION_INFO *ocspEntry,
							const BOOLEAN isRequest )
	{
	const int idSize = ( ocspEntry->type == CRYPT_ATTRIBUTE_NONE ) ? \
					   ocspEntry->dataLength : \
					   ( int ) sizeofObject( sizeofObject( ocspEntry->dataLength ) );
	int certStatusSize = 0;

	/* Remember the encoded attribute size for later when we write the
	   attributes */
	ocspEntry->attributeSize = sizeofAttributes( ocspEntry->attributes );

	/* Determine the size of the cert status field */
	if( !isRequest )
		certStatusSize = ( ocspEntry->status != CRYPT_OCSPSTATUS_REVOKED ) ? \
						 sizeofNull() : ( int ) sizeofObject( sizeofGeneralizedTime() );

	return( ( int ) sizeofObject( idSize + \
						( isRequest ? 0 : sizeofGeneralizedTime() ) + \
						certStatusSize + \
						( ( ocspEntry->attributeSize ) ? \
							( int ) sizeofObject( ocspEntry->attributeSize ) : 0 ) ) );
	}

static int writeOCSPentry( STREAM *stream, const REVOCATION_INFO *ocspEntry,
						   const time_t entryTime, const BOOLEAN isRequest )
	{
	const int idSize = ( ocspEntry->type == CRYPT_ATTRIBUTE_NONE ) ? \
					   ocspEntry->dataLength : \
					   ( int ) sizeofObject( sizeofObject( ocspEntry->dataLength ) );
	int certStatusSize = 0;

	/* Determine the size of the cert status field */
	if( !isRequest )
		certStatusSize = ( ocspEntry->status != CRYPT_OCSPSTATUS_REVOKED ) ? \
						 sizeofNull() : ( int ) sizeofObject( sizeofGeneralizedTime() );

	/* Write the OCSP entry */
	writeSequence( stream, idSize + \
				   ( isRequest ? 0 : sizeofGeneralizedTime() ) + \
				   certStatusSize + \
				   ( ( ocspEntry->attributeSize ) ? \
						( int ) sizeofObject( ocspEntry->attributeSize ) : 0 ) );
	if( ocspEntry->type == CRYPT_ATTRIBUTE_NONE )
		swrite( stream, ocspEntry->data, ocspEntry->dataLength );
	else
		{
		writeConstructed( stream, sizeofObject( ocspEntry->dataLength ),
						  OCSP_IDTYPE_CERTHASH );
		writeOctetString( stream, ocspEntry->data, ocspEntry->dataLength, 
						  DEFAULT_TAG );
		}
	if( !isRequest )
		{
		/* Write the cert status */
		if( ocspEntry->status == CRYPT_OCSPSTATUS_REVOKED )
			{
			writeConstructed( stream, sizeofGeneralizedTime(), 
							  CRYPT_OCSPSTATUS_REVOKED );
			writeGeneralizedTime( stream, ocspEntry->revocationTime, 
								  DEFAULT_TAG );
			}
		else
			writeNull( stream, ocspEntry->status );

		/* Write the current update time (which should be the current time).
		   Since new status information is always available, we don't write
		   a nextUpdate time */
		writeGeneralizedTime( stream, entryTime, DEFAULT_TAG );
		}

	/* Write the per-entry extensions if necessary.  Since these are per-
	   entry extensions we write them as CRYPT_CERTTYPE_NONE rather than
	   CRYPT_CERTTYPE_OCSP to make sure they're processed as required */
	if( ocspEntry->attributeSize )
		writeAttributes( stream, ocspEntry->attributes, CRYPT_CERTTYPE_NONE,
						 ocspEntry->attributeSize );

	return( sGetStatus( stream ) );
	}

/****************************************************************************
*																			*
*							Write a Certificate Object						*
*																			*
****************************************************************************/

/* Write certificate information:

	CertificateInfo ::= SEQUENCE {
		version			  [ 0 ]	INTEGER DEFAULT(0),
		serialNumber			INTEGER,
		signature				AlgorithmIdentifier,
		issuer					Name
		validity				Validity,
		subject					Name,
		subjectPublicKeyInfo	SubjectPublicKeyInfo,
		extensions		  [ 3 ]	Extensions OPTIONAL
		}

   version is set to 2 if any extensions are present */

int writeCertInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
				   const CERT_INFO *issuerCertInfoPtr,
				   const CRYPT_CONTEXT iIssuerCryptContext )
	{
	RESOURCE_DATA msgData;
	int length, pubKeyDataSize, extensionSize, status;

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

	/* Determine how the issuer name will be encoded */
	subjectCertInfoPtr->issuerDNsize = \
							( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
							issuerCertInfoPtr->subjectDNsize : \
							sizeofDN( subjectCertInfoPtr->issuerName );
	subjectCertInfoPtr->subjectDNsize = \
								sizeofDN( subjectCertInfoPtr->subjectName );

	/* Determine the size of the certificate information */
	setResourceData( &msgData, NULL, 0 );
	status = krnlSendMessage( subjectCertInfoPtr->iCryptContext, 
							  RESOURCE_IMESSAGE_GETATTRIBUTE_S,
							  &msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
	if( cryptStatusError( status ) )
		return( status );
	pubKeyDataSize = msgData.length;
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	length = ( extensionSize ? ( int ) sizeofObject(
							sizeofShortInteger( X509VERSION_3 ) ) : 0 ) +
			 sizeofInteger( subjectCertInfoPtr->serialNumber,
							subjectCertInfoPtr->serialNumberLength ) +
			 sizeofContextAlgoID( iIssuerCryptContext, CRYPT_ALGO_SHA,
								  ALGOID_FLAG_ALGOID_ONLY ) +
			 subjectCertInfoPtr->issuerDNsize + 
			 ( int ) sizeofObject( sizeofUTCTime() * 2 ) +
			 subjectCertInfoPtr->subjectDNsize + pubKeyDataSize +
			 ( extensionSize ? \
				( int ) sizeofObject( sizeofObject( extensionSize ) ) : 0 );


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

	/* If there are extensions present, mark this as a v3 certificate */
	if( extensionSize )
		{
		writeCtag( stream, CTAG_CE_VERSION );
		writeLength( stream, sizeofShortInteger( X509VERSION_3 ) );
		writeShortInteger( stream, X509VERSION_3, DEFAULT_TAG );
		}

	/* Write the serial number and signature algorithm identifier */
	writeInteger( stream, subjectCertInfoPtr->serialNumber,
				  subjectCertInfoPtr->serialNumberLength, DEFAULT_TAG );
	status = writeContextAlgoID( stream, iIssuerCryptContext, CRYPT_ALGO_SHA,
								 ALGOID_FLAG_ALGOID_ONLY );
	if( cryptStatusError( status ) )
		return( status );

	/* Write the issuer name, validity period, and subject name */
	if( issuerCertInfoPtr->subjectDNptr != NULL )
		swrite( stream, issuerCertInfoPtr->subjectDNptr,
				issuerCertInfoPtr->subjectDNsize );
	else
		{
		status = writeDN( stream, subjectCertInfoPtr->issuerName, DEFAULT_TAG );
		if( cryptStatusError( status ) )
			return( status );
		}
	writeSequence( stream, sizeofUTCTime() * 2 );
	writeUTCTime( stream, subjectCertInfoPtr->startTime, DEFAULT_TAG );
	writeUTCTime( stream, subjectCertInfoPtr->endTime, DEFAULT_TAG );
	status = writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
	if( cryptStatusError( status ) )
		return( status );

	/* Write the public key information */
	if( !sIsNullStream( stream ) )
		{
		setResourceData( &msgData, sMemBufPtr( stream ), pubKeyDataSize );
		status = krnlSendMessage( subjectCertInfoPtr->iCryptContext, 
								  RESOURCE_IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
		if( cryptStatusError( status ) )
			return( status );
		}
	sSkip( stream, pubKeyDataSize );

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

	return( sGetStatus( stream ) );
	}

/* Write attribute certificate information:

	AttributeCertificateInfo ::= SEQUENCE {
		version					INTEGER DEFAULT(1),
		owner			  [ 1 ]	Name,
		issuer					Name,
		signature				AlgorithmIdentifier,
		serialNumber			INTEGER,
		validity				Validity,
		attributes				SEQUENCE OF Attribute,
		extensions				Extensions OPTIONAL
		} */

int writeAttributeCertInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
							const CERT_INFO *issuerCertInfoPtr,
							const CRYPT_CONTEXT iIssuerCryptContext )
	{
	int length, extensionSize, issuerNameSize, status;

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

	/* Determine how the issuer name will be encoded */
	issuerNameSize = ( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
					 issuerCertInfoPtr->subjectDNsize : \
					 sizeofDN( subjectCertInfoPtr->issuerName );

	/* Determine the size of the certificate information */
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	length = ( int ) sizeofObject( sizeofDN( subjectCertInfoPtr->subjectName ) ) +
			 issuerNameSize +
			 sizeofContextAlgoID( iIssuerCryptContext, CRYPT_ALGO_SHA,
								  ALGOID_FLAG_ALGOID_ONLY ) +
			 sizeofInteger( subjectCertInfoPtr->serialNumber,
							subjectCertInfoPtr->serialNumberLength ) +
			 ( int ) sizeofObject( sizeofUTCTime() * 2 ) +
			 ( int ) sizeofObject( 0 ) +
			 ( extensionSize ? ( int ) sizeofObject( extensionSize ) : 0 );

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

	/* Write the owner and issuer name */
	writeCtag( stream, CTAG_AC_ENTITYNAME );
	writeLength( stream, sizeofDN( subjectCertInfoPtr->subjectName ) );
	status = writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
	if( cryptStatusOK( status ) )
		{
		if( issuerCertInfoPtr->subjectDNptr != NULL )
			swrite( stream, issuerCertInfoPtr->subjectDNptr,
					issuerCertInfoPtr->subjectDNsize );
		else
			status = writeDN( stream, subjectCertInfoPtr->issuerName, DEFAULT_TAG );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Write the signature algorithm identifier, serial number and validity
	   period */
	writeContextAlgoID( stream, iIssuerCryptContext, CRYPT_ALGO_SHA,
						ALGOID_FLAG_ALGOID_ONLY );
	writeInteger( stream, subjectCertInfoPtr->serialNumber,
				  subjectCertInfoPtr->serialNumberLength, DEFAULT_TAG );
	writeSequence( stream, sizeofUTCTime() * 2 );
	writeUTCTime( stream, subjectCertInfoPtr->startTime, DEFAULT_TAG );
	writeUTCTime( stream, subjectCertInfoPtr->endTime, DEFAULT_TAG );

	/* Write the attributes */
	writeSequence( stream, 0 );

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

	return( sGetStatus( stream ) );
	}

/* Write certificate request information:

	CertificationRequestInfo ::= SEQUENCE {
		version					INTEGER (0),
		subject					Name,
		subjectPublicKeyInfo	SubjectPublicKeyInfo,
		attributes		  [ 0 ]	SET OF Attribute
		}

   Attributes are omitted if there are no extensions present and
   CRYPT_OPTION_CERT_PKCS10ALT is set to TRUE.  If extensions are present,
   they are encoded as:

	SEQUENCE {							-- Attribute from X.501
		OBJECT IDENTIFIER {pkcs-9 14},	--   type
		SET OF {						--   values
			SEQUENCE OF {				-- ExtensionReq from CMMF draft
				<X.509v3 extensions>
				}
			}
		}

   as per the CMMF draft */

int writeCertRequestInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
						  const CERT_INFO *issuerCertInfoPtr,
						  const CRYPT_CONTEXT iIssuerCryptContext )
	{
	RESOURCE_DATA msgData;
	int useAltEncoding, length, pubKeyDataSize, extensionSize, status;

	assert( issuerCertInfoPtr == NULL );

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

	/* Determine how big the encoded certificate request will be */
	krnlSendMessage( subjectCertInfoPtr->ownerHandle, 
					 RESOURCE_IMESSAGE_GETATTRIBUTE, &useAltEncoding, 
					 CRYPT_OPTION_CERT_PKCS10ALT );
	setResourceData( &msgData, NULL, 0 );
	status = krnlSendMessage( subjectCertInfoPtr->iCryptContext, 
							  RESOURCE_IMESSAGE_GETATTRIBUTE_S,
							  &msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
	if( cryptStatusError( status ) )
		return( status );
	pubKeyDataSize = msgData.length;
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	length = sizeofShortInteger( 0 ) +
			 sizeofDN( subjectCertInfoPtr->subjectName ) + pubKeyDataSize;
	if( extensionSize )
		length += ( int ) sizeofObject( sizeofObject( 11 +	/* PKCS #9 OID size */
					( int ) sizeofObject( sizeofObject( extensionSize ) ) ) );
	else
		if( !useAltEncoding )
			length += ( int ) sizeofObject( 0 );

	/* Write the header, version number, DN, and public key */
	writeSequence( stream, length );
	writeShortInteger( stream, 0, DEFAULT_TAG );
	writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
	if( !sIsNullStream( stream ) )
		{
		setResourceData( &msgData, sMemBufPtr( stream ), pubKeyDataSize );
		status = krnlSendMessage( subjectCertInfoPtr->iCryptContext, 
								  RESOURCE_IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
		if( cryptStatusError( status ) )
			return( status );
		}
	sSkip( stream, pubKeyDataSize );

	/* Write the attributes */
	if( extensionSize )
		{
		writeCtag( stream, CTAG_CR_ATTRIBUTES );
		writeLength( stream, ( int ) sizeofObject( 11 +	/* PKCS #9 OID size */
					 ( int ) sizeofObject( sizeofObject( extensionSize ) ) ) );
		writeAttributes( stream, subjectCertInfoPtr->attributes,
						 CRYPT_CERTTYPE_CERTREQUEST, extensionSize );
		}
	else
		/* If there are no attributes and we're not using the PKCS #10
		   alternative encoding, write an (erroneous) zero-length field */
		if( !useAltEncoding )
			{
			writeCtag( stream, CTAG_CR_ATTRIBUTES );
			writeLength( stream, 0 );
			}

	return( sGetStatus( stream ) );
	}

/* Write CRMF certificate request information:

	CertReq ::= SEQUENCE {
		certReqID				INTEGER (0),
		certTemplate			SEQUENCE {
			validity	  [ 4 ]	SEQUENCE {
				validFrom [ 0 ]	EXPLICIT GeneralizedTime OPTIONAL,
				validTo	  [ 1 ] EXPLICIT GeneralizedTime OPTIONAL
				} OPTIONAL,
			subject		  [ 5 ]	EXPLICIT Name OPTIONAL,
			publicKey	  [ 6 ]	SubjectPublicKeyInfo,
			extensions	  [ 9 ]	SET OF Attribute OPTIONAL
			}
		} */

int writeCRMFRequestInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
						  const CERT_INFO *issuerCertInfoPtr,
						  const CRYPT_CONTEXT iIssuerCryptContext )

⌨️ 快捷键说明

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