Skip to content

Commit 0067b38

Browse files
authored
Merge pull request SHA2017-badge#38 from SHA2017-badge/dialogs-and-more-emf-porting
SSL validation for sha2017.org subdomains
2 parents d6e961e + c2dd50b commit 0067b38

File tree

4 files changed

+222
-13
lines changed

4 files changed

+222
-13
lines changed

esp32/Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ INC += -I../lib/timeutils
5353
INC += -I../../components/badge
5454
INC += -I../../components/ugfx
5555
INC += -I../../components/graph
56+
INC += -I../../components/sha2017
5657
INC += -I../../main
5758
INC += -I../../ugfx/src/gdisp/mcufont
5859
INC += -I../../ugfx
@@ -154,8 +155,7 @@ SRC_C = \
154155
ugfx_styles.c \
155156
$(SRC_MOD)
156157

157-
### TODO remove hardcoded images when loader works ;)
158-
158+
### TODO fix hardcoded images when we can't get image loader to work
159159
#BADGE_MAIN_SRC_C = $(addprefix ../../main/,\
160160
# imgv2_menu.c \
161161
# imgv2_nick.c \
@@ -590,7 +590,7 @@ OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_WPA_SUPPLICANT_O))
590590
####################
591591
# Badge magic
592592

593-
$(BUILD)/components/%.o: CFLAGS += -Wno-strict-aliasing
593+
$(BUILD)/components/%.o:
594594
BADGE_COMPONENTS_O = $(addprefix $(BADGE)/components/,\
595595
badge/badge_base.o \
596596
badge/badge_eink.o \
@@ -613,6 +613,7 @@ BADGE_COMPONENTS_O = $(addprefix $(BADGE)/components/,\
613613
ugfx/gdisp_lld_framebuffer.o \
614614
ugfx/ginput_lld_toggle.o \
615615
ugfx/gfx_mk.o \
616+
sha2017/wildcard_sha2017_org.o \
616617
)
617618

618619
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(BADGE_COMPONENTS_O))

