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

📄 comp_get.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:

	assert( ( name == NULL && nameMaxLength == 0 ) || \
			( isWritePtr( name, nameMaxLength ) ) );
	assert( isWritePtr( nameLength, sizeof( int ) ) );
	assert( isReadPtr( encodedDn, encodedDnLength ) );

	REQUIRES( ( name == NULL && nameMaxLength == 0 ) || \
			  ( name != NULL && \
				nameMaxLength > 0 && \
			    nameMaxLength <= MAX_INTLENGTH_SHORT ) );
	REQUIRES( encodedDnLength > 0 && \
			  encodedDnLength < MAX_INTLENGTH_SHORT );

	/* Clear return values */
	if( name != NULL )
		memset( name, 0, min( 16, nameMaxLength ) );
	*nameLength = 0;
	
	/* Look for a pseudonym */
	status = extractDnComponent( encodedDn, encodedDnLength, 
								 "oid.2.5.4.65=", 13, &startPos, &length );
	if( cryptStatusOK( status ) && \
		length > 0 && length <= nameMaxLength )
		{
		return( attributeCopyParams( name, nameMaxLength, nameLength, 
									 encodedDn + startPos, length ) );
		}

	/* Look for givenName + surname */
	status = extractDnComponent( encodedDn, encodedDnLength, 
								 "G=", 2, &startPos, &length );
	if( cryptStatusOK( status ) && \
		length > 0 && length <= nameMaxLength )
		{
		char nameBuffer[ MAX_ATTRIBUTE_SIZE + 8 ];
		int startPos2, length2;

		status = extractDnComponent( encodedDn, encodedDnLength, 
									 "S=", 2, &startPos2, &length2 );
		if( cryptStatusOK( status ) && \
			length2 > 0 && length + length2 <= nameMaxLength && \
						   length + length2 < MAX_ATTRIBUTE_SIZE )
			{
			memcpy( nameBuffer, encodedDn + startPos, length );
			memcpy( nameBuffer + length, encodedDn + startPos2, length2 );
			return( attributeCopyParams( name, nameMaxLength, nameLength, 
										 nameBuffer, length + length2 ) );
			}
		}

	/* We couldn't find anything useful */	
	return( CRYPT_ERROR_NOTFOUND );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getHolderName( const CERT_INFO *certInfoPtr, 
						  OUT_BUFFER_OPT( certInfoMaxLength, \
										  certInfoLength ) void *certInfo, 
						  IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
						  OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	STREAM stream;
	char encodedDnBuffer[ MAX_ATTRIBUTE_SIZE + 8 ];
	int status;

	assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	/* First we try for a CN */
	status = getDNComponentValue( certInfoPtr->subjectName, 
								  CRYPT_CERTINFO_COMMONNAME, certInfo, 
								  certInfoMaxLength, certInfoLength );
	if( cryptStatusOK( status ) )
		return( status );

	/* If that fails we try for either a pseudonym or givenName + surname.
	   Since these are part of the vast collection of oddball DN attributes
	   that aren't handled directly we have to get the encoded DN form and
	   look for them by OID (ugh) */
	sMemOpen( &stream, encodedDnBuffer, MAX_ATTRIBUTE_SIZE );
	status = writeDNstring( &stream, certInfoPtr->subjectName );
	if( cryptStatusOK( status ) )
		status = getNameFromDN( certInfo, certInfoMaxLength, certInfoLength, 
								encodedDnBuffer, stell( &stream ) );
	sMemDisconnect( &stream );
	if( cryptStatusOK( status ) )
		return( status );

	/* It's possible (although highly unlikely) that a certificate won't 
	   have a usable CN-equivalent in some form, in which case we use the OU
	   instead.  If that also fails we use the O.  This gets a bit messy, 
	   but duplicating the OU / O into the CN seems to be the best way to 
	   handle this */
	status = getDNComponentValue( certInfoPtr->subjectName, 
								  CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, 
								  certInfo, certInfoMaxLength, 
								  certInfoLength );
	if( cryptStatusError( status ) )
		status = getDNComponentValue( certInfoPtr->subjectName, 
									  CRYPT_CERTINFO_ORGANIZATIONNAME, 
									  certInfo, certInfoMaxLength, 
									  certInfoLength );
	return( status );
	}

