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

📄 ccontrolthread.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	authwrit = byteFifoWrite(mOriginator? &mOAuthentication : &mAAuthentication, p, e-p);
	pgpAssert(authwrit == e-p);
	mControlOutQ->Send(_mt_controlPacket, p, e-p);
}

void
CControlThread::SetupEncryption(short dir)
{
	uchar s[256];
	ulong len;
	ushort keylen;
	uchar *p, *e;

	keylen = KeySize(mEncryptor);
	if(byteFifoSize(&mSharedSecret) < keylen)
		ProtocolViolation(_pv_badPrime);
	else
	{
		for(e=s;keylen;e+=len)
		{
			p = byteFifoGetBytes(&mSharedSecret, &len);
			len = (keylen < len ? keylen : len);
			pgp_memcpy(e, p, len);
			byteFifoSkipBytes(&mSharedSecret, len);
			keylen -= len;
		}
		if(dir)
			mOutHPP->ChangeTXKey(s, mEncryptor, 0, 0);
		else
			mInHPP->ChangeRXKey(s, mEncryptor, 0, 0);
#ifdef DEBUGCONFIG
		char t[256];
		short i, ks = KeySize(mEncryptor);
		
		for(i=0,p=(uchar *)t;i<ks;i++,p+=2)
			sprintf((char *)p, "%02x", s[i]);
		*p=0;
		if(dir)
			strcat(t, "(e)");
		else
			strcat(t, "(d)");
		mStatusPane->AddStatus(0,t);
		DebugLog("%s",t);
#endif
		memset(s, 0, 256);	// erase key material after use
	}
}

Boolean
CControlThread::ReceiveDHPublic(uchar *data, short length)
{
	Boolean good = TRUE;
	short plen, err;
	ulong len;
	uchar *e, *p, h[32];
	SHA hash;
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"ReceiveDHPublic");
#endif
	e = data;
	BUFFER_TO_SHORT(e, plen);
	e+=2;
	if((plen == mPrime->length) && (length == mPrime->length+sizeof(short)))
	{
		// Make sure the public field matches the hash they sent
		hash.Init();
		hash.Update(e, plen);
		hash.Final(h);
		if(!memcmp(h, mDHHash, SHS_DIGESTSIZE))
		{
			// Do second half of Diffie-Hellman
			// to obtain encryption keys
			err = dhSecondHalf(mPrime->prime, mPrime->length,
				dhGenerator, sizeof(dhGenerator),
				mDHPrivate, mPrime->length,
				e, mPrime->length, &mSharedSecret, NIL);
			pgpAssert(err>=0);
			mStatusPane->AddStatus(0,
				"Completed Diffie-Hellman key agreement.");
			hash.Init();
			len = byteFifoSize(&mOAuthentication);
			while((p = byteFifoGetBytes(&mOAuthentication, &len)) != NULL)
			{
				hash.Update(p, len);
				byteFifoSkipBytes(&mOAuthentication, len);
			}
			len = byteFifoSize(&mAAuthentication);
			while((p = byteFifoGetBytes(&mAAuthentication, &len)) != NULL)
			{
				hash.Update(p, len);
				byteFifoSkipBytes(&mAAuthentication, len);
			}
			hash.Final(h);
			pgp_memcpy(mAuthInfo, h, 4);
			// all future packets are now encrypted
			SetupEncryption(mOriginator);
			SetupEncryption(!mOriginator);
		}
		else
			good = FALSE;
	}
	else
		good = FALSE;
	return good;
}

void
CControlThread::SendDHPublic()
{
	uchar *p, *e, alen[4];
	long authwrit;
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"SendDHPublic");
#endif
	// the following block of code sends the _ctp_DHPublic packet
	// which is the result of the initial Diffie-Hellman
	// calculation previously committed to by the hash we
	// sent.
	p = e = (uchar *)pgp_malloc(768);
	pgpAssert(p);
	pgpAssert(mPrime->length < 700);
	*e++ = _ctp_DHPublic;
	SHORT_TO_BUFFER(mPrime->length, e);
	e+=2;
	pgp_memcpy(e, mDHPublic, mPrime->length);
	e+=mPrime->length;
	SHORT_TO_BUFFER((short)(e-p), alen);
	authwrit = byteFifoWrite(mOriginator? &mOAuthentication : &mAAuthentication, alen, 2);
	pgpAssert(authwrit == 2);
	authwrit = byteFifoWrite(mOriginator? &mOAuthentication : &mAAuthentication, p, e-p);
	pgpAssert(authwrit == e-p);
	mControlOutQ->Send(_mt_controlPacket, p, e-p);
}

