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

📄 pgpsecsh.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 4 页
字号:

	PGPFreePrivateKeyContext( privKeyCon );
	privKeyCon = kInvalidPGPPrivateKeyContextRef;

	if( bufSize > 32 )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_DecodeError );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}

	payload = (PGPByte *)PGPNewData( session->memMgr, kPGPsecsh_SessionIDSize, 0 );
	CKNULL( payload );

	err = PGPNewHashContext( session->pgpContext, kPGPHashAlgorithm_MD5,
							 &handshakeMD5 ); CKERR;
	
	PGPContinueHash( handshakeMD5, decryptBuf, bufSize );
	PGPContinueHash( handshakeMD5, session->sessionID, kPGPsecsh_SessionIDSize );

	PGPFinalizeHash( handshakeMD5, payload );
	PGPFreeHashContext( handshakeMD5 );
	handshakeMD5 = kInvalidPGPHashContextRef;

	err = pgpSECSHSendPacket( session, kPGPsecsh_CMsg_AuthRSAResponse,
							  payload, kPGPsecsh_SessionIDSize ); CKERR;

 done:
	if( IsntNull( payload ) )
		PGPFreeData( payload );
	if( IsntNull( decryptBuf ) )
		PGPFreeData( decryptBuf );
	if( PGPPrivateKeyContextRefIsValid( privKeyCon ) )
		PGPFreePrivateKeyContext( privKeyCon );
	if( PGPHashContextRefIsValid( handshakeMD5 ) )
		PGPFreeHashContext( handshakeMD5 );

	return err;
}


	PGPError
pgpSECSHReceivePublicKey(
	PGPsecshSessionPriv *			session,
	const PGPByte *					inBuffer,
	PGPSize							inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPHashContextRef	handshakeMD5 = kInvalidPGPHashContextRef;
	PGPUInt16			pktInx = 0;
	PGPUInt32			sbits;
	PGPUInt32			hbits;
	PGPUInt16			sKeyOff;
	PGPUInt16			hKeyOff;
	PGPSize				ilen;

	/* First read cookie */
	if( (PGPSize)(pktInx + kPGPsecsh_CookieSize) > inLength )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_DecodeError );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}
	pgpCopyMemory( (PGPByte *)inBuffer+pktInx, session->cookie, kPGPsecsh_CookieSize );
	pktInx += kPGPsecsh_CookieSize;

	/* Server key bits */
	if( pktInx + sizeof(PGPUInt32) > inLength )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_DecodeError );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}
	sbits = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
	pktInx += sizeof(PGPUInt32);

	/* Server key data */
	err = sDataToPGPKey( session, (PGPByte *)inBuffer+pktInx, inLength-pktInx,
						 &ilen, &session->remoteServerKeyDB,
						 &session->remoteServerKey ); CKERR;
	pktInx += ilen;
	sKeyOff = pktInx - (sbits+7)/8;

	/* Host key bits */
	if( pktInx + sizeof(PGPUInt32) > inLength )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_DecodeError );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}
	hbits = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
	pktInx += sizeof(PGPUInt32);

	/* Server key data */
	err = sDataToPGPKey( session, (PGPByte *)inBuffer+pktInx, inLength-pktInx,
						 &ilen, &session->remoteHostKeyDB,
						 &session->remoteHostKey ); CKERR;
	pktInx += ilen;
	hKeyOff = pktInx - (hbits+7)/8;

	/* Protocol flags, cipher mask, auth mask */
	if( pktInx + 3*sizeof(PGPUInt32) > inLength )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_DecodeError );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}
	session->remoteProtocolFlags = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx);
	pktInx += sizeof(PGPUInt32);
	session->cipherMask = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
	pktInx += sizeof(PGPUInt32);
	session->authMask = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
	pktInx += sizeof(PGPUInt32);

	/* Calculate session ID */
	err = PGPNewHashContext( session->pgpContext, kPGPHashAlgorithm_MD5,
							 &handshakeMD5 ); CKERR;
	
	PGPContinueHash( handshakeMD5, inBuffer+hKeyOff, (hbits+7)/8 );
	PGPContinueHash( handshakeMD5, inBuffer+sKeyOff, (sbits+7)/8 );
	PGPContinueHash( handshakeMD5, session->cookie, kPGPsecsh_CookieSize );
	PGPFinalizeHash( handshakeMD5, session->sessionID );
	PGPFreeHashContext( handshakeMD5 );
	handshakeMD5 = kInvalidPGPHashContextRef;
	
	err = PGPNewPublicKeyContext( session->remoteServerKey,
								  kPGPPublicKeyMessageFormat_PKCS1,
								  &session->remoteServerKeyContext ); CKERR;
	err = PGPNewPublicKeyContext( session->remoteHostKey,
								  kPGPPublicKeyMessageFormat_PKCS1,
								  &session->remoteHostKeyContext ); CKERR;

	err = pgpSECSHSendSessionKey( session ); CKERR;