/* Get the certificate holder's URI, usually an email address but sometimes
   also a URL */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getHolderURI( const CERT_INFO *certInfoPtr, 
						 OUT_BUFFER( certInfoMaxLength, \
									 certInfoLength ) void *certInfo, 
						 IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
						 OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	ATTRIBUTE_LIST *attributeListPtr;

	assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	/* Find the subjectAltName, which contains the URI info */
	attributeListPtr = findAttribute( certInfoPtr->attributes,
									  CRYPT_CERTINFO_SUBJECTALTNAME, 
									  TRUE );
	if( attributeListPtr == NULL )
		return( CRYPT_ERROR_NOTFOUND );

	/* There's altName data present try for an email address and if that 
	   fails, a URL and an FQDN */
	attributeListPtr = findAttributeField( attributeListPtr, 
										   CRYPT_CERTINFO_SUBJECTALTNAME,
										   CRYPT_CERTINFO_RFC822NAME );
	if( attributeListPtr == NULL )
		attributeListPtr = findAttributeField( attributeListPtr, 
											   CRYPT_CERTINFO_SUBJECTALTNAME,
											   CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );
	if( attributeListPtr == NULL )
		attributeListPtr = findAttributeField( attributeListPtr, 
											   CRYPT_CERTINFO_SUBJECTALTNAME,
											   CRYPT_CERTINFO_DNSNAME );
	if( attributeListPtr == NULL )
		return( CRYPT_ERROR_NOTFOUND );
	return( getCertAttributeComponentData( attributeListPtr, certInfo,
										   certInfoMaxLength,
										   certInfoLength ) );
	}

/* Get the ESSCertID for a certificate */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getESSCertID( INOUT CERT_INFO *certInfoPtr, 
						 OUT_BUFFER( certInfoMaxLength, \
									 certInfoLength ) void *certInfo, 
						 IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
						 OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	STREAM stream;
	HASHFUNCTION_ATOMIC hashFunctionAtomic;
	int hashSize, issuerSerialDataSize, status;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	/* Get the hash algorithm information and hash the certificate to get 
	   the certificate ID if necessary */
	getHashAtomicParameters( CRYPT_ALGO_SHA1, &hashFunctionAtomic, &hashSize );
	if( !certInfoPtr->certHashSet )
		{
		hashFunctionAtomic( certInfoPtr->certHash, KEYID_SIZE,
							certInfoPtr->certificate, 
							certInfoPtr->certificateSize );
		certInfoPtr->certHashSet = TRUE;
		}
	REQUIRES( certInfoPtr->cCertCert->serialNumber != NULL );

	/* Write the ESSCertID:

		ESSCertID ::= SEQUENCE {
			certHash		OCTET STRING SIZE(20),
			issuerSerial	SEQUENCE {
				issuer		SEQUENCE { [4] EXPLICIT Name },
				serial		INTEGER
				}
			} */
	issuerSerialDataSize = ( int ) \
			sizeofObject( sizeofObject( certInfoPtr->issuerDNsize ) ) + \
			sizeofInteger( certInfoPtr->cCertCert->serialNumber,
						   certInfoPtr->cCertCert->serialNumberLength );
	*certInfoLength = ( int ) \
			sizeofObject( sizeofObject( hashSize ) + \
						  sizeofObject( issuerSerialDataSize ) );
	if( certInfo == NULL )
		return( CRYPT_OK );
	if( *certInfoLength > certInfoMaxLength )
		return( CRYPT_ERROR_OVERFLOW );
	sMemOpen( &stream, certInfo, *certInfoLength );
	writeSequence( &stream, sizeofObject( hashSize ) + \
							sizeofObject( issuerSerialDataSize ) );
	writeOctetString( &stream, certInfoPtr->certHash, hashSize, DEFAULT_TAG );
	writeSequence( &stream, issuerSerialDataSize );
	writeSequence( &stream, sizeofObject( certInfoPtr->issuerDNsize ) );
	writeConstructed( &stream, certInfoPtr->issuerDNsize, 4 );
	swrite( &stream, certInfoPtr->issuerDNptr, certInfoPtr->issuerDNsize );
	status = writeInteger( &stream, certInfoPtr->cCertCert->serialNumber,
						   certInfoPtr->cCertCert->serialNumberLength, 
						   DEFAULT_TAG );
	sMemDisconnect( &stream );
	ENSURES( cryptStatusOK( status ) );

	return( status );
	}

