mirror of
https://github.com/polhenarejos/pico-keys-sdk
synced 2026-05-25 15:45:11 +02:00
Add base64url routines.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/hkdf.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/base64.h"
|
||||
#include "crypto_utils.h"
|
||||
#include "otp.h"
|
||||
#include "random.h"
|
||||
@@ -308,3 +309,52 @@ uint32_t crc32c(const uint8_t *buf, size_t len) {
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
int base64url_encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen) {
|
||||
int rc = mbedtls_base64_encode(dst, dlen, olen, src, slen);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
for (size_t i = 0; i < *olen; i++) {
|
||||
if (dst[i] == '+') {
|
||||
dst[i] = '-';
|
||||
}
|
||||
else if (dst[i] == '/') {
|
||||
dst[i] = '_';
|
||||
}
|
||||
}
|
||||
uint8_t *p = dst + *olen - 1;
|
||||
while (*p == '=') {
|
||||
*p-- = '\0';
|
||||
(*olen)--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int base64url_decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen) {
|
||||
// First convert from base64url to standard base64
|
||||
unsigned char *b64_src = (unsigned char *)malloc(slen + 2); // +2 for padding if needed
|
||||
if (b64_src == NULL) {
|
||||
return PICOKEYS_ERR_MEMORY_FATAL;
|
||||
}
|
||||
for (size_t i = 0; i < slen; i++) {
|
||||
if (src[i] == '-') {
|
||||
b64_src[i] = '+';
|
||||
}
|
||||
else if (src[i] == '_') {
|
||||
b64_src[i] = '/';
|
||||
}
|
||||
else {
|
||||
b64_src[i] = src[i];
|
||||
}
|
||||
}
|
||||
size_t padding = (4 - (slen % 4)) % 4;
|
||||
for (size_t i = 0; i < padding; i++) {
|
||||
b64_src[slen + i] = '=';
|
||||
}
|
||||
size_t b64_len = slen + padding;
|
||||
|
||||
int rc = mbedtls_base64_decode(dst, dlen, olen, b64_src, b64_len);
|
||||
free(b64_src);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ extern int aes_encrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *d
|
||||
extern int aes_decrypt_cfb_256(const uint8_t *key, const uint8_t *iv, uint8_t *data, uint16_t len);
|
||||
extern mbedtls_ecp_group_id ec_get_curve_from_prime(const uint8_t *prime, size_t prime_len);
|
||||
extern uint32_t crc32c(const uint8_t *buf, size_t len);
|
||||
extern int base64url_encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen);
|
||||
extern int base64url_decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen);
|
||||
|
||||
#define PIN_KDF_SIZE(x) (12 + (x) + 16)
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "rest.h"
|
||||
#include <strings.h>
|
||||
#include "random.h"
|
||||
#include "crypto_utils.h"
|
||||
|
||||
#define REST_MAX_SESSIONS 4
|
||||
|
||||
@@ -34,6 +35,11 @@ rest_session_t *rest_session_create(const rest_session_role_t role, rest_session
|
||||
random_fill_buffer(rest_sessions[i].id, sizeof(rest_sessions[i].id));
|
||||
rest_sessions[i].created_at = board_millis();
|
||||
rest_sessions[i].last_activity_timestamp = rest_sessions[i].created_at;
|
||||
size_t olen = 0;
|
||||
if (base64url_encode(rest_sessions[i].id_str, sizeof(rest_sessions[i].id_str), &olen, (const unsigned char *)rest_sessions[i].id, sizeof(rest_sessions[i].id)) != 0) {
|
||||
memset(&rest_sessions[i], 0, sizeof(rest_session_t));
|
||||
return NULL;
|
||||
}
|
||||
return &rest_sessions[i];
|
||||
}
|
||||
}
|
||||
@@ -54,6 +60,20 @@ rest_session_t *rest_session_get(const uint8_t *id, size_t id_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rest_session_t *rest_session_get_by_id_str(const char *id_str) {
|
||||
if (id_str == NULL || strlen(id_str) != 22) {
|
||||
return NULL;
|
||||
}
|
||||
for (int i = 0; i < REST_MAX_SESSIONS; i++) {
|
||||
if (rest_sessions[i].status != REST_SESSION_UNKNOWN && rest_sessions[i].status != REST_SESSION_EXPIRED && rest_sessions[i].status != REST_SESSION_TERMINATED) {
|
||||
if (strcmp((const char *)rest_sessions[i].id_str, id_str) == 0) {
|
||||
return &rest_sessions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rest_session_terminate(const uint8_t *id, size_t id_len) {
|
||||
rest_session_t *session = rest_session_get(id, id_len);
|
||||
if (session == NULL) {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include "cJSON.h"
|
||||
#include "mbedtls/base64.h"
|
||||
|
||||
#define REST_MAX_REQUEST_SIZE 1024
|
||||
#define REST_MAX_METHOD_SIZE 8
|
||||
@@ -85,9 +86,9 @@ typedef struct {
|
||||
} rest_route_t;
|
||||
|
||||
typedef enum {
|
||||
REST_SESSION_NONE = 0,
|
||||
REST_SESSION_USER = 0x1,
|
||||
REST_SESSION_ADMIN = 0x2
|
||||
REST_SESSION_ROLE_NONE = 0,
|
||||
REST_SESSION_ROLE_USER = 0x1,
|
||||
REST_SESSION_ROLE_ADMIN = 0x2
|
||||
} rest_session_role_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -102,6 +103,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
uint8_t id[16];
|
||||
uint8_t id_str[25];
|
||||
time_t last_activity_timestamp;
|
||||
time_t created_at;
|
||||
uint32_t last_seq;
|
||||
@@ -120,6 +122,7 @@ const rest_route_t *rest_get_routes(size_t *count);
|
||||
|
||||
extern rest_session_t *rest_session_create(const rest_session_role_t role, rest_session_status_t status);
|
||||
extern rest_session_t *rest_session_get(const uint8_t *id, size_t id_len);
|
||||
extern rest_session_t *rest_session_get_by_id_str(const char *id_str);
|
||||
extern int rest_session_terminate(const uint8_t *id, size_t id_len);
|
||||
extern int rest_session_update_activity(const uint8_t *id, size_t id_len);
|
||||
extern int rest_session_set_status(const uint8_t *id, size_t id_len, rest_session_status_t status);
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <strings.h>
|
||||
#include "mbedtls/base64.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/hkdf.h"
|
||||
#include "crypto_utils.h"
|
||||
@@ -615,7 +614,7 @@ static int rest_verify_request_signature(const rest_request_t *request, const re
|
||||
if (md_info == NULL) {
|
||||
return PICOKEYS_ERR_MEMORY_FATAL;
|
||||
}
|
||||
if (mbedtls_base64_decode(hmac_x, sizeof(hmac_x), &olen, (const unsigned char *)request->headers[REST_HEADER_X_SIGNATURE], strlen(request->headers[REST_HEADER_X_SIGNATURE])) != 0) {
|
||||
if (base64url_decode(hmac_x, sizeof(hmac_x), &olen, (const unsigned char *)request->headers[REST_HEADER_X_SIGNATURE], strlen(request->headers[REST_HEADER_X_SIGNATURE])) != 0) {
|
||||
return PICOKEYS_EXEC_ERROR;
|
||||
}
|
||||
mbedtls_md_init(&ctx);
|
||||
@@ -707,7 +706,7 @@ void rest_handle_request(rest_conn_t *conn) {
|
||||
send_json_error(conn, 401, "authentication_required");
|
||||
return;
|
||||
}
|
||||
rest_session_t *session = rest_session_get((const uint8_t *)request->headers[REST_HEADER_X_SESSION_ID], strlen(request->headers[REST_HEADER_X_SESSION_ID]));
|
||||
rest_session_t *session = rest_session_get_by_id_str(request->headers[REST_HEADER_X_SESSION_ID]);
|
||||
if (!session) {
|
||||
send_json_error(conn, 401, "authentication_required");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user