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

📄 pgptls.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:

	PGPError
pgpTLSSendAlert(
	PGPtlsSessionPriv *	session,
	PGPByte				level,
	PGPtlsAlert			type )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				buffer[32];
	PGPSize				pktLen = 0;
	
	buffer[0] = level;
	buffer[1] = type;
	pktLen = 2;
	err = pgpTLSSendRecordLayer( session, kPGPtls_RT_Alert, buffer, pktLen );
	if( level == kPGPtls_AL_FatalAlert )
	{
		session->state		= kPGPtls_FatalErrorState;
		session->fatalAlert	= type;
	}
	return err;
}

	PGPError
pgpTLSSendClientHello(
	PGPtlsSessionPriv *	session )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				buffer[384];
	PGPUInt16			suiteIndex,
						pktLen = 0;
	
	/* client_version */
	buffer[pktLen++] = kPGPtls_MajorVersion;
#ifdef PGPTLS_FORCESSL3
	buffer[pktLen++] = kPGPtls_SSL3MinorVersion;
#else
	buffer[pktLen++] = kPGPtls_MinorVersion;	/* always latest version */
#endif
	/* random */
	*((PGPUInt32 *)&session->cRandom[0]) = PGPGetTime();
	err = PGPContextGetRandomBytes( session->pgpContext,
									&session->cRandom[4],
									kPGPtls_RandomSeedSize ); CKERR;
	pgpCopyMemory( session->cRandom, &buffer[pktLen], kPGPtls_RandomSize );
	pktLen += kPGPtls_RandomSize;
	/* session ID ##### */
	buffer[pktLen++] = 0;
	/* cipher_suites */
	PGPUInt16ToEndian( (PGPUInt16)( session->numCipherSuites * 2 ),
						kPGPBigEndian, &buffer[pktLen] );
	pktLen += sizeof(PGPUInt16);
	for( suiteIndex = 0; suiteIndex < session->numCipherSuites; suiteIndex++ )
	{
		buffer[pktLen++] = session->cipherSuites[suiteIndex].id[0];
		buffer[pktLen++] = session->cipherSuites[suiteIndex].id[1];
	}
	/* compression_methods */
	buffer[pktLen++] = 1;
	buffer[pktLen++] = kPGPtls_CT_None;
	
	pgpAssert( pktLen < sizeof(buffer) );
	
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_ClientHello,
										buffer, pktLen );
done:
	return err;
}

	PGPError
pgpTLSSendServerHello(
	PGPtlsSessionPriv *	session )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				buffer[128];
	PGPUInt16			pktLen = 0;
	
	/* server_version */
	buffer[pktLen++] = kPGPtls_MajorVersion;
	buffer[pktLen++] = session->minorVersion;
	/* random */
	*((PGPUInt32 *)&session->sRandom[0]) = PGPGetTime();
	err = PGPContextGetRandomBytes( session->pgpContext,
									&session->sRandom[4],
									kPGPtls_RandomSeedSize ); CKERR;
	pgpCopyMemory( session->sRandom, &buffer[pktLen], kPGPtls_RandomSize );
	pktLen += kPGPtls_RandomSize;
	/* session_id ##### */
	buffer[pktLen++] = 0;
	/* cipher_suite */
	buffer[pktLen++] = session->cipherSuites[session->cipherSuiteIndex].id[0];
	buffer[pktLen++] = session->cipherSuites[session->cipherSuiteIndex].id[1];
	/* compression_method */
	buffer[pktLen++] = kPGPtls_CT_None;
	
	pgpAssert( pktLen < sizeof(buffer) );
	
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_ServerHello,
										buffer, pktLen );
done:
	return err;
}

	PGPError
