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

📄 write.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
			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, NULL, NULL );
			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 ] )
				noncePtr[ 0 ]++;
			}

		/* 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 = certRevInfo->revocations;
		 revocationInfo != NULL; revocationInfo = revocationInfo->next )
		revocationInfoLength += sizeofOcspRequestEntry( revocationInfo );
	extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
	length = ( ( subjectCertInfoPtr->version == 2 ) ? \
				 sizeofObject( sizeofShortInteger( CTAG_OR_VERSION ) ) : 0 ) + \
			 ( ( issuerCertInfoPtr != NULL ) ? \
				 sizeofObject( sizeofObject( issuerCertInfoPtr->subjectDNsize ) ) : 0 ) + \
			 sizeofObject( revocationInfoLength ) + \
			 ( extensionSize ? \
			   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;
		 cryptStatusOK( status ) && revocationInfo != NULL;
		 revocationInfo = revocationInfo->next )
		status = writeOcspRequestEntry( stream, revocationInfo );
	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,
		}

	RTCSResponse ::= SEQUENCE {
		responses		SEQUENCE OF Response,
		exts			Extensions OPTIONAL
		} */

static int writeOcspResponseInfo( STREAM *stream,
								  CERT_INFO *subjectCertInfoPtr,
								  const CERT_INFO *issuerCertInfoPtr,
								  const CRYPT_CONTEXT iIssuerCryptContext )
	{
	CERT_REV_INFO *certRevInfo = subjectCertInfoPtr->cCertRev;
	REVOCATION_INFO *revocationInfo;
	int length = 0, extensionSize, revocationInfoLength = 0, status;

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

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

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

	/* Write the outer SEQUENCE wrapper, and, if it's an OCSP response, mark
	   it as a v1 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 */
	status = writeSequence( stream, revocationInfoLength );
	for( revocationInfo = certRevInfo->revocations;
		 cryptStatusOK( status ) && revocationInfo != NULL;
		 revocationInfo = revocationInfo->next )
		status = writeOcspResponseEntry( stream, revocationInfo,
										 subjectCertInfoPtr->startTime );
	if( cryptStatusError( status ) || extensionSize <= 0 )
		return( status );

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

/* Write PKI user info */

int writePkiUserInfo( STREAM *stream, CERT_INFO *userInfoPtr,
					  const CERT_INFO *issuerCertInfoPtr,
					  const CRYPT_CONTEXT iIssuerCryptContext )
	{
	CERT_PKIUSER_INFO *certUserInfo = userInfoPtr->cCertUser;
	BYTE userInfo[ 128 ], algoID[ 128 ];
	int extensionSize, userInfoSize, algoIDsize, status;

	UNUSED( issuerCertInfoPtr );

	if( sIsNullStream( stream ) )
		{
		RESOURCE_DATA msgData;
		BYTE keyID[ 16 ];
		int keyIDlength;

		/* Generate the key identifier.  Once it's in user-encoded form the
		   full identifier can't quite fit so we adjust the size to the
		   maximum amount we can encode.  This is necessary because it's
		   also used to locate the user info in a key store, if we used the
		   un-adjusted form for the key ID we couldn't locate the stored
		   user info using the adjusted form */
		setMessageData( &msgData, keyID, 16 );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
		if( cryptStatusError( status ) )
			return( status );
		keyIDlength = adjustPKIUserValue( keyID, 3 );
		addAttributeField( &userInfoPtr->attributes,
						   CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
						   CRYPT_ATTRIBUTE_NONE, keyID, keyIDlength,
						   ATTR_FLAG_NONE, NULL, NULL );
		status = checkAttributes( ATTRIBUTE_CERTIFICATE,
								  userInfoPtr->attributes,
								  &userInfoPtr->errorLocus,
								  &userInfoPtr->errorType );
		if( cryptStatusError( status ) )
			return( status );

		/* We can't generate the user info yet since we're doing the pre-
		   encoding pass and writing to a null stream so we leave it for the
		   actual encoding pass and only provide a size estimate for now */
		userInfoSize = PKIUSER_ENCR_AUTHENTICATOR_SIZE;

		/* Since we can't use the fixed CA key yet, we set the algo ID size
		   to the size of the info for the fixed 3DES key */
		algoIDsize = 22;
		}
	else
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;
		RESOURCE_DATA msgData;
		STREAM userInfoStream;

		/* Create an RC4 context and use it to generate the user passwords.
		   These aren't encryption keys but just authenticators used for
		   MACing so we don't go to the usual extremes to protect them */
		setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_RC4 );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
								  OBJECT_TYPE_CONTEXT );
		if( cryptStatusError( status ) )
			return( status );
		sMemOpen( &userInfoStream, userInfo, 128 );
		writeSequence( &userInfoStream,
					   2 * sizeofObject( PKIUSER_AUTHENTICATOR_SIZE ) );
		status = krnlSendMessage( createInfo.cryptHandle, IMESSAGE_CTX_GENKEY,
								  NULL, FALSE );
		if( cryptStatusOK( status ) )
			{
			krnlSendMessage( createInfo.cryptHandle, IMESSAGE_CTX_ENCRYPT,
							 certUserInfo->pkiIssuePW,
							 PKIUSER_AUTHENTICATOR_SIZE );
			writeOctetString( &userInfoStream, certUserInfo->pkiIssuePW,
							  PKIUSER_AUTHENTICATOR_SIZE, DEFAULT_TAG );
			status = krnlSendMessage( createInfo.cryptHandle,
									  IMESSAGE_CTX_ENCRYPT,
									  certUserInfo->pkiRevPW,
									  PKIUSER_AUTHENTICATOR_SIZE );
			writeOctetString( &userInfoStream, certUserInfo->pkiRevPW,
							  PKIUSER_AUTHENTICATOR_SIZE, DEFAULT_TAG );
			userInfoSize = stell( &userInfoStream );
			}
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		sMemDisconnect( &userInfoStream );
		if( cryptStatusError( status ) )
			return( status );

		/* Encrypt the user info.  Since user objects aren't fully
		   implemented yet, we use a fixed key as the CA key for now.  When
		   user objects are fully implemented, we'd need to lock the CA key
		   around the following operations */
		setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_3DES );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
								  OBJECT_TYPE_CONTEXT );
		if( cryptStatusError( status ) )
			return( status );
		setMessageData( &msgData, "interop interop interop ", 24 );
		status = krnlSendMessage( createInfo.cryptHandle,
								  IMESSAGE_SETATTRIBUTE_S, &msgData,
								  CRYPT_CTXINFO_KEY );
		if( cryptStatusOK( status ) )
			{
			int i;

			/* Add PKCS #5 padding to the end of the user info and encrypt
			   it */
			assert( userInfoSize + 2 == PKIUSER_ENCR_AUTHENTICATOR_SIZE );
			for( i = 0; i < 2; i++ )
				userInfo[ userInfoSize++ ] = 2;
			krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_CTX_GENIV );
			status = krnlSendMessage( createInfo.cryptHandle,
									  IMESSAGE_CTX_ENCRYPT, userInfo,
									  userInfoSize );
			if( cryptStatusOK( status ) )
				{
				STREAM algoIDstream;

				sMemOpen( &algoIDstream, algoID, 128 );
				status = writeContextAlgoID( &algoIDstream,
									createInfo.cryptHandle, CRYPT_ALGO_NONE,
									ALGOID_FLAG_NONE );
				algoIDsize = stell( &algoIDstream );
				sMemDisconnect( &algoIDstream );
				}
			}
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Write the user DN, encrypted user info, and any supplementary
	   information */
	extensionSize = sizeofAttributes( userInfoPtr->attributes );
	writeDN( stream, userInfoPtr->subjectName, DEFAULT_TAG );
	swrite( stream, algoID, algoIDsize );
	writeOctetString( stream, userInfo, userInfoSize, DEFAULT_TAG );
	return( writeAttributes( stream, userInfoPtr->attributes,
							 CRYPT_CERTTYPE_PKIUSER, extensionSize ) );
	}