Boolean
CControlThread::ReceiveHello(uchar *data, short length)
{
	uchar *p, *e, *u, *t, *v, s[NUM_DH_PRIMES * 8], rmtSalt[8], h[32],
			*foundHash=NIL, alg;
	short len, num, inx, cnt, cryp, j, found, foundPrime=-1, localPrime=-1;
	uchar vers;
	Boolean good;
	SHA hash;
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"ReceiveHello");
#endif
	good = TRUE;
	len = 0;
	for(p=data,e=data+length;p<e;p+=len)
	{
		num = *p++;
		if(p == e)
		{
			good = FALSE;
			break;
		}
		len = *p++;
		if(e-p < len)
		{
			good = FALSE;
			break;
		}
		switch(num)
		{
			case _cti_Version:
				vers = *p;
				if(vers > pgpfMajorProtocolVersion)
				{
					mStatusPane->AddStatus(0, "Incompatible PGPfone versions, terminating call.");
					mStatusPane->AddStatus(0, "Please get the latest PGPfone at:");
					mStatusPane->AddStatus(0, "http://web.mit.edu/pgp");
					good = FALSE;
				}
				break;
			case _cti_PublicName:
				if(len>0)
				{
					if(len>63)
						len=63;
					pgp_memcpy(mRemotePublicName,p,len);
					mRemotePublicName[len]=0;
				}
				break;
			case _cti_HashAlg:
				if(len >= 4)
				{
					if(memcmp(p, "SHA1", 4))	// only SHA for now
					{
						mStatusPane->AddStatus(0,
							"Could not negotiate a hash algorithm.");
						good = FALSE;
					}
				}
				break;
			case _cti_PrimeHashList:
				mPrime = NIL;
				if(len >= 16)
				{
					pgp_memcpy(rmtSalt, p, 8);
					for(u=s,inx=0;inx<mNumPrimes;inx++,u+=8)
					{
						hash.Init();
						hash.Update(rmtSalt, 8);
						alg = 2;
						hash.Update(&alg, 1);
						hash.Update(mPrimes[inx]->prime,
									mPrimes[inx]->length);
						hash.Final(h);
						pgp_memcpy(u, h, 8);
					}
					v=p+8;
					found = (len - 8) / 8;
					for(u=s,inx=0;inx<mNumPrimes;inx++,u+=8)
					{
						for(t=v,j=0;j<found;j++,t+=8)
						{
							if(!memcmp(u, t, 8))
							{
								// Remember this prime if it's earlier
								// (more preferred) in their list than
								// the one we've already found.
								if(!foundHash || (t<foundHash))
								{
									foundHash=t;
									foundPrime=inx;
								}
								// Remember the first prime we find (in
								// descending order of *our* priority)
								// that's on their list.
								if(localPrime<0)
									localPrime = inx;
							}
						}
					}
					if(localPrime>=0 && foundPrime>=0)
					{
						if(mPrimes[localPrime]->length > mPrimes[foundPrime]->length)
							mPrime = mPrimes[localPrime];
						else if(mPrimes[localPrime]->length < mPrimes[foundPrime]->length)
							mPrime = mPrimes[foundPrime];
						else if(memcmp(mPrimes[localPrime]->prime,
										mPrimes[foundPrime]->prime,
										mPrimes[localPrime]->length) > 0)
							mPrime = mPrimes[localPrime];
						else
							mPrime = mPrimes[foundPrime];
					}
					if(mPrime)
					{
						char str[32];

						sprintf(str,"DH(%d)",mPrime->length * 8);
						mPFWindow->SetKeyExchange(str);
						mStatusPane->AddStatus(0,
							"Agreed upon a %d bit prime.",
							mPrime->length * 8);
					}
				}
				if(!mPrime)
				{
					mStatusPane->AddStatus(0,
						"Could not negotiate a prime.");
					good = FALSE;
				}
				break;
			case _cti_EncryptAlgorithms:
				cnt = len / 4;
				if(mOriginator)
				{
					found = -1;
					for(u=p,inx=0;inx<cnt;inx++,u+=4)
						if(!memcmp(sCryptorHash[gPGFOpts.popt.prefEncryptor], u, 4))
						{
							found = gPGFOpts.popt.prefEncryptor;
							break;
						}
					if(found < 0)
						for(cryp=0;cryp<NUMCRYPTORS && found<0;cryp++)
							if((cryp != gPGFOpts.popt.prefEncryptor) &&
								(gPGFOpts.popt.cryptorMask & (1<<cryp)))
							{
								for(u=p,inx=0;inx<cnt;inx++,u+=4)
									if(!memcmp(sCryptorHash[cryp], u, 4))
									{
										found = cryp;
										break;
									}
							}
					
				}
				else
				{
					for(u=p,inx=0;inx<cnt;inx++,u+=4)
						if(gPGFOpts.popt.cryptorMask & (1<<(cryp=GetCryptorID(u))))
						{
							found = cryp;
							break;
						}
				}
				if(found>=0)
					pgp_memcpy(mEncryptor, sCryptorHash[found], 4);
				else
				{
					mStatusPane->AddStatus(0, "Could not negotiate encryption.");
					good = FALSE;
				}
				break;
			default:
				// unknown data, so ignore it
				break;
		}
	}
	return good;
}

