mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-23 06:02:37 +01:00
ttls: improve avp build approach
This commit is contained in:
parent
7903432e85
commit
2aefd8badf
@ -29,6 +29,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ell/ell.h>
|
#include <ell/ell.h>
|
||||||
#include <ell/tls-private.h>
|
#include <ell/tls-private.h>
|
||||||
|
#include <ell/private.h>
|
||||||
|
|
||||||
#include "eap.h"
|
#include "eap.h"
|
||||||
#include "eap-private.h"
|
#include "eap-private.h"
|
||||||
@ -48,82 +49,78 @@ enum radius_attr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct avp_builder {
|
struct avp_builder {
|
||||||
uint8_t flags;
|
uint32_t capacity;
|
||||||
size_t capacity;
|
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
size_t offset;
|
uint32_t pos;
|
||||||
uint32_t current_len;
|
uint8_t *avp_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void avp_builder_grow(struct avp_builder *builder)
|
static uint8_t *avp_builder_reserve(struct avp_builder *builder,
|
||||||
|
uint32_t alignment, size_t len)
|
||||||
{
|
{
|
||||||
builder->buf = l_realloc(builder->buf, builder->capacity * 2);
|
size_t aligned_pos = align_len(builder->pos, alignment);
|
||||||
|
size_t end = aligned_pos + len;
|
||||||
|
|
||||||
memset(builder->buf + builder->capacity, 0, builder->capacity);
|
if (end > builder->capacity) {
|
||||||
|
builder->buf = l_realloc(builder->buf, end);
|
||||||
builder->capacity *= 2;
|
builder->capacity = end;
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t *avp_builder_reserve(struct avp_builder *builder, size_t len)
|
|
||||||
{
|
|
||||||
while (builder->offset + TTLS_AVP_HEADER_LEN + builder->current_len
|
|
||||||
+ len >= builder->capacity) {
|
|
||||||
avp_builder_grow(builder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder->buf + builder->offset + TTLS_AVP_HEADER_LEN +
|
if (aligned_pos - builder->pos > 0)
|
||||||
builder->current_len;
|
memset(builder->buf + builder->pos, 0,
|
||||||
|
aligned_pos - builder->pos);
|
||||||
|
|
||||||
|
builder->pos = end;
|
||||||
|
|
||||||
|
return builder->buf + aligned_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void avp_builder_finalize_avp(struct avp_builder *builder)
|
static bool avp_builder_finalize_avp(struct avp_builder *builder)
|
||||||
{
|
{
|
||||||
uint8_t *p = builder->buf + builder->offset;
|
uint8_t *p;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
if (builder->current_len & 3) {
|
if (!builder->avp_start)
|
||||||
/*
|
return false;
|
||||||
* If an AVP is not a multiple of four octets, it must be padded
|
|
||||||
* with zeros to the next four-octet boundary.
|
|
||||||
*/
|
|
||||||
uint8_t pad_len = 4 - (builder->current_len & 3);
|
|
||||||
|
|
||||||
memset(avp_builder_reserve(builder, pad_len), 0, pad_len);
|
p = builder->buf + builder->pos;
|
||||||
}
|
|
||||||
|
|
||||||
builder->current_len += TTLS_AVP_HEADER_LEN;
|
len = l_get_be32(builder->avp_start + 4);
|
||||||
builder->offset += (builder->current_len + 3) & ~3;
|
len |= p - builder->avp_start;
|
||||||
builder->current_len |= builder->flags << 24;
|
l_put_be32(len, builder->avp_start + 4);
|
||||||
|
|
||||||
l_put_be32(builder->current_len, p + 4);
|
builder->avp_start = 0;
|
||||||
|
|
||||||
builder->flags = 0;
|
return true;
|
||||||
builder->current_len = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool avp_builder_start_avp(struct avp_builder *builder,
|
static bool avp_builder_start_avp(struct avp_builder *builder,
|
||||||
enum radius_attr type,
|
enum radius_attr type,
|
||||||
bool mandatory, uint32_t vendor_id)
|
bool mandatory, uint32_t vendor_id)
|
||||||
{
|
{
|
||||||
uint8_t *p;
|
uint32_t flags;
|
||||||
|
|
||||||
if (builder->current_len)
|
if (builder->avp_start)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (builder->offset + TTLS_AVP_HEADER_LEN + (vendor_id ? 4 : 0)
|
builder->avp_start = avp_builder_reserve(builder, 4,
|
||||||
>= builder->capacity)
|
TTLS_AVP_HEADER_LEN +
|
||||||
avp_builder_grow(builder);
|
(vendor_id ? 4 : 0));
|
||||||
|
|
||||||
p = builder->buf + builder->offset;
|
l_put_be32(type, builder->avp_start);
|
||||||
l_put_be32(type, p);
|
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
if (mandatory)
|
if (mandatory)
|
||||||
builder->flags |= TTLS_AVP_FLAG_M;
|
flags |= TTLS_AVP_FLAG_M;
|
||||||
|
|
||||||
if (vendor_id) {
|
if (vendor_id) {
|
||||||
builder->flags |= TTLS_AVP_FLAG_V;
|
flags |= TTLS_AVP_FLAG_V;
|
||||||
l_put_be32(vendor_id, p + TTLS_AVP_HEADER_LEN);
|
l_put_be32(vendor_id, builder->avp_start + TTLS_AVP_HEADER_LEN);
|
||||||
builder->current_len += 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l_put_be32(flags << 24, builder->avp_start + 4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +154,7 @@ static uint8_t *avp_builder_free(struct avp_builder *builder, bool free_data,
|
|||||||
ret = builder->buf;
|
ret = builder->buf;
|
||||||
|
|
||||||
if (out_size)
|
if (out_size)
|
||||||
*out_size = builder->offset;
|
*out_size = builder->pos;
|
||||||
|
|
||||||
l_free(builder);
|
l_free(builder);
|
||||||
|
|
||||||
@ -168,7 +165,6 @@ static bool avp_builder_put_bytes(struct avp_builder *builder,
|
|||||||
const void *data, size_t len)
|
const void *data, size_t len)
|
||||||
{
|
{
|
||||||
memcpy(avp_builder_reserve(builder, len), data, len);
|
memcpy(avp_builder_reserve(builder, len), data, len);
|
||||||
builder->current_len += len;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user