From 93c4a6a3f70e389b466fbc7a4f1ad2e1df87c93f Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 21 Sep 2016 10:52:53 +1000 Subject: all: Remove 'name' member from mp_obj_module_t struct. One can instead lookup __name__ in the modules dict to get the value. --- extmod/modbtree.c | 1 - extmod/modframebuf.c | 1 - extmod/modlwip.c | 1 - extmod/modubinascii.c | 1 - extmod/moductypes.c | 1 - extmod/moduhashlib.c | 1 - extmod/moduheapq.c | 1 - extmod/modujson.c | 1 - extmod/modurandom.c | 1 - extmod/modure.c | 1 - extmod/modussl_axtls.c | 1 - extmod/moduzlib.c | 1 - extmod/modwebrepl.c | 3 +-- extmod/modwebsocket.c | 1 - 14 files changed, 1 insertion(+), 15 deletions(-) (limited to 'extmod') diff --git a/extmod/modbtree.c b/extmod/modbtree.c index ea2ea582c..0f9ae8270 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -387,7 +387,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_btree_globals, mp_module_btree_globals_tab const mp_obj_module_t mp_module_btree = { .base = { &mp_type_module }, - .name = MP_QSTR_btree, .globals = (mp_obj_dict_t*)&mp_module_btree_globals, }; diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 3c884c689..cd7f1c5e4 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -213,7 +213,6 @@ STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_tab const mp_obj_module_t mp_module_framebuf = { .base = { &mp_type_module }, - .name = MP_QSTR_framebuf, .globals = (mp_obj_dict_t*)&framebuf_module_globals, }; diff --git a/extmod/modlwip.c b/extmod/modlwip.c index 80df66264..ec37919e6 100644 --- a/extmod/modlwip.c +++ b/extmod/modlwip.c @@ -1309,7 +1309,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table const mp_obj_module_t mp_module_lwip = { .base = { &mp_type_module }, - .name = MP_QSTR_lwip, .globals = (mp_obj_dict_t*)&mp_module_lwip_globals, }; diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index 562c754b5..2b59b1a1f 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -232,7 +232,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globa const mp_obj_module_t mp_module_ubinascii = { .base = { &mp_type_module }, - .name = MP_QSTR_ubinascii, .globals = (mp_obj_dict_t*)&mp_module_binascii_globals, }; diff --git a/extmod/moductypes.c b/extmod/moductypes.c index a3071af98..9995f637b 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -710,7 +710,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uctypes_globals, mp_module_uctypes_globals const mp_obj_module_t mp_module_uctypes = { .base = { &mp_type_module }, - .name = MP_QSTR_uctypes, .globals = (mp_obj_dict_t*)&mp_module_uctypes_globals, }; diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 6cd690a67..13525cc3f 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -151,7 +151,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_hashlib_globals, mp_module_hashlib_globals const mp_obj_module_t mp_module_uhashlib = { .base = { &mp_type_module }, - .name = MP_QSTR_uhashlib, .globals = (mp_obj_dict_t*)&mp_module_hashlib_globals, }; diff --git a/extmod/moduheapq.c b/extmod/moduheapq.c index 84ffe54f9..567ee83da 100644 --- a/extmod/moduheapq.c +++ b/extmod/moduheapq.c @@ -116,7 +116,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uheapq_globals, mp_module_uheapq_globals_t const mp_obj_module_t mp_module_uheapq = { .base = { &mp_type_module }, - .name = MP_QSTR_uheapq, .globals = (mp_obj_dict_t*)&mp_module_uheapq_globals, }; diff --git a/extmod/modujson.c b/extmod/modujson.c index 4e080c975..0d0781e06 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -260,7 +260,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_ujson_globals, mp_module_ujson_globals_tab const mp_obj_module_t mp_module_ujson = { .base = { &mp_type_module }, - .name = MP_QSTR_ujson, .globals = (mp_obj_dict_t*)&mp_module_ujson_globals, }; diff --git a/extmod/modurandom.c b/extmod/modurandom.c index 27d717720..995b0a266 100644 --- a/extmod/modurandom.c +++ b/extmod/modurandom.c @@ -215,7 +215,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_urandom_globals, mp_module_urandom_globals const mp_obj_module_t mp_module_urandom = { .base = { &mp_type_module }, - .name = MP_QSTR_urandom, .globals = (mp_obj_dict_t*)&mp_module_urandom_globals, }; diff --git a/extmod/modure.c b/extmod/modure.c index 9821e235a..b8c242429 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -237,7 +237,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_re_globals, mp_module_re_globals_table); const mp_obj_module_t mp_module_ure = { .base = { &mp_type_module }, - .name = MP_QSTR_ure, .globals = (mp_obj_dict_t*)&mp_module_re_globals, }; diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c index ce86263c2..775474e6a 100644 --- a/extmod/modussl_axtls.c +++ b/extmod/modussl_axtls.c @@ -196,7 +196,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table); const mp_obj_module_t mp_module_ussl = { .base = { &mp_type_module }, - .name = MP_QSTR_ussl, .globals = (mp_obj_dict_t*)&mp_module_ssl_globals, }; diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 65cbc5eb0..68a087bc1 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -204,7 +204,6 @@ STATIC MP_DEFINE_CONST_DICT(mp_module_uzlib_globals, mp_module_uzlib_globals_tab const mp_obj_module_t mp_module_uzlib = { .base = { &mp_type_module }, - .name = MP_QSTR_uzlib, .globals = (mp_obj_dict_t*)&mp_module_uzlib_globals, }; diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c index 858d2c1c0..8e0580966 100644 --- a/extmod/modwebrepl.c +++ b/extmod/modwebrepl.c @@ -340,7 +340,7 @@ STATIC const mp_obj_type_t webrepl_type = { }; STATIC const mp_map_elem_t webrepl_module_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_websocket) }, + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR__webrepl) }, { MP_OBJ_NEW_QSTR(MP_QSTR__webrepl), (mp_obj_t)&webrepl_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_password), (mp_obj_t)&webrepl_set_password_obj }, }; @@ -349,7 +349,6 @@ STATIC MP_DEFINE_CONST_DICT(webrepl_module_globals, webrepl_module_globals_table const mp_obj_module_t mp_module_webrepl = { .base = { &mp_type_module }, - .name = MP_QSTR__webrepl, .globals = (mp_obj_dict_t*)&webrepl_module_globals, }; diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c index f46dac177..8200ea708 100644 --- a/extmod/modwebsocket.c +++ b/extmod/modwebsocket.c @@ -313,7 +313,6 @@ STATIC MP_DEFINE_CONST_DICT(websocket_module_globals, websocket_module_globals_t const mp_obj_module_t mp_module_websocket = { .base = { &mp_type_module }, - .name = MP_QSTR_websocket, .globals = (mp_obj_dict_t*)&websocket_module_globals, }; -- cgit v1.2.3 From 9ea2882317259a0c802db5936e51d49464914292 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 21 Sep 2016 21:25:33 +0300 Subject: extmod/modussl_mbedtls: Initial implementation of mbedTLS ussl module. --- extmod/modussl_mbedtls.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 extmod/modussl_mbedtls.c (limited to 'extmod') diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c new file mode 100644 index 000000000..e380b1b02 --- /dev/null +++ b/extmod/modussl_mbedtls.c @@ -0,0 +1,259 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Linaro Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mpconfig.h" +#if MICROPY_PY_USSL && MICROPY_SSL_MBEDTLS + +#include +#include +#include + +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/stream.h" + +// mbedtls_time_t +#include "mbedtls/include/mbedtls/platform.h" +#include "mbedtls/include/mbedtls/net.h" +#include "mbedtls/include/mbedtls/ssl.h" +#include "mbedtls/include/mbedtls/entropy.h" +#include "mbedtls/include/mbedtls/ctr_drbg.h" +#include "mbedtls/include/mbedtls/debug.h" + +typedef struct _mp_obj_ssl_socket_t { + mp_obj_base_t base; + mp_obj_t sock; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + mbedtls_x509_crt cacert; +} mp_obj_ssl_socket_t; + +STATIC const mp_obj_type_t ussl_socket_type; + +static void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) { + printf("DBG:%s:%04d: %s\n", file, line, str); +} + +// TODO: FIXME! +int null_entropy_func(void *data, unsigned char *output, size_t len) { + // enjoy random bytes + return 0; +} + +int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { + mp_obj_t sock = *(mp_obj_t*)ctx; + + const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_WRITE); + int err; + + int out_sz = sock_stream->write(sock, buf, len, &err); + if (out_sz == MP_STREAM_ERROR) { + return -err; + } else { + return out_sz; + } +} + +int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { + mp_obj_t sock = *(mp_obj_t*)ctx; + + const mp_stream_p_t *sock_stream = mp_get_stream_raise(sock, MP_STREAM_OP_READ); + int err; + + int out_sz = sock_stream->read(sock, buf, len, &err); + if (out_sz == MP_STREAM_ERROR) { + return -err; + } else { + return out_sz; + } +} + + +STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) { + mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); + o->base.type = &ussl_socket_type; + + int ret; + mbedtls_ssl_init(&o->ssl); + mbedtls_ssl_config_init(&o->conf); + mbedtls_x509_crt_init(&o->cacert); + mbedtls_ctr_drbg_init(&o->ctr_drbg); + // Debug level (0-4) + mbedtls_debug_set_threshold(0); + + mbedtls_entropy_init(&o->entropy); + const byte seed[] = "upy"; + ret = mbedtls_ctr_drbg_seed(&o->ctr_drbg, null_entropy_func/*mbedtls_entropy_func*/, &o->entropy, seed, sizeof(seed)); + if (ret != 0) { + printf("ret=%d\n", ret); + assert(0); + } + + ret = mbedtls_ssl_config_defaults(&o->conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) { + assert(0); + } + + mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE); + mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg); + mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL); + + ret = mbedtls_ssl_setup(&o->ssl, &o->conf); + if (ret != 0) { + assert(0); + } + + // delme + ret = mbedtls_ssl_set_hostname(&o->ssl, "mbed TLS Server 1"); + if (ret != 0) { + assert(0); + } + + o->sock = sock; + mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); + + if (server_side) { + assert(0); + } else { + while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + //assert(0); + printf("mbedtls_ssl_handshake error: -%x\n", -ret); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EIO))); + } + } + } + + return o; +} + +STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + (void)kind; + mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "<_SSLSocket %p>", self); +} + +STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { + mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); + + int ret = mbedtls_ssl_read(&o->ssl, buf, size); + if (ret >= 0) { + return ret; + } + *errcode = ret; + return MP_STREAM_ERROR; +} + +STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) { + mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); + + int ret = mbedtls_ssl_write(&o->ssl, buf, size); + if (ret >= 0) { + return ret; + } + *errcode = ret; + return MP_STREAM_ERROR; +} + +STATIC mp_obj_t socket_close(mp_obj_t self_in) { + mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); + + mbedtls_x509_crt_free(&self->cacert); + mbedtls_ssl_free(&self->ssl); + mbedtls_ssl_config_free(&self->conf); + mbedtls_ctr_drbg_free(&self->ctr_drbg); + mbedtls_entropy_free(&self->entropy); + + mp_obj_t dest[2]; + mp_load_method(self->sock, MP_QSTR_close, dest); + return mp_call_method_n_kw(0, 0, dest); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close); + +STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readall), MP_ROM_PTR(&mp_stream_readall_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table); + +STATIC const mp_stream_p_t ussl_socket_stream_p = { + .read = socket_read, + .write = socket_write, +}; + +STATIC const mp_obj_type_t ussl_socket_type = { + { &mp_type_type }, + // Save on qstr's, reuse same as for module + .name = MP_QSTR_ussl, + .print = socket_print, + .getiter = NULL, + .iternext = NULL, + .protocol = &ussl_socket_stream_p, + .locals_dict = (void*)&ussl_socket_locals_dict, +}; + +STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // TODO: Implement more args + static const mp_arg_t allowed_args[] = { + { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + // TODO: Check that sock implements stream protocol + mp_obj_t sock = pos_args[0]; + + struct { + mp_arg_val_t server_side; + } args; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, + MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); + + return MP_OBJ_FROM_PTR(socket_new(sock, args.server_side.u_bool)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket); + +STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) }, + { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table); + +const mp_obj_module_t mp_module_ussl = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_ssl_globals, +}; + +#endif // MICROPY_PY_USSL -- cgit v1.2.3 From b84e1231c969debe387fad3b5ee924cb56824e0b Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 20 Sep 2016 23:50:06 -0700 Subject: extmod/uctypes: Allow full 32-bit address range. Use mp_obj_int_get_truncated to allow the full 32-bit address range as first parameter. --- extmod/moductypes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'extmod') diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 9995f637b..6249a4940 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -125,7 +125,7 @@ STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args mp_arg_check_num(n_args, n_kw, 2, 3, false); mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); o->base.type = type; - o->addr = (void*)(uintptr_t)mp_obj_get_int(args[0]); + o->addr = (void*)(uintptr_t)mp_obj_int_get_truncated(args[0]); o->desc = args[1]; o->flags = LAYOUT_NATIVE; if (n_args == 3) { -- cgit v1.2.3 From 7f5a541b84da9944bde7eb0c5d07595d53bb25ca Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Wed, 21 Sep 2016 17:19:48 +0200 Subject: extmod/modubinascii: Fix crc32() function on 32-bit platforms. --- extmod/modubinascii.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'extmod') diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index 2b59b1a1f..2ef1a6f21 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -208,9 +208,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64); mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); - uint32_t crc = (n_args > 1) ? mp_obj_get_int(args[1]) : 0; + uint32_t crc = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 0; crc = uzlib_crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff); - return MP_OBJ_NEW_SMALL_INT(crc ^ 0xffffffff); + return mp_obj_new_int_from_uint(crc ^ 0xffffffff); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_binascii_crc32); #endif -- cgit v1.2.3 From 5f0ecb72c27e5e1eebc9fa6928b7333ec1e45658 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 22 Sep 2016 00:17:44 +0300 Subject: extmod/modussl_mbedtls: Implement key= and cert= args to wrap_socket(). Unlike standard keyfile= and certfile=, these accept byte buffer objects (to not depend on FS implementation). --- extmod/modussl_mbedtls.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) (limited to 'extmod') diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index e380b1b02..20ae1c197 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -39,6 +39,8 @@ #include "mbedtls/include/mbedtls/platform.h" #include "mbedtls/include/mbedtls/net.h" #include "mbedtls/include/mbedtls/ssl.h" +#include "mbedtls/include/mbedtls/x509_crt.h" +#include "mbedtls/include/mbedtls/pk.h" #include "mbedtls/include/mbedtls/entropy.h" #include "mbedtls/include/mbedtls/ctr_drbg.h" #include "mbedtls/include/mbedtls/debug.h" @@ -51,8 +53,16 @@ typedef struct _mp_obj_ssl_socket_t { mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt cacert; + mbedtls_x509_crt cert; + mbedtls_pk_context pkey; } mp_obj_ssl_socket_t; +struct ssl_args { + mp_arg_val_t key; + mp_arg_val_t cert; + mp_arg_val_t server_side; +}; + STATIC const mp_obj_type_t ussl_socket_type; static void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) { @@ -94,7 +104,7 @@ int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { } -STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) { +STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); o->base.type = &ussl_socket_type; @@ -102,6 +112,8 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) { mbedtls_ssl_init(&o->ssl); mbedtls_ssl_config_init(&o->conf); mbedtls_x509_crt_init(&o->cacert); + mbedtls_x509_crt_init(&o->cert); + mbedtls_pk_init(&o->pkey); mbedtls_ctr_drbg_init(&o->ctr_drbg); // Debug level (0-4) mbedtls_debug_set_threshold(0); @@ -140,7 +152,24 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) { o->sock = sock; mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); - if (server_side) { + if (args->key.u_obj != MP_OBJ_NULL) { + mp_uint_t key_len; + const byte *key = (const byte*)mp_obj_str_get_data(args->key.u_obj, &key_len); + // len should include terminating null + ret = mbedtls_pk_parse_key(&o->pkey, key, key_len + 1, NULL, 0); + assert(ret == 0); + + mp_uint_t cert_len; + const byte *cert = (const byte*)mp_obj_str_get_data(args->cert.u_obj, &cert_len); + // len should include terminating null + ret = mbedtls_x509_crt_parse(&o->cert, cert, cert_len + 1); + assert(ret == 0); + + ret = mbedtls_ssl_conf_own_cert(&o->conf, &o->cert, &o->pkey); + assert(ret == 0); + } + + if (args->server_side.u_bool) { assert(0); } else { while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) { @@ -228,19 +257,19 @@ STATIC const mp_obj_type_t ussl_socket_type = { STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // TODO: Implement more args static const mp_arg_t allowed_args[] = { + { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; // TODO: Check that sock implements stream protocol mp_obj_t sock = pos_args[0]; - struct { - mp_arg_val_t server_side; - } args; + struct ssl_args args; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); - return MP_OBJ_FROM_PTR(socket_new(sock, args.server_side.u_bool)); + return MP_OBJ_FROM_PTR(socket_new(sock, &args)); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket); -- cgit v1.2.3 From 080e4d44f3396f63b33953f6c607b2f70a10ad01 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 22 Sep 2016 01:30:48 +0300 Subject: extmod/modussl_mbedtls: Use 2-component include paths. This is required to use mbedTLS versions from various sources, e.g. mainline vs embedded into Zephyr RTOS. --- extmod/modussl_mbedtls.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'extmod') diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index 20ae1c197..3e0a5c281 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -36,14 +36,14 @@ #include "py/stream.h" // mbedtls_time_t -#include "mbedtls/include/mbedtls/platform.h" -#include "mbedtls/include/mbedtls/net.h" -#include "mbedtls/include/mbedtls/ssl.h" -#include "mbedtls/include/mbedtls/x509_crt.h" -#include "mbedtls/include/mbedtls/pk.h" -#include "mbedtls/include/mbedtls/entropy.h" -#include "mbedtls/include/mbedtls/ctr_drbg.h" -#include "mbedtls/include/mbedtls/debug.h" +#include "mbedtls/platform.h" +#include "mbedtls/net.h" +#include "mbedtls/ssl.h" +#include "mbedtls/x509_crt.h" +#include "mbedtls/pk.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/debug.h" typedef struct _mp_obj_ssl_socket_t { mp_obj_base_t base; -- cgit v1.2.3 From ec078af985a9a1d47023861794358f52c51de434 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Thu, 15 Sep 2016 01:08:03 +0200 Subject: extmod/machine_i2c: Add clock stretching support. When the clock is too fast for the i2c slave, it can temporarily hold down the scl line to signal to the master that it needs to wait. The master should check the scl line when it is releasing it after transmitting data, and wait for it to be released. This change has been tested with a logic analyzer and an i2c slace implemented on an atmega328p using its twi peripheral, clocked at 8Mhz. Without the change, the i2c communication works up to aboy 150kHz frequency, and above that results in the slave stuck in an unresponsive state. With this change, communication has been tested to work up to 400kHz. --- extmod/machine_i2c.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'extmod') diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index ceddf0730..f7d238024 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -34,6 +34,9 @@ #if MICROPY_PY_MACHINE_I2C +// Clock stretching limit, so that we don't get stuck. +#define I2C_STRETCH_LIMIT 255 + typedef struct _machine_i2c_obj_t { mp_obj_base_t base; uint32_t us_delay; @@ -53,6 +56,11 @@ STATIC void mp_hal_i2c_scl_low(machine_i2c_obj_t *self) { STATIC void mp_hal_i2c_scl_release(machine_i2c_obj_t *self) { mp_hal_pin_od_high(self->scl); + mp_hal_i2c_delay(self); + // For clock stretching, wait for the SCL pin to be released, with timeout. + for (int count = I2C_STRETCH_LIMIT; mp_hal_pin_read(self->scl) == 0 && count; --count) { + mp_hal_delay_us_fast(1); + } } STATIC void mp_hal_i2c_sda_low(machine_i2c_obj_t *self) { @@ -71,7 +79,6 @@ STATIC void mp_hal_i2c_start(machine_i2c_obj_t *self) { mp_hal_i2c_sda_release(self); mp_hal_i2c_delay(self); mp_hal_i2c_scl_release(self); - mp_hal_i2c_delay(self); mp_hal_i2c_sda_low(self); mp_hal_i2c_delay(self); } @@ -81,7 +88,6 @@ STATIC void mp_hal_i2c_stop(machine_i2c_obj_t *self) { mp_hal_i2c_sda_low(self); mp_hal_i2c_delay(self); mp_hal_i2c_scl_release(self); - mp_hal_i2c_delay(self); mp_hal_i2c_sda_release(self); mp_hal_i2c_delay(self); } @@ -108,14 +114,12 @@ STATIC int mp_hal_i2c_write_byte(machine_i2c_obj_t *self, uint8_t val) { } mp_hal_i2c_delay(self); mp_hal_i2c_scl_release(self); - mp_hal_i2c_delay(self); mp_hal_i2c_scl_low(self); } mp_hal_i2c_sda_release(self); mp_hal_i2c_delay(self); mp_hal_i2c_scl_release(self); - mp_hal_i2c_delay(self); int ret = mp_hal_i2c_sda_read(self); mp_hal_i2c_delay(self); @@ -150,7 +154,6 @@ STATIC int mp_hal_i2c_read_byte(machine_i2c_obj_t *self, uint8_t *val, int nack) uint8_t data = 0; for (int i = 7; i >= 0; i--) { mp_hal_i2c_scl_release(self); - mp_hal_i2c_delay(self); data = (data << 1) | mp_hal_i2c_sda_read(self); mp_hal_i2c_scl_low(self); mp_hal_i2c_delay(self); @@ -163,7 +166,6 @@ STATIC int mp_hal_i2c_read_byte(machine_i2c_obj_t *self, uint8_t *val, int nack) } mp_hal_i2c_delay(self); mp_hal_i2c_scl_release(self); - mp_hal_i2c_delay(self); mp_hal_i2c_scl_low(self); mp_hal_i2c_sda_release(self); -- cgit v1.2.3 From 46ab042230510d71b05df04ab73131a5fd4f3d2d Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 23 Sep 2016 01:44:23 +0300 Subject: extmod/modussl_mbedtls: Add server_hostname param for wrap_socket(). In CPython, module-level .wrap_socket() function actually doesn't accept (or document) this param, only SSLContext.wrap_socket() has. --- extmod/modussl_mbedtls.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'extmod') diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index 3e0a5c281..29ea7d357 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -61,6 +61,7 @@ struct ssl_args { mp_arg_val_t key; mp_arg_val_t cert; mp_arg_val_t server_side; + mp_arg_val_t server_hostname; }; STATIC const mp_obj_type_t ussl_socket_type; @@ -143,10 +144,12 @@ STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { assert(0); } - // delme - ret = mbedtls_ssl_set_hostname(&o->ssl, "mbed TLS Server 1"); - if (ret != 0) { - assert(0); + if (args->server_hostname.u_obj != mp_const_none) { + const char *sni = mp_obj_str_get_str(args->server_hostname.u_obj); + ret = mbedtls_ssl_set_hostname(&o->ssl, sni); + if (ret != 0) { + assert(0); + } } o->sock = sock; @@ -260,6 +263,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_ { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; // TODO: Check that sock implements stream protocol -- cgit v1.2.3 From d8a4d9d67c16c5c827ed5c70c4d9d8042f9273cb Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 24 Sep 2016 15:28:51 +0300 Subject: extmod/uzlib: Add tinfgzip.c (gzip header parsing) from upstream. --- extmod/uzlib/tinfgzip.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 extmod/uzlib/tinfgzip.c (limited to 'extmod') diff --git a/extmod/uzlib/tinfgzip.c b/extmod/uzlib/tinfgzip.c new file mode 100644 index 000000000..3eb1803c9 --- /dev/null +++ b/extmod/uzlib/tinfgzip.c @@ -0,0 +1,107 @@ +/* + * tinfgzip - tiny gzip decompressor + * + * Copyright (c) 2003 by Joergen Ibsen / Jibz + * All Rights Reserved + * + * http://www.ibsensoftware.com/ + * + * Copyright (c) 2014-2016 by Paul Sokolovsky + * + * This software is provided 'as-is', without any express + * or implied warranty. In no event will the authors be + * held liable for any damages arising from the use of + * this software. + * + * Permission is granted to anyone to use this software + * for any purpose, including commercial applications, + * and to alter it and redistribute it freely, subject to + * the following restrictions: + * + * 1. The origin of this software must not be + * misrepresented; you must not claim that you + * wrote the original software. If you use this + * software in a product, an acknowledgment in + * the product documentation would be appreciated + * but is not required. + * + * 2. Altered source versions must be plainly marked + * as such, and must not be misrepresented as + * being the original software. + * + * 3. This notice may not be removed or altered from + * any source distribution. + */ + +#include "tinf.h" + +#define FTEXT 1 +#define FHCRC 2 +#define FEXTRA 4 +#define FNAME 8 +#define FCOMMENT 16 + +void tinf_skip_bytes(TINF_DATA *d, int num) +{ + while (num--) uzlib_get_byte(d); +} + +uint16_t tinf_get_uint16(TINF_DATA *d) +{ + unsigned int v = uzlib_get_byte(d); + v = (uzlib_get_byte(d) << 8) | v; + return v; +} + +int uzlib_gzip_parse_header(TINF_DATA *d) +{ + unsigned char flg; + + /* -- check format -- */ + + /* check id bytes */ + if (uzlib_get_byte(d) != 0x1f || uzlib_get_byte(d) != 0x8b) return TINF_DATA_ERROR; + + /* check method is deflate */ + if (uzlib_get_byte(d) != 8) return TINF_DATA_ERROR; + + /* get flag byte */ + flg = uzlib_get_byte(d); + + /* check that reserved bits are zero */ + if (flg & 0xe0) return TINF_DATA_ERROR; + + /* -- find start of compressed data -- */ + + /* skip rest of base header of 10 bytes */ + tinf_skip_bytes(d, 6); + + /* skip extra data if present */ + if (flg & FEXTRA) + { + unsigned int xlen = tinf_get_uint16(d); + tinf_skip_bytes(d, xlen); + } + + /* skip file name if present */ + if (flg & FNAME) { while (uzlib_get_byte(d)); } + + /* skip file comment if present */ + if (flg & FCOMMENT) { while (uzlib_get_byte(d)); } + + /* check header crc if present */ + if (flg & FHCRC) + { + /*unsigned int hcrc =*/ tinf_get_uint16(d); + + // TODO: Check! +// if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff)) +// return TINF_DATA_ERROR; + } + + /* initialize for crc32 checksum */ + d->checksum_type = TINF_CHKSUM_CRC; + d->checksum = ~0; + + return TINF_OK; +} -- cgit v1.2.3 From 7b901d6fb7e136c23cf6b728179bd86f9c9bd95e Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 24 Sep 2016 15:30:11 +0300 Subject: extmod/moduzlib: DecompIO: Add support for gzip-formatted streams. This uses extension introduced in CPython 3.5: if wbits (dictionary size code) has value 16 + 8..15, it means that gzip-formatted stream expected. --- extmod/moduzlib.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'extmod') diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 68a087bc1..b0e0b005e 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -81,10 +81,18 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size if (n_args > 1) { dict_opt = mp_obj_get_int(args[1]); } - if (dict_opt >= 0) { + + if (dict_opt >= 16) { + int st = uzlib_gzip_parse_header(&o->decomp); + if (st != TINF_OK) { + goto header_error; + } + dict_sz = 1 << (dict_opt - 16); + } else if (dict_opt >= 0) { dict_opt = uzlib_zlib_parse_header(&o->decomp); if (dict_opt < 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "zlib header")); +header_error: + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "compression header")); } dict_sz = 1 << dict_opt; } else { @@ -212,6 +220,7 @@ const mp_obj_module_t mp_module_uzlib = { #include "uzlib/tinflate.c" #include "uzlib/tinfzlib.c" +#include "uzlib/tinfgzip.c" #include "uzlib/adler32.c" #include "uzlib/crc32.c" -- cgit v1.2.3 From 67d52d8cb9f7894a8d50251a67ece3c7a6178270 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 24 Sep 2016 16:07:18 +0300 Subject: extmod/uzlib/: Update uzlib to v2.0.3. Fixes for more pedantic warnings. --- extmod/uzlib/tinfgzip.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'extmod') diff --git a/extmod/uzlib/tinfgzip.c b/extmod/uzlib/tinfgzip.c index 3eb1803c9..f1afdd0b8 100644 --- a/extmod/uzlib/tinfgzip.c +++ b/extmod/uzlib/tinfgzip.c @@ -41,6 +41,9 @@ #define FNAME 8 #define FCOMMENT 16 +void tinf_skip_bytes(TINF_DATA *d, int num); +uint16_t tinf_get_uint16(TINF_DATA *d); + void tinf_skip_bytes(TINF_DATA *d, int num) { while (num--) uzlib_get_byte(d); -- cgit v1.2.3