20 #include <openssl/err.h>
21 #include <openssl/evp.h>
22 #include <openssl/pem.h>
29 #include "btrMgr_logger.h"
32 #define _DEBUG_CRYPTO_ 1
35 typedef unsigned char byte_t;
67 char const* encoded_data);
71 EVP_PKEY* private_key,
83 ECC_ReadPrivateKeyFromFile(
87 ECC_ReadPublicKeyFromPEM(
88 char const* pem_data);
91 ECC_ReadPublicKeyFromFile(
96 char const* private_key_path,
97 char const* peer_public_key,
99 char const* cipher_text,
101 int* clear_text_length);
107 int main(
int argc,
char* argv[])
111 cJSON* wifi_settings;
116 wifi_settings = NULL;
120 ERR_load_crypto_strings();
122 fin = fopen(argv[1],
"r");
123 fread(buff.data, 1, buff.length, fin);
126 reply = cJSON_Parse((
char const *)buff.data);
127 ECDH_DecryptWiFiSettings(reply, &wifi_settings);
131 char* s = cJSON_Print(wifi_settings);
134 cJSON_Delete(wifi_settings);
145 char const* private_key_path,
146 char const* peer_public_key,
148 char const* cipher_text,
150 int* clear_text_length)
155 EVP_PKEY* private_key;
169 baInit(&shared_secret, 0);
171 baInit(&decrypted, 0);
173 baFromBase64(&ivector, iv);
174 baFromBase64(&encrypted, cipher_text);
177 private_key = ECC_ReadPrivateKeyFromFile(private_key_path);
180 BTRMGRLOG_ERROR(
"failed to read private key from '%s'\n", private_key_path);
186 peer_key = ECC_ReadPublicKeyFromPEM(peer_public_key);
189 BTRMGRLOG_ERROR(
"failed to read public key from pem data\n");
190 BTRMGRLOG_INFO(
" --------- PEER PUBLIC KEY -----------\n%s\n",
197 ret = ECDH_SharedKeyDerive(private_key, peer_key, &shared_secret);
200 BTRMGRLOG_ERROR(
"failed to derive shared key\n");
205 ret = AESDecrypt(&shared_secret, &ivector, &encrypted, &decrypted);
208 BTRMGRLOG_ERROR(
"failed to decrypt data\n");
213 p = (
char *) malloc(
sizeof(byte_t) * (decrypted.length + 1));
214 memcpy(p, decrypted.data, decrypted.length);
215 p[decrypted.length] =
'\0';
218 *clear_text_length = decrypted.length;
222 baClear(&shared_secret);
229 EVP_PKEY_free(private_key);
232 EVP_PKEY_free(peer_key);
238 baFromBase64(
byteArray_t* decoded_data,
char const* encoded_data)
242 size_t encoded_length;
243 size_t bytes_written;
252 BTRMGRLOG_ERROR(
"no parameter sepcified to base64 decode into\n");
258 BTRMGRLOG_ERROR(
"no parameter specified to base64 decode\n");
262 encoded_length = strlen(encoded_data);
264 b64 = BIO_new(BIO_f_base64());
265 buff = BIO_new_mem_buf(encoded_data, encoded_length);
266 buff = BIO_push(b64, buff);
267 BIO_set_flags(buff, BIO_FLAGS_BASE64_NO_NL);
268 BIO_set_flags(buff, BIO_CLOSE);
270 baInit(decoded_data, encoded_length);
271 memset(decoded_data->data, 0, encoded_length);
272 decoded_data->length = 0;
274 bytes_written = BIO_read(buff, decoded_data->data, encoded_length);
275 decoded_data->length = bytes_written;
290 s = (
char *) malloc(v->length + 1);
292 for (i = 0; i < v->length; ++i)
293 s[i] = (
char) v->data[i];
309 EVP_CIPHER_CTX* cipher_ctx;
316 baInit(plain_data, encrypted_data->length);
319 baPrint(key,
"KEY\n");
321 baPrint(encrypted_data,
"ENCRYPTED DATA\n");
324 cipher_ctx = EVP_CIPHER_CTX_new();
327 BTRMGRLOG_ERROR(
"EVP_CIPHER_CTX_new failed. %s\n", CRYPTO_Error());
332 ret = EVP_DecryptInit_ex(cipher_ctx, EVP_aes_256_cbc(), NULL, key->data, iv->data);
335 BTRMGRLOG_ERROR(
"EVP_DecryptInit_ex failed. %s\n", CRYPTO_Error());
336 EVP_CIPHER_CTX_free(cipher_ctx);
341 EVP_CIPHER_CTX_set_padding(ctx.get(), 1);
342 EVP_CIPHER_CTX_set_key_length(ctx.get(), 16);
345 ret = EVP_DecryptUpdate(cipher_ctx, plain_data->data, &n, encrypted_data->data, encrypted_data->length);
352 BTRMGRLOG_ERROR(
"EVP_DecryptUpdate failed. %s\n", CRYPTO_Error());
353 EVP_CIPHER_CTX_free(cipher_ctx);
357 ret = EVP_DecryptFinal_ex(cipher_ctx, (plain_data->data + length), &n);
364 BTRMGRLOG_ERROR(
"EVP_DecryptFinal_ex failed. %s\n", CRYPTO_Error());
365 EVP_CIPHER_CTX_free(cipher_ctx);
369 if (length > 0 && length < plain_data->length)
371 plain_data->length = length;
372 plain_data->data[length] =
'\0';
375 EVP_CIPHER_CTX_free(cipher_ctx);
380 ECC_ReadPublicKeyFromPEM(
381 char const* pem_data)
383 EVP_PKEY* public_key;
389 static char const pem_header[] =
"-----BEGIN PUBLIC KEY-----";
390 static char const pem_footer[] =
"-----END PUBLIC KEY-----";
395 buff = BIO_new(BIO_s_mem());
396 BIO_write(buff, pem_header, strlen(pem_header));
397 BIO_write(buff,
"\n", 1);
398 BIO_write(buff, pem_data, strlen(pem_data));
399 BIO_write(buff,
"\n", 1);
400 BIO_write(buff, pem_footer, strlen(pem_footer));
402 public_key = PEM_read_bio_PUBKEY(buff, NULL, NULL, NULL);
405 BTRMGRLOG_ERROR(
"failed to parse PEM data for public key. %s\n", CRYPTO_Error());
413 ECC_ReadPublicKeyFromFile(
417 EVP_PKEY* public_key;
424 BTRMGRLOG_ERROR(
"can't read public key from NULL filename\n");
428 fin = fopen(fname,
"r");
432 BTRMGRLOG_ERROR(
"failed to open file to read public key '%s'. %d\n",
437 public_key = PEM_read_PUBKEY(fin, NULL, NULL, NULL);
444 ECC_ReadPrivateKeyFromFile(
char const* fname)
447 EVP_PKEY* private_key;
452 fin = fopen(fname,
"r");
456 BTRMGRLOG_ERROR(
"failed to open file to read private key '%s'. %d\n",
461 private_key = PEM_read_PrivateKey(fin, NULL, NULL, NULL);
468 ECDH_SharedKeyDerive(
469 EVP_PKEY* private_key,
474 EVP_PKEY_CTX* key_ctx;
477 baInit(shared_secret, 0);
480 key_ctx = EVP_PKEY_CTX_new(private_key, NULL);
483 unsigned long err = ERR_get_error();
484 BTRMGRLOG_ERROR(
"EVP_PKEY_CTX_new failed:%lu", err);
488 if (!EVP_PKEY_derive_init(key_ctx))
490 BTRMGRLOG_ERROR(
"EVP_PKEY_derive_init failed. %s", CRYPTO_Error());
491 EVP_PKEY_CTX_free(key_ctx);
495 if (!EVP_PKEY_derive_set_peer(key_ctx, peer_key))
497 BTRMGRLOG_ERROR(
"EVP_PKEY_derive_set_peer failed. %s", CRYPTO_Error());
498 EVP_PKEY_CTX_free(key_ctx);
502 if (!EVP_PKEY_derive(key_ctx, NULL, &len))
504 BTRMGRLOG_ERROR(
"EVP_PKEY_derive failed. %s", CRYPTO_Error());
505 EVP_PKEY_CTX_free(key_ctx);
509 baInit(shared_secret, len);
511 if (!EVP_PKEY_derive(key_ctx, shared_secret->data, &len))
513 BTRMGRLOG_ERROR(
"EVP_PKEY_derive failed. %s", CRYPTO_Error());
514 EVP_PKEY_CTX_free(key_ctx);
519 shared_secret->length = len;
522 EVP_PKEY_CTX_free(key_ctx);
536 size_t n =
sizeof(byte_t) * length;
537 v->data = (byte_t *) malloc(n);
538 memset(v->data, 0, n);
571 printf(
"----- BEGIN %s -----\n", name);
572 for (i = 0; i < v->length; ++i)
574 if (i > 0 && i % 8 == 0)
576 printf(
"0x%02x ", v->data[i]);
578 printf(
"\n----- END %s -----\n", name);
584 ECDH_DecryptWiFiSettings(
585 cJSON * server_reply,
586 cJSON** wifi_settings)
593 int clear_text_length;
600 clear_text_length = 0;
604 BTRMGRLOG_ERROR(
"null server_reply\n");
610 BTRMGRLOG_ERROR(
"null wifi_settings\n");
614 settings = cJSON_GetObjectItem(server_reply,
"wifi-settings");
617 BTRMGRLOG_INFO(
"found un-encrypted settings, using those\n");
618 *wifi_settings = cJSON_Duplicate(settings, 1);
622 settings = cJSON_GetObjectItem(server_reply,
"secure-wifi-settings");
625 BTRMGRLOG_ERROR(
"failed to find 'secure-wifi-settings' in wifi settings object\n");
626 *wifi_settings = NULL;
630 iv = cJSON_GetObjectItem(server_reply,
"iv");
633 BTRMGRLOG_ERROR(
"failed to find 'iv' in wifi settings object\n");
634 *wifi_settings = NULL;
638 peer_key = cJSON_GetObjectItem(server_reply,
"pubKey");
641 BTRMGRLOG_ERROR(
"failed to find 'pubKey' in wifi settings object\n");
645 ret = ECDH_Decrypt(kPrivateKeyPath, peer_key->valuestring, iv->valuestring,
646 settings->valuestring, &clear_text, &clear_text_length);
649 BTRMGRLOG_ERROR(
"failed to decrypt secure wifi settings from '%s'",
650 settings->valuestring);
656 BTRMGRLOG_ERROR(
"encryption returned NULL clear text string\n");
660 *wifi_settings = cJSON_Parse(clear_text);
663 BTRMGRLOG_ERROR(
"failed to parse secure wifi settings json string '%s'",
675 static char buff[512];
677 unsigned long err = ERR_get_error();
678 ERR_error_string_n(err, buff,
sizeof(buff));