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

📄 comp_set.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
	   exit */
	if( pkiUserInfoPtr->subjectName == NULL )
		return( copyPkiUserAttributes( certInfoPtr, 
									   pkiUserInfoPtr->attributes ) );

	/* There's both a request DN and PKI user DN present.  If the request
	   contains only a CN, combine it with the PKI user DN and update the
	   request */
	status = getDNComponentValue( certInfoPtr->subjectName,
								  CRYPT_CERTINFO_COMMONNAME, commonName,
								  &commonNameLength, CRYPT_MAX_TEXTSIZE );
	if( cryptStatusOK( status ) )
		{
		void *tempDN = NULL;
		BOOLEAN isCommonNameDN;

		/* Check whether the request DN contains only a CN.  There's no easy
		   way to do this directly, the only way we can do it is by creating
		   a temporary DN consisting of only the CN and comparing it to the
		   request DN.  We use sizeofDN() rather than compareDN() since it's
		   much faster than a full DN comparison, this is safe because we
		   know that both contain at least the same CN so any size mismatch
		   indicates a DN value mismatch */
		status = insertDNComponent( &tempDN, CRYPT_CERTINFO_COMMONNAME,
									commonName, commonNameLength,
									&certInfoPtr->errorType );
		if( cryptStatusError( status ) )
			return( status );
		isCommonNameDN = sizeofDN( certInfoPtr->subjectName ) == \
						 sizeofDN( tempDN );
		deleteDN( &tempDN );

		/* If the request DN consists only of a CN, append it to the PKI
		   user DN */
		if( isCommonNameDN )
			{
			STREAM stream;
			void *tempDNdata;
			int tempDNsize;

			/* Copy the DN template, append the user-supplied CN, and
			   allocate room for the encoded form */
			status = copyDN( &tempDN, pkiUserInfoPtr->subjectName );
			if( cryptStatusError( status ) )
				return( status );
			status = insertDNComponent( &tempDN, CRYPT_CERTINFO_COMMONNAME,
										commonName, commonNameLength,
										&certInfoPtr->errorType );
			if( cryptStatusOK( status ) )
				{
				tempDNsize = sizeofDN( tempDN );
				if( ( tempDNdata = clAlloc( "copyPkiUserInfo",
											tempDNsize ) ) == NULL )
					status = CRYPT_ERROR_MEMORY;
				}
			if( cryptStatusError( status ) )
				{
				if( tempDN != NULL )
					deleteDN( &tempDN );
				return( status );
				}

			/* Everything went OK, replace the existing DN with the new one
			   and set up the encoded form */
			deleteDN( &certInfoPtr->subjectName );
			certInfoPtr->subjectName = tempDN;
			sMemOpen( &stream, tempDNdata, tempDNsize );
			writeDN( &stream, tempDN, DEFAULT_TAG );
			assert( sStatusOK( &stream ) );
			sMemDisconnect( &stream );
			certInfoPtr->subjectDNdata = \
				certInfoPtr->subjectDNptr = tempDNdata;
			certInfoPtr->subjectDNsize = tempDNsize;

			/* Copy any additional attributes across */
			return( copyPkiUserAttributes( certInfoPtr, 
										   pkiUserInfoPtr->attributes ) );
			}
		}

	/* There are full DNs present in both objects, make sure that they're
	   the same and copy any additional attributes across */
	if( !compareDN( certInfoPtr->subjectName,
					pkiUserInfoPtr->subjectName, FALSE ) )
		return( CRYPT_ERROR_INVALID );
	return( copyPkiUserAttributes( certInfoPtr, 
								   pkiUserInfoPtr->attributes ) );
	}

/****************************************************************************
*																			*
*									Set Cert Info							*
*																			*
****************************************************************************/

/* Set XYZZY certificate info */

