sslConn_t *sslDoHandshake(sslConn_t *conn, short cipherSuite) { char buf[1024]; int bytes, status, rc; conn->insock.size = 1024; conn->insock.start = conn->insock.end = conn->insock.buf = (unsigned char *)malloc(conn->insock.size); conn->outsock.size = 1024; conn->outsock.start = conn->outsock.end = conn->outsock.buf = (unsigned char *)malloc(conn->outsock.size); conn->inbuf.size = 0; conn->inbuf.start = conn->inbuf.end = conn->inbuf.buf = NULL; bytes = matrixSslEncodeClientHello(conn->ssl, &conn->outsock, cipherSuite); if (bytes < 0) { fprintf(stderr, "error %s:%d\n",__FILE__,__LINE__); socketAssert(bytes < 0); goto error; } if (psSocketWrite(conn->fd, &conn->outsock) < 0) { fprintf(stdout, "Error in socketWrite\n"); goto error; } conn->outsock.start = conn->outsock.end = conn->outsock.buf; readMore: rc = sslRead(conn, buf, sizeof(buf), &status); if (rc == 0) { if (status == SSLSOCKET_EOF || status == SSLSOCKET_CLOSE_NOTIFY) { fprintf(stderr, "error %s:%d\n",__FILE__,__LINE__); goto error; } if (matrixSslHandshakeIsComplete(conn->ssl) == 0) { goto readMore; } } else if (rc > 0) { fprintf(stderr, "sslRead got %d data in sslDoHandshake %s\n", rc, buf); goto readMore; } else { fprintf(stderr, "sslRead error in sslDoHandhake\n"); goto error; } return conn; error: fprintf(stderr, "error %s:%d\n",__FILE__,__LINE__); sslFreeConnection(&conn); return NULL; }
/* Server initiated rehandshake. Builds and sends the HELLO_REQUEST message */ void sslRehandshake(sslConn_t *cp) { matrixSslEncodeHelloRequest(cp->ssl, &cp->outsock); psSocketWrite(cp->fd, &cp->outsock); cp->outsock.start = cp->outsock.end = cp->outsock.buf; }
/* Construct the initial HELLO message to send to the server and initiate the SSL handshake. Can be used in the re-handshake scenario as well. */ sslConn_t *sslDoHandshake(sslConn_t *conn, short cipherSuite) { char buf[1024]; int bytes, status, rc; /* MatrixSSL doesn't provide buffers for data internally. Define them here to support buffered reading and writing for non-blocking sockets. Although it causes quite a bit more work, we support dynamically growing the buffers as needed. Alternately, we could define 16K buffers here and not worry about growing them. */ conn->insock.size = 1024; conn->insock.start = conn->insock.end = conn->insock.buf = (unsigned char *)malloc(conn->insock.size); conn->outsock.size = 1024; conn->outsock.start = conn->outsock.end = conn->outsock.buf = (unsigned char *)malloc(conn->outsock.size); conn->inbuf.size = 0; conn->inbuf.start = conn->inbuf.end = conn->inbuf.buf = NULL; bytes = matrixSslEncodeClientHello(conn->ssl, &conn->outsock, cipherSuite); if (bytes < 0) { socketAssert(bytes < 0); goto error; } /* Send the hello with a blocking write */ if (psSocketWrite(conn->fd, &conn->outsock) < 0) { fprintf(stdout, "Error in socketWrite\n"); goto error; } conn->outsock.start = conn->outsock.end = conn->outsock.buf; /* Call sslRead to work through the handshake. Not actually expecting data back, so the finished case is simply when the handshake is complete. */ readMore: rc = sslRead(conn, buf, sizeof(buf), &status); /* Reading handshake records should always return 0 bytes, we aren't expecting any data yet. */ if (rc == 0) { if (status == SSLSOCKET_EOF || status == SSLSOCKET_CLOSE_NOTIFY) { goto error; } if (matrixSslHandshakeIsComplete(conn->ssl) == 0) { goto readMore; } } else if (rc > 0) { fprintf(stderr, "sslRead got %d data in sslDoHandshake %s\n", rc, buf); goto readMore; } else { fprintf(stderr, "sslRead error in sslDoHandhake\n"); goto error; } return conn; error: sslFreeConnection(&conn); return NULL; }