Crypt-MatrixSSL

 view release on metacpan or  search on metacpan

matrixssl-1-8-6-open/src/sslv3.c  view on Meta::CPAN

		matrixSha1Update(&sha1Ctx, salt[i], i + 1);
		matrixSha1Update(&sha1Ctx, ssl->sec.premaster, ssl->sec.premasterSize);
		matrixSha1Update(&sha1Ctx, ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE);
		matrixSha1Update(&sha1Ctx, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE);
		matrixSha1Final(&sha1Ctx, buf);
		
		matrixMd5Init(&md5Ctx);
		matrixMd5Update(&md5Ctx, ssl->sec.premaster, ssl->sec.premasterSize);
		matrixMd5Update(&md5Ctx, buf, SSL_SHA1_HASH_SIZE);
		matrixMd5Final(&md5Ctx, tmp);
		tmp += SSL_MD5_HASH_SIZE;
	}
	memset(buf, 0x0, SSL_MD5_HASH_SIZE + SSL_SHA1_HASH_SIZE);
/*
	premaster is now allocated for DH reasons.  Can free here
*/
	psFree(ssl->sec.premaster);
	ssl->sec.premaster = NULL;
	ssl->sec.premasterSize = 0;

skipPremaster:
	if (createKeyBlock(ssl, ssl->sec.clientRandom, ssl->sec.serverRandom, 
			ssl->sec.masterSecret, SSL_HS_MASTER_SIZE) < 0) {
		matrixStrDebugMsg("Unable to create key block\n", NULL);
		return -1;
	}
	
	return SSL_HS_MASTER_SIZE;
}

/******************************************************************************/
/*
	Generate the key block as follows.  '+' indicates concatination.  
	key_block =
		MD5(master_secret + SHA(`A' + master_secret +
			ServerHello.random + ClientHello.random)) +
		MD5(master_secret + SHA(`BB' + master_secret +
			ServerHello.random + ClientHello.random)) +
		MD5(master_secret + SHA(`CCC' + master_secret +
			ServerHello.random + ClientHello.random)) + 
		[...];
*/
static int32 createKeyBlock(ssl_t *ssl, unsigned char *clientRandom,
						  unsigned char *serverRandom,
						  unsigned char *masterSecret, int32 secretLen)
{
	sslMd5Context_t		md5Ctx;
	sslSha1Context_t	sha1Ctx;
	unsigned char		buf[SSL_MD5_HASH_SIZE + SSL_SHA1_HASH_SIZE];
	unsigned char		*tmp;
	int32				keyIter, i, ret = 0;
	int32				reqKeyLen;

/*
	We must generate enough key material to fill the various keys
*/
	reqKeyLen = 2 * ssl->cipher->macSize + 
				2 * ssl->cipher->keySize + 
				2 * ssl->cipher->ivSize;
/*
	Find the right number of iterations to make the requested length key block
*/
	keyIter = 1;
	while (SSL_MD5_HASH_SIZE * keyIter < reqKeyLen) {
		keyIter++;
	}
	if (keyIter > sizeof(salt)/sizeof(char*)) {
		matrixIntDebugMsg("Error: Not enough salt for key length of %d\n",
			reqKeyLen);
		return -1;
	}

	tmp = ssl->sec.keyBlock;
	for (i = 0; i < keyIter; i++) {
		matrixSha1Init(&sha1Ctx);
		matrixSha1Update(&sha1Ctx, salt[i], i + 1);
		matrixSha1Update(&sha1Ctx, masterSecret, secretLen);
		matrixSha1Update(&sha1Ctx, serverRandom, SSL_HS_RANDOM_SIZE);
		matrixSha1Update(&sha1Ctx, clientRandom, SSL_HS_RANDOM_SIZE);
		matrixSha1Final(&sha1Ctx, buf);
		
		matrixMd5Init(&md5Ctx);
		matrixMd5Update(&md5Ctx, masterSecret, secretLen);
		matrixMd5Update(&md5Ctx, buf, SSL_SHA1_HASH_SIZE);
		matrixMd5Final(&md5Ctx, tmp);
		tmp += SSL_MD5_HASH_SIZE;
		ret += SSL_MD5_HASH_SIZE;
	}
	memset(buf, 0x0, SSL_MD5_HASH_SIZE + SSL_SHA1_HASH_SIZE);
/*
	Client and server use different read/write values, with the Client 
	write value being the server read value.
*/
	if (ssl->flags & SSL_FLAGS_SERVER) {
		ssl->sec.rMACptr = ssl->sec.keyBlock;
		ssl->sec.wMACptr = ssl->sec.rMACptr + ssl->cipher->macSize;
		ssl->sec.rKeyptr = ssl->sec.wMACptr + ssl->cipher->macSize;
		ssl->sec.wKeyptr = ssl->sec.rKeyptr + ssl->cipher->keySize;
		ssl->sec.rIVptr = ssl->sec.wKeyptr + ssl->cipher->keySize;
		ssl->sec.wIVptr = ssl->sec.rIVptr + ssl->cipher->ivSize;
	} else {
		ssl->sec.wMACptr = ssl->sec.keyBlock;
		ssl->sec.rMACptr = ssl->sec.wMACptr + ssl->cipher->macSize;
		ssl->sec.wKeyptr = ssl->sec.rMACptr + ssl->cipher->macSize;
		ssl->sec.rKeyptr = ssl->sec.wKeyptr + ssl->cipher->keySize;
		ssl->sec.wIVptr = ssl->sec.rKeyptr + ssl->cipher->keySize;
		ssl->sec.rIVptr = ssl->sec.wIVptr + ssl->cipher->ivSize;
	}

	return ret;
}

/******************************************************************************/
/*
	Combine the running hash of the handshake mesages with some constants
	and mix them up a bit more.  Output the result to the given buffer.
	This data will be part of the Finished handshake message.
*/
int32 sslGenerateFinishedHash(sslMd5Context_t *md5, sslSha1Context_t *sha1, 
								unsigned char *masterSecret,
								unsigned char *out, int32 sender)



( run in 0.583 second using v1.01-cache-2.11-cpan-71847e10f99 )