예제 #1
0
static int updateMacInfo( INOUT SESSION_INFO *sessionInfoPtr,
						  INOUT CMP_PROTOCOL_INFO *protocolInfo,
						  INOUT STREAM *stream,
						  const BOOLEAN isRevocation )
	{
	const ATTRIBUTE_LIST *passwordPtr = \
					findSessionInfo( sessionInfoPtr->attributeList,
									 CRYPT_SESSINFO_PASSWORD );
	BYTE macKey[ 64 + 8 ];
	BOOLEAN decodedMacKey = FALSE;
	const void *macKeyPtr;
	const int streamPos = stell( stream );
	int macKeyLength, status;

	REQUIRES( passwordPtr != NULL );

	sseek( stream, protocolInfo->macInfoPos );
	if( isRevocation && protocolInfo->altMacKeySize > 0 )
		{
		/* If it's a revocation and we're using a distinct revocation
		   password (which we've already decoded into a MAC key), use
		   that */
		macKeyPtr = protocolInfo->altMacKey;
		macKeyLength = protocolInfo->altMacKeySize;
		}
	else
		{
		/* It's a standard issue (or we're using the same password/key
		   for the issue and revocation), use that */
		if( passwordPtr->flags & ATTR_FLAG_ENCODEDVALUE )
			{
			/* It's an encoded value, get the decoded form */
			macKeyPtr = macKey;
			status = decodePKIUserValue( macKey, 64, &macKeyLength, 
										 passwordPtr->value, 
										 passwordPtr->valueLength );
			ENSURES( cryptStatusOK( status ) );
			decodedMacKey = TRUE;
			}
		else
			{
			macKeyPtr = passwordPtr->value;
			macKeyLength = passwordPtr->valueLength;
			}
		}
	status = readMacInfo( stream, protocolInfo, macKeyPtr,
						  macKeyLength, SESSION_ERRINFO );
	if( decodedMacKey )
		zeroise( macKey, 64 );
	if( cryptStatusError( status ) )
		return( status );
	sseek( stream, streamPos );

	return( CRYPT_OK );
	}
