Added TLS CA validation option as an alternative to Fingerprint validation

This commit is contained in:
Stephan Hadinger 2019-06-10 19:58:57 +02:00
parent 006462f17e
commit 844840a851
6 changed files with 311 additions and 271 deletions

View File

@ -38,7 +38,7 @@ uint32_t *stack_thunk_light_save = NULL; /* Saved A1 while in BearSSL */
uint32_t stack_thunk_light_refcnt = 0;
//#define _stackSize (5600/4)
#define _stackSize (4600/4) // using a light version of bearssl we can save 1KB
#define _stackSize (4800/4) // using a light version of bearssl we can save 1KB
#define _stackPaint 0xdeadbeef
/* Add a reference, and allocate the stack if necessary */

View File

@ -45,7 +45,7 @@ extern "C" {
#include "my_user_config.h"
//#define DEBUG_TLS
#define DEBUG_TLS
#ifdef DEBUG_TLS
#include "coredecls.h"
@ -182,6 +182,9 @@ void WiFiClientSecure_light::_clear() {
_fingerprint_any = true; // by default accept all fingerprints
_fingerprint1 = nullptr;
_fingerprint2 = nullptr;
_chain_P = nullptr;
_sk_ec_P = nullptr;
_ta_P = nullptr;
}
// Constructor
@ -218,16 +221,15 @@ void WiFiClientSecure_light::allocateBuffers(void) {
void WiFiClientSecure_light::setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk,
unsigned allowed_usages, unsigned cert_issuer_key_type) {
_chain_P = cert;
_chain.data_len = _chain_P->data_len;
_chain.data = nullptr;
_sk_ec_P = sk;
_sk_ec.curve = _sk_ec_P->curve;
_sk_ec.xlen = _sk_ec_P->xlen;
_sk_ec.x = nullptr;
_allowed_usages = allowed_usages;
_cert_issuer_key_type = cert_issuer_key_type;
}
void WiFiClientSecure_light::setTrustAnchor(const br_x509_trust_anchor *ta) {
_ta_P = ta;
}
void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) {
// Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately)
const int MAX_OUT_OVERHEAD = 85;
@ -781,121 +783,160 @@ extern "C" {
// Returns if the SSL handshake succeeded.
bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
#ifdef USE_MQTT_AWS_IOT
br_ec_private_key sk_ec;
br_x509_certificate chain;
#ifdef USE_MQTT_AWS_IOT_SKEY_ON_STACK
unsigned char chain_data[_chain_P->data_len];
unsigned char sk_data[_sk_ec_P->xlen];
#endif
br_ec_private_key sk_ec = {0, nullptr, 0};
br_x509_certificate chain = {nullptr, 0};
if ((!_chain_P) || (!_sk_ec_P)) {
setLastError(ERR_MISSING_EC_KEY);
return false;
}
#endif
// Validation context, either full CA validation or checking only fingerprints
#ifdef USE_MQTT_TLS_CA_CERT
br_x509_minimal_context *x509_minimal;
br_x509_trust_anchor ta; // = {{nullptr,0},0,{0,{.rsa={nullptr,0,nullptr,0}}}};
memset(&ta, 0, sizeof(ta));
if (!_ta_P) {
setLastError(ERR_MISSING_CA);
return false;
}
#else
br_x509_pubkeyfingerprint_context *x509_insecure;
#endif
LOG_HEAP_SIZE("_connectSSL.start");
stack_thunk_light_add_ref();
LOG_HEAP_SIZE("Thunk allocated");
DEBUG_BSSL("_connectSSL: start connection\n");
_freeSSL();
clearLastError();
do { // used to exit on Out of Memory error and keep all cleanup code at the same place
// ============================================================
// allocate Thunk stack, move to alternate stack and initialize
stack_thunk_light_add_ref();
LOG_HEAP_SIZE("Thunk allocated");
DEBUG_BSSL("_connectSSL: start connection\n");
_freeSSL();
clearLastError();
if (!stack_thunk_light_get_stack_bot()) break;
_ctx_present = true;
_eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
br_ssl_client_base_init(_sc.get());
// ============================================================
// Copy server CA from PROGMEM to RAM
#ifdef USE_MQTT_TLS_CA_CERT
memcpy_P(&ta, _ta_P, sizeof(ta)); // copy the whole structure first
unsigned char rsa_e[_ta_P->pkey.key.rsa.elen]; // it's only 3 bytes long, spare the malloc
ta.pkey.key.rsa.e = rsa_e;
ta.dn.data = (unsigned char *) malloc(ta.dn.len);
if (!ta.dn.data) break;
ta.pkey.key.rsa.n = (unsigned char *) malloc(ta.pkey.key.rsa.nlen);
if (!ta.pkey.key.rsa.n) break;
memcpy_P(ta.dn.data, _ta_P->dn.data, ta.dn.len);
memcpy_P(ta.pkey.key.rsa.n, _ta_P->pkey.key.rsa.n, ta.pkey.key.rsa.nlen);
memcpy_P(rsa_e, _ta_P->pkey.key.rsa.e, ta.pkey.key.rsa.elen);
LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation");
// Only failure possible in the installation is OOM
x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context));
#endif
br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2,
_recv_fingerprint, _fingerprint_any);
br_ssl_engine_set_x509(_eng, &x509_insecure->vtable);
_ctx_present = true;
_eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
br_ssl_client_base_init(_sc.get());
LOG_HEAP_SIZE("_connectSSL after PrivKey allocation");
#ifdef USE_MQTT_AWS_IOT
// allocate Private key and client certificate
chain.data_len = _chain_P->data_len;
#ifdef USE_MQTT_AWS_IOT_SKEY_ON_STACK // allocate on stack
chain.data = &chain_data[0];
#else // allocate with malloc
chain.data = (unsigned char *) malloc(chain.data_len);
#endif
if (chain.data) memcpy_P(chain.data, _chain_P->data, chain.data_len);
// ============================================================
// Allocatte and initialize Decoder Context
LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation");
// Only failure possible in the installation is OOM
#ifdef USE_MQTT_TLS_CA_CERT
x509_minimal = (br_x509_minimal_context*) malloc(sizeof(br_x509_minimal_context));
if (!x509_minimal) break;
br_x509_minimal_init(x509_minimal, &br_sha256_vtable, &ta, 1);
br_x509_minimal_set_rsa(x509_minimal, br_ssl_engine_get_rsavrfy(_eng));
br_x509_minimal_set_hash(x509_minimal, br_sha256_ID, &br_sha256_vtable);
br_ssl_engine_set_x509(_eng, &x509_minimal->vtable);
sk_ec.curve = _sk_ec_P->curve;
sk_ec.xlen = _sk_ec_P->xlen;
#ifdef USE_MQTT_AWS_IOT_SKEY_ON_STACK
sk_ec.x = &sk_data[0];
#else // USE_MQTT_AWS_IOT_SKEY_ON_STACK
sk_ec.x = (unsigned char *) malloc(sk_ec.xlen);
#endif // USE_MQTT_AWS_IOT_SKEY_ON_STACK
if (sk_ec.x) memcpy_P(sk_ec.x, _sk_ec_P->x, sk_ec.xlen);
LOG_HEAP_SIZE("_connectSSL after PrivKey allocation");
#endif // USE_MQTT_AWS_IOT
#else
x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context));
//x509_insecure = std::unique_ptr<br_x509_pubkeyfingerprint_context>(new br_x509_pubkeyfingerprint_context);
if (!x509_insecure) break;
br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2, _recv_fingerprint, _fingerprint_any);
br_ssl_engine_set_x509(_eng, &x509_insecure->vtable);
#endif
LOG_HEAP_SIZE("_connectSSL after DecoderContext allocation");
// check if memory was correctly allocated
#ifdef USE_MQTT_AWS_IOT
if ((!stack_thunk_light_get_stack_bot()) || (!x509_insecure) ||
(!chain.data) || (!sk_ec.x)) {
#ifndef USE_MQTT_AWS_IOT_SKEY_ON_STACK
free(chain.data);
free(sk_ec.x);
#endif // USE_MQTT_AWS_IOT_SKEY_ON_STACK
#else
if ((!stack_thunk_light_get_stack_bot()) || (!x509_insecure)) {
#endif // USE_MQTT_AWS_IOT
// memory allocation problem
setLastError(ERR_OOM);
free(x509_insecure);
// ============================================================
// Set send/receive buffers
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
// ============================================================
// allocate Private key if needed, only if USE_MQTT_AWS_IOT
LOG_HEAP_SIZE("_connectSSL before PrivKey allocation");
#ifdef USE_MQTT_AWS_IOT
// allocate Private key and client certificate
chain.data_len = _chain_P->data_len;
chain.data = (unsigned char *) malloc(chain.data_len);
if (!chain.data) break;
memcpy_P(chain.data, _chain_P->data, chain.data_len);
sk_ec.curve = _sk_ec_P->curve;
sk_ec.xlen = _sk_ec_P->xlen;
sk_ec.x = (unsigned char *) malloc(sk_ec.xlen);
if (!sk_ec.x) break;
memcpy_P(sk_ec.x, _sk_ec_P->x, sk_ec.xlen);
LOG_HEAP_SIZE("_connectSSL after PrivKey allocation");
// ============================================================
// Set the EC Private Key, only USE_MQTT_AWS_IOT
// limited to P256 curve
br_ssl_client_set_single_ec(_sc.get(), &chain, 1,
&sk_ec, _allowed_usages,
_cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default());
#endif // USE_MQTT_AWS_IOT
// ============================================================
// Start TLS connection, ALL
if (!br_ssl_client_reset(_sc.get(), hostName, 0)) break;
auto ret = _wait_for_handshake();
#ifdef DEBUG_ESP_SSL
if (!ret) {
DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError());
} else {
DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus());
}
#endif
LOG_HEAP_SIZE("_connectSSL.end");
stack_thunk_light_del_ref();
DEBUG_BSSL("_connectSSL: Out of memory\n");
return false;
}
//stack_thunk_light_repaint();
LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk");
#if defined(USE_MQTT_AWS_IOT)
free(chain.data);
free(sk_ec.x);
#endif
#ifdef USE_MQTT_AWS_IOT
// limited to P256 curve
br_ssl_client_set_single_ec(_sc.get(), &chain, 1,
&sk_ec, _allowed_usages,
_cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default());
#endif
#ifdef USE_MQTT_TLS_CA_CERT
free(x509_minimal);
free(ta.dn.data);
free(ta.pkey.key.rsa.n);
#else
free(x509_insecure);
#endif
LOG_HEAP_SIZE("_connectSSL after release of Priv Key");
return ret;
} while (0);
if (!br_ssl_client_reset(_sc.get(), hostName, 0)) {
#ifdef USE_MQTT_AWS_IOT
#ifndef USE_MQTT_AWS_IOT_SKEY_ON_STACK
free(chain.data);
free(sk_ec.x);
#endif
#endif
free(x509_insecure);
stack_thunk_light_del_ref();
_freeSSL();
DEBUG_BSSL("_connectSSL: Can't reset client\n");
return false;
}
auto ret = _wait_for_handshake();
#ifdef DEBUG_ESP_SSL
if (!ret) {
DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError());
} else {
DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus());
}
#endif
LOG_HEAP_SIZE("_connectSSL.end");
// ============================================================
// if we arrived here, this means we had an OOM error, cleaning up
setLastError(ERR_OOM);
DEBUG_BSSL("_connectSSL: Out of memory\n");
stack_thunk_light_del_ref();
//stack_thunk_light_repaint();
LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk");
#ifdef USE_MQTT_AWS_IOT
#ifndef USE_MQTT_AWS_IOT_SKEY_ON_STACK
free(chain.data);
free(sk_ec.x);
#endif
#ifdef USE_MQTT_TLS_CA_CERT
free(x509_minimal);
free(ta.dn.data);
free(ta.pkey.key.rsa.n);
#else
free(x509_insecure);
#endif
free(x509_insecure);
LOG_HEAP_SIZE("_connectSSL after release of Priv Key");
return ret;
LOG_HEAP_SIZE("_connectSSL clean_on_error");
return false;
}
};

