Compare commits
3 Commits
7f9db9f2cc
...
b800b90337
| Author | SHA1 | Date | |
|---|---|---|---|
| b800b90337 | |||
| b5acda292d | |||
| 77c3702986 |
@@ -135,6 +135,46 @@ void crypto_print_priv_key()
|
|||||||
mbedtls_entropy_free(&entropy);
|
mbedtls_entropy_free(&entropy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get secret point value of our private key
|
||||||
|
*/
|
||||||
|
static bool crypto_get_priv_key_mpi(mbedtls_mpi *dst)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
unsigned char *key_buff = malloc(PRV_KEY_DER_MAX_BYTES);
|
||||||
|
size_t key_len = storage_get_priv_key(key_buff);
|
||||||
|
assert(key_len > 0);
|
||||||
|
|
||||||
|
mbedtls_pk_context key;
|
||||||
|
mbedtls_pk_init(&key);
|
||||||
|
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
seed_ctr_drbg_context(&entropy, &ctr_drbg);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Parse private key (len = %d)\n", key_len);
|
||||||
|
if ((ret = mbedtls_pk_parse_key(&key, key_buff, key_len, NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg)) != 0)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, " failed\n ! mbedtls_pk_parse_key returned -0x%04x",
|
||||||
|
(unsigned int)-ret);
|
||||||
|
reboot();
|
||||||
|
}
|
||||||
|
free(key_buff);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Extract private key");
|
||||||
|
mbedtls_ecp_keypair *kp = mbedtls_pk_ec(key);
|
||||||
|
|
||||||
|
mbedtls_mpi_init(dst);
|
||||||
|
mbedtls_mpi_copy(dst, &kp->private_d);
|
||||||
|
|
||||||
|
mbedtls_pk_free(&key);
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
char *crypto_get_csr()
|
char *crypto_get_csr()
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -217,11 +257,92 @@ char *crypto_encode_base64_safe_url(const char *src, size_t srclen)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out[olen - 1] == '=')
|
// Convert base64 encoding to base64URL
|
||||||
out[olen - 1] = '\0';
|
for (size_t i = 0; i < olen; i++)
|
||||||
|
{
|
||||||
if (out[olen - 2] == '=')
|
switch (out[i])
|
||||||
out[olen - 2] = '\0';
|
{
|
||||||
|
case '+':
|
||||||
|
out[i] = '-';
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
out[i] = '_';
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
out[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HASH_LEN 32
|
||||||
|
|
||||||
|
char *crypto_sign_sha256_payload(const char *src, const size_t src_len, size_t *dstlen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint8_t r_be[32] = {0};
|
||||||
|
uint8_t s_be[32] = {0};
|
||||||
|
|
||||||
|
// Load private key
|
||||||
|
mbedtls_mpi key_mpi;
|
||||||
|
if (!crypto_get_priv_key_mpi(&key_mpi))
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to load private key MPI!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
seed_ctr_drbg_context(&entropy, &ctr_drbg);
|
||||||
|
|
||||||
|
mbedtls_mpi r, s;
|
||||||
|
mbedtls_mpi_init(&r);
|
||||||
|
mbedtls_mpi_init(&s);
|
||||||
|
|
||||||
|
mbedtls_ecdsa_context ecdsa_context;
|
||||||
|
mbedtls_ecdsa_init(&ecdsa_context);
|
||||||
|
|
||||||
|
mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
|
||||||
|
|
||||||
|
// Compute sha256
|
||||||
|
uint8_t sha256_out[HASH_LEN] = {0};
|
||||||
|
mbedtls_sha256((unsigned char *)src, src_len, sha256_out, 0);
|
||||||
|
|
||||||
|
// Compute signature
|
||||||
|
ret = mbedtls_ecdsa_sign(&ecdsa_context.MBEDTLS_PRIVATE(grp), &r, &s, &key_mpi, sha256_out, HASH_LEN, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||||
|
|
||||||
|
// Extract R & S (as per RFC 7518)
|
||||||
|
mbedtls_mpi_write_binary(&r, r_be, 32);
|
||||||
|
mbedtls_mpi_write_binary(&s, s_be, 32);
|
||||||
|
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
|
||||||
|
mbedtls_mpi_free(&r);
|
||||||
|
mbedtls_mpi_free(&s);
|
||||||
|
mbedtls_mpi_free(&key_mpi);
|
||||||
|
|
||||||
|
mbedtls_ecdsa_free(&ecdsa_context);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to perfom base64 encoding!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare output
|
||||||
|
char *out = calloc(1, 64);
|
||||||
|
if (!out)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to allocate memory to store signature!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(out, &r_be, 32);
|
||||||
|
memcpy(out + 32, &s_be, 32);
|
||||||
|
|
||||||
|
*dstlen = 64;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
@@ -39,6 +39,11 @@ extern "C"
|
|||||||
*/
|
*/
|
||||||
char *crypto_encode_base64_safe_url(const char *src, size_t srclen);
|
char *crypto_encode_base64_safe_url(const char *src, size_t srclen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign some data using sha256
|
||||||
|
*/
|
||||||
|
char *crypto_sign_sha256_payload(const char *src, const size_t src_len, size_t *dstlen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -77,10 +77,39 @@ char *jwt_gen(cJSON *payload)
|
|||||||
free(header_b64);
|
free(header_b64);
|
||||||
free(body_b64);
|
free(body_b64);
|
||||||
|
|
||||||
// TODO : wip
|
size_t sig_len = 0;
|
||||||
printf("unsigned = %s\n", unsigned_jwt);
|
char *sig = crypto_sign_sha256_payload(unsigned_jwt, strlen(unsigned_jwt), &sig_len);
|
||||||
free(unsigned_jwt);
|
|
||||||
|
|
||||||
// TODO : continue
|
if (!sig || sig_len == 0)
|
||||||
return strdup("TODO:)");
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to sign JWT!");
|
||||||
|
if (sig)
|
||||||
|
free(sig);
|
||||||
|
free(unsigned_jwt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *sig_b64 = crypto_encode_base64_safe_url(sig, sig_len);
|
||||||
|
free(sig);
|
||||||
|
if (!sig_b64)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to encode base64 signature to base64!");
|
||||||
|
free(unsigned_jwt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *jwt = calloc(1, 1 + strlen(unsigned_jwt) + 1 + strlen(sig_b64));
|
||||||
|
if (!jwt)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to allocate memory to store final JWT!");
|
||||||
|
free(unsigned_jwt);
|
||||||
|
free(sig_b64);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sprintf(jwt, "%s.%s", unsigned_jwt, sig_b64);
|
||||||
|
|
||||||
|
free(unsigned_jwt);
|
||||||
|
free(sig_b64);
|
||||||
|
|
||||||
|
return jwt;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user