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

📄 pgptls.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:
		case kPGPPublicKeyAlgorithm_RSA:
		{
			PGPByte		signedData[kPGPtls_HA_MD5Size + kPGPtls_HA_SHASize];
			
			/* Do the additional MD5 hash for RSA */
			err = PGPNewHashContext( session->memMgr, kPGPHashAlgorithm_MD5,
								&skeHashMD5 ); CKERR;
			(void)PGPContinueHash( skeHashMD5, session->cRandom,
									kPGPtls_RandomSize);
			(void)PGPContinueHash( skeHashMD5, session->sRandom,
									kPGPtls_RandomSize);
			(void)PGPContinueHash( skeHashMD5, buffer, pktLen);
			(void)PGPFinalizeHash( skeHashMD5, signedData );
			(void)PGPFinalizeHash( skeHashSHA, signedData +
						kPGPtls_HA_MD5Size );
			
			/* Create the Signature */			
			err = PGPPrivateKeySignRaw( privKeyCon, signedData,
									kPGPtls_HA_MD5Size + kPGPtls_HA_SHASize,
									buffer + pktLen + 2, &actSigSize ); CKERR;
			PGPUInt16ToEndian( (PGPUInt16) actSigSize, kPGPBigEndian,
								&buffer[pktLen] );
			break;
		}
		
		default:
			break;
	}
	pgpAssert( actSigSize <= sigSize );
	pktLen += sizeof(PGPUInt16) + actSigSize;
	
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_ServerKeyExchange,
										buffer, pktLen );
done:
	if( IsntNull( secretX ) )
		(void)PGPFreeData( secretX );
	if( IsntNull( buffer ) )
		(void)PGPFreeData( buffer );
	if( PGPPrivateKeyContextRefIsValid( privKeyCon ) )
		(void)PGPFreePrivateKeyContext( privKeyCon );
	if( PGPHashContextRefIsValid( skeHashMD5 ) )
		(void)PGPFreeHashContext( skeHashMD5 );
	if( PGPHashContextRefIsValid( skeHashSHA ) )
		(void)PGPFreeHashContext( skeHashSHA );
	return err;
}

	PGPError