void
CControlThread::SendHello()
{
	uchar *p, *e, *r, *u, s[128], alg, alen[4];
	ulong authwrit;
	short inx, cnt;
	SHA hash;
	static DHPrime *primes[NUM_DH_PRIMES] = {
		&DH_768bitPrime, &DH_1024bitPrime,
		&DH_1536bitPrime, &DH_2048bitPrime, &DH_3072bitPrime,
		&DH_4096bitPrime };
	
#ifdef DEBUGCONFIG
	mStatusPane->AddStatus(0,"SendHello");
#endif
	// the following block of code sends the _ctp_Hello packet
	// which is the first config packet establishing basic
	// parameters such as which prime and which encryption
	// algorithms to use.
	p = e = (uchar *)pgp_malloc(512);
	pgpAssert(p);
	*e++ = _ctp_Hello;
	*e++ = _cti_Version;
	*e++ = 2;
	*e++ = pgpfMajorProtocolVersion;
	*e++ = pgpfMinorProtocolVersion;
	if(gPGFOpts.popt.idUnencrypted &&
		((mOriginator && gPGFOpts.popt.idOutgoing) ||
		(!mOriginator && gPGFOpts.popt.idIncoming)) &&
		gPGFOpts.popt.identity[0])
	{
		*e++ = _cti_PublicName;
		*e++ = strlen(gPGFOpts.popt.identity);
		strcpy((char *)e, gPGFOpts.popt.identity);
		e+= strlen((char *)e);
	}
	*e++ = _cti_HashAlg;
	*e++ = 4;
	pgp_memcpy(e, "SHA1", 4);
	e+=4;
	*e++ = _cti_PrimeHashList;
	u=e++;
	// Setup internal structure of prime preferences
	// Start with preferred prime upwards and then down
	for(inx=gPGFOpts.popt.prefPrime;inx<NUM_DH_PRIMES;inx++)
	{
		if(gPGFOpts.popt.primeMask & (1 << inx))
		{
			mPrimes[mNumPrimes] = primes[inx];
			mNumPrimes++;
		}
	}
	for(inx=gPGFOpts.popt.prefPrime-1;inx>=0;inx--)
	{
		if(gPGFOpts.popt.primeMask & (1 << inx))
		{
			mPrimes[mNumPrimes] = primes[inx];
			mNumPrimes++;
		}
	}
	// send random salt to obscure primes
	randPoolGetBytes(r=e, 8);
	e+=8;
	cnt = 8;
	// send salted hashes of allowed primes in preferred order 
	for(inx=0;inx<mNumPrimes;inx++)
	{
		hash.Init();
		hash.Update(r, 8);	// Hash the salt with the prime
		alg = 2;			// Diffie-Hellman Algorithm Identifier
		hash.Update(&alg, 1);
		hash.Update(mPrimes[inx]->prime, mPrimes[inx]->length);
		hash.Final(s);
		pgp_memcpy(e, s, 8);
		e+=8;
		cnt+=8;
	}
	*u = cnt;
	// send a list of the encryption algorithms we support preference first
	*e++ = _cti_EncryptAlgorithms;
	u=e++;	cnt = 0;
	if(mOriginator && (gPGFOpts.popt.prefEncryptor >= 0))
	{
		pgp_memcpy(e, sCryptorHash[gPGFOpts.popt.prefEncryptor], 4); e+=4; cnt+=4;
	}
	for(inx=0;inx<NUMCRYPTORS;inx++)
	{
		if((!mOriginator || (inx != gPGFOpts.popt.prefEncryptor)) &&
			(gPGFOpts.popt.cryptorMask & (1<<inx)))
		{
			pgp_memcpy(e, sCryptorHash[inx], 4); e+=4; cnt+=4;
		}
	}
	*u = cnt;
	if(gPGFOpts.popt.cryptorMask & (1 << _enc_none))
		mAllowNone = TRUE;
	SHORT_TO_BUFFER((short)(e-p), alen);
	authwrit = byteFifoWrite(mOriginator? &mOAuthentication : &mAAuthentication, alen, 2);
	pgpAssert(authwrit == 2);
	authwrit = byteFifoWrite(mOriginator? &mOAuthentication : &mAAuthentication, p, e-p);
	pgpAssert(authwrit == e-p);
	mControlOutQ->Send(_mt_controlPacket, p, e-p);
}

