/* 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; }
/* 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; } }
/* 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); }
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); } }
/* 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; }
/* 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; }
void shape::writeShape( FILE * out, int recordNumber ) { writeRecordHeader( out, recordNumber ); //Write a NULL SHAPE fwrite(&shapetype,sizeof(int),1, out); }