/* Encode PKI user information into the external format and return it */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int getPkiUserInfo( const CERT_INFO *certInfoPtr, 
						   IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType, 
						   OUT_BUFFER( certInfoMaxLength, \
									   certInfoLength ) void *certInfo, 
						   IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
						   OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	CERT_PKIUSER_INFO *certUserInfo = certInfoPtr->cCertUser;
	char encUserInfo[ CRYPT_MAX_TEXTSIZE + 8 ];
	BYTE userInfo[ 128 + 8 ], *userInfoPtr = userInfo;
	int userInfoLength, encUserInfoLength, status;

	assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( certInfoType == CRYPT_CERTINFO_PKIUSER_ID || \
			  certInfoType == CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD || \
			  certInfoType == CRYPT_CERTINFO_PKIUSER_REVPASSWORD );
	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	if( certInfoType == CRYPT_CERTINFO_PKIUSER_ID )
		{
		status = getCertAttributeComponent( certInfoPtr,
											CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
											userInfo, 128, &userInfoLength );
		ENSURES( cryptStatusOK( status ) );
		}
	else
		{
		userInfoPtr = ( certInfoType == CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD ) ? \
					  certUserInfo->pkiIssuePW : certUserInfo->pkiRevPW;
		userInfoLength = PKIUSER_AUTHENTICATOR_SIZE;
		}
	status = encodePKIUserValue( encUserInfo, CRYPT_MAX_TEXTSIZE, 
								 &encUserInfoLength, userInfoPtr,
								 userInfoLength,
								 ( certInfoType == \
								   CRYPT_CERTINFO_PKIUSER_ID ) ? 3 : 4 );
	zeroise( userInfo, CRYPT_MAX_TEXTSIZE );
	if( cryptStatusError( status ) )
		return( status );
	ENSURES( cryptStatusOK( \
				decodePKIUserValue( userInfo, 128, &userInfoLength,
									encUserInfo, encUserInfoLength ) ) );
	status = attributeCopyParams( certInfo, certInfoMaxLength, 
								  certInfoLength, encUserInfo, 
								  encUserInfoLength );
	zeroise( encUserInfo, CRYPT_MAX_TEXTSIZE );

	return( status );
	}

/* Get a pointer to the currently selected revocation/validity time */

CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1 ) ) \
time_t *getRevocationTimePtr( const CERT_INFO *certInfoPtr )
	{
	time_t *timePtr;

	assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	/* If there's a specific validity/revocation entry selected, get its 
	   invalidity/revocation time, otherwise if there are invalid/revoked 
	   certificates present get the first certificate's 
	   invalidity/revocation time, otherwise get the default 
	   invalidity/revocation time */
	if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
		{
		CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;

		timePtr = ( certValInfo->currentValidity != NULL ) ? \
					&certValInfo->currentValidity->invalidityTime : \
				  ( certValInfo->validityInfo != NULL ) ? \
					&certValInfo->validityInfo->invalidityTime : NULL;
		}
	else
		{
		CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;

		timePtr = ( certRevInfo->currentRevocation != NULL ) ? \
					&certRevInfo->currentRevocation->revocationTime : \
				  ( certRevInfo->revocations != NULL ) ? \
					&certRevInfo->revocations->revocationTime : \
				  ( certRevInfo->revocationTime ) ? \
					&certRevInfo->revocationTime : NULL;
		}

	return( timePtr );
	}

/* Create a copy of a certificate object for external use.  This is used 
   principally to sanitise internal certificate objects, for example if 
   they're attached to a private key or internal-use only.  Since the object 
   can be either a standalone certificate or a complete certificate chain we 
   have to process it somewhat indirectly rather than just instantiating a 
   new certificate from the encoded certificate data.

   It's also used to convert to/from data-only certificates, for example to 
   convert from a stored data-only certificate to a full certificate capable 
   of being used for signature checking, this is easier than trying to 
   retroactively attach a public-key context to a data-only certificate */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int getCertCopy( const CERT_INFO *certInfoPtr, 
						OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertCopy,
						const BOOLEAN isDataOnlyCert )
	{
	const CRYPT_CERTFORMAT_TYPE formatType = \
		( certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE ) ? \

⌨️ 快捷键说明

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