pgpTLSSendClientKeyExchange(
	PGPtlsSessionPriv *		session )
{
	PGPError				err	= kPGPError_NoErr;
	PGPByte					buffer[1024];
	PGPUInt16				pktLen = 0,
							preMasterSize = 0;
	PGPByte *				secretX = NULL;
	PGPByte *				preMaster = NULL;
	PGPBigNumRef			dhSecret = kPGPInvalidBigNumRef;
	PGPPublicKeyContextRef	pubKeyCon = kInvalidPGPPublicKeyContextRef;
	
	if( session->cipherSuites[session->cipherSuiteIndex].ephemeral )
	{
		PGPUInt32		modBits,
						modBytes,
						expBytes = 0,
						expBits;
		
		/* Send ClientDiffieHellmanPublic */
		
		modBits	 = PGPBigNumGetSignificantBits( session->dhP );
		modBytes = ( modBits + 7 ) / 8;
		(void)PGPDiscreteLogExponentBits(modBits, &expBytes);
		expBytes = ( expBytes * 3 / 2 + 7 ) / 8;
		expBits  = 8 * expBytes;
		secretX  = PGPNewSecureData( session->memMgr, expBytes, 0 );
		if( IsNull( secretX ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		err = PGPContextGetRandomBytes( session->pgpContext, secretX,
					expBytes );
		CKERR;
		secretX[0] |= 0x80;
		err = PGPNewBigNum( session->memMgr, TRUE, &session->dhX ); CKERR;
		err = PGPBigNumInsertBigEndianBytes(session->dhX, secretX, 0,
					expBytes );
		CKERR;
		err = PGPNewBigNum( session->memMgr, TRUE, &session->dhYc ); CKERR;
		err = PGPBigNumExpMod( session->dhG, session->dhX, session->dhP,
								session->dhYc ); CKERR;
		/* Setup outgoing packet, sending client Y with 2 byte length */
		PGPUInt16ToEndian( (PGPUInt16) modBytes, kPGPBigEndian, buffer );
		err = PGPBigNumExtractBigEndianBytes( session->dhYc,
										buffer + sizeof(PGPUInt16),
										0, modBytes ); CKERR;
		pktLen = modBytes + sizeof(PGPUInt16);
		
		/* Calculate the shared secret */
		err = PGPNewBigNum( session->memMgr, TRUE, &dhSecret ); CKERR;
		err = PGPBigNumExpMod( session->dhYs, session->dhX, session->dhP,
								dhSecret ); CKERR;
		
		/* Load premastersecret with the shared secret */
		preMasterSize = modBytes;
		preMaster = PGPNewSecureData( session->memMgr, preMasterSize, 0 );
		if( IsNull( preMaster ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		(void)PGPBigNumExtractBigEndianBytes( dhSecret, preMaster,
				0, modBytes );
	}
	else
	{
		PGPSize					encSize;
		
		/* Send EncryptedPreMasterSecret */
		err = PGPNewPublicKeyContext(	session->remoteKey,
										kPGPPublicKeyMessageFormat_PKCS1,
										&pubKeyCon ); CKERR;
		err = PGPGetPublicKeyOperationSizes( pubKeyCon, NULL,
											&encSize, NULL );CKERR;
		preMasterSize = kPGPtls_MasterSecretSize;
		preMaster = PGPNewSecureData( session->memMgr, preMasterSize, 0 );
		if( IsNull( preMaster ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		preMaster[0] = kPGPtls_MajorVersion;
#ifdef PGPTLS_FORCESSL3
		preMaster[1] = kPGPtls_SSL3MinorVersion;
#else
		preMaster[1] = kPGPtls_MinorVersion;	/* always latest version */
#endif
		err = PGPContextGetRandomBytes( session->pgpContext,
									&preMaster[2],
									kPGPtls_MasterSecretSize - 2 ); CKERR;
		if( session->minorVersion > kPGPtls_SSL3MinorVersion )
		{
			PGPUInt16ToEndian( (PGPUInt16) encSize, kPGPBigEndian, buffer );
			pktLen += sizeof(PGPUInt16);
		}
		err = PGPPublicKeyEncrypt( pubKeyCon, preMaster, preMasterSize,
									buffer + pktLen, &encSize ); CKERR;
		pktLen += encSize;
	}
	pgpAssert( pktLen < sizeof(buffer) );
	
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_ClientKeyExchange,
										buffer, pktLen );

	/* Calculate the Master Secret */
	err = pgpTLSCalculateMasterSecret( session, preMaster, preMasterSize );
	
done:
	if( IsntNull( secretX ) )
		(void)PGPFreeData( secretX );
	if( IsntNull( preMaster ) )
		(void)PGPFreeData( preMaster );
	if( dhSecret != kPGPInvalidBigNumRef )
		(void)PGPFreeBigNum( dhSecret );
	if( PGPPublicKeyContextRefIsValid( pubKeyCon ) )
		(void)PGPFreePublicKeyContext( pubKeyCon );
	return err;
}

	PGPError
pgpTLSSendFinished(
	PGPtlsSessionPriv *	session )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				buffer[128];
	PGPSize				pktLen = 0;

	err = pgpTLSCalculateFinished( session, session->isClientSide,
									buffer, &pktLen ); CKERR;
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_Finished,
										buffer, pktLen );
done:
	return err;
}

	PGPError
pgpTLSSendFinalHandshake( 
	PGPtlsSessionPriv *	session )
{
	PGPError			err	= kPGPError_NoErr;
	
	/* Change the cipher spec */
	err = pgpTLSSendChangeCipherSpec( session ); CKERR;
	
	/* Activate the pending client keys */
	err = pgpTLSActivateWriteKeys( session ); CKERR;
	
	/* Signal that our side of the handshake is complete */
	err = pgpTLSSendFinished( session ); CKERR;
	
done:
	return err;
}

	PGPError
pgpTLSSendChangeCipherSpec(
	PGPtlsSessionPriv *	session )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				buffer[16];
	PGPUInt16			pktLen = 0;
	
	buffer[0]	= 1;
	pktLen		= 1;
	
	pgpAssert( pktLen < sizeof(buffer) );
	
	err = pgpTLSSendRecordLayer( session, kPGPtls_RT_ChangeCipherSpec,
									buffer, pktLen );
	return err;
}

	PGPError
pgpTLSReceiveServerHello(
	PGPtlsSessionPriv *	session,
	PGPByte *			inBuffer,
	const PGPSize		inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPUInt16			pktInx = 0,
						suiteIndex;
	PGPtlsCipherSuiteID	cipherID;
	Boolean				foundSuite = FALSE;
	
	PGPValidatePtr( inBuffer );
	pgpAssert( inLength >= 38 );
	
	if( inLength < 38 )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_DecodeError );
		FATALTLS( kPGPError_TLSProtocolViolation );
	}
	/* server_version */
	if( ( inBuffer[pktInx++] != kPGPtls_MajorVersion ) ||
		( inBuffer[pktInx] != kPGPtls_MinorVersion &&
		inBuffer[pktInx] != kPGPtls_SSL3MinorVersion ) )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_ProtocolVersion );
		FATALTLS( kPGPError_TLSVersionUnsupported );
	}
	session->minorVersion = inBuffer[pktInx++];
	/* server_random */
	pgpCopyMemory( &inBuffer[pktInx], session->sRandom,
					kPGPtls_RandomSize );
	pktInx += kPGPtls_RandomSize;
	/* session_id */
	pktInx += inBuffer[pktInx] + 1; /* skip for now ##### */
	/* cipher_suite */
	cipherID[0] = inBuffer[pktInx++];
	cipherID[1] = inBuffer[pktInx++];
	
	for( suiteIndex = 0; suiteIndex < session->numCipherSuites; suiteIndex++ )
	{
		if( ( cipherID[0] == session->cipherSuites[suiteIndex].id[0] ) &&
			( cipherID[1] == session->cipherSuites[suiteIndex].id[1] ) )
		{
			session->cipherSuiteIndex = suiteIndex;
			foundSuite = TRUE;
			break;
		}
	}
	if( !foundSuite )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_InsufficientSecurity );
		FATALTLS( kPGPError_TLSProtocolViolation );
	}
	/* compression_method */
	if( inBuffer[pktInx++] != kPGPtls_CT_None )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_DecodeError );
		FATALTLS( kPGPError_TLSProtocolViolation );
	}
	/*	do not verify that we have handled all data in this packet,
		this packet is allowed to contain data we do not understand. */
