Beispiel #1
0
/*
	ServerHelloDone message is a blank handshake message
*/
static int32 writeServerHelloDone(ssl_t *ssl, sslBuf_t *out)
{
	unsigned char	*c, *end, *encryptStart;
	char			padLen;
	int32				messageSize, rc;

	c = out->end;
	end = out->buf + out->size;
	messageSize =
		ssl->recordHeadLen +
		ssl->hshakeHeadLen;

	if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
			SSL_HS_SERVER_HELLO_DONE, &messageSize, &padLen,
			&encryptStart, &end, &c)) < 0) {
		return rc;
	}

	if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
			padLen, encryptStart, out, &c)) < 0) {
		return rc;
	}

	if (c - out->end != messageSize) {
		matrixStrDebugMsg("Error generating hello done for write\n", NULL);
		return SSL_ERROR;
	}
	out->end = c;
	return SSL_SUCCESS;
}
Beispiel #2
0
/*
	Write a Certificate message.
	The encoding of the message is as follows:
		3 byte length of certificate data (network byte order)
		If there is no certificate,
			3 bytes of 0
		If there is one certificate,
			3 byte length of certificate + 3
			3 byte length of certificate
			certificate data
		For more than one certificate:
			3 byte length of all certificate data
			3 byte length of first certificate
			first certificate data
			3 byte length of second certificate
			second certificate data
	Certificate data is the base64 section of an X.509 certificate file
	in PEM format decoded to binary.  No additional interpretation is required.
*/
static int32 writeCertificate(ssl_t *ssl, sslBuf_t *out, int32 notEmpty)
{
	sslLocalCert_t	*cert;
	unsigned char	*c, *end, *encryptStart;
	char			padLen;
	int32			totalCertLen, certLen, lsize, messageSize, i, rc;


	c = out->end;
	end = out->buf + out->size;

/*
	Determine total length of certs
*/
	totalCertLen = i = 0;
	if (notEmpty) {
		cert = &ssl->keys->cert;
		for (; cert != NULL; i++) {
			totalCertLen += cert->certLen;
			cert = cert->next;
		}
	}
/*
	Account for the 3 bytes of certChain len for each cert and get messageSize
*/
	lsize = 3 + (i * 3);
	messageSize =
		ssl->recordHeadLen +
		ssl->hshakeHeadLen +
		lsize + totalCertLen;

	if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
			SSL_HS_CERTIFICATE, &messageSize, &padLen, &encryptStart,
			&end, &c)) < 0) {
		return rc;
	}

/*
	Write out the certs
*/
	*c = ((totalCertLen + (lsize - 3)) & 0xFF0000) >> 16; c++;
	*c = ((totalCertLen + (lsize - 3)) & 0xFF00) >> 8; c++;
	*c = ((totalCertLen + (lsize - 3)) & 0xFF); c++;

	if (notEmpty) {
		cert = &ssl->keys->cert;
		while (cert) {
			certLen = cert->certLen;
			if (certLen > 0) {
				*c = (certLen & 0xFF0000) >> 16; c++;
				*c = (certLen & 0xFF00) >> 8; c++;
				*c = (certLen & 0xFF); c++;
				memcpy(c, cert->certBin, certLen);
				c += certLen;
			}
			cert = cert->next;
		}
	}
