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

📄 pgpsecsh.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 4 页
字号:
	{
		if( PGPCFBContextRefIsValid( session->readCipherCFB ) )
		{
			PGPCFBDecrypt( session->readCipherCFB, buffer, bufLength, buffer );
		} else if( PGPCBCContextRefIsValid( session->readCipherCBC ) ) {
			PGPCBCDecrypt( session->readCipherCBC, buffer, bufLength, buffer );
		}
	}

	/* Verify CRC */
	sCalculateCRC( buffer, bufLength - kPGPsecsh_CRCSize, crcCheck );

	if( !pgpMemoryEqual( crcCheck, buffer + bufLength - kPGPsecsh_CRCSize,
						 kPGPsecsh_CRCSize ) )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_BadRecordCRC );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}

	*outBuffer  = (PGPByte *) PGPNewData(session->memMgr,
										 length - 1 - kPGPsecsh_CRCSize, 0 );
	CKNULL( *outBuffer );
	pgpCopyMemory( buffer + padLength + 1, *outBuffer, length - kPGPsecsh_CRCSize );
	
	*outType = buffer[padLength];
	*outLength	= length - 1 - kPGPsecsh_CRCSize;

done:
	if( IsntNull( buffer ) )
	{
		(void)PGPFreeData( buffer );
	}
	return err;
}


	PGPError
pgpSECSHReceiveServerVersion(
	PGPsecshSessionPriv *	session,
	PGPByte *				outMajor,
	PGPByte *				outMinor )
{
	PGPError				err	= kPGPError_NoErr;
    PGPError            	rerr = kPGPError_NoErr;
	PGPByte 				buffer[kPGPsecsh_MaximumIDStringSize];
	PGPByte *				bp0;
	PGPByte *				bp1;
	PGPByte *				bp2;
	PGPSize					rcvd;
	PGPByte					major;
	PGPByte					minor;
	PGPInt32				bytesRead;

	*outMajor	= 0;
	*outMinor	= 0;

	rcvd = sizeof(buffer) - 1;
	err = pgpSECSHExtractRawData( session, buffer, &rcvd );	CKERR;
	buffer[rcvd] = '\0';
	while( IsNull( bp0 = strchr( buffer, '\n' ) ) )
	{
		bytesRead = (session->secshReceiveProc)( session->secshReceiveUserData,
						buffer + rcvd,
						(PGPInt32)( sizeof(buffer) - 1 - rcvd ) );
		if( bytesRead < 0 )
		{
			if( bytesRead != kPGPError_SECSHWouldBlock )
			{
				FATALSECSH( kPGPError_SECSHUnexpectedClose );
			}
			else
            {
                rerr = kPGPError_SECSHWouldBlock;
				bytesRead = 0;
            }
		}
		if( bytesRead == 0 )
		{
			if( session->blocking )
			{
				FATALSECSH( kPGPError_SECSHUnexpectedClose );
			}
			else
			{
				if( rcvd )
                {
                    err = pgpSECSHBufferRawData( session, buffer, rcvd );  CKERR;
                    if(rerr == kPGPError_SECSHWouldBlock)
                    /* check to see if receive call returned a blocking error */
                    {
                        err = kPGPError_SECSHWouldBlock;
                    }
                }
                else if(rerr == kPGPError_SECSHWouldBlock)
                /* check for blocking error */
                {
                    err = kPGPError_SECSHWouldBlock;
                }
				goto done;
			}
		}
		rcvd += bytesRead;
		buffer[rcvd] = '\0';
	}

	if( !pgpMemoryEqual( buffer, SECSHIDPREFIX, strlen(SECSHIDPREFIX) )
		|| IsNull( bp2 = strchr( buffer, '.' ) ) )
	{
		(void)pgpSECSHAlert( session,	kPGPsecsh_AL_FatalAlert,
									kPGPsecsh_AT_IDFailure );
		FATALSECSH( kPGPError_SECSHProtocolViolation );
	}

	if( rcvd > (PGPSize)(bp0 - buffer + 1) )
	{
		err = pgpSECSHBufferRawData( session, bp0 + 1,
									 rcvd - (bp0 - buffer + 1) );  CKERR;
	}

	bp1 = buffer + strlen( SECSHIDPREFIX );
	major = atoi( bp1 );
	minor = atoi( bp2 + 1 );

	*outMajor	= major;
	*outMinor	= minor;
done:
	return err;
}


	PGPError
pgpSECSHSendQueueIdleInternal(
	PGPsecshSessionPriv *	session )
{
	PGPError			err = kPGPError_NoErr;
	PGPInt32			serr;
	
	if( IsntNull( session->queuedSendData ) && ( session->queuedSendSize > 0 ) )
	{
		serr = (session->secshSendProc)( session->secshSendUserData,
							session->queuedSendData,
							(PGPInt32) session->queuedSendSize );
		if( serr == kPGPError_SECSHWouldBlock )
		{
			err = kPGPError_SECSHWouldBlock;
		}
		else if( serr == (PGPInt32) session->queuedSendSize )
		{
			session->queuedSendSize = 0;
			err = PGPReallocData( session->memMgr,
					(void **) &session->queuedSendData, 0, 0 ); CKERR;
		}
		else
			FATALSECSH( kPGPError_SECSHUnexpectedClose );
	}
done:
	return err;
}


	PGPError
pgpSECSHSendPacket(
	PGPsecshSessionPriv *	session,
	PGPByte					pktType,
	const PGPByte *			inBuffer,
	PGPSize					inLength )
{
	PGPError				err	= kPGPError_NoErr;
	PGPByte *				buffer = NULL;
	PGPSize					bufLength = 0,
							padLength = 0,
							bufOff = 0;
	PGPInt32				serr = 0;
	
	PGPValidatePtr( inBuffer );
	if( inLength+1 > kPGPsecsh_MaximumPacketSize )
	{
		err = kPGPError_BufferTooSmall;
		goto done;				/* non-fatal */
	}

	padLength = 8 - ((inLength+5) & 7);
	bufLength = padLength + 1 + inLength + kPGPsecsh_CRCSize;
	bufOff = sizeof(PGPUInt32);		/* skip past length */
	buffer = (PGPByte *) PGPNewData(session->memMgr, bufLength+bufOff, 0 );
	CKNULL( buffer );

	/* Store length */
	PGPUInt32ToEndian( 1+inLength+kPGPsecsh_CRCSize, kPGPBigEndian, buffer );

	/* Store padding and packet type */
	PGPContextGetRandomBytes( session->pgpContext, buffer+bufOff, padLength );
	buffer[bufOff+padLength] = pktType;

	/* Store data */
	pgpCopyMemory( inBuffer, buffer+bufOff+padLength+1, inLength );

	sCalculateCRC( buffer+bufOff, bufLength - kPGPsecsh_CRCSize,
				   buffer + bufOff + bufLength - kPGPsecsh_CRCSize );


	if( session->encrypting )
	{
		if( PGPCFBContextRefIsValid( session->writeCipherCFB ) )
		{
			PGPCFBEncrypt( session->writeCipherCFB, buffer+bufOff,
						   bufLength, buffer+bufOff );
		} else if( PGPCBCContextRefIsValid( session->writeCipherCBC ) ) {
			PGPCBCEncrypt( session->writeCipherCBC, buffer+bufOff,
						   bufLength, buffer+bufOff );
		}
	}

	err = pgpSECSHSendQueueIdleInternal( session );
	if( err == kPGPError_SECSHWouldBlock )
		serr = err;
	
	if( IsntPGPError( err ) && ( bufLength > 0 ) )
	{
		if( serr != kPGPError_SECSHWouldBlock )
			serr = (session->secshSendProc)( session->secshSendUserData,
										buffer, (PGPInt32)(bufLength+bufOff) );
		if( serr == kPGPError_SECSHWouldBlock )
		{
			err = pgpSECSHBufferSendData( session, buffer, bufLength+bufOff ); CKERR;
			err = kPGPError_SECSHWouldBlock;
		}
		else if( (PGPSize)serr != bufLength+bufOff )
			FATALSECSH( kPGPError_SECSHUnexpectedClose );
	}
done:
	if( IsntNull( buffer ) )
		(void)PGPFreeData( buffer );
	return err;
}


	PGPError
pgpSECSHSendRawData(
	PGPsecshSessionPriv *	session,
	const PGPByte *			inBuffer,
	PGPSize					inLength )
{
	PGPError				err	= kPGPError_NoErr;
	PGPInt32				serr = 0;
	
	PGPValidatePtr( inBuffer );
	if( inLength > kPGPsecsh_MaximumPacketSize )
	{
		err = kPGPError_BufferTooSmall;
		goto done;				/* non-fatal */
	}

	err = pgpSECSHSendQueueIdleInternal( session );
	if( err == kPGPError_SECSHWouldBlock )
		serr = err;
	
	if( IsntPGPError( err ) && ( inLength > 0 ) )
	{
		if( serr != kPGPError_SECSHWouldBlock )
			serr = (session->secshSendProc)( session->secshSendUserData,
										inBuffer, (PGPInt32) inLength );
		if( serr == kPGPError_SECSHWouldBlock )
		{
			err = pgpSECSHBufferSendData( session, inBuffer, inLength ); CKERR;
			err = kPGPError_SECSHWouldBlock;
		}
		else if( (PGPSize)serr != inLength )
			FATALSECSH( kPGPError_SECSHUnexpectedClose );
	}
done:
	return err;
}


	PGPError