done:
	return err;
}	

	PGPError
pgpTLSReceiveClientHello(
	PGPtlsSessionPriv *	session,
	PGPByte *			inBuffer,
	const PGPSize		inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPUInt16			pktInx = 0,
						suiteIndex,
						numSuites,
						intSuiteIndex;
	PGPtlsCipherSuiteID	cipherID;
	Boolean				foundSuite = FALSE;
	
	PGPValidatePtr( inBuffer );
	pgpAssert( inLength >= 40 );
	
	if( inLength < 40 )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_DecodeError );
		FATALTLS( kPGPError_TLSProtocolViolation );
	}
	
	/* client_version */
	if( inBuffer[pktInx++] != kPGPtls_MajorVersion )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_ProtocolVersion );
		FATALTLS( kPGPError_TLSVersionUnsupported );
	}
#ifdef PGPTLS_FORCESSL3
	if( inBuffer[pktInx] > kPGPtls_SSL3MinorVersion )
		session->minorVersion = kPGPtls_SSL3MinorVersion;
#else
	if( inBuffer[pktInx] > kPGPtls_MinorVersion )
		session->minorVersion = kPGPtls_MinorVersion;
#endif
	else
		session->minorVersion = inBuffer[pktInx];
	session->originalClientVersion = inBuffer[pktInx];
	pktInx++;
	/* client_random */
	pgpCopyMemory( &inBuffer[pktInx], session->cRandom,
					kPGPtls_RandomSize );
	pktInx += kPGPtls_RandomSize;
	/* session_id */
	pktInx += inBuffer[pktInx] + 1; /* skip for now ##### */
	/* cipher_suites */
	numSuites = PGPEndianToUInt16( kPGPBigEndian, &inBuffer[pktInx] ) / 2;
	pktInx += sizeof(PGPUInt16);
	if( pktInx + numSuites * sizeof(PGPUInt16) >= inLength )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_DecodeError );
		FATALTLS( kPGPError_TLSProtocolViolation );
	}
	for( suiteIndex = 0; suiteIndex < numSuites; suiteIndex++ )
	{
		cipherID[0] = inBuffer[pktInx++];
		cipherID[1] = inBuffer[pktInx++];
		if( foundSuite )
			continue;
		for( intSuiteIndex = 0; intSuiteIndex < session->numCipherSuites;
				intSuiteIndex++ )
		{
			if( ( cipherID[0] == session->cipherSuites[intSuiteIndex].id[0] ) &&
			 	( cipherID[1] == session->cipherSuites[intSuiteIndex].id[1] ) )
			{
				if( session->localKeyAlg ==
					session->cipherSuites[intSuiteIndex].sigAlg )
				{
					session->cipherSuiteIndex = intSuiteIndex;
					foundSuite = TRUE;
				}
			}
		}
	}
	if( !foundSuite )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_InsufficientSecurity );
		FATALTLS( kPGPError_TLSNoCommonCipher );
	}
	/* compression_methods */
	/* Nobody actually supports this, it's only in the spec for looks */
	pktInx += inBuffer[pktInx];
	
	/*	do not verify that we have handled all data in this packet,
		this packet is allowed to contain data we do not understand. */
	
	err = pgpTLSSendServerHello( session );	CKERR;
	err = pgpTLSSendCertificate( session );	CKERR;
	if( session->cipherSuites[session->cipherSuiteIndex].ephemeral )
	{
		err = pgpTLSSendServerKeyExchange( session );	CKERR;
	}
	if( session->requestCert )
	{
		err = pgpTLSSendCertificateRequest( session );	CKERR;
	}
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_ServerHelloDone,
										NULL, 0 ); CKERR;