esp32/modules/dialogs.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
### Author: EMF Badge team
2+
### Author: SHA2017Badge team
3+
### Description: Some basic UGFX powered dialogs
4+
### License: MIT
5+
6+
import ugfx, badge, utime as time
7+
8+
def notice(text, title="SHA2017", close_text="Close", width = 296, height = 128, font="Roboto_Regular12"):
9+
prompt_boolean(text, title = title, true_text = close_text, false_text = None, width = width, height = height, font=font)
10+
11+
def prompt_boolean(text, title="SHA2017", true_text="Yes", false_text="No", width = 296, height = 128, font="Roboto_Regular12"):
12+
"""A simple one and two-options dialog
13+
14+
if 'false_text' is set to None only one button is displayed.
15+
If both 'true_text' and 'false_text' are given a boolean is returned
16+
"""
17+
window = ugfx.Container((ugfx.width() - width) // 2, (ugfx.height() - height) // 2, width, height)
18+
window.show()
19+
ugfx.set_default_font(font)
20+
window.text(5, 10, title, TILDA_COLOR)
21+
window.line(0, 30, width, 30, ugfx.BLACK)
22+
23+
if false_text:
24+
true_text = "A: " + true_text
25+
false_text = "B: " + false_text
26+
27+
label = ugfx.Label(5, 30, width - 10, height - 80, text = text, parent=window)
28+
button_yes = ugfx.Button(5, height - 40, width // 2 - 15 if false_text else width - 15, 30 , true_text, parent=window)
29+
button_no = ugfx.Button(width // 2 + 5, height - 40, width // 2 - 15, 30 , false_text, parent=window) if false_text else None
30+
31+
try:
32+
ugfx.input_init()
33+
34+
# button_yes.attach_input(ugfx.BTN_A,0)
35+
# if button_no: button_no.attach_input(ugfx.BTN_B,0)
36+
37+
window.show()
38+
39+
# while True:
40+
# pyb.wfi() # TODO make this!!
41+
# if buttons.is_triggered("BTN_A"): return True
42+
# if buttons.is_triggered("BTN_B"): return False
43+
44+
finally:
45+
window.hide()
46+
window.destroy()
47+
button_yes.destroy()
48+
if button_no: button_no.destroy()
49+
label.destroy()
50+
51+
def prompt_text(description, init_text = "", true_text="OK", false_text="Back", width = 300, height = 200, font="Roboto_BlackItalic24"):
52+
"""Shows a dialog and keyboard that allows the user to input/change a string
53+
54+
Returns None if user aborts with button B
55+
"""
56+
57+
window = ugfx.Container(int((ugfx.width()-width)/2), int((ugfx.height()-height)/2), width, height)
58+
59+
if false_text:
60+
true_text = "M: " + true_text
61+
false_text = "B: " + false_text
62+
63+
# if buttons.has_interrupt("BTN_MENU"):
64+
# buttons.disable_interrupt("BTN_MENU")
65+
66+
ugfx.set_default_font("Roboto_Regular18")
67+
kb = ugfx.Keyboard(0, int(height/2), width, int(height/2), parent=window)
68+
edit = ugfx.Textbox(5, int(height/2)-30, int(width*4/5)-10, 25, text = init_text, parent=window)
69+
ugfx.set_default_font("Roboto_Regular12")
70+
button_yes = ugfx.Button(int(width*4/5), int(height/2)-30, int(width*1/5)-3, 25 , true_text, parent=window)
71+
button_no = ugfx.Button(int(width*4/5), int(height/2)-30-30, int(width/5)-3, 25 , false_text, parent=window) if false_text else None
72+
ugfx.set_default_font(font)
73+
label = ugfx.Label(int(width/10), int(height/10), int(width*4/5), int(height*2/5)-60, description, parent=window)
74+
75+
try:
76+
ugfx.input_init()
77+
78+
# button_yes.attach_input(ugfx.BTN_MENU,0)
79+
# if button_no: button_no.attach_input(ugfx.BTN_B,0)
80+
# TODO ^^
81+
82+
window.show()
83+
edit.set_focus()
84+
# while True:
85+
# pyb.wfi()
86+
# ugfx.poll()
87+
# #if buttons.is_triggered("BTN_A"): return edit.text()
88+
# if buttons.is_triggered("BTN_B"): return None
89+
# if buttons.is_triggered("BTN_MENU"): return edit.text()
90+
91+
finally:
92+
window.hide()
93+
window.destroy()
94+
button_yes.destroy()
95+
if button_no: button_no.destroy()
96+
label.destroy()
97+
kb.destroy()
98+
edit.destroy();
99+
return
100+
101+
def prompt_option(options, index=0, text = "Please select one of the following:", title=None, select_text="OK", none_text=None):
102+
"""Shows a dialog prompting for one of multiple options
103+
104+
If none_text is specified the user can use the B or Menu button to skip the selection
105+
if title is specified a blue title will be displayed about the text
106+
"""
107+
ugfx.set_default_font("Roboto_Regular12")
108+
window = ugfx.Container(5, 5, ugfx.width() - 10, ugfx.height() - 10)
109+
window.show()
110+
111+
list_y = 30
112+
if title:
113+
window.text(5, 10, title, ugfxBLACK)
114+
window.line(0, 25, ugfx.width() - 10, 25, ugfx.BLACK)
115+
window.text(5, 30, text, ugfx.BLACK)
116+
list_y = 50
117+
else:
118+
window.text(5, 10, text, ugfx.BLACK)
119+
120+
options_list = ugfx.List(5, list_y, ugfx.width() - 25, 180 - list_y, parent = window)
121+
122+
for option in options:
123+
if isinstance(option, dict) and option["title"]:
124+
options_list.add_item(option["title"])
125+
else:
126+
options_list.add_item(str(option))
127+
options_list.selected_index(index)
128+
129+
select_text = "A: " + select_text
130+
if none_text:
131+
none_text = "B: " + none_text
132+
133+
button_select = ugfx.Button(5, ugfx.height() - 50, 140 if none_text else ugfx.width() - 25, 30 , select_text, parent=window)
134+
button_none = ugfx.Button(ugfx.width() - 160, ugfx.height() - 50, 140, 30 , none_text, parent=window) if none_text else None
135+
136+
try:
137+
ugfx.input_init()
138+
139+
# while True:
140+
# pyb.wfi() # BLABLA TODO
141+
# ugfx.poll()
142+
# if buttons.is_triggered("BTN_A"): return options[options_list.selected_index()]
143+
# if button_none and buttons.is_triggered("BTN_B"): return None
144+
# if button_none and buttons.is_triggered("BTN_MENU"): return None
145+
146+
finally:
147+
window.hide()
148+
window.destroy()
149+
options_list.destroy()
150+
button_select.destroy()
151+
if button_none: button_none.destroy()
152+
ugfx.poll()
153+
154+
class WaitingMessage:
155+
"""Shows a dialog with a certain message that can not be dismissed by the user"""
156+
def __init__(self, text = "Please Wait...", title="TiLDA"):
157+
self.window = ugfx.Container(30, 30, ugfx.width() - 60, ugfx.height() - 60)
158+
self.window.show()
159+
self.window.text(5, 10, title, TILDA_COLOR)
160+
self.window.line(0, 30, ugfx.width() - 60, 30, ugfx.BLACK)
161+
self.label = ugfx.Label(5, 40, self.window.width() - 10, ugfx.height() - 40, text = text, parent=self.window)
162+
163+
# Indicator to show something is going on
164+
self.indicator = ugfx.Label(ugfx.width() - 100, 0, 20, 20, text = "...", parent=self.window)
165+
self.timer = pyb.Timer(3)
166+
self.timer.init(freq=3)
167+
self.timer.callback(lambda t: self.indicator.visible(not self.indicator.visible()))
168+
169+
def destroy(self):
170+
self.timer.deinit()
171+
self.label.destroy()
172+
self.indicator.destroy()
173+
self.window.destroy()
174+
175+
def text(self):
176+
return self.label.text()
177+
178+
def text(self, value):
179+
self.label.text(value)
180+
181+
def __enter__(self):
182+
return self
183+
184+
def __exit__(self, exc_type, exc_value, traceback):
185+
self.destroy()

esp32/modules/woezel.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,7 @@ def expandhome(s):
104104

105105
import ussl
106106
import usocket
107-
warn_ussl = True
108107
def url_open(url):
109-
global warn_ussl
110-
111108
if debug:
112109
print(url)
113110

@@ -128,9 +125,6 @@ def url_open(url):
128125

129126
if proto == "https:":
130127
s = ussl.wrap_socket(s, server_hostname=host)
131-
if warn_ussl:
132-
print("Warning: %s SSL certificate is not validated" % host)
133-
warn_ussl = False
134128

135129
# MicroPython rawsocket module supports file interface directly
136130
s.write("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n" % (urlpath, host))

extmod/modussl_mbedtls.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2424
* THE SOFTWARE.
2525
*/
26+
#define _GNU_SOURCE
2627

2728
#include "py/mpconfig.h"
2829
#if MICROPY_PY_USSL && MICROPY_SSL_MBEDTLS
2930

3031
#include <stdio.h>
3132
#include <string.h>
3233
#include <errno.h>
34+
#include <string.h>
3335

3436
#include "py/nlr.h"
3537
#include "py/runtime.h"
@@ -45,6 +47,8 @@
4547
#include "mbedtls/ctr_drbg.h"
4648
#include "mbedtls/debug.h"
4749

50+
#include "wildcard_sha2017_org.h"
51+
4852
typedef struct _mp_obj_ssl_socket_t {
4953
mp_obj_base_t base;
5054
mp_obj_t sock;
@@ -136,7 +140,7 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
136140
mbedtls_pk_init(&o->pkey);
137141
mbedtls_ctr_drbg_init(&o->ctr_drbg);
138142
// Debug level (0-4)
139-
mbedtls_debug_set_threshold(0);
143+
mbedtls_debug_set_threshold(4);
140144

141145
mbedtls_entropy_init(&o->entropy);
142146
const byte seed[] = "upy";
@@ -146,6 +150,26 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
146150
assert(0);
147151
}
148152

153+
bool sha2017_subdomain = false;
154+
if (args->server_hostname.u_obj != mp_const_none) {
155+
const char *sni = mp_obj_str_get_str(args->server_hostname.u_obj);
156+
char *ptr;
157+
sha2017_subdomain = ((ptr = strcasestr(sni, ".sha2017.org")) != NULL && ptr[12] == 0);
158+
if (sha2017_subdomain) {
159+
printf("Validating certificate for: %s\n", sni);
160+
} else {
161+
printf("Warning: %s SSL certificate is not validated\n", sni);
162+
}
163+
}
164+
165+
if (sha2017_subdomain) {
166+
ret = mbedtls_x509_crt_parse_der(&o->cacert, wildcard_sha2017_org, 856);
167+
if(ret < 0) {
168+
printf("mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
169+
assert(0);
170+
}
171+
}
172+
149173
ret = mbedtls_ssl_config_defaults(&o->conf,
150174
MBEDTLS_SSL_IS_CLIENT,
151175
MBEDTLS_SSL_TRANSPORT_STREAM,
@@ -154,7 +178,12 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
154178
assert(0);
155179
}
156180

157-
mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE);
181+
if (sha2017_subdomain) {
182+
mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
183+
mbedtls_ssl_conf_ca_chain(&o->conf, &o->cacert, NULL);
184+
} else {
185+
mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE);
186+
}
158187
mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg);
159188
mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL);
160189

@@ -223,7 +252,7 @@ STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errc
223252
return 0;
224253
}
225254

226-
if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
255+
if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
227256
*errcode = EWOULDBLOCK;
228257
return 0;
229258
}
@@ -243,7 +272,7 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in
243272
return ret;
244273
}
245274

246-
if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
275+
if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
247276
*errcode = EWOULDBLOCK;
248277
return 0;
249278
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy