Support processing of partial TLS record headers
This commit is contained in:
+39
-15
@@ -55,6 +55,15 @@ ENUM_NEXT(tls_handshake_type_names, TLS_FINISHED, TLS_FINISHED, TLS_CLIENT_KEY_E
|
|||||||
"Finished");
|
"Finished");
|
||||||
ENUM_END(tls_handshake_type_names, TLS_FINISHED);
|
ENUM_END(tls_handshake_type_names, TLS_FINISHED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TLS record
|
||||||
|
*/
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
u_int8_t type;
|
||||||
|
u_int16_t version;
|
||||||
|
u_int16_t length;
|
||||||
|
char data[];
|
||||||
|
} tls_record_t;
|
||||||
|
|
||||||
typedef struct private_tls_t private_tls_t;
|
typedef struct private_tls_t private_tls_t;
|
||||||
|
|
||||||
@@ -147,17 +156,17 @@ struct private_tls_t {
|
|||||||
* Number of bytes processed from output buffer
|
* Number of bytes processed from output buffer
|
||||||
*/
|
*/
|
||||||
size_t outpos;
|
size_t outpos;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TLS record
|
* Partial TLS record header received
|
||||||
*/
|
*/
|
||||||
typedef struct __attribute__((packed)) {
|
tls_record_t head;
|
||||||
u_int8_t type;
|
|
||||||
u_int16_t version;
|
/**
|
||||||
u_int16_t length;
|
* Position in partially received record header
|
||||||
char data[];
|
*/
|
||||||
} tls_record_t;
|
size_t headpos;
|
||||||
|
};
|
||||||
|
|
||||||
METHOD(tls_t, process, status_t,
|
METHOD(tls_t, process, status_t,
|
||||||
private_tls_t *this, void *buf, size_t buflen)
|
private_tls_t *this, void *buf, size_t buflen)
|
||||||
@@ -166,12 +175,32 @@ METHOD(tls_t, process, status_t,
|
|||||||
status_t status;
|
status_t status;
|
||||||
u_int len;
|
u_int len;
|
||||||
|
|
||||||
|
if (this->headpos)
|
||||||
|
{ /* have a partial TLS record header, try to complete it */
|
||||||
|
len = min(buflen, sizeof(this->head) - this->headpos);
|
||||||
|
memcpy(((char*)&this->head) + this->headpos, buf, len);
|
||||||
|
this->headpos += len;
|
||||||
|
buflen -= len;
|
||||||
|
buf += len;
|
||||||
|
if (this->headpos == sizeof(this->head))
|
||||||
|
{ /* header complete, allocate space with new header */
|
||||||
|
len = untoh16(&this->head.length);
|
||||||
|
this->input = chunk_alloc(len + sizeof(tls_record_t));
|
||||||
|
memcpy(this->input.ptr, &this->head, sizeof(this->head));
|
||||||
|
this->inpos = sizeof(this->head);
|
||||||
|
this->headpos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (buflen)
|
while (buflen)
|
||||||
{
|
{
|
||||||
if (this->input.len == 0)
|
if (this->input.len == 0)
|
||||||
{
|
{
|
||||||
if (buflen < sizeof(tls_record_t))
|
if (buflen < sizeof(tls_record_t))
|
||||||
{
|
{
|
||||||
|
DBG2(DBG_TLS, "received incomplete TLS record header");
|
||||||
|
memcpy(&this->head, buf, buflen);
|
||||||
|
this->headpos = buflen;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
@@ -226,11 +255,6 @@ METHOD(tls_t, process, status_t,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buflen != 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_TLS, "received incomplete TLS record header");
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user