void
CControlThread::ProtocolViolation(enum ProtViolation id)
{
	// This function is intended to receive notices from the lower
	// layers about protocol violations so it can decide what to
	// do about them.
	
	switch(id)
	{
		case _pv_invalidSound:
			// In the case of serial, we want to disconnect here.  The most
			// likely cause is that the remote party has disconnected
			// unexpectedly and our own packets are being echoed back
			// to us, decrypted by the wrong key, and attempted to be
			// played.
			// In the case of internet or appletalk, we'll just ignore it
			// because connection shutdown is very clean on both of those.
			
			if(mControlState != _con_Disconnecting)
			{
				AbortSync(FALSE, TRUE);	//act like the other side hungup
				mStatusPane->AddStatus(0, "Unexpected disconnection.");
			}
			break;
		case _pv_badPrime:
			// The Diffie-Hellman prime selected is not adequate for the
			// encryption algorithms selected.
			
			if(mControlState != _con_Disconnecting)
			{
				AbortSync(FALSE, FALSE);
				mStatusPane->AddStatus(0, "Diffie-Hellman prime not large enough, terminating call.");
			}
			break;
		case _pv_noRemote:
			// The remote end has failed to respond to a reliable packet.
			// We retry 10 times over 20 seconds.  No response disconnects
			// the call.
			
			if(mControlState != _con_Disconnecting)
			{
				AbortSync(FALSE, TRUE);
				mStatusPane->AddStatus(0, "Remote is not responding, terminating call.");
			}
			break;
	}
}

void
CControlThread::GetCryptorName(short id, uchar *name)
{
	switch(id)
	{
		case _enc_none:		pgp_memcpy(name, "NONE", 4);	break;
		case _enc_tripleDES:pgp_memcpy(name, "TDEA", 4);	break;
		case _enc_blowfish:	pgp_memcpy(name, "BLOW", 4);	break;
		case _enc_cast:		pgp_memcpy(name, "CAST", 4);	break;
	}
}

short
CControlThread::GetCryptorID(uchar *name)
{
	if(!memcmp(name, "TDEA", 4))
		return _enc_tripleDES;
	else if(!memcmp(name, "BLOW", 4))
		return _enc_blowfish;
	else if(!memcmp(name, "CAST", 4))
		return _enc_cast;
	else if(!memcmp(name, "NONE", 4))
		return _enc_none;
	return _enc_none+1;		// return one higher than known for invalid
}

void
CControlThread::GetRemoteName(char *name)
{
	strcpy(name, mRemotePublicName);
}

void
CControlThread::SetRemoteName(char *name)
{
	strcpy(mRemotePublicName, name);
}

void
CControlThread::PlayInsecureWarning()
{
#ifdef	PGP_MACINTOSH
	SndListHandle respSound;
	
	if((respSound = (SndListHandle)GetNamedResource('snd ', "\pInsecure")) != NULL)
	{
		HLock((Handle)respSound);
		SndPlay(nil, respSound, false);
		HUnlock((Handle)respSound);
	}
#elif	PGP_WIN32
	PlaySound("INSECURE.WAV", NULL, SND_FILENAME+SND_SYNC);
#endif
}

void
CControlThread::SetXferWindow(CXferWindow *xferWindow)
{
	mXferWindow = xferWindow;
}

enum SystType
CControlThread::GetRemoteSystemType()
{
	return mRemoteSystemType;
}

⌨️ 快捷键说明

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