static int setXyzzyInfo( CERT_INFO *certInfoPtr )
	{
	ATTRIBUTE_LIST *attributeListPtr;
	const int keyUsage = CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
						 CRYPT_KEYUSAGE_NONREPUDIATION | \
						 CRYPT_KEYUSAGE_KEYENCIPHERMENT | \
						 CRYPT_KEYUSAGE_KEYCERTSIGN | \
						 CRYPT_KEYUSAGE_CRLSIGN;
	const time_t currentTime = getApproxTime();
	int status;

	/* Make sure that we haven't already set up this certificate as a XYZZY
	   cert */
	attributeListPtr = findAttributeField( certInfoPtr->attributes,
										   CRYPT_CERTINFO_CERTPOLICYID,
										   CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL && \
		attributeListPtr->valueLength == sizeofOID( OID_CRYPTLIB_XYZZYCERT ) && \
		!memcmp( attributeListPtr->value, OID_CRYPTLIB_XYZZYCERT,
				 attributeListPtr->valueLength ) )
		{
		setErrorInfo( certInfoPtr, CRYPT_CERTINFO_XYZZY,
					  CRYPT_ERRTYPE_ATTR_PRESENT );
		return( CRYPT_ERROR_INITED );
		}

	/* Clear any existing attribute values before trying to set new ones */
	certInfoPtr->startTime = certInfoPtr->endTime = 0;
	deleteCertComponent( certInfoPtr, CRYPT_CERTINFO_KEYUSAGE );
	deleteCertComponent( certInfoPtr, CRYPT_CERTINFO_CERTIFICATEPOLICIES );

	/* Give the cert a 20-year expiry time, make it a self-signed CA cert
	   with all key usage types enabled, and set the policy OID to identify
	   it as a XYZZY cert */
	certInfoPtr->startTime = currentTime;
	certInfoPtr->endTime = certInfoPtr->startTime + ( 86400 * 365 * 20 );
	certInfoPtr->flags |= CERT_FLAG_SELFSIGNED;
	status = addCertComponent( certInfoPtr, CRYPT_CERTINFO_CA,
							   MESSAGE_VALUE_TRUE, CRYPT_UNUSED );
	if( cryptStatusOK( status ) )
		status = addCertComponent( certInfoPtr, CRYPT_CERTINFO_KEYUSAGE,
								   &keyUsage, CRYPT_UNUSED );
	if( cryptStatusOK( status ) )
		status = addCertComponent( certInfoPtr, CRYPT_CERTINFO_CERTPOLICYID,
								   OID_CRYPTLIB_XYZZYCERT,
								   sizeofOID( OID_CRYPTLIB_XYZZYCERT ) );
	if( cryptStatusOK( status ) )
		findAttributeFieldEx( certInfoPtr->attributes,
					CRYPT_CERTINFO_CERTPOLICYID )->flags |= ATTR_FLAG_LOCKED;
	return( status );
	}

/* Set certificate cursor info */