pgpTLSSendCertificate(
	PGPtlsSessionPriv *	session )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte *			buffer = NULL;
	PGPUInt16			pktLen = 0;
	PGPByte *			keyBuffer = NULL;
	PGPSize				keyBufferLen;
	
	if( session->isClientSide && !session->certMatched )
	{
		if( session->minorVersion == kPGPtls_SSL3MinorVersion )
		{
			err = pgpTLSSendAlert( session,	kPGPtls_AL_WarningAlert,
									kPGPtls_AT_NoCertificate ); CKERR;
			goto done;
		}
		else if( !session->cipherSuites[session->cipherSuiteIndex].usePGPKeys )
		{
			buffer = PGPNewData( session->memMgr, 3, 0 );
			if( IsNull( buffer ) )
			{
				err = kPGPError_OutOfMemory;
				goto done;
			}
			buffer[pktLen++] = 0;
			buffer[pktLen++] = 0;
			buffer[pktLen++] = 0;
		}
	}
	else if( session->cipherSuites[session->cipherSuiteIndex].usePGPKeys )
	{
		pgpAssert( PGPKeyRefIsValid( session->localKey ) );
		
		err = PGPExport( session->pgpContext,
			PGPOExportKey( session->pgpContext, session->localKey ),
			PGPOAllocatedOutputBuffer( session->pgpContext,
				(void **) &keyBuffer, MAX_PGPUInt32, &keyBufferLen ),
			PGPOArmorOutput( session->pgpContext, FALSE ),
			PGPOLastOption( session->pgpContext ) );	CKERR;
		buffer = PGPNewData( session->memMgr, keyBufferLen + 4, 0 );
		if( IsNull( buffer ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		buffer[0] = ( keyBufferLen >> 16 ) & 0xFF;
		buffer[1] = ( keyBufferLen >> 8 ) & 0xFF;
		buffer[2] = keyBufferLen & 0xFF;
		pgpCopyMemory( keyBuffer, &buffer[3], keyBufferLen );
		pktLen = keyBufferLen + 3;
	}
	else
	{
		PGPSigRef	curCert;
		
		pgpAssert( PGPSigRefIsValid( session->localCert ) );
		pktLen = 3;
		buffer = PGPNewData( session->memMgr, pktLen, 0 );
		if( IsNull( buffer ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		curCert = session->localCert;
		do
		{
			err = PGPExport( session->pgpContext,
				PGPOExportSig( session->pgpContext, curCert ),
				PGPOAllocatedOutputBuffer( session->pgpContext,
					(void **) &keyBuffer, MAX_PGPUInt32, &keyBufferLen ),
				PGPOExportFormat( session->pgpContext, kPGPExportFormat_X509Cert ),
				PGPOLastOption( session->pgpContext ) );	CKERR;
			err = PGPReallocData( session->memMgr, (void **) &buffer,
									pktLen + keyBufferLen + 3, 0 );	CKERR;
			*( buffer + pktLen )		= ( keyBufferLen >> 16 ) & 0xFF;
			*( buffer + pktLen + 1 )	= ( keyBufferLen >> 8 ) & 0xFF;
			*( buffer + pktLen + 2 )	= keyBufferLen & 0xFF;
			pgpCopyMemory( keyBuffer, buffer + pktLen + 3, keyBufferLen );
			pktLen += keyBufferLen + 3;
			(void)PGPFreeData( keyBuffer );
			keyBuffer = NULL;
			if( PGPKeySetRefIsValid( session->localCertChain ) )
			{
				PGPSigRef	nextCert;
				
				err = PGPGetSigX509CertifierSig( curCert, session->localCertChain,
													&nextCert );	CKERR;
				if( nextCert == curCert )
					curCert = kInvalidPGPSigRef;
				else
					curCert = nextCert;
			}
			else
				curCert = kInvalidPGPSigRef;
		} while( PGPSigRefIsValid( curCert ) );
		{
			PGPSize		chainLen = pktLen - 3;
			buffer[0] = ( chainLen >> 16 ) & 0xFF;
			buffer[1] = ( chainLen >> 8 ) & 0xFF;
			buffer[2] = chainLen & 0xFF;
		}
	}
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_Certificate,
										buffer, pktLen );
done:
	if( IsntNull( buffer ) )
		(void)PGPFreeData( buffer );
	if( IsntNull( keyBuffer ) )
		(void)PGPFreeData( keyBuffer );
	return err;
}

	PGPError
pgpTLSSendCertVerify(
	PGPtlsSessionPriv *			session )
{
	PGPError					err	= kPGPError_NoErr;
	PGPByte						buffer[640],
								sigData[640];
	PGPSize						pktLen = 0,
								sigDataLen;
	PGPPrivateKeyContextRef		privKeyCon = kInvalidPGPPrivateKeyContextRef;
	PGPSize						actSigSize;
	PGPPublicKeyMessageFormat	format;
	
	if( ( session->localKeyAlg == kPGPPublicKeyAlgorithm_DSA ) &&
		( session->minorVersion > kPGPtls_SSL3MinorVersion ) )
		format = kPGPPublicKeyMessageFormat_X509;
	else
		format = kPGPPublicKeyMessageFormat_PKCS1;
	/* DSS uses ASN.1, RSA uses PKCS1 */
	err = PGPNewPrivateKeyContext( session->localKey,
		format, &privKeyCon, session->localKeyUsePasskey ?
		PGPOPasskeyBuffer( session->pgpContext, session->localKeyPasskeyBuffer,
							session->localKeyPasskeySize ) :
		PGPOPassphrase( session->pgpContext, session->localKeyPassphrase ),
		PGPOLastOption( session->pgpContext ) );	CKERR;

	err = pgpTLSCalculateCertVerify( session, sigData, &sigDataLen ); CKERR;
	pgpAssert( sigDataLen < sizeof( sigData ) );
	/* Create the Signature */
	err = PGPPrivateKeySignRaw( privKeyCon, sigData, sigDataLen,
				buffer + pktLen + 2, &actSigSize ); CKERR;
	PGPUInt16ToEndian( (PGPUInt16) actSigSize, kPGPBigEndian, &buffer[pktLen] );
	pktLen += sizeof(PGPUInt16) + actSigSize;
	pgpAssert( pktLen < sizeof(buffer) );
	err = pgpTLSSendHandshakePacket( session, kPGPtls_HT_CertificateVerify,
										buffer, pktLen );
done:
	if( PGPPrivateKeyContextRefIsValid( privKeyCon ) )
		(void)PGPFreePrivateKeyContext( privKeyCon );
	return err;
}

	PGPError
pgpTLSSendCertificateRequest(
	PGPtlsSessionPriv *	session )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				buffer[512];
	PGPUInt16			pktLen = 1,
						numAlgs = 0;
	
	/* allowed ClientCertificateTypes */
	if( pubAlgSupported( kPGPPublicKeyAlgorithm_DSA ) )
	{
		buffer[pktLen++]	= kPGPtls_CC_DSASign;
		numAlgs ++;
	}
	if( pubAlgSupported( kPGPPublicKeyAlgorithm_RSA ) )
	{
		buffer[pktLen++]	= kPGPtls_CC_RSASign;
		numAlgs ++;
	}
	buffer[0]			= (PGPByte) numAlgs;
	
	/* Clear length field for distinguished name fields */
	buffer[pktLen++] = 0;
	buffer[pktLen++] = 0;
	
	pgpAssert( pktLen < sizeof(buffer) );
	
	if( IsntPGPError( err ) )
	{
		err = pgpTLSSendHandshakePacket(	session,
											kPGPtls_HT_CertificateRequest,
											buffer, pktLen );
		session->certRequested = TRUE;
	}
	
	return err;
}

	PGPError
pgpTLSSendServerKeyExchange(
	PGPtlsSessionPriv *		session )
{
	PGPError				err	= kPGPError_NoErr;
	PGPByte *				buffer = NULL;
	PGPUInt16				pktLen = 0;
	PGPByte *				secretX = NULL;
	PGPPrivateKeyContextRef	privKeyCon = kInvalidPGPPrivateKeyContextRef;
	PGPSize					sigSize,
							actSigSize;
	PGPHashContextRef		skeHashSHA = kInvalidPGPHashContextRef,
							skeHashMD5 = kInvalidPGPHashContextRef;
	DHPrime *				prime;
	PGPByte const			dhGenerator[1] = { 2 };
	PGPUInt32				modBits,
							modBytes,
							expBytes = 0,
							expBits,
							pSize,
							gSize,
							ySSize;
	PGPPublicKeyMessageFormat	format;
	
	if( ( session->localKeyAlg == kPGPPublicKeyAlgorithm_DSA ) &&
		( session->minorVersion > kPGPtls_SSL3MinorVersion ) )
		format = kPGPPublicKeyMessageFormat_X509;
	else
		format = kPGPPublicKeyMessageFormat_PKCS1;
	err = PGPNewPrivateKeyContext( 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, NULL, NULL, &sigSize );
	CKERR;
	
	switch( session->requestedPrime )
	{
		case kPGPtls_DHPrime1024:
			prime = &DH_1024bitPrime;
			break;
		case kPGPtls_DHPrime1536:
			prime = &DH_1536bitPrime;
			break;
		default:
		case kPGPtls_DHPrime2048:
			prime = &DH_2048bitPrime;
			break;
		case kPGPtls_DHPrime3072:
			prime = &DH_3072bitPrime;
			break;
		case kPGPtls_DHPrime4096:
			prime = &DH_4096bitPrime;
			break;
	}
	/* Load up the prime modulus */
	err = PGPNewBigNum( session->memMgr, TRUE, &session->dhP ); CKERR;
	err =  PGPBigNumInsertBigEndianBytes(	session->dhP,
											prime->prime,
											0, prime->length ); CKERR;
	/* We always use a generator of 2 for speed */
	err = PGPNewBigNum( session->memMgr, TRUE, &session->dhG ); CKERR;
	err =  PGPBigNumInsertBigEndianBytes(	session->dhG,
											dhGenerator,
											0, sizeof(dhGenerator) ); CKERR;
	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;
	}
	/* Generate the secret random X value */
	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;
	/* Generate our server Y value */
	err = PGPNewBigNum( session->memMgr, TRUE, &session->dhYs ); CKERR;
	err = PGPBigNumExpMod( session->dhG, session->dhX, session->dhP,
							session->dhYs ); CKERR;
	pSize = ( ( PGPBigNumGetSignificantBits( session->dhP ) + 7 ) / 8 );
	gSize = ( ( PGPBigNumGetSignificantBits( session->dhG ) + 7 ) / 8 );
	ySSize = ( ( PGPBigNumGetSignificantBits( session->dhYs ) + 7 ) / 8 );
	buffer  = PGPNewData( session->memMgr,
							pSize + gSize + ySSize + 8 + sigSize, 0 );
	if( IsNull( buffer ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}
	/* Write out p */
	PGPUInt16ToEndian( (PGPUInt16) pSize, kPGPBigEndian, &buffer[pktLen] );
	pktLen += sizeof(PGPUInt16);
	err = PGPBigNumExtractBigEndianBytes( session->dhP,
									&buffer[pktLen],
									0, pSize ); CKERR;
	pktLen += pSize;
	/* Write out g */
	PGPUInt16ToEndian( (PGPUInt16) gSize, kPGPBigEndian, &buffer[pktLen] );
	pktLen += sizeof(PGPUInt16);
	err = PGPBigNumExtractBigEndianBytes( session->dhG,
									&buffer[pktLen],
									0, gSize ); CKERR;
	pktLen += gSize;
	/* Write out yS */
	PGPUInt16ToEndian( (PGPUInt16) ySSize, kPGPBigEndian, &buffer[pktLen] );
	pktLen += sizeof(PGPUInt16);
	err = PGPBigNumExtractBigEndianBytes( session->dhYs,
									&buffer[pktLen],
									0, ySSize ); CKERR;
	pktLen += ySSize;
	err = PGPNewHashContext( session->memMgr, kPGPHashAlgorithm_SHA,
						&skeHashSHA ); CKERR;
	(void)PGPContinueHash( skeHashSHA, session->cRandom, kPGPtls_RandomSize);
	(void)PGPContinueHash( skeHashSHA, session->sRandom, kPGPtls_RandomSize);
	(void)PGPContinueHash( skeHashSHA, buffer, pktLen);
	switch( session->cipherSuites[session->cipherSuiteIndex].sigAlg )
	{
		case kPGPPublicKeyAlgorithm_DSA:
		{
			PGPByte		signedData[ kPGPtls_HA_SHASize ];
			
			/* Create the Signature */			
			(void)PGPFinalizeHash( skeHashSHA, signedData );
			err = PGPPrivateKeySignRaw( privKeyCon, signedData,
									kPGPtls_HA_SHASize, buffer + pktLen + 2,
									&actSigSize ); CKERR;
			PGPUInt16ToEndian( (PGPUInt16) actSigSize, kPGPBigEndian,
								&buffer[pktLen] );
			break;
		}

⌨️ 快捷键说明

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