done:
	if( PGPHashContextRefIsValid( handshakeMD5 ) )
		PGPFreeHashContext( handshakeMD5 );
	return err;
}

	PGPError
pgpSECSHReceiveRSAChallenge(
	PGPsecshSessionPriv *			session,
	const PGPByte *					inBuffer,
	PGPSize							inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte *			rsaChallenge = NULL;
	PGPUInt16			pktInx = 0;
	PGPUInt16			chalBits;
	PGPSize				chalSize;

	chalBits = (inBuffer[pktInx] << 8) + inBuffer[pktInx+1];
	chalSize = (chalBits + 7) / 8;
	pktInx += 2;

	if( inLength != (PGPSize) (chalSize + pktInx) )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_DecodeError );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}
	rsaChallenge = (PGPByte *)PGPNewData( session->memMgr, chalSize, 0 );
	CKNULL( rsaChallenge );

	pgpCopyMemory( inBuffer+pktInx, rsaChallenge, chalSize );

	err = pgpSECSHSendRSAResponse( session, rsaChallenge, chalSize );  CKERR;
		
 done:
	if( IsntNull( rsaChallenge ) )
		PGPFreeData( rsaChallenge );
	return err;
}


	PGPError
pgpSECSHReceiveDebug(
	PGPsecshSessionPriv *			session,
	const PGPByte *					inBuffer,
	PGPSize							inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPUInt16			pktInx = 0;
	PGPUInt32			strCount;

	/* Read count of characters */
	strCount = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
	pktInx += sizeof(PGPUInt32);
	if( strCount > inLength - pktInx )
		strCount = inLength - pktInx;

#if PGP_DEBUG
	{
		char *str = PGPNewData( session->memMgr, strCount+1, 0 );
		pgpCopyMemory( inBuffer+pktInx, str, strCount );
		str[strCount] = 0;
		pgpDebugFmtMsg((pgpaFmtPrefix, "SECSH debug message: %s\n", str ));
		PGPFreeData( str );
	}
#endif
	
	return err;
}




/* Receive a success/failure message.  State has already changed. */
	PGPError
pgpSECSHReceiveSuccessFail(
	PGPsecshSessionPriv *			session,
	const PGPByte *					inBuffer,
	PGPSize							inLength )
{
	(void) inBuffer;
	(void) inLength;

	if( session->intState == 2 )
		pgpSECSHSendUserName( session );
	else if( session->intState == 3 )
		pgpSECSHSendRSAChallengeRequest( session );
	else
		pgpAssert( 0 );
	return kPGPError_NoErr;
}


	PGPError
pgpSECSHAlert(
	PGPsecshSessionPriv *	session,
	PGPByte					level,
	PGPsecshAlert			type )
{
	PGPError			err	= kPGPError_NoErr;
	
	if( level == kPGPsecsh_AL_FatalAlert )
	{
		session->state		= kPGPsecsh_FatalErrorState;
		session->fatalAlert	= type;
	}
	return err;
}



	PGPInt8