static int setCertCursorInfo( CERT_INFO *certInfoPtr, const int value )
	{
	const BOOLEAN isCertChain = \
					( certInfoPtr->type == CRYPT_CERTTYPE_CERTCHAIN ) ? \
					TRUE : FALSE;
	const BOOLEAN isRTCS = \
					( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST || \
					  certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE ) ? \
					TRUE : FALSE;

	assert( isCertChain || certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE || \
			certInfoPtr->type == CRYPT_CERTTYPE_CRL || isRTCS || \
			certInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST || \
			certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE );

	/* If it's a single cert, there's nothing to do.  See the
	   CRYPT_CERTINFO_CURRENT_CERTIFICATE ACL comment for why we 
	   (apparently) allow cursor movement movement on single certificates */
	if( certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE )
		{
		assert( certInfoPtr->cCertCert->chainEnd <= 0 );

		return( ( value == CRYPT_CURSOR_FIRST || \
				  value == CRYPT_CURSOR_LAST ) ? \
				CRYPT_OK : CRYPT_ERROR_NOTFOUND );
		}

	switch( value )
		{
		case CRYPT_CURSOR_FIRST:
			if( isCertChain )
				certInfoPtr->cCertCert->chainPos = CRYPT_ERROR;
			else
				if( isRTCS )
					{
					CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;

					certValInfo->currentValidity = certValInfo->validityInfo;
					if( certValInfo->currentValidity == NULL )
						return( CRYPT_ERROR_NOTFOUND );
					}
				else
					{
					CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;

					certRevInfo->currentRevocation = certRevInfo->revocations;
					if( certRevInfo->currentRevocation == NULL )
						return( CRYPT_ERROR_NOTFOUND );
					}
			break;

		case CRYPT_CURSOR_PREVIOUS:
			if( isCertChain )
				{
				if( certInfoPtr->cCertCert->chainPos < 0 )
					return( CRYPT_ERROR_NOTFOUND );
				certInfoPtr->cCertCert->chainPos--;
				}
			else
				if( isRTCS )
					{
					CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;
					VALIDITY_INFO *valInfo = certValInfo->validityInfo;

					if( valInfo == NULL || \
						certValInfo->currentValidity == NULL || \
						valInfo == certValInfo->currentValidity )
						/* No validity info or we're already at the start of
						   the list */
						return( CRYPT_ERROR_NOTFOUND );

					/* Find the previous element in the list */
					while( valInfo != NULL && \
						   valInfo->next != certValInfo->currentValidity )
						valInfo = valInfo->next;
					certValInfo->currentValidity = valInfo;
					}
				else
					{
					CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;
					REVOCATION_INFO *revInfo = certRevInfo->revocations;

					if( revInfo == NULL || \
						certRevInfo->currentRevocation == NULL || \
						revInfo == certRevInfo->currentRevocation )
						/* No revocations or we're already at the start of
						   the list */
						return( CRYPT_ERROR_NOTFOUND );

					/* Find the previous element in the list */
					while( revInfo != NULL && \
						   revInfo->next != certRevInfo->currentRevocation )
						revInfo = revInfo->next;
					certRevInfo->currentRevocation = revInfo;
					}
			break;

		case CRYPT_CURSOR_NEXT:
			if( isCertChain )
				{
				if( certInfoPtr->cCertCert->chainPos >= certInfoPtr->cCertCert->chainEnd - 1 )
					return( CRYPT_ERROR_NOTFOUND );
				certInfoPtr->cCertCert->chainPos++;
				}
			else
				if( isRTCS )
					{
					CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;

					if( certValInfo->currentValidity == NULL || \
						certValInfo->currentValidity->next == NULL )
						return( CRYPT_ERROR_NOTFOUND );
					certValInfo->currentValidity = certValInfo->currentValidity->next;
					}
				else
					{
					CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;

					if( certRevInfo->currentRevocation == NULL || \
						certRevInfo->currentRevocation->next == NULL )
						return( CRYPT_ERROR_NOTFOUND );
					certRevInfo->currentRevocation = certRevInfo->currentRevocation->next;
					}
			break;

		case CRYPT_CURSOR_LAST:
			if( isCertChain )
				certInfoPtr->cCertCert->chainPos = certInfoPtr->cCertCert->chainEnd - 1;
			else
				if( isRTCS )
					{
					CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;
					VALIDITY_INFO *valInfo = certValInfo->validityInfo;

					if( valInfo == NULL )
						/* No validity info present */
						return( CRYPT_ERROR_NOTFOUND );

					/* Go to the end of the list */
					while( valInfo->next != NULL )
						valInfo = valInfo->next;
					certValInfo->currentValidity = valInfo;
					}
				else
					{
					CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;
					REVOCATION_INFO *revInfo = certRevInfo->revocations;

					if( revInfo == NULL )
						/* No revocations present */
						return( CRYPT_ERROR_NOTFOUND );

					/* Go to the end of the list */
					while( revInfo->next != NULL )
						revInfo = revInfo->next;
					certRevInfo->currentRevocation = revInfo;
					}
			break;

		default:
			return( CRYPT_ARGERROR_NUM1 );
		}

	return( CRYPT_OK );
	}

/* Set attribute cursor info */

static int setCursorInfo( CERT_INFO *certInfoPtr,
						  const CRYPT_ATTRIBUTE_TYPE certInfoType,
						  const int value )
	{
	assert( certInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP || \
			certInfoType == CRYPT_ATTRIBUTE_CURRENT || \
			certInfoType == CRYPT_ATTRIBUTE_CURRENT_INSTANCE );

	/* If the new position is specified relative to a previous position, try
	   and move to that position.  Note that the seemingly illogical
	   comparison is used because the cursor positioning codes are negative
	   values */
	if( value <= CRYPT_CURSOR_FIRST && value >= CRYPT_CURSOR_LAST )
		{
		ATTRIBUTE_LIST *attributeCursor;

		/* If we're moving to an extension field and there's a saved
		   GeneralName selection present, we've tried to select a non-present
		   GeneralName, so we can't move to a field in it */
		if( certInfoType != CRYPT_ATTRIBUTE_CURRENT_GROUP && \
			certInfoPtr->currentSelection.generalName != CRYPT_ATTRIBUTE_NONE )
			return( CRYPT_ERROR_NOTFOUND );

		/* If it's an absolute positioning code, pre-set the attribute
		   cursor if required */
		if( value == CRYPT_CURSOR_FIRST || value == CRYPT_CURSOR_LAST )
			{
			if( certInfoPtr->attributes == NULL )
				return( CRYPT_ERROR_NOTFOUND );

⌨️ 快捷键说明

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