示例#1
0
ssize_t SslSocket::read(x0::Buffer& result)
{
	if (result.size() == result.capacity())
		result.reserve(result.size() + 4096);

	ssize_t rv = gnutls_read(session_, result.end(), result.capacity() - result.size());
	if (rv < 0)
		return rv;

	result.resize(result.size() + rv);
	return rv;
}
bool DTLS_Decrypt(NetworkAddress * sourceAddress, uint8_t * encrypted, int encryptedLength, uint8_t * decryptBuffer, int decryptBufferLength, int * decryptedLength, void *context)
{
    bool result = false;
    DTLS_Session * session = GetSession(sourceAddress);
    if (session)
    {
        session->Buffer = encrypted;
        session->BufferLength = encryptedLength;
        if (session->SessionEstablished)
        {
            *decryptedLength = gnutls_read(session->Session, decryptBuffer, decryptBufferLength);
            result = (*decryptedLength > 0);
            if (!result)
            {
                FreeSession(session);
                session = NULL;
            }
        }
        else
        {
            *decryptedLength = 0;
            session->SessionEstablished = (gnutls_handshake(session->Session) == GNUTLS_E_SUCCESS);
            if (session->SessionEstablished)
                Lwm2m_Info("Session established");
        }
    }

    if (!session)
    {
        int index;
        for (index = 0;index < MAX_DTLS_SESSIONS; index++)
        {
            if (!sessions[index].Session)
            {
                SetupNewSession(index, sourceAddress, false);
                sessions[index].UserContext = context;
                gnutls_transport_set_push_function(sessions[index].Session, SSLSendCallBack);
                sessions[index].Buffer = encrypted;
                sessions[index].BufferLength = encryptedLength;
                sessions[index].SessionEstablished = (gnutls_handshake(sessions[index].Session) == GNUTLS_E_SUCCESS);
                break;
            }
        }
    }
    return result;
}
示例#3
0
ssize_t
ConnSSL_Read(CONNECTION *c, void * buf, size_t count)
{
	ssize_t br;

	Conn_OPTION_DEL(c, CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ);
#ifdef HAVE_LIBSSL
        br = (ssize_t) SSL_read(c->ssl_state.ssl, buf, count);
	if (br > 0)	/* on EOF we have to call ConnSSL_HandleError(), see SSL_read(3) */
		return br;
#endif
#ifdef HAVE_LIBGNUTLS
	br = gnutls_read(c->ssl_state.gnutls_session, buf, count);
	if (br >= 0)	/* on EOF we must _not_ call ConnSSL_HandleError, see gnutls_record_recv(3) */
		return br;
#endif
	/* error on read: switch ConnSSL_HandleError() return values -> 0 is "try again", so return -1 and set EAGAIN */
	if (ConnSSL_HandleError(c, br, "ConnSSL_Read") == 0) {
		errno = EAGAIN;
		return -1;
	}
	return 0;
}
示例#4
0
/* the correct response to a return value of 0 is almost
   certainly tlscomm_close(scs): don't _expect() anything
   unless anything else would represent failure */
int
tlscomm_expect(struct connection_state *scs,
			   const char *prefix, char *linebuf, int buflen)
{
	int prefixlen = (int) strlen(prefix);
	int buffered_bytes = 0;
	memset(linebuf, 0, buflen);
	TDM(DEBUG_INFO, "%s: expecting: %s\n", scs->name, prefix);
	/*     if(scs->unprocessed[0]) {
	   TDM(DEBUG_INFO, "%s: buffered: %s\n", scs->name, scs->unprocessed);
	   } */
	while (scs->unprocessed[0] != '\0'
		   || wait_for_it(scs->sd, EXPECT_TIMEOUT)) {
		if (scs->unprocessed[buffered_bytes] == '\0') {
			int thisreadbytes;
#ifdef USE_GNUTLS
			if (scs->tls_state) {
				/* BUF_SIZE - 1 leaves room for trailing \0 */
				thisreadbytes =
					gnutls_read(scs->tls_state,
								&scs->unprocessed[buffered_bytes],
								BUF_SIZE - 1 - buffered_bytes);
				if (thisreadbytes < 0) {
					handle_gnutls_read_error(thisreadbytes, scs);
					return 0;
				}
			} else
#endif
			{
				thisreadbytes =
					read(scs->sd, &scs->unprocessed[buffered_bytes],
						 BUF_SIZE - 1 - buffered_bytes);
				if (thisreadbytes < 0) {
					TDM(DEBUG_ERROR, "%s: error reading: %s\n",
						scs->name, strerror(errno));
					return 0;
				}
			}
			buffered_bytes += thisreadbytes;
			/* force null termination */
			scs->unprocessed[buffered_bytes] = '\0';
			if (buffered_bytes == 0) {
				return 0;		/* bummer */
			}
		} else {
			buffered_bytes = strlen(scs->unprocessed);
		}
		while (buffered_bytes >= prefixlen) {
			int linebytes;
			linebytes =
				getline_from_buffer(scs->unprocessed, linebuf, buflen);
			if (linebytes == 0) {
				buffered_bytes = 0;
			} else {
				buffered_bytes -= linebytes;
				if (strncmp(linebuf, prefix, prefixlen) == 0) {
					TDM(DEBUG_INFO, "%s: got: %*s", scs->name,
						linebytes, linebuf);
					return 1;	/* got it! */
				}
				TDM(DEBUG_INFO, "%s: dumped(%d/%d): %.*s", scs->name,
					linebytes, buffered_bytes, linebytes, linebuf);
			}
		}
	}
	if (buffered_bytes == -1) {
		TDM(DEBUG_INFO, "%s: timed out while expecting '%s'\n",
			scs->name, prefix);
	} else {
		TDM(DEBUG_ERROR, "%s: expecting: '%s', saw (%d): %s%s",
			scs->name, prefix, buffered_bytes, linebuf,
			/* only print the newline if the linebuf lacks it */
			(linebuf[strlen(linebuf) - 1] == '\n') ? "\n" : "");
	}
	return 0;					/* wait_for_it failed */
}