View File

@ -74,6 +74,8 @@ class WiFiClientSecure_light : public WiFiClient {
void setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk,
unsigned allowed_usages, unsigned cert_issuer_key_type);
void setTrustAnchor(const br_x509_trust_anchor *ta);
// Sets the requested buffer size for transmit and receive
void setBufferSizes(int recv, int xmit);
@ -128,10 +130,9 @@ class WiFiClientSecure_light : public WiFiClient {
bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting
// Optional client certificate
br_x509_certificate _chain; // local RAM copy
const br_x509_certificate *_chain_P; // PROGMEM certificate
br_ec_private_key _sk_ec;
const br_ec_private_key *_sk_ec_P; // PROGMEM private key
const br_x509_trust_anchor *_ta_P; // PROGMEM server CA
unsigned _allowed_usages;
unsigned _cert_issuer_key_type;
@ -140,6 +141,72 @@ class WiFiClientSecure_light : public WiFiClient {
#define ERR_OOM -1000
#define ERR_CANT_RESOLVE_IP -1001
#define ERR_TCP_CONNECT -1002
#define ERR_MISSING_EC_KEY -1003
#define ERR_MISSING_CA -1004
// For reference, BearSSL error codes:
// #define BR_ERR_OK 0
// #define BR_ERR_BAD_PARAM 1
// #define BR_ERR_BAD_STATE 2
// #define BR_ERR_UNSUPPORTED_VERSION 3
// #define BR_ERR_BAD_VERSION 4
// #define BR_ERR_BAD_LENGTH 5
// #define BR_ERR_TOO_LARGE 6
// #define BR_ERR_BAD_MAC 7
// #define BR_ERR_NO_RANDOM 8
// #define BR_ERR_UNKNOWN_TYPE 9
// #define BR_ERR_UNEXPECTED 10
// #define BR_ERR_BAD_CCS 12
// #define BR_ERR_BAD_ALERT 13
// #define BR_ERR_BAD_HANDSHAKE 14
// #define BR_ERR_OVERSIZED_ID 15
// #define BR_ERR_BAD_CIPHER_SUITE 16
// #define BR_ERR_BAD_COMPRESSION 17
// #define BR_ERR_BAD_FRAGLEN 18
// #define BR_ERR_BAD_SECRENEG 19
// #define BR_ERR_EXTRA_EXTENSION 20
// #define BR_ERR_BAD_SNI 21
// #define BR_ERR_BAD_HELLO_DONE 22
// #define BR_ERR_LIMIT_EXCEEDED 23
// #define BR_ERR_BAD_FINISHED 24
// #define BR_ERR_RESUME_MISMATCH 25
// #define BR_ERR_INVALID_ALGORITHM 26
// #define BR_ERR_BAD_SIGNATURE 27
// #define BR_ERR_WRONG_KEY_USAGE 28
// #define BR_ERR_NO_CLIENT_AUTH 29
// #define BR_ERR_IO 31
// #define BR_ERR_RECV_FATAL_ALERT 256
// #define BR_ERR_SEND_FATAL_ALERT 512
// #define BR_ERR_X509_OK 32
// #define BR_ERR_X509_INVALID_VALUE 33
// #define BR_ERR_X509_TRUNCATED 34
// #define BR_ERR_X509_EMPTY_CHAIN 35
// #define BR_ERR_X509_INNER_TRUNC 36
// #define BR_ERR_X509_BAD_TAG_CLASS 37
// #define BR_ERR_X509_BAD_TAG_VALUE 38
// #define BR_ERR_X509_INDEFINITE_LENGTH 39
// #define BR_ERR_X509_EXTRA_ELEMENT 40
// #define BR_ERR_X509_UNEXPECTED 41
// #define BR_ERR_X509_NOT_CONSTRUCTED 42
// #define BR_ERR_X509_NOT_PRIMITIVE 43
// #define BR_ERR_X509_PARTIAL_BYTE 44
// #define BR_ERR_X509_BAD_BOOLEAN 45
// #define BR_ERR_X509_OVERFLOW 46
// #define BR_ERR_X509_BAD_DN 47
// #define BR_ERR_X509_BAD_TIME 48
// #define BR_ERR_X509_UNSUPPORTED 49
// #define BR_ERR_X509_LIMIT_EXCEEDED 50
// #define BR_ERR_X509_WRONG_KEY_TYPE 51
// #define BR_ERR_X509_BAD_SIGNATURE 52
// #define BR_ERR_X509_TIME_UNKNOWN 53
// #define BR_ERR_X509_EXPIRED 54
// #define BR_ERR_X509_DN_MISMATCH 55
// #define BR_ERR_X509_BAD_SERVER_NAME 56
// #define BR_ERR_X509_CRITICAL_EXTENSION 57
// #define BR_ERR_X509_NOT_CA 58
// #define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59
// #define BR_ERR_X509_WEAK_PUBLIC_KEY 60
// #define BR_ERR_X509_NOT_TRUSTED 62
};

View File

@ -264,12 +264,12 @@
// -- MQTT - TLS - AWS IoT ----------------------------------
//#define USE_MQTT_TLS // Use TLS for MQTT connection (+56.7k code, +6.0k mem and +6.6k additional during connection handshake)
//#define USE_MQTT_TLS_CA_CERT // Force full CA validation instead of fingerprints, uses more memory and slower, but simpler to use
//#define USE_MQTT_AWS_IOT // Enable MQTT for AWS IoT - requires a private key (+56.7k code, +6.0k mem and +6.6k additional during connection handshake)
// note: enabling USE_MQTT_AWS_IOT autoamtically enables USE_MQTT_TLS
// you need to generate a private key + certificate per device
// and update 'sonoff/sonoff_aws_iot.cpp'
// Full documentation here: https://github.com/arendst/Sonoff-Tasmota/wiki/AWS-IoT
#define USE_MQTT_AWS_IOT_SKEY_ON_STACK // copy private key+cert on stack rather than on heap, don't disable unless you see crashes during connections
// -- KNX IP Protocol -----------------------------

View File

@ -22,39 +22,30 @@
// However, the CA are available below for future use if it appears to be useful
#ifdef USE_MQTT_TLS_CA_CERT
#ifndef USE_MQTT_AWS_IOT
/*********************************************************************************************\
* LetsEncrypt IdenTrust DST Root CA X3 certificate, RSA 2048 bits SHA 256, valid until 20210417
*
* https://letsencrypt.org/certificates/
* Downloaded from https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt
*
* to convert do: bearssl chain lets-encrypt-x3-cross-signed.pem.txt
* to convert do: bearssl ta lets-encrypt-x3-cross-signed.pem.txt
* then copy and paste below, chain the generic names to the same as below
* remove static and add PROGMEM
\*********************************************************************************************/
const unsigned char PROGMEM LetsencryptRootCA3[] = {
0x30, 0x82, 0x04, 0x92, 0x30, 0x82, 0x03, 0x7A, 0xA0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x10, 0x0A, 0x01, 0x41, 0x42, 0x00, 0x00, 0x01, 0x53, 0x85,
0x73, 0x6A, 0x0B, 0x85, 0xEC, 0xA7, 0x08, 0x30, 0x0D, 0x06, 0x09, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x3F,
0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x44,
0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x69, 0x67, 0x6E, 0x61,
0x74, 0x75, 0x72, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43,
0x6F, 0x2E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
0x0E, 0x44, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41,
0x20, 0x58, 0x33, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36, 0x30, 0x33, 0x31,
0x37, 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5A, 0x17, 0x0D, 0x32, 0x31,
0x30, 0x33, 0x31, 0x37, 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5A, 0x30,
0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13,
0x0D, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6E, 0x63, 0x72, 0x79,
0x70, 0x74, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
0x1A, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6E, 0x63, 0x72, 0x79,
0x70, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
0x20, 0x58, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00,
static const unsigned char PROGMEM TA0_DN[] = {
0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A,
0x13, 0x0D, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6E, 0x63, 0x72,
0x79, 0x70, 0x74, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03,
0x13, 0x1A, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6E, 0x63, 0x72,
0x79, 0x70, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74,
0x79, 0x20, 0x58, 0x33
};
static const unsigned char PROGMEM TA0_RSA_N[] = {
0x9C, 0xD3, 0x0C, 0xF0, 0x5A, 0xE5, 0x2E, 0x47, 0xB7, 0x72, 0x5D, 0x37,
0x83, 0xB3, 0x68, 0x63, 0x30, 0xEA, 0xD7, 0x35, 0x26, 0x19, 0x25, 0xE1,
0xBD, 0xBE, 0x35, 0xF1, 0x70, 0x92, 0x2F, 0xB7, 0xB8, 0x4B, 0x41, 0x05,
@ -76,71 +67,28 @@ const unsigned char PROGMEM LetsencryptRootCA3[] = {
0xC3, 0x30, 0x7F, 0xA2, 0x79, 0x31, 0x13, 0x3D, 0x2D, 0x36, 0xF8, 0xE3,
0xFC, 0xF2, 0x33, 0x6A, 0xB9, 0x39, 0x31, 0xC5, 0xAF, 0xC4, 0x8D, 0x0D,
0x1D, 0x64, 0x16, 0x33, 0xAA, 0xFA, 0x84, 0x29, 0xB6, 0xD4, 0x0B, 0xC0,
0xD8, 0x7D, 0xC3, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01,
0x7D, 0x30, 0x82, 0x01, 0x79, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1D, 0x13,
0x01, 0x01, 0xFF, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01,
0x00, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04,
0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x7F, 0x06, 0x08, 0x2B, 0x06, 0x01,
0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x73, 0x30, 0x71, 0x30, 0x32, 0x06,
0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x26, 0x68,
0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x69, 0x73, 0x72, 0x67, 0x2E, 0x74,
0x72, 0x75, 0x73, 0x74, 0x69, 0x64, 0x2E, 0x6F, 0x63, 0x73, 0x70, 0x2E,
0x69, 0x64, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x63, 0x6F,
0x6D, 0x30, 0x3B, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
0x02, 0x86, 0x2F, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x70,
0x70, 0x73, 0x2E, 0x69, 0x64, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74,
0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x72, 0x6F, 0x6F, 0x74, 0x73, 0x2F, 0x64,
0x73, 0x74, 0x72, 0x6F, 0x6F, 0x74, 0x63, 0x61, 0x78, 0x33, 0x2E, 0x70,
0x37, 0x63, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30,
0x16, 0x80, 0x14, 0xC4, 0xA7, 0xB1, 0xA4, 0x7B, 0x2C, 0x71, 0xFA, 0xDB,
0xE1, 0x4B, 0x90, 0x75, 0xFF, 0xC4, 0x15, 0x60, 0x85, 0x89, 0x10, 0x30,
0x54, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04, 0x4D, 0x30, 0x4B, 0x30, 0x08,
0x06, 0x06, 0x67, 0x81, 0x0C, 0x01, 0x02, 0x01, 0x30, 0x3F, 0x06, 0x0B,
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDF, 0x13, 0x01, 0x01, 0x01, 0x30,
0x30, 0x30, 0x2E, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02,
0x01, 0x16, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x63, 0x70,
0x73, 0x2E, 0x72, 0x6F, 0x6F, 0x74, 0x2D, 0x78, 0x31, 0x2E, 0x6C, 0x65,
0x74, 0x73, 0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2E, 0x6F, 0x72,
0x67, 0x30, 0x3C, 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x35, 0x30, 0x33,
0x30, 0x31, 0xA0, 0x2F, 0xA0, 0x2D, 0x86, 0x2B, 0x68, 0x74, 0x74, 0x70,
0x3A, 0x2F, 0x2F, 0x63, 0x72, 0x6C, 0x2E, 0x69, 0x64, 0x65, 0x6E, 0x74,
0x72, 0x75, 0x73, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x44, 0x53, 0x54,
0x52, 0x4F, 0x4F, 0x54, 0x43, 0x41, 0x58, 0x33, 0x43, 0x52, 0x4C, 0x2E,
0x63, 0x72, 0x6C, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16,
0x04, 0x14, 0xA8, 0x4A, 0x6A, 0x63, 0x04, 0x7D, 0xDD, 0xBA, 0xE6, 0xD1,
0x39, 0xB7, 0xA6, 0x45, 0x65, 0xEF, 0xF3, 0xA8, 0xEC, 0xA1, 0x30, 0x0D,
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05,
0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xDD, 0x33, 0xD7, 0x11, 0xF3, 0x63,
0x58, 0x38, 0xDD, 0x18, 0x15, 0xFB, 0x09, 0x55, 0xBE, 0x76, 0x56, 0xB9,
0x70, 0x48, 0xA5, 0x69, 0x47, 0x27, 0x7B, 0xC2, 0x24, 0x08, 0x92, 0xF1,
0x5A, 0x1F, 0x4A, 0x12, 0x29, 0x37, 0x24, 0x74, 0x51, 0x1C, 0x62, 0x68,
0xB8, 0xCD, 0x95, 0x70, 0x67, 0xE5, 0xF7, 0xA4, 0xBC, 0x4E, 0x28, 0x51,
0xCD, 0x9B, 0xE8, 0xAE, 0x87, 0x9D, 0xEA, 0xD8, 0xBA, 0x5A, 0xA1, 0x01,
0x9A, 0xDC, 0xF0, 0xDD, 0x6A, 0x1D, 0x6A, 0xD8, 0x3E, 0x57, 0x23, 0x9E,
0xA6, 0x1E, 0x04, 0x62, 0x9A, 0xFF, 0xD7, 0x05, 0xCA, 0xB7, 0x1F, 0x3F,
0xC0, 0x0A, 0x48, 0xBC, 0x94, 0xB0, 0xB6, 0x65, 0x62, 0xE0, 0xC1, 0x54,
0xE5, 0xA3, 0x2A, 0xAD, 0x20, 0xC4, 0xE9, 0xE6, 0xBB, 0xDC, 0xC8, 0xF6,
0xB5, 0xC3, 0x32, 0xA3, 0x98, 0xCC, 0x77, 0xA8, 0xE6, 0x79, 0x65, 0x07,
0x2B, 0xCB, 0x28, 0xFE, 0x3A, 0x16, 0x52, 0x81, 0xCE, 0x52, 0x0C, 0x2E,
0x5F, 0x83, 0xE8, 0xD5, 0x06, 0x33, 0xFB, 0x77, 0x6C, 0xCE, 0x40, 0xEA,
0x32, 0x9E, 0x1F, 0x92, 0x5C, 0x41, 0xC1, 0x74, 0x6C, 0x5B, 0x5D, 0x0A,
0x5F, 0x33, 0xCC, 0x4D, 0x9F, 0xAC, 0x38, 0xF0, 0x2F, 0x7B, 0x2C, 0x62,
0x9D, 0xD9, 0xA3, 0x91, 0x6F, 0x25, 0x1B, 0x2F, 0x90, 0xB1, 0x19, 0x46,
0x3D, 0xF6, 0x7E, 0x1B, 0xA6, 0x7A, 0x87, 0xB9, 0xA3, 0x7A, 0x6D, 0x18,
0xFA, 0x25, 0xA5, 0x91, 0x87, 0x15, 0xE0, 0xF2, 0x16, 0x2F, 0x58, 0xB0,
0x06, 0x2F, 0x2C, 0x68, 0x26, 0xC6, 0x4B, 0x98, 0xCD, 0xDA, 0x9F, 0x0C,
0xF9, 0x7F, 0x90, 0xED, 0x43, 0x4A, 0x12, 0x44, 0x4E, 0x6F, 0x73, 0x7A,
0x28, 0xEA, 0xA4, 0xAA, 0x6E, 0x7B, 0x4C, 0x7D, 0x87, 0xDD, 0xE0, 0xC9,
0x02, 0x44, 0xA7, 0x87, 0xAF, 0xC3, 0x34, 0x5B, 0xB4, 0x42
0xD8, 0x7D, 0xC3, 0x93
};
const br_x509_certificate PROGMEM LetsencryptRootCA3_chain[] = {
{ (unsigned char *)LetsencryptRootCA3, sizeof LetsencryptRootCA3 }
static const unsigned char TA0_RSA_E[] = {
0x01, 0x00, 0x01
};
#define LETSENCRYPTROOTCA3LEN 1
static const br_x509_trust_anchor PROGMEM LetsEncryptX3CrossSigned_TA = {
{ (unsigned char *)TA0_DN, sizeof TA0_DN },
BR_X509_TA_CA,
{
BR_KEYTYPE_RSA,
{ .rsa = {
(unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N,
(unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E,
} }
}
};
#endif // USE_MQTT_TLS_CA_CERT
#define TAs_NUM 1
#endif // not USE_MQTT_AWS_IOT
#ifdef USE_MQTT_AWS_IOT
/*********************************************************************************************\
@ -149,88 +97,63 @@ const br_x509_certificate PROGMEM LetsencryptRootCA3_chain[] = {
* https://letsencrypt.org/certificates/
* Downloaded from https://www.amazontrust.com/repository/AmazonRootCA1.pem
*
* to convert do: bearssl chain AmazonRootCA1.pem
* to convert do: bearssl ta AmazonRootCA1.pem
* then copy and paste below, chain the generic names to the same as below
* remove static and add PROGMEM
\*********************************************************************************************/
const unsigned char PROGMEM AmazonRootCA1[] = {
0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xA0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x13, 0x06, 0x6C, 0x9F, 0xCF, 0x99, 0xBF, 0x8C, 0x0A, 0x39,
0xE2, 0xF0, 0x78, 0x8A, 0x43, 0xE6, 0x96, 0x36, 0x5B, 0xCA, 0x30, 0x0D,
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05,
0x00, 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04,
0x0A, 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30,
0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A,
0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31,
0x30, 0x1E, 0x17, 0x0D, 0x31, 0x35, 0x30, 0x35, 0x32, 0x36, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x33, 0x38, 0x30, 0x31, 0x31,
0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x30, 0x39, 0x31, 0x0B,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x06, 0x41, 0x6D,
0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04,
0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x20, 0x52, 0x6F,
0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30,
0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02,
0x82, 0x01, 0x01, 0x00, 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3,
0x71, 0xAF, 0x47, 0x80, 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76,
0xF4, 0x99, 0x68, 0xF7, 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F,
0xAC, 0x02, 0x2D, 0x86, 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0,
0x36, 0xBA, 0x01, 0xBE, 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C,
0xF4, 0xEE, 0x88, 0x23, 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8,
0x49, 0x68, 0xB0, 0xDE, 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4,
0xFE, 0x82, 0x36, 0xA5, 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD,
0xB4, 0x16, 0xFA, 0x74, 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0,
0x20, 0x50, 0x06, 0x6C, 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC,
0x47, 0x19, 0x8F, 0x50, 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8,
0xBA, 0xD5, 0xA9, 0xF9, 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E,
0x6F, 0x89, 0xA3, 0x51, 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA,
0x54, 0xEB, 0xA3, 0xC3, 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30,
0x2D, 0x7D, 0x2D, 0x74, 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4,
0x59, 0x6E, 0xBB, 0x73, 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43,
0xFA, 0xB7, 0x1D, 0xAA, 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B,
0xF7, 0x71, 0x5C, 0x5E, 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A,
0xAE, 0x50, 0x38, 0x6F, 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E,
0x54, 0xE1, 0x77, 0xE0, 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F,
0x40, 0x20, 0x7F, 0x20, 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26,
0x8E, 0x04, 0xAE, 0x6C, 0x9A, 0xC8, 0xAA, 0x0D, 0x02, 0x03, 0x01, 0x00,
0x01, 0xA3, 0x42, 0x30, 0x40, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13,
0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0E,
0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02,
0x01, 0x86, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04,
0x14, 0x84, 0x18, 0xCC, 0x85, 0x34, 0xEC, 0xBC, 0x0C, 0x94, 0x94, 0x2E,
0x08, 0x59, 0x9C, 0xC7, 0xB2, 0x10, 0x4E, 0x0A, 0x08, 0x30, 0x0D, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00,
0x03, 0x82, 0x01, 0x01, 0x00, 0x98, 0xF2, 0x37, 0x5A, 0x41, 0x90, 0xA1,
0x1A, 0xC5, 0x76, 0x51, 0x28, 0x20, 0x36, 0x23, 0x0E, 0xAE, 0xE6, 0x28,
0xBB, 0xAA, 0xF8, 0x94, 0xAE, 0x48, 0xA4, 0x30, 0x7F, 0x1B, 0xFC, 0x24,
0x8D, 0x4B, 0xB4, 0xC8, 0xA1, 0x97, 0xF6, 0xB6, 0xF1, 0x7A, 0x70, 0xC8,
0x53, 0x93, 0xCC, 0x08, 0x28, 0xE3, 0x98, 0x25, 0xCF, 0x23, 0xA4, 0xF9,
0xDE, 0x21, 0xD3, 0x7C, 0x85, 0x09, 0xAD, 0x4E, 0x9A, 0x75, 0x3A, 0xC2,
0x0B, 0x6A, 0x89, 0x78, 0x76, 0x44, 0x47, 0x18, 0x65, 0x6C, 0x8D, 0x41,
0x8E, 0x3B, 0x7F, 0x9A, 0xCB, 0xF4, 0xB5, 0xA7, 0x50, 0xD7, 0x05, 0x2C,
0x37, 0xE8, 0x03, 0x4B, 0xAD, 0xE9, 0x61, 0xA0, 0x02, 0x6E, 0xF5, 0xF2,
0xF0, 0xC5, 0xB2, 0xED, 0x5B, 0xB7, 0xDC, 0xFA, 0x94, 0x5C, 0x77, 0x9E,
0x13, 0xA5, 0x7F, 0x52, 0xAD, 0x95, 0xF2, 0xF8, 0x93, 0x3B, 0xDE, 0x8B,
0x5C, 0x5B, 0xCA, 0x5A, 0x52, 0x5B, 0x60, 0xAF, 0x14, 0xF7, 0x4B, 0xEF,
0xA3, 0xFB, 0x9F, 0x40, 0x95, 0x6D, 0x31, 0x54, 0xFC, 0x42, 0xD3, 0xC7,
0x46, 0x1F, 0x23, 0xAD, 0xD9, 0x0F, 0x48, 0x70, 0x9A, 0xD9, 0x75, 0x78,
0x71, 0xD1, 0x72, 0x43, 0x34, 0x75, 0x6E, 0x57, 0x59, 0xC2, 0x02, 0x5C,
0x26, 0x60, 0x29, 0xCF, 0x23, 0x19, 0x16, 0x8E, 0x88, 0x43, 0xA5, 0xD4,
0xE4, 0xCB, 0x08, 0xFB, 0x23, 0x11, 0x43, 0xE8, 0x43, 0x29, 0x72, 0x62,
0xA1, 0xA9, 0x5D, 0x5E, 0x08, 0xD4, 0x90, 0xAE, 0xB8, 0xD8, 0xCE, 0x14,
0xC2, 0xD0, 0x55, 0xF2, 0x86, 0xF6, 0xC4, 0x93, 0x43, 0x77, 0x66, 0x61,
0xC0, 0xB9, 0xE8, 0x41, 0xD7, 0x97, 0x78, 0x60, 0x03, 0x6E, 0x4A, 0x72,
0xAE, 0xA5, 0xD1, 0x7D, 0xBA, 0x10, 0x9E, 0x86, 0x6C, 0x1B, 0x8A, 0xB9,
0x59, 0x33, 0xF8, 0xEB, 0xC4, 0x90, 0xBE, 0xF1, 0xB9
const unsigned char PROGMEM TA0_DN[] = {
0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A,
0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17,
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F,
0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31
};
const br_x509_certificate PROGMEM AmazonRootCA1_chain[] = {
{ (unsigned char *)AmazonRootCA1, sizeof AmazonRootCA1 }
const unsigned char PROGMEM TA0_RSA_N[] = {
0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80,
0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7,
0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86,
0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE,
0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23,
0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE,
0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5,
0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74,
0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C,
0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50,
0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9,
0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51,
0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3,
0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74,
0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73,
0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA,
0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E,
0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F,
0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0,
0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20,
0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C,
0x9A, 0xC8, 0xAA, 0x0D
};
#define AMAZONROOTCA1_LEN 1
static const unsigned char PROGMEM TA0_RSA_E[] = {
0x01, 0x00, 0x01
};
#endif
const br_x509_trust_anchor PROGMEM AmazonRootCA1_TA = {
{ (unsigned char *)TA0_DN, sizeof TA0_DN },
BR_X509_TA_CA,
{
BR_KEYTYPE_RSA,
{ .rsa = {
(unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N,
(unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E,
} }
}
};
#define TAs_NUM 1
#endif // USE_MQTT_AWS_IOT
#endif // USE_MQTT_TLS_CA_CERT

View File

@ -127,8 +127,17 @@ void MqttInit(void) {
0xFFFF /* all usages, don't care */, 0);
#endif
#ifdef USE_MQTT_TLS_CA_CERT
tlsClient->setTrustAnchor(&LetsEncryptX3CrossSigned_TA);
#ifdef USE_MQTT_AWS_IOT
tlsClient->setTrustAnchor(&AmazonRootCA1_TA);
#else
// LETSENCRYPT CA TODO
#endif // USE_MQTT_AWS_IOT
#endif // USE_MQTT_TLS_CA_CERT
MqttClient.setClient(*tlsClient);
#endif
#endif // USE_MQTT_AWS_IOT
}
@ -480,8 +489,8 @@ void MqttReconnect(void)
MqttClient.setServer(Settings.mqtt_host, Settings.mqtt_port);
#endif
#ifdef USE_MQTT_TLS
uint32_t mqtt_connect_time = millis();
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
bool allow_all_fingerprints = false;
bool learn_fingerprint1 = is_fingerprint_mono_value(Settings.mqtt_fingerprint[0], 0x00);
bool learn_fingerprint2 = is_fingerprint_mono_value(Settings.mqtt_fingerprint[1], 0x00);
@ -499,15 +508,16 @@ void MqttReconnect(void)
if (MqttClient.connect(mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, true, mqtt_data, MQTT_CLEAN_SESSION)) {
#endif
#ifdef USE_MQTT_TLS
// create a printable version of the fingerprint received
char buf_fingerprint[64];
to_hex((unsigned char *)tlsClient->getRecvPubKeyFingerprint(), 20, buf_fingerprint, 64);
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms"), millis() - mqtt_connect_time);
if (!tlsClient->getMFLNStatus()) {
AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR("MFLN not supported by TLS server"));
}
#ifndef USE_MQTT_TLS_CA_CERT // don't bother with fingerprints if using CA validation
// create a printable version of the fingerprint received
char buf_fingerprint[64];
to_hex((unsigned char *)tlsClient->getRecvPubKeyFingerprint(), 20, buf_fingerprint, 64);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "Server fingerprint: %s"), buf_fingerprint);
if (learn_fingerprint1 || learn_fingerprint2) {
// we potentially need to learn the fingerprint just seen
bool fingerprint_matched = false;
@ -531,6 +541,7 @@ void MqttReconnect(void)
SettingsSaveAll(); // save settings
}
}
#endif // !USE_MQTT_TLS_CA_CERT
#endif // USE_MQTT_TLS
MqttConnected();
} else {
@ -639,7 +650,7 @@ bool MqttCommand(void)
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, GetStateText(index -1));
}
#ifdef USE_MQTT_TLS
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
else if ((CMND_MQTTFINGERPRINT == command_code) && (index > 0) && (index <= 2)) {
char fingerprint[60];
if ((data_len > 0) && (data_len < sizeof(fingerprint))) {
@ -934,11 +945,9 @@ bool Xdrv02(uint8_t function)
if (Settings.flag.mqtt_enabled) {
switch (function) {
#ifdef USE_MQTT_TLS
case FUNC_PRE_INIT:
MqttInit();
break;
#endif
case FUNC_EVERY_50_MSECOND: // https://github.com/knolleary/pubsubclient/issues/556
MqttClient.loop();
break;