done:
	return err;
}	

	PGPError
pgpTLSReceiveClientKeyExchange(
	PGPtlsSessionPriv *		session,
	PGPByte *				inBuffer,
	const PGPSize			inLength )
{
	PGPError				err	= kPGPError_NoErr;
	PGPUInt16				pktInx = 0;
	PGPSize					preMasterSize = 0;
	PGPBigNumRef			dhSecret = kPGPInvalidBigNumRef;
	PGPByte *				preMaster = NULL;
	PGPPrivateKeyContextRef	privKeyCon = kInvalidPGPPrivateKeyContextRef;
	
	PGPValidatePtr( inBuffer );
	
	if( session->cipherSuites[session->cipherSuiteIndex].ephemeral )
	{
		PGPUInt32		modBytes,

		varLen = PGPEndianToUInt16( kPGPBigEndian, &inBuffer[pktInx] );
		pktInx += sizeof(PGPUInt16);
		err = PGPNewBigNum( session->memMgr, TRUE, &session->dhYc ); CKERR;
		err = PGPBigNumInsertBigEndianBytes(session->dhYc, &inBuffer[pktInx],
											0, varLen ); CKERR;
		pktInx += varLen;
		
		if( pktInx != inLength )
		{
			(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
										kPGPtls_AT_UnexpectedMessage );
			FATALTLS( kPGPError_TLSProtocolViolation );
		}

		/* Calculate the shared secret */
		err = PGPNewBigNum( session->memMgr, TRUE, &dhSecret ); CKERR;
		err = PGPBigNumExpMod( session->dhYc, session->dhX, session->dhP,
								dhSecret ); CKERR;
		/* Load premastersecret with the shared secret */
		modBytes = ( PGPBigNumGetSignificantBits( session->dhYc )

⌨️ 快捷键说明

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