Crypt-MatrixSSL
view release on metacpan or search on metacpan
matrixssl-1-8-6-open/examples/sslSocket.c view on Meta::CPAN
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;
}
/******************************************************************************/
/*
An example socket sslRead implementation that handles the ssl handshake
transparently. Caller passes in allocated buf and length.
Return codes are as follows:
-1 return code is an error. If a socket level error, error code is
contained in status parameter. If using a non-blocking socket
implementation the caller should check for non-fatal errors such as
WOULD_BLOCK before closing the connection. A zero value
in status indicates an error with this routine.
A positive integer return code is the number of bytes successfully read
into the supplied buffer. User can call sslRead again on the updated
buffer is there is more to be read.
0 return code indicates the read was successful, but there was no data
to be returned. If status is set to zero, this is a case internal
to the sslAccept and sslConnect functions that a handshake
message has been exchanged. If status is set to SOCKET_EOF
the connection has been closed by the other side.
*/
int sslRead(sslConn_t *cp, char *buf, int len, int *status)
{
int bytes, rc, remaining;
unsigned char error, alertLevel, alertDescription, performRead;
*status = 0;
if (cp->ssl == NULL || len <= 0) {
return -1;
}
/*
If inbuf is valid, then we have previously decoded data that must be
returned, return as much as possible. Once all buffered data is
returned, free the inbuf.
*/
if (cp->inbuf.buf) {
if (cp->inbuf.start < cp->inbuf.end) {
remaining = (int)(cp->inbuf.end - cp->inbuf.start);
bytes = (int)min(len, remaining);
memcpy(buf, cp->inbuf.start, bytes);
cp->inbuf.start += bytes;
return bytes;
}
free(cp->inbuf.buf);
cp->inbuf.buf = NULL;
}
/*
Pack the buffered socket data (if any) so that start is at zero.
*/
if (cp->insock.buf < cp->insock.start) {
if (cp->insock.start == cp->insock.end) {
cp->insock.start = cp->insock.end = cp->insock.buf;
} else {
memmove(cp->insock.buf, cp->insock.start, cp->insock.end - cp->insock.start);
cp->insock.end -= (cp->insock.start - cp->insock.buf);
cp->insock.start = cp->insock.buf;
}
}
/*
Read up to as many bytes as there are remaining in the buffer. We could
( run in 1.017 second using v1.01-cache-2.11-cpan-e93a5daba3e )