pgpSECSHSendSessionKey(
	PGPsecshSessionPriv *	session)
{
	PGPByte *				sessionKey = NULL;
	PGPCipherAlgorithm		cipher;
	PGPSize					sbufSize;
	PGPSize					lbufSize;
	PGPPublicKeyContextRef	smallContext;
	PGPPublicKeyContextRef	largeContext;
	PGPByte *				sBuffer = NULL;
	PGPByte *				lBuffer = NULL;
	PGPUInt32				lbufOff;
	PGPUInt16				lbufBits;
	PGPByte *				payload = NULL;
	PGPSize					payloadLen;
	PGPUInt32				payOff;
	PGPByte					iv[16];
	PGPInt32				i;
	PGPSymmetricCipherContextRef
							symContext;
	PGPError				err = kPGPError_NoErr;

	err = pgpSECSHClientChooseAlgorithm( session, &cipher ); CKERR;

	sessionKey = (PGPByte *)PGPNewSecureData( session->memMgr, kPGPsecsh_SessionKeySize, 0 );
	CKNULL( sessionKey );

	PGPContextGetRandomBytes( session->pgpContext, sessionKey, kPGPsecsh_SessionKeySize );

	PGPGetPublicKeyOperationSizes( session->remoteServerKeyContext, NULL,
								   &sbufSize, NULL );
	PGPGetPublicKeyOperationSizes( session->remoteHostKeyContext, NULL,
								   &lbufSize, NULL );
	if( sbufSize < lbufSize )
	{
		smallContext = session->remoteServerKeyContext;
		largeContext = session->remoteHostKeyContext;
	} else {
		PGPUInt32 t = sbufSize; sbufSize = lbufSize; lbufSize = t;
		smallContext = session->remoteHostKeyContext;
		largeContext = session->remoteServerKeyContext;
	}

	sBuffer = (PGPByte *)PGPNewData( session->memMgr, sbufSize, 0 ); CKNULL( sBuffer );
	lBuffer = (PGPByte *)PGPNewData( session->memMgr, lbufSize, 0 ); CKNULL( lBuffer );
	
	err = PGPPublicKeyEncrypt( smallContext, sessionKey, kPGPsecsh_SessionKeySize,
							   sBuffer, &sbufSize ); CKERR;
	err = PGPPublicKeyEncrypt( largeContext, sBuffer, sbufSize, lBuffer,
							   &lbufSize ); CKERR;
	lbufBits = sCountBits( lBuffer, lbufSize, &lbufOff );

	payloadLen = 1 + kPGPsecsh_CookieSize + sizeof(PGPUInt16)
		+ lbufSize-lbufOff + sizeof(PGPUInt32);
	payload = (PGPByte *)PGPNewData( session->memMgr, payloadLen, 0 ); CKNULL( payload );

	payOff = 0;

	payload[payOff++] = (cipher==kPGPCipherAlgorithm_IDEA) ? kPGPsecsh_CT_IDEA
														   : kPGPsecsh_CT_3DES;
	pgpCopyMemory( session->cookie, payload+payOff, kPGPsecsh_CookieSize );
	payOff += kPGPsecsh_CookieSize;
	PGPUInt16ToEndian( lbufBits, kPGPBigEndian, payload+payOff );
	payOff += sizeof( PGPUInt16 );
	pgpCopyMemory( lBuffer+lbufOff, payload+payOff, lbufSize-lbufOff );
	payOff += lbufSize - lbufOff;
	PGPUInt32ToEndian( session->localProtocolFlags, kPGPBigEndian, payload+payOff );
	payOff += sizeof( PGPUInt32 );
	pgpAssert( payOff == payloadLen );

	err = pgpSECSHSendPacket( session, kPGPsecsh_CMsg_SessionKey, payload, payloadLen ); CKERR;

	/* Done with host key encryption */
	(void) PGPFreePublicKeyContext( session->remoteHostKeyContext );
	(void) PGPFreePublicKeyContext( session->remoteServerKeyContext );
	session->remoteHostKeyContext   = kInvalidPGPPublicKeyContextRef;
	session->remoteServerKeyContext = kInvalidPGPPublicKeyContextRef;


	/* Set up IV and keys for symmetric encryption */
	pgpClearMemory( iv, sizeof( iv ) );
	for( i=0; i<kPGPsecsh_SessionIDSize; ++i )
	{
		sessionKey[i] ^= session->sessionID[i];
	}

	if( cipher == kPGPCipherAlgorithm_IDEA )
	{
		err = PGPNewSymmetricCipherContext( session->pgpContext,
											kPGPCipherAlgorithm_IDEA,
											&symContext ); CKERR;
		err = PGPNewCFBContext( symContext, 1, &session->writeCipherCFB ); CKERR;
		symContext = kInvalidPGPSymmetricCipherContextRef;
		err = PGPInitCFB( session->writeCipherCFB, sessionKey, iv ); CKERR;
		err = PGPNewSymmetricCipherContext( session->pgpContext,
											kPGPCipherAlgorithm_IDEA,
											&symContext ); CKERR;
		err = PGPNewCFBContext( symContext, 1, &session->readCipherCFB ); CKERR;
		symContext = kInvalidPGPSymmetricCipherContextRef;
		err = PGPInitCFB( session->readCipherCFB, sessionKey, iv ); CKERR;
	} else {
		pgpAssert( 0 );
	}

	session->encrypting = TRUE;


	
done:
	if( PGPSymmetricCipherContextRefIsValid( symContext ) )
		PGPFreeSymmetricCipherContext( symContext );
	if( IsntNull( sessionKey ) )
		PGPFreeData( sessionKey );
	if( IsntNull( payload ) )
		PGPFreeData( payload );
	if( IsntNull( sBuffer ) )
		PGPFreeData( sBuffer );
	if( IsntNull( lBuffer ) )
		PGPFreeData( lBuffer );

	return err;
}


	PGPError
