Tomato 1.26
[tomato.git] / release / src / router / matrixssl / src / sslEncode.c
blob605a3a499c66290f5997e9cb9508390c8bf20f30
1 /*
2 * sslEncode.c
3 * Release $Name: MATRIXSSL_1_8_8_OPEN $
5 * Secure Sockets Layer message encoding
6 */
7 /*
8 * Copyright (c) PeerSec Networks, 2002-2009. All Rights Reserved.
9 * The latest version of this code is available at http://www.matrixssl.org
11 * This software is open source; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This General Public License does NOT permit incorporating this software
17 * into proprietary programs. If you are unable to comply with the GPL, a
18 * commercial license for this software may be purchased from PeerSec Networks
19 * at http://www.peersec.com
21 * This program is distributed in WITHOUT ANY WARRANTY; without even the
22 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 * See the GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * http://www.gnu.org/copyleft/gpl.html
30 /******************************************************************************/
32 #include "matrixInternal.h"
34 /******************************************************************************/
36 static int32 writeCertificate(ssl_t *ssl, sslBuf_t *out, int32 notEmpty);
37 static int32 writeChangeCipherSpec(ssl_t *ssl, sslBuf_t *out);
38 static int32 writeFinished(ssl_t *ssl, sslBuf_t *out);
39 static int32 writeAlert(ssl_t *ssl, unsigned char level,
40 unsigned char description, sslBuf_t *out);
41 static int32 writeRecordHeader(ssl_t *ssl, int32 type, int32 hsType, int32 *messageSize,
42 char *padLen, unsigned char **encryptStart,
43 unsigned char **end, unsigned char **c);
45 static int32 encryptRecord(ssl_t *ssl, int32 type, int32 messageSize, int32 padLen,
46 unsigned char *encryptStart, sslBuf_t *out,
47 unsigned char **c);
49 #ifdef USE_CLIENT_SIDE_SSL
50 static int32 writeClientKeyExchange(ssl_t *ssl, sslBuf_t *out);
51 #endif /* USE_CLIENT_SIDE_SSL */
53 #ifdef USE_SERVER_SIDE_SSL
54 static int32 writeServerHello(ssl_t *ssl, sslBuf_t *out);
55 static int32 writeServerHelloDone(ssl_t *ssl, sslBuf_t *out);
56 #endif /* USE_SERVER_SIDE_SSL */
59 static int32 secureWriteAdditions(ssl_t *ssl, int32 numRecs);
61 /******************************************************************************/
63 Encode the incoming data into the out buffer for sending to remote peer.
65 FUTURE SECURITY - If sending the first application data record, we could
66 prepend it with a blank SSL record to avoid a timing attack. We're fine
67 for now, because this is an impractical attack and the solution is
68 incompatible with some SSL implementations (including some versions of IE).
69 http://www.openssl.org/~bodo/tls-cbc.txt
71 int32 matrixSslEncode(ssl_t *ssl, unsigned char *in, int32 inlen, sslBuf_t *out)
73 unsigned char *c, *end, *encryptStart;
74 char padLen;
75 int32 messageSize, rc;
77 If we've had a protocol error, don't allow further use of the session
78 Also, don't allow a application data record to be encoded unless the
79 handshake is complete.
81 if (ssl->flags & SSL_FLAGS_ERROR || ssl->hsState != SSL_HS_DONE ||
82 ssl->flags & SSL_FLAGS_CLOSED) {
83 return SSL_ERROR;
85 c = out->end;
86 end = out->buf + out->size;
87 messageSize = ssl->recordHeadLen + inlen;
90 Validate size constraint
92 if (messageSize > SSL_MAX_BUF_SIZE) {
93 return SSL_ERROR;
96 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_APPLICATION_DATA, 0,
97 &messageSize, &padLen, &encryptStart, &end, &c)) < 0) {
98 return rc;
101 memcpy(c, in, inlen);
102 c += inlen;
104 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_APPLICATION_DATA,
105 messageSize, padLen, encryptStart, out, &c)) < 0) {
106 return rc;
108 out->end = c;
110 return (int32)(out->end - out->start);
113 /******************************************************************************/
115 We indicate to the caller through return codes in sslDecode when we need
116 to write internal data to the remote host. The caller will call this
117 function to generate a message appropriate to our state.
119 int32 sslEncodeResponse(ssl_t *ssl, sslBuf_t *out)
121 int32 messageSize;
122 int32 rc = SSL_ERROR;
123 #ifdef USE_SERVER_SIDE_SSL
124 int32 totalCertLen, i;
125 sslLocalCert_t *cert;
126 #endif /* USE_SERVER_SIDE_SSL */
127 #ifdef USE_CLIENT_SIDE_SSL
128 int32 ckeSize;
129 #endif /* USE_CLIENT_SIDE_SSL */
132 We may be trying to encode an alert response if there is an error marked
133 on the connection.
135 if (ssl->err != SSL_ALERT_NONE) {
136 rc = writeAlert(ssl, SSL_ALERT_LEVEL_FATAL, ssl->err, out);
137 if (rc == SSL_ERROR) {
138 ssl->flags |= SSL_FLAGS_ERROR;
140 return rc;
145 We encode a set of response messages based on our current state
146 We have to pre-verify the size of the outgoing buffer against
147 all the messages to make the routine transactional. If the first
148 write succeeds and the second fails because of size, we cannot
149 rollback the state of the cipher and MAC.
151 switch (ssl->hsState) {
153 If we're waiting for the ClientKeyExchange message, then we need to
154 send the messages that would prompt that result on the client
156 #ifdef USE_SERVER_SIDE_SSL
157 case SSL_HS_CLIENT_KEY_EXCHANGE:
160 This is the entry point for a server encoding the first flight
161 of a non-DH, non-client-auth handshake.
163 totalCertLen = 0;
164 cert = &ssl->keys->cert;
165 for (i = 0; cert != NULL; i++) {
166 totalCertLen += cert->certLen;
167 cert = cert->next;
169 messageSize =
170 3 * ssl->recordHeadLen +
171 3 * ssl->hshakeHeadLen +
172 38 + SSL_MAX_SESSION_ID_SIZE + /* server hello */
173 3 + (i * 3) + totalCertLen; /* certificate */
176 messageSize += secureWriteAdditions(ssl, 3);
178 if ((out->buf + out->size) - out->end < messageSize) {
179 return SSL_FULL;
182 Message size complete. Begin the flight write
184 rc = writeServerHello(ssl, out);
186 if (rc == SSL_SUCCESS) {
187 rc = writeCertificate(ssl, out, 1);
190 if (rc == SSL_SUCCESS) {
191 rc = writeServerHelloDone(ssl, out);
193 break;
195 #endif /* USE_SERVER_SIDE_SSL */
198 If we're not waiting for any message from client, then we need to
199 send our finished message
201 case SSL_HS_DONE:
202 messageSize = 2 * ssl->recordHeadLen +
203 ssl->hshakeHeadLen +
204 1 + /* change cipher spec */
205 SSL_MD5_HASH_SIZE + SSL_SHA1_HASH_SIZE; /* finished */
207 Account for possible overhead in CCS message with secureWriteAdditions
208 then always account for the encrypted FINISHED message
210 messageSize += secureWriteAdditions(ssl, 1);
211 messageSize += ssl->enMacSize + /* handshake msg hash */
212 (ssl->cipher->blockSize - 1); /* max padding */
214 if ((out->buf + out->size) - out->end < messageSize) {
215 return SSL_FULL;
217 rc = writeChangeCipherSpec(ssl, out);
218 if (rc == SSL_SUCCESS) {
219 rc = writeFinished(ssl, out);
221 break;
223 If we're expecting a Finished message, as a server we're doing
224 session resumption. As a client, we're completing a normal
225 handshake
227 case SSL_HS_FINISHED:
228 #ifdef USE_SERVER_SIDE_SSL
229 if (ssl->flags & SSL_FLAGS_SERVER) {
230 messageSize =
231 3 * ssl->recordHeadLen +
232 2 * ssl->hshakeHeadLen +
233 38 + SSL_MAX_SESSION_ID_SIZE + /* server hello */
234 1 + /* change cipher spec */
235 SSL_MD5_HASH_SIZE + SSL_SHA1_HASH_SIZE; /* finished */
237 Account for possible overhead with secureWriteAdditions
238 then always account for the encrypted FINISHED message
240 messageSize += secureWriteAdditions(ssl, 2);
241 messageSize += ssl->enMacSize + /* handshake msg hash */
242 (ssl->cipher->blockSize - 1); /* max padding */
243 if ((out->buf + out->size) - out->end < messageSize) {
244 return SSL_FULL;
246 rc = writeServerHello(ssl, out);
247 if (rc == SSL_SUCCESS) {
248 rc = writeChangeCipherSpec(ssl, out);
250 if (rc == SSL_SUCCESS) {
251 rc = writeFinished(ssl, out);
254 #endif /* USE_SERVER_SIDE_SSL */
255 #ifdef USE_CLIENT_SIDE_SSL
257 Encode entry point for client side final flight encodes.
258 First task here is to find out size of ClientKeyExchange message
260 if (!(ssl->flags & SSL_FLAGS_SERVER)) {
261 ckeSize = 0;
263 Normal RSA auth cipher suite case
265 if (ssl->sec.cert == NULL) {
266 ssl->flags |= SSL_FLAGS_ERROR;
267 return SSL_ERROR;
269 ckeSize = ssl->sec.cert->publicKey.size;
271 messageSize = 0;
273 Client authentication requires the client to send a CERTIFICATE
274 and CERTIFICATE_VERIFY message. Account for the length. It
275 is possible the client didn't have a match for the requested cert.
276 Send an empty certificate message in that case (or alert for SSLv3)
278 if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) {
279 if (ssl->sec.certMatch > 0) {
281 Account for the certificate and certificateVerify messages
283 messageSize += 6 + (2 * ssl->recordHeadLen) +
284 (2 * ssl->hshakeHeadLen) + ssl->keys->cert.certLen +
285 2 + ssl->keys->cert.privKey->size;
286 } else {
288 SSLv3 sends a no_certificate warning alert for no match
290 if (ssl->majVer == SSL3_MAJ_VER
291 && ssl->minVer == SSL3_MIN_VER) {
292 messageSize += 2 + ssl->recordHeadLen;
293 } else {
295 TLS just sends an empty certificate message
297 messageSize += 3 + ssl->recordHeadLen +
298 ssl->hshakeHeadLen;
303 Account for the header and message size for all records. The
304 finished message will always be encrypted, so account for one
305 largest possible MAC size and block size. Minus one
306 for padding. The finished message is not accounted for in the
307 writeSecureAddition calls below since it is accounted for here.
309 messageSize +=
310 3 * ssl->recordHeadLen +
311 2 * ssl->hshakeHeadLen + /* change cipher has no hsHead */
312 ckeSize + /* client key exchange */
313 1 + /* change cipher spec */
314 SSL_MD5_HASH_SIZE + SSL_SHA1_HASH_SIZE + /* SSLv3 finished */
315 SSL_MAX_MAC_SIZE + SSL_MAX_BLOCK_SIZE - 1;
316 if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) {
318 Secure write for ClientKeyExchange, ChangeCipherSpec,
319 Certificate, and CertificateVerify. Don't account for
320 Certificate and/or CertificateVerify message if no auth cert.
321 This will also cover the NO_CERTIFICATE alert sent in
322 replacement of the NULL certificate message in SSLv3.
324 if (ssl->sec.certMatch > 0) {
325 messageSize += secureWriteAdditions(ssl, 4);
326 } else {
327 messageSize += secureWriteAdditions(ssl, 3);
329 } else {
330 messageSize += secureWriteAdditions(ssl, 2);
335 The actual buffer size test to hold this flight
337 if ((out->buf + out->size) - out->end < messageSize) {
338 return SSL_FULL;
340 rc = SSL_SUCCESS;
342 if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) {
343 if (ssl->sec.certMatch == 0 && ssl->majVer == SSL3_MAJ_VER
344 && ssl->minVer == SSL3_MIN_VER) {
345 rc = writeAlert(ssl, SSL_ALERT_LEVEL_WARNING,
346 SSL_ALERT_NO_CERTIFICATE, out);
347 } else {
348 rc = writeCertificate(ssl, out, ssl->sec.certMatch);
352 if (rc == SSL_SUCCESS) {
353 rc = writeClientKeyExchange(ssl, out);
355 if (rc == SSL_SUCCESS) {
356 rc = writeChangeCipherSpec(ssl, out);
358 if (rc == SSL_SUCCESS) {
359 rc = writeFinished(ssl, out);
362 #endif /* USE_CLIENT_SIDE_SSL */
363 break;
365 if (rc == SSL_ERROR) {
366 ssl->flags |= SSL_FLAGS_ERROR;
368 return rc;
371 /******************************************************************************/
373 Message size must account for any additional length a secure-write
374 would add to the message. It would be too late to check length in
375 the writeRecordHeader call since some of the handshake hashing could
376 have already taken place and we can't rewind those hashes.
378 static int32 secureWriteAdditions(ssl_t *ssl, int32 numRecs)
380 int32 add = 0;
382 There is a slim chance for a false FULL message due to the fact that
383 the maximum padding is being calculated rather than the actual number.
384 Caller must simply grow buffer and try again.
386 if (ssl->flags & SSL_FLAGS_WRITE_SECURE) {
387 add += (numRecs * ssl->enMacSize) + /* handshake msg hash */
388 (numRecs * (ssl->enBlockSize - 1)); /* max padding */
390 return add;
393 /******************************************************************************/
395 Write out a closure alert message (the only user initiated alert)
396 The user would call this when about to initate a socket close
398 int32 matrixSslEncodeClosureAlert(ssl_t *ssl, sslBuf_t *out)
401 If we've had a protocol error, don't allow further use of the session
403 if (ssl->flags & SSL_FLAGS_ERROR) {
404 return SSL_ERROR;
406 return writeAlert(ssl, SSL_ALERT_LEVEL_WARNING, SSL_ALERT_CLOSE_NOTIFY,
407 out);
410 /******************************************************************************/
412 Generic record header construction for alerts, handshake messages, and
413 change cipher spec. Determines message length for encryption and
414 writes out to buffer up to the real message data.
416 static int32 writeRecordHeader(ssl_t *ssl, int32 type, int32 hsType,
417 int32 *messageSize, char *padLen, unsigned char **encryptStart,
418 unsigned char **end, unsigned char **c)
420 int32 messageData, msn;
422 messageData = *messageSize - ssl->recordHeadLen;
423 if (type == SSL_RECORD_TYPE_HANDSHAKE) {
424 messageData -= ssl->hshakeHeadLen;
429 If this session is already in a secure-write state, determine padding
431 *padLen = 0;
432 if (ssl->flags & SSL_FLAGS_WRITE_SECURE) {
433 *messageSize += ssl->enMacSize;
434 *padLen = sslPadLenPwr2(*messageSize - ssl->recordHeadLen,
435 ssl->enBlockSize);
436 *messageSize += *padLen;
439 if (*end - *c < *messageSize) {
441 Callers other than sslEncodeResponse do not necessarily check for
442 FULL before calling. We do it here for them.
444 return SSL_FULL;
448 *c += psWriteRecordInfo(ssl, type, *messageSize - ssl->recordHeadLen, *c);
451 All data written after this point is to be encrypted (if secure-write)
453 *encryptStart = *c;
454 msn = 0;
458 Handshake records have another header layer to write here
460 if (type == SSL_RECORD_TYPE_HANDSHAKE) {
461 *c += psWriteHandshakeHeader(ssl, hsType, messageData, msn, 0,
462 messageData, *c);
464 return 0;
467 /******************************************************************************/
469 Encrypt the message using the current cipher. This call is used in
470 conjunction with the writeRecordHeader function above to finish writing
471 an SSL record. Updates handshake hash if necessary, generates message
472 MAC, writes the padding, and does the encrytion.
474 static int32 encryptRecord(ssl_t *ssl, int32 type, int32 messageSize,
475 int32 padLen, unsigned char *encryptStart,
476 sslBuf_t *out, unsigned char **c)
478 if (type == SSL_RECORD_TYPE_HANDSHAKE) {
479 sslUpdateHSHash(ssl, encryptStart, (int32)(*c - encryptStart));
481 *c += ssl->generateMac(ssl, type, encryptStart,
482 (int32)(*c - encryptStart), *c);
484 *c += sslWritePad(*c, padLen);
486 if (ssl->encrypt(&ssl->sec.encryptCtx, encryptStart, encryptStart,
487 (int32)(*c - encryptStart)) < 0 || *c - out->end != messageSize) {
488 matrixStrDebugMsg("Error encrypting message for write\n", NULL);
489 return SSL_ERROR;
492 return 0;
495 #ifdef USE_SERVER_SIDE_SSL
496 /******************************************************************************/
498 Write out the ServerHello message
500 static int32 writeServerHello(ssl_t *ssl, sslBuf_t *out)
502 unsigned char *c, *end, *encryptStart;
503 char padLen;
504 int32 messageSize, rc;
505 time_t t;
507 c = out->end;
508 end = out->buf + out->size;
510 Calculate the size of the message up front, and verify we have room
511 We assume there will be a sessionId in the message, and make adjustments
512 below if there is no sessionId.
514 messageSize =
515 ssl->recordHeadLen +
516 ssl->hshakeHeadLen +
517 38 + SSL_MAX_SESSION_ID_SIZE;
520 First 4 bytes of the serverRandom are the unix time to prevent replay
521 attacks, the rest are random
523 t = time(0);
524 ssl->sec.serverRandom[0] = (unsigned char)((t & 0xFF000000) >> 24);
525 ssl->sec.serverRandom[1] = (unsigned char)((t & 0xFF0000) >> 16);
526 ssl->sec.serverRandom[2] = (unsigned char)((t & 0xFF00) >> 8);
527 ssl->sec.serverRandom[3] = (unsigned char)(t & 0xFF);
528 if (sslGetEntropy(ssl->sec.serverRandom + 4, SSL_HS_RANDOM_SIZE - 4) < 0) {
529 matrixStrDebugMsg("Error gathering serverRandom entropy\n", NULL);
530 return SSL_ERROR;
533 We register session here because at this point the serverRandom value is
534 populated. If we are able to register the session, the sessionID and
535 sessionIdLen fields will be non-NULL, otherwise the session couldn't
536 be registered.
538 if (!(ssl->flags & SSL_FLAGS_RESUMED)) {
539 matrixRegisterSession(ssl);
541 messageSize -= (SSL_MAX_SESSION_ID_SIZE - ssl->sessionIdLen);
543 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
544 SSL_HS_SERVER_HELLO, &messageSize, &padLen, &encryptStart,
545 &end, &c)) < 0) {
546 return rc;
549 First two fields in the ServerHello message are the major and minor
550 SSL protocol versions we agree to talk with
552 *c = ssl->majVer; c++;
553 *c = ssl->minVer; c++;
555 The next 32 bytes are the server's random value, to be combined with
556 the client random and premaster for key generation later
558 memcpy(c, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE);
559 c += SSL_HS_RANDOM_SIZE;
561 The next data is a single byte containing the session ID length,
562 and up to 32 bytes containing the session id.
563 First register the session, which will give us a session id and length
564 if not all session slots in the table are used
566 *c = ssl->sessionIdLen; c++;
567 if (ssl->sessionIdLen > 0) {
568 memcpy(c, ssl->sessionId, ssl->sessionIdLen);
569 c += ssl->sessionIdLen;
572 Two byte cipher suite we've chosen based on the list sent by the client
573 and what we support.
574 One byte compression method (always zero)
576 *c = (ssl->cipher->id & 0xFF00) >> 8; c++;
577 *c = ssl->cipher->id & 0xFF; c++;
578 *c = 0; c++;
580 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
581 padLen, encryptStart, out, &c)) < 0) {
582 return rc;
585 If we're resuming a session, we now have the clientRandom, master and
586 serverRandom, so we can derive keys which we'll be using shortly.
588 if (ssl->flags & SSL_FLAGS_RESUMED) {
589 sslDeriveKeys(ssl);
592 Verify that we've calculated the messageSize correctly, really this
593 should never fail; it's more of an implementation verification
595 if (c - out->end != messageSize) {
596 return SSL_ERROR;
598 out->end = c;
599 return SSL_SUCCESS;
602 /******************************************************************************/
604 ServerHelloDone message is a blank handshake message
606 static int32 writeServerHelloDone(ssl_t *ssl, sslBuf_t *out)
608 unsigned char *c, *end, *encryptStart;
609 char padLen;
610 int32 messageSize, rc;
612 c = out->end;
613 end = out->buf + out->size;
614 messageSize =
615 ssl->recordHeadLen +
616 ssl->hshakeHeadLen;
618 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
619 SSL_HS_SERVER_HELLO_DONE, &messageSize, &padLen,
620 &encryptStart, &end, &c)) < 0) {
621 return rc;
624 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
625 padLen, encryptStart, out, &c)) < 0) {
626 return rc;
629 if (c - out->end != messageSize) {
630 matrixStrDebugMsg("Error generating hello done for write\n", NULL);
631 return SSL_ERROR;
633 out->end = c;
634 return SSL_SUCCESS;
638 /******************************************************************************/
640 Server initiated rehandshake public API call.
642 int32 matrixSslEncodeHelloRequest(ssl_t *ssl, sslBuf_t *out)
644 unsigned char *c, *end, *encryptStart;
645 char padLen;
646 int32 messageSize, rc;
648 if (ssl->flags & SSL_FLAGS_ERROR || ssl->flags & SSL_FLAGS_CLOSED) {
649 return SSL_ERROR;
651 if (!(ssl->flags & SSL_FLAGS_SERVER) || (ssl->hsState != SSL_HS_DONE)) {
652 return SSL_ERROR;
655 c = out->end;
656 end = out->buf + out->size;
657 messageSize =
658 ssl->recordHeadLen +
659 ssl->hshakeHeadLen;
660 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
661 SSL_HS_HELLO_REQUEST, &messageSize, &padLen,
662 &encryptStart, &end, &c)) < 0) {
663 return rc;
666 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
667 padLen, encryptStart, out, &c)) < 0) {
668 return rc;
671 if (c - out->end != messageSize) {
672 matrixStrDebugMsg("Error generating hello request for write\n", NULL);
673 return SSL_ERROR;
675 out->end = c;
677 return SSL_SUCCESS;
679 #else /* USE_SERVER_SIDE_SSL */
680 int32 matrixSslEncodeHelloRequest(ssl_t *ssl, sslBuf_t *out)
682 matrixStrDebugMsg("Library not built with USE_SERVER_SIDE_SSL\n", NULL);
683 return -1;
685 #endif /* USE_SERVER_SIDE_SSL */
687 /******************************************************************************/
689 Write a Certificate message.
690 The encoding of the message is as follows:
691 3 byte length of certificate data (network byte order)
692 If there is no certificate,
693 3 bytes of 0
694 If there is one certificate,
695 3 byte length of certificate + 3
696 3 byte length of certificate
697 certificate data
698 For more than one certificate:
699 3 byte length of all certificate data
700 3 byte length of first certificate
701 first certificate data
702 3 byte length of second certificate
703 second certificate data
704 Certificate data is the base64 section of an X.509 certificate file
705 in PEM format decoded to binary. No additional interpretation is required.
707 static int32 writeCertificate(ssl_t *ssl, sslBuf_t *out, int32 notEmpty)
709 sslLocalCert_t *cert;
710 unsigned char *c, *end, *encryptStart;
711 char padLen;
712 int32 totalCertLen, certLen, lsize, messageSize, i, rc;
715 c = out->end;
716 end = out->buf + out->size;
719 Determine total length of certs
721 totalCertLen = i = 0;
722 if (notEmpty) {
723 cert = &ssl->keys->cert;
724 for (; cert != NULL; i++) {
725 totalCertLen += cert->certLen;
726 cert = cert->next;
730 Account for the 3 bytes of certChain len for each cert and get messageSize
732 lsize = 3 + (i * 3);
733 messageSize =
734 ssl->recordHeadLen +
735 ssl->hshakeHeadLen +
736 lsize + totalCertLen;
738 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
739 SSL_HS_CERTIFICATE, &messageSize, &padLen, &encryptStart,
740 &end, &c)) < 0) {
741 return rc;
745 Write out the certs
747 *c = ((totalCertLen + (lsize - 3)) & 0xFF0000) >> 16; c++;
748 *c = ((totalCertLen + (lsize - 3)) & 0xFF00) >> 8; c++;
749 *c = ((totalCertLen + (lsize - 3)) & 0xFF); c++;
751 if (notEmpty) {
752 cert = &ssl->keys->cert;
753 while (cert) {
754 certLen = cert->certLen;
755 if (certLen > 0) {
756 *c = (certLen & 0xFF0000) >> 16; c++;
757 *c = (certLen & 0xFF00) >> 8; c++;
758 *c = (certLen & 0xFF); c++;
759 memcpy(c, cert->certBin, certLen);
760 c += certLen;
762 cert = cert->next;
765 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
766 padLen, encryptStart, out, &c)) < 0) {
767 return rc;
770 if (c - out->end != messageSize) {
771 matrixStrDebugMsg("Error parsing certificate for write\n", NULL);
772 return SSL_ERROR;
774 out->end = c;
775 return SSL_SUCCESS;
778 /******************************************************************************/
780 Write the ChangeCipherSpec message. It has its own message type
781 and contains just one byte of value one. It is not a handshake
782 message, so it isn't included in the handshake hash.
784 static int32 writeChangeCipherSpec(ssl_t *ssl, sslBuf_t *out)
786 unsigned char *c, *end, *encryptStart;
787 char padLen;
788 int32 messageSize, rc;
790 c = out->end;
791 end = out->buf + out->size;
792 messageSize = ssl->recordHeadLen + 1;
794 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC, 0,
795 &messageSize, &padLen, &encryptStart, &end, &c)) < 0) {
796 return rc;
798 *c = 1; c++;
800 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC,
801 messageSize, padLen, encryptStart, out, &c)) < 0) {
802 return rc;
805 if (c - out->end != messageSize) {
806 matrixStrDebugMsg("Error generating change cipher for write\n", NULL);
807 return SSL_ERROR;
809 out->end = c;
811 After the peer parses the ChangeCipherSpec message, it will expect
812 the next message to be encrypted, so activate encryption on outgoing
813 data now
815 sslActivateWriteCipher(ssl);
818 return SSL_SUCCESS;
821 /******************************************************************************/
823 Write the Finished message
824 The message contains the 36 bytes, the 16 byte MD5 and 20 byte SHA1 hash
825 of all the handshake messages so far (excluding this one!)
827 static int32 writeFinished(ssl_t *ssl, sslBuf_t *out)
829 unsigned char *c, *end, *encryptStart;
830 char padLen;
831 int32 messageSize, verifyLen, rc;
833 c = out->end;
834 end = out->buf + out->size;
835 verifyLen = SSL_MD5_HASH_SIZE + SSL_SHA1_HASH_SIZE;
836 messageSize = ssl->recordHeadLen + ssl->hshakeHeadLen + verifyLen;
838 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE, SSL_HS_FINISHED,
839 &messageSize, &padLen, &encryptStart, &end, &c)) < 0) {
840 return rc;
843 Output the hash of messages we've been collecting so far into the buffer
845 c += sslSnapshotHSHash(ssl, c, ssl->flags & SSL_FLAGS_SERVER);
847 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
848 padLen, encryptStart, out, &c)) < 0) {
849 return rc;
852 if (c - out->end != messageSize) {
853 matrixStrDebugMsg("Error generating finished for write\n", NULL);
854 return SSL_ERROR;
856 out->end = c;
859 #ifdef USE_CLIENT_SIDE_SSL
861 Free handshake pool, of which the cert is the primary member.
862 There is also an attempt to free the handshake pool during
863 the reciept of the finished message. Both cases are attempted
864 to keep the lifespan of this pool as short as possible. This
865 is the default case for the client side.
867 if (ssl->sec.cert) {
868 matrixX509FreeCert(ssl->sec.cert);
869 ssl->sec.cert = NULL;
871 #endif /* USE_CLIENT_SIDE */
874 return SSL_SUCCESS;
877 /******************************************************************************/
879 Write an Alert message
880 The message contains two bytes: AlertLevel and AlertDescription
882 static int32 writeAlert(ssl_t *ssl, unsigned char level,
883 unsigned char description, sslBuf_t *out)
885 unsigned char *c, *end, *encryptStart;
886 char padLen;
887 int32 messageSize, rc;
889 c = out->end;
890 end = out->buf + out->size;
891 messageSize = 2 + ssl->recordHeadLen;
893 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_ALERT, 0, &messageSize,
894 &padLen, &encryptStart, &end, &c)) < 0) {
895 return rc;
897 *c = level; c++;
898 *c = description; c++;
900 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_ALERT, messageSize,
901 padLen, encryptStart, out, &c)) < 0) {
902 return rc;
905 out->end = c;
906 return SSL_SUCCESS;
909 #ifdef USE_CLIENT_SIDE_SSL
910 /******************************************************************************/
912 Write out the ClientHello message to a buffer
914 int32 matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out,
915 unsigned short cipherSpec)
917 unsigned char *c, *end, *encryptStart;
918 char padLen;
919 int32 messageSize, rc, cipherLen, cookieLen;
920 time_t t;
922 if (ssl->flags & SSL_FLAGS_ERROR || ssl->flags & SSL_FLAGS_CLOSED) {
923 return SSL_ERROR;
925 if (ssl->flags & SSL_FLAGS_SERVER || (ssl->hsState != SSL_HS_SERVER_HELLO &&
926 ssl->hsState != SSL_HS_DONE &&
927 ssl->hsState != SSL_HS_HELLO_REQUEST )) {
928 return SSL_ERROR;
931 sslInitHSHash(ssl);
933 cookieLen = 0;
935 If session resumption is being done on a rehandshake, make sure we are
936 sending the same cipher spec as the currently negotiated one. If no
937 resumption, clear the RESUMED flag in case the caller forgot to clear
938 it with matrixSslSetSessionOption.
940 if (ssl->sessionIdLen > 0) {
941 cipherSpec = ssl->cipher->id;
942 } else {
943 ssl->flags &= ~SSL_FLAGS_RESUMED;
947 If a cipher is specified it is two bytes length and two bytes data.
949 if (cipherSpec == 0) {
950 cipherLen = sslGetCipherSpecListLen();
951 } else {
952 if (sslGetCipherSpec(cipherSpec) == NULL) {
953 matrixIntDebugMsg("Cipher suite not supported: %d\n", cipherSpec);
954 return SSL_ERROR;
956 cipherLen = 4;
959 c = out->end;
960 end = out->buf + out->size;
962 Calculate the size of the message up front, and write header
964 messageSize = ssl->recordHeadLen + ssl->hshakeHeadLen +
965 5 + SSL_HS_RANDOM_SIZE + ssl->sessionIdLen + cipherLen + cookieLen;
968 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
969 SSL_HS_CLIENT_HELLO, &messageSize, &padLen, &encryptStart,
970 &end, &c)) < 0) {
971 return rc;
975 First 4 bytes of the serverRandom are the unix time to prevent replay
976 attacks, the rest are random
979 t = time(0);
980 ssl->sec.clientRandom[0] = (unsigned char)((t & 0xFF000000) >> 24);
981 ssl->sec.clientRandom[1] = (unsigned char)((t & 0xFF0000) >> 16);
982 ssl->sec.clientRandom[2] = (unsigned char)((t & 0xFF00) >> 8);
983 ssl->sec.clientRandom[3] = (unsigned char)(t & 0xFF);
984 if (sslGetEntropy(ssl->sec.clientRandom + 4, SSL_HS_RANDOM_SIZE - 4) < 0) {
985 matrixStrDebugMsg("Error gathering clientRandom entropy\n", NULL);
986 return SSL_ERROR;
989 First two fields in the ClientHello message are the maximum major
990 and minor SSL protocol versions we support
992 *c = ssl->majVer; c++;
993 *c = ssl->minVer; c++;
995 The next 32 bytes are the server's random value, to be combined with
996 the client random and premaster for key generation later
998 memcpy(c, ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE);
999 c += SSL_HS_RANDOM_SIZE;
1001 The next data is a single byte containing the session ID length,
1002 and up to 32 bytes containing the session id.
1003 If we are asking to resume a session, then the sessionId would have
1004 been set at session creation time.
1006 *c = ssl->sessionIdLen; c++;
1007 if (ssl->sessionIdLen > 0) {
1008 memcpy(c, ssl->sessionId, ssl->sessionIdLen);
1009 c += ssl->sessionIdLen;
1012 Write out the length and ciphers we support
1013 Client can request a single specific cipher in the cipherSpec param
1015 if (cipherSpec == 0) {
1016 if ((rc = sslGetCipherSpecList(c, (int32)(end - c))) < 0) {
1017 return SSL_FULL;
1019 c += rc;
1020 } else {
1021 if ((int32)(end - c) < 4) {
1022 return SSL_FULL;
1024 *c = 0; c++;
1025 *c = 2; c++;
1026 *c = (cipherSpec & 0xFF00) >> 8; c++;
1027 *c = cipherSpec & 0xFF; c++;
1030 Followed by two bytes (len and compression method (always zero))
1032 *c = 1; c++;
1033 *c = 0; c++;
1036 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
1037 padLen, encryptStart, out, &c)) < 0) {
1038 return rc;
1041 Verify that we've calculated the messageSize correctly, really this
1042 should never fail; it's more of an implementation verification
1044 if (c - out->end != messageSize) {
1045 return SSL_ERROR;
1047 out->end = c;
1050 Could be a rehandshake so clean up old context if necessary.
1051 Always explicitly set state to beginning.
1053 if (ssl->hsState == SSL_HS_DONE) {
1054 sslResetContext(ssl);
1058 Could be a rehandshake on a previous connection that used client auth.
1059 Reset our local client auth state as the server is always the one
1060 responsible for initiating it.
1062 ssl->flags &= ~SSL_FLAGS_CLIENT_AUTH;
1063 ssl->hsState = SSL_HS_SERVER_HELLO;
1064 return SSL_SUCCESS;
1067 /******************************************************************************/
1069 Write a ClientKeyExchange message.
1071 static int32 writeClientKeyExchange(ssl_t *ssl, sslBuf_t *out)
1073 unsigned char *c, *end, *encryptStart;
1074 char padLen;
1075 int32 messageSize, keyLen, explicitLen, rc;
1077 c = out->end;
1078 end = out->buf + out->size;
1079 messageSize = keyLen = 0;
1084 Determine messageSize for the record header
1086 /* Standard RSA auth suites */
1087 keyLen = ssl->sec.cert->publicKey.size;
1089 messageSize += ssl->recordHeadLen + ssl->hshakeHeadLen + keyLen;
1090 explicitLen = 0;
1092 if ((rc = writeRecordHeader(ssl, SSL_RECORD_TYPE_HANDSHAKE,
1093 SSL_HS_CLIENT_KEY_EXCHANGE, &messageSize, &padLen,
1094 &encryptStart, &end, &c)) < 0) {
1095 return rc;
1099 ClientKeyExchange message contains the encrypted premaster secret.
1100 The base premaster is the original SSL protocol version we asked for
1101 followed by 46 bytes of random data.
1102 These 48 bytes are padded to the current RSA key length and encrypted
1103 with the RSA key.
1105 if (explicitLen == 1) {
1108 Add the two bytes of key length
1110 if (keyLen > 0) {
1111 *c = (keyLen & 0xFF00) >> 8; c++;
1112 *c = (keyLen & 0xFF); c++;
1118 Standard RSA suite
1120 ssl->sec.premasterSize = SSL_HS_RSA_PREMASTER_SIZE;
1121 ssl->sec.premaster = psMalloc(ssl->hsPool,
1122 SSL_HS_RSA_PREMASTER_SIZE);
1124 ssl->sec.premaster[0] = ssl->reqMajVer;
1125 ssl->sec.premaster[1] = ssl->reqMinVer;
1126 if (sslGetEntropy(ssl->sec.premaster + 2,
1127 SSL_HS_RSA_PREMASTER_SIZE - 2) < 0) {
1128 matrixStrDebugMsg("Error gathering premaster entropy\n", NULL);
1129 return SSL_ERROR;
1132 sslActivatePublicCipher(ssl);
1134 if (ssl->encryptPub(ssl->hsPool, &(ssl->sec.cert->publicKey),
1135 ssl->sec.premaster, ssl->sec.premasterSize, c,
1136 (int32)(end - c)) != keyLen) {
1137 matrixStrDebugMsg("Error encrypting premaster\n", NULL);
1138 return SSL_FULL;
1141 c += keyLen;
1143 if ((rc = encryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, messageSize,
1144 padLen, encryptStart, out, &c)) < 0) {
1145 return rc;
1148 if (c - out->end != messageSize) {
1149 matrixStrDebugMsg("Invalid ClientKeyExchange length\n", NULL);
1150 return SSL_ERROR;
1154 Now that we've got the premaster secret, derive the various symmetric
1155 keys using it and the client and server random values
1157 sslDeriveKeys(ssl);
1159 out->end = c;
1160 return SSL_SUCCESS;
1164 #else /* USE_CLIENT_SIDE_SSL */
1165 /******************************************************************************/
1167 Stub out this function rather than ifdef it out in the public header
1169 int32 matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out,
1170 unsigned short cipherSpec)
1172 matrixStrDebugMsg("Library not built with USE_CLIENT_SIDE_SSL\n", NULL);
1173 return -1;
1175 #endif /* USE_CLIENT_SIDE_SSL */
1178 /******************************************************************************/
1180 Write out a SSLv3 record header.
1181 Assumes 'c' points to a buffer of at least SSL3_HEADER_LEN bytes
1182 1 byte type (SSL_RECORD_TYPE_*)
1183 1 byte major version
1184 1 byte minor version
1185 2 bytes length (network byte order)
1186 Returns the number of bytes written
1188 int32 psWriteRecordInfo(ssl_t *ssl, unsigned char type, int32 len, unsigned char *c)
1190 *c = type; c++;
1191 *c = ssl->majVer; c++;
1192 *c = ssl->minVer; c++;
1193 *c = (len & 0xFF00) >> 8; c++;
1194 *c = (len & 0xFF);
1196 return ssl->recordHeadLen;
1199 /******************************************************************************/
1201 Write out an ssl handshake message header.
1202 Assumes 'c' points to a buffer of at least ssl->hshakeHeadLen bytes
1203 1 byte type (SSL_HS_*)
1204 3 bytes length (network byte order)
1205 Returns the number of bytes written
1207 int32 psWriteHandshakeHeader(ssl_t *ssl, unsigned char type, int32 len,
1208 int32 seq, int32 fragOffset, int32 fragLen,
1209 unsigned char *c)
1211 *c = type; c++;
1212 *c = (len & 0xFF0000) >> 16; c++;
1213 *c = (len & 0xFF00) >> 8; c++;
1214 *c = (len & 0xFF);
1216 return ssl->hshakeHeadLen;
1219 /******************************************************************************/
1221 Write pad bytes and pad length per the TLS spec. Most block cipher
1222 padding fills each byte with the number of padding bytes, but SSL/TLS
1223 pretends one of these bytes is a pad length, and the remaining bytes are
1224 filled with that length. The end result is that the padding is identical
1225 to standard padding except the values are one less. For SSLv3 we are not
1226 required to have any specific pad values, but they don't hurt.
1228 PadLen Result
1230 1 00
1231 2 01 01
1232 3 02 02 02
1233 4 03 03 03 03
1234 5 04 04 04 04 04
1235 6 05 05 05 05 05 05
1236 7 06 06 06 06 06 06 06
1237 8 07 07 07 07 07 07 07 07
1239 We calculate the length of padding required for a record using
1240 sslPadLenPwr2()
1242 int32 sslWritePad(unsigned char *p, unsigned char padLen)
1244 unsigned char c = padLen;
1246 while (c-- > 0) {
1247 *p++ = padLen - 1;
1249 return padLen;
1252 /******************************************************************************/