pgpSECSHPacketToEvent(
	PGPByte		packetType )
{
	PGPInt8		event = 0;
	
	switch( packetType )
	{
		case kPGPsecsh_SMsg_PublicKey:
			event = kPGPsecsh_EV_ReceiveServerPublicKey;
			break;
		case kPGPsecsh_SMsg_AuthRSAChallenge:
			event = kPGPsecsh_EV_ReceiveRSAChallenge;
			break;
		case kPGPsecsh_SMsg_Success:
			event = kPGPsecsh_EV_ReceiveSuccess;
			break;
		case kPGPsecsh_SMsg_Failure:
			event = kPGPsecsh_EV_ReceiveFailure;
			break;
		case kPGPsecsh_SMsg_Debug:
			event = kPGPsecsh_EV_ReceiveDebug;
			break;
		default:
			event = kPGPsecsh_EV_ReceiveUnknownPacket;
			break;
	}
	return event;
}


	PGPError
pgpSECSHClientHandshake(
	PGPsecshSessionPriv *	session )
{
	PGPError				err	= kPGPError_NoErr;
	PGPByte					pktType;
	PGPByte *				packet = NULL;
	PGPSize					pktLen;
	PGPInt8					newState;
	PGPByte					serverMajor;
	PGPByte					serverMinor;
	PGPBoolean				handshaking = TRUE;
	
	if( ( session->state == kPGPsecsh_IdleState ) || 
		( session->state == kPGPsecsh_ReadyState ) )
	{
		session->state = kPGPsecsh_HandshakeState;
		err = pgpSECSHReceiveServerVersion( session, &serverMajor,
											&serverMinor );
		if( IsPGPError( err ) )
			goto done;
		if( serverMajor > 1 )
		{
			(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
										kPGPsecsh_AT_UnsupportedVersion );
			FATALSECSH( kPGPError_SECSHProtocolViolation );
		}
		err = pgpSECSHSendRawData( session, SECSHID, strlen( SECSHID ) );
		if( IsPGPError( err ) )
			goto done;

	}
	while( handshaking &&
			IsntPGPError( err = pgpSECSHReceivePacket( session,
			&pktType, &packet, &pktLen ) ) && IsntNull( packet ) )
	{
		newState = pgpSECSHNextState( session, pgpSECSHPacketToEvent( pktType ) );
		if( newState == -2 )
		{
			(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
										kPGPsecsh_AT_UnexpectedMessage );
			FATALSECSH( kPGPError_SECSHProtocolViolation );
		}
		else if( newState == -1 )
		{
			/* do nothing */
		}
		else if( newState == SECSHNUMCLIENTSTATES )
		{
			session->state = kPGPsecsh_ReadyState;
			handshaking = FALSE;

		}
		else switch( pktType )
		{
			case kPGPsecsh_SMsg_PublicKey:
				err = pgpSECSHReceivePublicKey( session, packet, pktLen );
				break;
			case kPGPsecsh_SMsg_Success:
			case kPGPsecsh_SMsg_Failure:
				err = pgpSECSHReceiveSuccessFail( session, packet, pktLen );
				break;
			case kPGPsecsh_SMsg_AuthRSAChallenge:
				err = pgpSECSHReceiveRSAChallenge( session, packet, pktLen );
				break;
			case kPGPsecsh_SMsg_Debug:
				err = pgpSECSHReceiveDebug( session, packet, pktLen );
				break;
			default:
				pgpAssert( 0 );
		}
		(void)PGPFreeData( packet );
		packet = NULL;
		if( IsPGPError( err ) )
			goto done;
		if( !session->blocking )
			break;
	}
done:
	if( IsntNull( packet ) )
		(void)PGPFreeData( packet );
	return err;
}



	PGPError