pgpSECSHSendUserName(
	PGPsecshSessionPriv *	session)
{
	PGPByte *				payload = NULL;
	PGPUInt32				payOff = 0;
	PGPSize					payloadSize;
	PGPUInt32				nameLen;
	PGPError				err = kPGPError_NoErr;

	nameLen = strlen( session->userName );
	payloadSize = sizeof(PGPUInt32) + nameLen;

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

	PGPUInt32ToEndian( nameLen, kPGPBigEndian, payload+payOff );
	payOff += sizeof( PGPUInt32 );
	pgpCopyMemory( session->userName, payload+payOff, nameLen );
	payOff += nameLen;
	pgpAssert( payOff == payloadSize );
	
	err = pgpSECSHSendPacket( session, kPGPsecsh_CMsg_User, payload, payloadSize ); CKERR;

 done:
	if( IsntNull( payload ) )
		PGPFreeData( payload );
	return err;
}


	PGPError
pgpSECSHSendRSAChallengeRequest(
	PGPsecshSessionPriv *	session)
{
	void *					vbuf;
	PGPByte *				mbuf = NULL;
	PGPSize					mbufSize;
	PGPUInt16				mbufBits;
	PGPError				err = kPGPError_NoErr;

	/* Send modulus of local authentication key */
	err = PGPGetKeyDBObjAllocatedDataProperty( session->localKey,
											   kPGPKeyProperty_KeyData,
											   &vbuf, &mbufSize ); CKERR;
	mbuf = vbuf;
	mbufBits = (mbuf[0] << 8) | mbuf[1];
	mbufSize = 2 + ((mbufBits + 7) / 8);

	err = pgpSECSHSendPacket( session, kPGPsecsh_CMsg_AuthRSA, mbuf, mbufSize ); CKERR;

 done:
	if( IsntNull( mbuf ) )
		PGPFreeData( mbuf );
	return err;
}


	PGPError
pgpSECSHSendRSAResponse(
	PGPsecshSessionPriv *		session,
	const PGPByte *				inChallenge,
	PGPSize						inLength )
{
	PGPPrivateKeyContextRef		privKeyCon = kInvalidPGPPrivateKeyContextRef;
	PGPPublicKeyMessageFormat	format;
	PGPSize						bufSize;
	PGPByte *					decryptBuf = NULL;
	PGPByte *					payload = NULL;
	PGPHashContextRef			handshakeMD5 = kInvalidPGPHashContextRef;
	PGPError					err;
	
	format = kPGPPublicKeyMessageFormat_PKCS1;
	err = PGPNewPrivateKeyContext( PGPPeekKeyDBObjKey( session->localKey ),
		format, &privKeyCon, session->localKeyUsePasskey ?
		PGPOPasskeyBuffer( session->pgpContext, session->localKeyPasskeyBuffer,
							session->localKeyPasskeySize ) :
		PGPOPassphrase( session->pgpContext, session->localKeyPassphrase ),
		PGPOLastOption( session->pgpContext ) );	CKERR;

	err = PGPGetPrivateKeyOperationSizes( privKeyCon, &bufSize, NULL, NULL ); CKERR;
	decryptBuf = (PGPByte *)PGPNewData( session->memMgr, bufSize, 0 );
	CKNULL( decryptBuf );

	err = PGPPrivateKeyDecrypt( privKeyCon, inChallenge, inLength, decryptBuf,
								&bufSize ); CKERR;

⌨️ 快捷键说明

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