예제 #2
0
static int checkPkiUserInfo( INOUT SESSION_INFO *sessionInfoPtr,
							 INOUT SCEP_PROTOCOL_INFO *protocolInfo )
	{
	const ATTRIBUTE_LIST *userNamePtr = \
				findSessionInfo( sessionInfoPtr->attributeList,
								 CRYPT_SESSINFO_USERNAME );
	MESSAGE_KEYMGMT_INFO getkeyInfo;
	MESSAGE_DATA msgData;
	BYTE keyID[ 64 + 8 ];
	BYTE requestPassword[ CRYPT_MAX_TEXTSIZE + 8 ];
	BYTE userPassword[ CRYPT_MAX_TEXTSIZE + 8 ];
	int requestPasswordSize, userPasswordSize = DUMMY_INIT;
	int keyIDsize, status;

	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
	assert( isWritePtr( protocolInfo, sizeof( SCEP_PROTOCOL_INFO ) ) );

	REQUIRES( userNamePtr != NULL );
	
	/* Get the password from the PKCS #10 request */
	setMessageData( &msgData, requestPassword, CRYPT_MAX_TEXTSIZE );
	status = krnlSendMessage( sessionInfoPtr->iCertRequest, 
							  IMESSAGE_GETATTRIBUTE_S, &msgData, 
							  CRYPT_CERTINFO_CHALLENGEPASSWORD );
	if( cryptStatusError( status ) )
		{
		retExt( status,
				( status, SESSION_ERRINFO, 
				  "Couldn't get challenge password from PKCS #10 request" ) );
		}
	requestPasswordSize = msgData.length;

	/* Since it's a cryptlib encoded user ID we need to decode it before we 
	   can look up a PKI user with it */
	REQUIRES( userNamePtr->flags & ATTR_FLAG_ENCODEDVALUE );
	status = decodePKIUserValue( keyID, 64, &keyIDsize,
								 userNamePtr->value, 
								 userNamePtr->valueLength );
	ENSURES( cryptStatusOK( status ) );

	/* Get the user information for the request from the certificate 
	   store */
	setMessageKeymgmtInfo( &getkeyInfo, CRYPT_IKEYID_KEYID, keyID, 
						   keyIDsize, NULL, 0, KEYMGMT_FLAG_NONE );
	status = krnlSendMessage( sessionInfoPtr->cryptKeyset,
							  IMESSAGE_KEY_GETKEY, &getkeyInfo, 
							  KEYMGMT_ITEM_PKIUSER );
	if( cryptStatusError( status ) )
		{
		char userID[ CRYPT_MAX_TEXTSIZE + 8 ];
		int userIDlen;

		zeroise( requestPassword, CRYPT_MAX_TEXTSIZE );
		userIDlen = min( userNamePtr->valueLength, CRYPT_MAX_TEXTSIZE );
		memcpy( userID, userNamePtr->value, userIDlen );
		retExtObj( status, 
				   ( status, SESSION_ERRINFO, sessionInfoPtr->cryptKeyset,
					 "Couldn't find PKI user information for %s",
					 sanitiseString( userID, CRYPT_MAX_TEXTSIZE, 
									 userIDlen ) ) );
		}

	/* Get the password from the PKI user object */
	setMessageData( &msgData, userPassword, CRYPT_MAX_TEXTSIZE );
	status = krnlSendMessage( getkeyInfo.cryptHandle, 
							  IMESSAGE_GETATTRIBUTE_S, &msgData,
							  CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD );
	if( cryptStatusOK( status ) )
		{
		userPasswordSize = msgData.length;
		status = updateSessionInfo( &sessionInfoPtr->attributeList, 
									CRYPT_SESSINFO_PASSWORD, 
									userPassword, userPasswordSize, 
									CRYPT_MAX_TEXTSIZE, 
									ATTR_FLAG_ENCODEDVALUE );
		}
	if( cryptStatusError( status ) )
		{
		zeroise( requestPassword, CRYPT_MAX_TEXTSIZE );
		zeroise( userPassword, CRYPT_MAX_TEXTSIZE );
		krnlSendNotifier( getkeyInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		retExt( status, 
				( status, SESSION_ERRINFO, 
				  "Couldn't copy read PKI user data from PKI user object "
				  "into session object" ) );
		}

	/* Make sure that the password matches the one in the request */
	if( userPasswordSize != requestPasswordSize || \
		!compareDataConstTime( userPassword, requestPassword, 
							   userPasswordSize ) )
		{
		zeroise( requestPassword, CRYPT_MAX_TEXTSIZE );
		zeroise( userPassword, CRYPT_MAX_TEXTSIZE );
		krnlSendNotifier( getkeyInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		retExt( status, 
				( status, SESSION_ERRINFO, 
				  "Password in PKCS #10 request doesn't match PKI user "
				  "password" ) );
		}
	zeroise( userPassword, CRYPT_MAX_TEXTSIZE );

	/* If the subject only knows their CN, they may send a CN-only subject DN 
	   in the hope that we can fill it in for them.  In addition there may be 
	   other constraints that the CA wants to apply, these are handled by
	   applying the PKI user information to the request */
	status = krnlSendMessage( sessionInfoPtr->iCertRequest,
							  IMESSAGE_SETATTRIBUTE, &getkeyInfo.cryptHandle,
							  CRYPT_IATTRIBUTE_PKIUSERINFO );
	krnlSendNotifier( getkeyInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		{
		retExt( CRYPT_ERROR_INVALID, 
				( CRYPT_ERROR_INVALID, SESSION_ERRINFO, 
				  "User information in PKCS #10 request can't be "
				  "reconciled with stored information for the user" ) );
		}

	return( CRYPT_OK );
	}