PGPsecshHandshake(
	PGPsecshSessionRef		ref )
{
	PGPError				err	= kPGPError_NoErr;
	PGPsecshSessionPriv *	session;
	
	PGPValidatePtr( ref );

	session = (PGPsecshSessionPriv *) ref;
	PGPValidatePtr( session->secshReceiveProc );
	PGPValidatePtr( session->secshSendProc );

	if( ( session->state != kPGPsecsh_ReadyState ) &&
		( session->state != kPGPsecsh_IdleState ) &&
		( ( session->state != kPGPsecsh_HandshakeState ) ||
		session->blocking ) )
	{
		err = kPGPError_SECSHWrongState;
		goto done;
	}
	
/*
	if( session->isClientSide )
		err = pgpSECSHClientHandshake( session );
	else
		err = pgpSECSHServerHandshake( session );
*/
	err = pgpSECSHClientHandshake( session );
	
	if(err == kPGPError_SECSHWouldBlock)
		return kPGPError_NoErr;
	if( IsPGPError( err ) && session->state != kPGPsecsh_FatalErrorState )
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_InternalError );
done:
	return err;
}


	PGPError
PGPsecshSetProtocolOptions(
	PGPsecshSessionRef		ref,
	PGPsecshFlags			options,
	PGPsecshProtocolFlags	pflags  )
{
	PGPsecshSessionPriv *	session;

	PGPValidatePtr( ref );
	
	session = (PGPsecshSessionPriv *) ref;
	
	if( options & kPGPsecshFlags_ServerSide )
		session->isClientSide = FALSE;
	if( options & kPGPsecshFlags_ClientSide )
		session->isClientSide = TRUE;
	if( options & kPGPsecshFlags_NonBlockingIO )
		session->blocking = FALSE;

	session->localProtocolFlags = (PGPUInt32) pflags;

	return kPGPError_NoErr;
}


static const PGPOptionType sSECSHOptionSet[] =
{
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey
};


	PGPError
PGPsecshSetLocalPrivateKey(
	PGPsecshSessionRef		ref,
	char *					inUserName,
	PGPKeyDBObjRef			inKeyObject,
	char *					inHostName,
	PGPKeySetRef			inHostKeys,
	PGPOptionListRef		firstOption,
	... )
{
	PGPError				err	= kPGPError_NoErr;
	PGPsecshSessionPriv *		session;
	PGPBoolean				secret,
							disabled,
							revoked,
							expired,
							canDecrypt;
	PGPInt32				algID;
	void					*passedPhrase = NULL;
	PGPSize					passedLength;
	PGPOptionListRef		optionList = kInvalidPGPOptionListRef;
	va_list					args;
	PGPUInt32				userNameLen;
	PGPUInt32				hostNameLen;
	
	PGPValidatePtr( ref );
	PGPValidatePtr( inKeyObject );

	session = (PGPsecshSessionPriv *) ref;

	userNameLen = strlen( inUserName );
	session->userName = (char *)PGPNewData( session->memMgr, userNameLen, 0 );
	CKNULL( session->userName );
	pgpCopyMemory( inUserName, session->userName, userNameLen+1 );

	hostNameLen = strlen( inHostName );
	session->hostName = (char *)PGPNewData( session->memMgr, hostNameLen, 0 );
	CKNULL( session->hostName );
	pgpCopyMemory( inHostName, session->hostName, hostNameLen+1 );

	session->remoteHostLookupKeyset = inHostKeys;

	va_start( args, firstOption );
	optionList = pgpBuildOptionListArgs(session->pgpContext,
									FALSE, firstOption, args);
	va_end( args );
	
	pgpAssert( pgpOptionListIsValid( optionList ) );
	err = pgpGetOptionListError( optionList );	CKERR;
	err = pgpCheckOptionsInSet( optionList, sSECSHOptionSet,
				sizeof(sSECSHOptionSet) / sizeof(PGPOptionType) ); CKERR;
	

⌨️ 快捷键说明

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