Beispiel #3
0
/*
	Encode the incoming data into the out buffer for sending to remote peer.

	FUTURE SECURITY - If sending the first application data record, we could
	prepend it with a blank SSL record to avoid a timing attack.  We're fine
	for now, because this is an impractical attack and the solution is 
	incompatible with some SSL implementations (including some versions of IE).
	http://www.openssl.org/~bodo/tls-cbc.txt
*/
int32 matrixSslEncode(ssl_t *ssl, unsigned char *in, int32 inlen, sslBuf_t *out)
{
	unsigned char	*c, *end, *encryptStart;
	char			padLen;
	int32			messageSize, rc;
/*
	If we've had a protocol error, don't allow further use of the session
	Also, don't allow a application data record to be encoded unless the
	handshake is complete.
*/
	if (ssl->flags & SSL_FLAGS_ERROR || ssl->hsState != SSL_HS_DONE ||
			ssl->flags & SSL_FLAGS_CLOSED) {
		return SSL_ERROR;
	}
	c = out->end;
	end = out->buf + out->size;
	messageSize = ssl->recordHeadLen + inlen;

/*
	Validate size constraint
*/
	if (messageSize > SSL_MAX_BUF_SIZE) {
		return SSL_ERROR;
	}

	if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_APPLICATION_DATA, 0,
			&messageSize, &padLen, &encryptStart, &end, &c)) < 0) {
		return rc;
	}

	memcpy(c, in, inlen);
	c += inlen;

	if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_APPLICATION_DATA,
			messageSize, padLen, encryptStart, out, &c)) < 0) {
		return rc;
	}
	out->end = c;

	return (int32)(out->end - out->start);
}
Beispiel #4
0
void shp_polyline::writeShape( FILE * out, int recordNumber )
{	writeRecordHeader( out, recordNumber );
	
	fwrite(&shapetype,sizeof(int),1, out);
	
	double shapeBounds[4];
	shapeBounds[0] = topLeft.getX();
	shapeBounds[1] = bottomRight.getY();
	shapeBounds[2] = bottomRight.getX();
	shapeBounds[3] = topLeft.getY();
	fwrite(shapeBounds,sizeof(double),4, out);
	
	int numParts = parts.size();
	if( numParts <= 0 )
		numParts = 1;
	fwrite(&numParts,sizeof(int),1, out);
	int numPoints = allPoints.size();
	fwrite(&numPoints,sizeof(int),1, out);
	
	if( parts.size() > 0 )
	{	for( int i = 0; i < parts.size(); i++ )
		{	int recordPart = parts[i];
			fwrite(&recordPart,sizeof(int), 1, out);		
		}
	}
	else
	{	int recordPart = 0;
		fwrite( &recordPart, sizeof(int), 1, out );
	}

	//Input points
	double x,y;
	for( int j = 0; j < allPoints.size(); j++ )
	{	api_point p = allPoints[j];
		x = p.getX();
		y = p.getY();		
		fwrite(&x,sizeof(double),1, out);
		fwrite(&y,sizeof(double),1, out);
	}
}
Beispiel #5
0
/*
	Server initiated rehandshake public API call.
*/
int32 matrixSslEncodeHelloRequest(ssl_t *ssl, sslBuf_t *out)
{
	unsigned char	*c, *end, *encryptStart;
	char			padLen;
	int32				messageSize, rc;

	if (ssl->flags & SSL_FLAGS_ERROR || ssl->flags & SSL_FLAGS_CLOSED) {
		return SSL_ERROR;
	}
	if (!(ssl->flags & SSL_FLAGS_SERVER) || (ssl->hsState != SSL_HS_DONE)) {
		return SSL_ERROR;
	}

	c = out->end;
	end = out->buf + out->size;
	messageSize =
		ssl->recordHeadLen +
		ssl->hshakeHeadLen;
	if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
			SSL_HS_HELLO_REQUEST, &messageSize, &padLen,
			&encryptStart, &end, &c)) < 0) {
		return rc;
	}

	if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
			padLen, encryptStart, out, &c)) < 0) {
		return rc;
	}

	if (c - out->end != messageSize) {
		matrixStrDebugMsg("Error generating hello request for write\n", NULL);
		return SSL_ERROR;
	}
	out->end = c;

	return SSL_SUCCESS;
}
Beispiel #6
0
/*
	Write out the ServerHello message
*/
static int32 writeServerHello(ssl_t *ssl, sslBuf_t *out)
{
	unsigned char	*c, *end, *encryptStart;
	char			padLen;
	int32				messageSize, rc;
	time_t			t;

	c = out->end;
	end = out->buf + out->size;
/*
	Calculate the size of the message up front, and verify we have room
	We assume there will be a sessionId in the message, and make adjustments
	below if there is no sessionId.
*/
	messageSize =
		ssl->recordHeadLen +
		ssl->hshakeHeadLen +
		38 + SSL_MAX_SESSION_ID_SIZE;
/*
	First 4 bytes of the serverRandom are the unix time to prevent replay
	attacks, the rest are random
*/
	t = time(0);
	ssl->sec.serverRandom[0] = (unsigned char)((t & 0xFF000000) >> 24);
	ssl->sec.serverRandom[1] = (unsigned char)((t & 0xFF0000) >> 16);
	ssl->sec.serverRandom[2] = (unsigned char)((t & 0xFF00) >> 8);
	ssl->sec.serverRandom[3] = (unsigned char)(t & 0xFF);
	if (sslGetEntropy(ssl->sec.serverRandom + 4, SSL_HS_RANDOM_SIZE - 4) < 0) {
		matrixStrDebugMsg("Error gathering serverRandom entropy\n", NULL);
		return SSL_ERROR;
	}
/*
	We register session here because at this point the serverRandom value is
	populated.  If we are able to register the session, the sessionID and
	sessionIdLen fields will be non-NULL, otherwise the session couldn't
	be registered.
*/
	if (!(ssl->flags & SSL_FLAGS_RESUMED)) {
		matrixRegisterSession(ssl);
	}
	messageSize -= (SSL_MAX_SESSION_ID_SIZE - ssl->sessionIdLen);

	if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
			SSL_HS_SERVER_HELLO, &messageSize, &padLen, &encryptStart,
			&end, &c)) < 0) {
		return rc;
	}
/*
	First two fields in the ServerHello message are the major and minor
	SSL protocol versions we agree to talk with
*/
	*c = ssl->majVer; c++;
	*c = ssl->minVer; c++;
/*
	The next 32 bytes are the server's random value, to be combined with
	the client random and premaster for key generation later
*/
	memcpy(c, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE);
	c += SSL_HS_RANDOM_SIZE;
/*
	The next data is a single byte containing the session ID length,
	and up to 32 bytes containing the session id.
	First register the session, which will give us a session id and length
	if not all session slots in the table are used
*/
	*c = ssl->sessionIdLen; c++;
	if (ssl->sessionIdLen > 0) {
        memcpy(c, ssl->sessionId, ssl->sessionIdLen);
		c += ssl->sessionIdLen;
	}
/*
	Two byte cipher suite we've chosen based on the list sent by the client
	and what we support.
	One byte compression method (always zero)
*/
	*c = (ssl->cipher->id & 0xFF00) >> 8; c++;
	*c = ssl->cipher->id & 0xFF; c++;
	*c = 0; c++;

	if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
			padLen, encryptStart, out, &c)) < 0) {
		return rc;
	}
/*
	If we're resuming a session, we now have the clientRandom, master and 
	serverRandom, so we can derive keys which we'll be using shortly.
*/
	if (ssl->flags & SSL_FLAGS_RESUMED) {
		sslDeriveKeys(ssl);
	}
/*
	Verify that we've calculated the messageSize correctly, really this
	should never fail; it's more of an implementation verification
*/
	if (c - out->end != messageSize) {
		return SSL_ERROR;
	}
	out->end = c;
	return SSL_SUCCESS;
}
Beispiel #7
0
void shape::writeShape( FILE * out, int recordNumber )
{	writeRecordHeader( out, recordNumber );
	//Write a NULL SHAPE
	fwrite(&shapetype,sizeof(int),1, out);	
}