24
24
#include " Https.h"
25
25
#include < SPIFFS.h>
26
26
#include < FS.h>
27
+ #include " esp_task_wdt.h"
27
28
28
29
using namespace httpsserver ;
29
30
31
+ static volatile bool isCertReady = 0 ;
32
+
30
33
// "20190101000000"
31
34
static std::string toCertDate (time_t theTime) {
32
35
char date[32 ];
@@ -39,12 +42,75 @@ static std::string toCertDate(time_t theTime) {
39
42
return std::string (date);
40
43
}
41
44
45
+ static std::string createDn () {
46
+ char dn[128 ];
47
+ const uint64_t chipid_num = ESP.getEfuseMac ();
48
+ // Placed the date in here - firefox does complain about duplicate cert
49
+ // otherwise (we can not increase the serial number from here).
50
+ snprintf (dn, sizeof (dn),
51
+ " CN=obs.local,O=openbikesensor.org,OU=%04x%08x,L=%s,C=DE" ,
52
+ (uint16_t )(chipid_num >> 32 ),
53
+ (uint32_t )(chipid_num),
54
+ toCertDate (time (nullptr )).c_str ());
55
+ return std::string (dn);
56
+ }
57
+
58
+ static void createCert (void *param) {
59
+ std::string fromDate;
60
+ std::string toDate;
61
+ time_t now = time (nullptr );
62
+ if (now > (2020 - 1970 ) * 365 * 24 * 60 * 60 ) {
63
+ fromDate = toCertDate (now);
64
+ // Suggestion for hardware devices is to set the validity of the
65
+ // cert to a high value. But Apple limits this value to 825
66
+ // days in https://support.apple.com/HT210176
67
+ toDate = toCertDate (now + 824 * 24 * 60 * 60 );
68
+ } else {
69
+ fromDate = " 20210513090700" ;
70
+ toDate = " 20301232235959" ;
71
+ }
42
72
73
+ log_i (" DN will be %s" , createDn ().c_str ());
74
+
75
+ SSLCert newCert;
76
+ int res = createSelfSignedCert (newCert,
77
+ KEYSIZE_2048,
78
+ createDn (),
79
+ fromDate,
80
+ toDate);
81
+ log_i (" PK Length %d, Key Length %d" , newCert.getPKLength (), newCert.getCertLength ());
82
+
83
+ if (res != 0 ) {
84
+ // Certificate generation failed. Inform the user.
85
+ log_e (" An error occured during certificate generation." );
86
+ log_e (" Error code is 0x%04x" , res);
87
+ log_e (" You may have a look at SSLCert.h to find the reason for this error." );
88
+ } else {
89
+ SSLCert *cert = static_cast <SSLCert *>(param);
90
+ cert->setCert (newCert.getCertData (), newCert.getCertLength ());
91
+ cert->setPK (newCert.getPKData (), newCert.getPKLength ());
92
+ log_i (" Created new cert." );
93
+ };
94
+
95
+ // Can this be done more elegant?
96
+ isCertReady = 1 ;
97
+ vTaskDelete (nullptr );
98
+ }
99
+
100
+ /* Just ensure there is a cert! */
101
+ void Https::ensureCertificate () {
102
+ delete getCertificate ();
103
+ }
104
+
105
+ bool Https::existsCertificate () {
106
+ return SPIFFS.exists (" /key.der" ) && SPIFFS.exists (" /cert.der" );
107
+ }
43
108
44
109
/* Load or create cert.
45
110
* Based on https://github.com/fhessel/esp32_https_server/blob/de1876cf6fe717cf236ad6603a97e88f22e38d62/examples/REST-API/REST-API.ino#L219
111
+ * https://github.com/fhessel/esp32_https_server/issues/48
46
112
*/
47
- SSLCert *Https::getCertificate () {
113
+ SSLCert *Https::getCertificate (std::function< void ()> progress ) {
48
114
// Try to open key and cert file to see if they exist
49
115
File keyFile = SPIFFS.open (" /key.der" );
50
116
File certFile = SPIFFS.open (" /cert.der" );
@@ -56,27 +122,22 @@ SSLCert *Https::getCertificate() {
56
122
log_i (" This may take up to a minute, so please stand by :)" );
57
123
58
124
SSLCert * newCert = new SSLCert ();
59
- // The part after the CN= is the domain that this certificate will match, in this
60
- // case, it's esp32.local.
61
- // However, as the certificate is self-signed, your browser won't trust the server
62
- // anyway.
63
-
64
- std::string fromDate;
65
- std::string toDate;
66
- time_t now = time (nullptr );
67
- if (now > (2020 - 1970 ) * 365 * 24 * 60 * 60 ) {
68
- fromDate = toCertDate (now);
69
- toDate = toCertDate (now + 365 * 24 * 60 * 60 );
70
- } else {
71
- fromDate = " 20210513090700" ;
72
- toDate = " 20301232235959" ;
125
+
126
+ TaskHandle_t xHandle;
127
+ xTaskCreate (reinterpret_cast <TaskFunction_t>(createCert), " createCert" ,
128
+ 16 * 1024 , newCert, 1 , &xHandle);
129
+
130
+ while (!isCertReady) {
131
+ if (progress) {
132
+ progress ();
133
+ }
134
+ delay (100 );
135
+ yield ();
136
+ esp_task_wdt_reset ();
73
137
}
74
138
75
- int res = createSelfSignedCert (*newCert,
76
- KEYSIZE_1024,
77
- " CN=obs.local,O=openbikesensor.org,C=DE" ,
78
- fromDate,
79
- toDate);
139
+ log_i (" PK Length %d, Key Length %d" , newCert->getPKLength (), newCert->getCertLength ());
140
+ int res = 0 ;
80
141
if (res == 0 ) {
81
142
// We now have a certificate. We store it on the SPIFFS to restore it on next boot.
82
143
0 commit comments