/****************************************************************************
*																			*
*						Read Function Access Information					*
*																			*
****************************************************************************/

const CERTWRITE_INFO certWriteTable[] = {
	{ CRYPT_CERTTYPE_CERTIFICATE, writeCertInfo },
	{ CRYPT_CERTTYPE_CERTCHAIN, writeCertInfo },
	{ CRYPT_CERTTYPE_ATTRIBUTE_CERT, writeAttributeCertInfo },
	{ CRYPT_CERTTYPE_CERTREQUEST, writeCertRequestInfo },
	{ CRYPT_CERTTYPE_REQUEST_CERT, writeCrmfRequestInfo },
	{ CRYPT_CERTTYPE_REQUEST_REVOCATION, writeRevRequestInfo },
	{ CRYPT_CERTTYPE_CRL, writeCRLInfo },
	{ CRYPT_CERTTYPE_CMS_ATTRIBUTES, writeCmsAttributes },
	{ CRYPT_CERTTYPE_RTCS_REQUEST, writeRtcsRequestInfo },
	{ CRYPT_CERTTYPE_RTCS_RESPONSE, writeRtcsResponseInfo },
	{ CRYPT_CERTTYPE_OCSP_REQUEST, writeOcspRequestInfo },
	{ CRYPT_CERTTYPE_OCSP_RESPONSE, writeOcspResponseInfo },
	{ CRYPT_CERTTYPE_PKIUSER, writePkiUserInfo },
	{ CRYPT_CERTTYPE_NONE, NULL }
	};

⌨️ 快捷键说明

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