Skip to content

Instantly share code, notes, and snippets.

@master-q
Created January 26, 2018 23:10
Show Gist options
  • Save master-q/ddc97f0ff2ff278b30187f4092d95289 to your computer and use it in GitHub Desktop.
Save master-q/ddc97f0ff2ff278b30187f4092d95289 to your computer and use it in GitHub Desktop.
WICED StudioにwolfSSLを移植する
= WICED StudioにwolfSSLを移植する
[2017-12-08 15:09]
<<<WICED
<<<Cypress
<<<wolfSSL
https://github.com/wolfSSL/wolfssl/issues/1266 で議論を継続。
== Plan
```
1) Please create a list of areas in the WICED SDK that currently use mbedtls
(ex: TLS server, wpa_supplicant, etc), along with your time estimate for porting into each area.
We can then use that list to prioritize the areas we should work on first.
2) Please update your existing time estimates based on new research
```
計画は以下:
1. [ ] Just port wolfSSL side of mbed TLS on WICED SDK and FreeRTOS, which needs 1 week.
3. [ ] Get runnable wolfcrypt/test/test.c on WICED SDK, which needs 1 week.
2. [ ] Incrementally replace `WICED/*` library's API calling with wolfSSL, which needs 2 weeks.
4. [ ] Incrementally replace remaining API calling with wolfSSL, which needs 1 week.
5. [ ] Introduce a make target to switch wolfSSL and mbed TLS, which needs 3 days.
6. [ ] Find the method to test replaced API calling, which needs 1 week.
と計画を立ててみたが、当面以下の計画で進める:
v #01 - Get wolfSSL compiling in the WICED Studio environment,
using our existing FreeRTOS and LwIP port layers if possible, which needs 1 week.
v #02 - Get the wolfCrypt test application (wolfcrypt/test/test.c) compiled in WICED Studio,
which needs a half week.
v #03 - Run the wolfCrypt test application (wolfcrypt/test/test.c) in WICED Studio,
which needs a half week.
v #04 - Find method to test replaced API calling, which needs a half week.
v #05 - Create HTTPS client application on WICED with mbed TLS, which needs 1 week.
v #06 - Introduce a make target to switch wolfSSL and mbed TLS, which needs a half week.
#07 - Port "apps/snip/https_client" to wolfSSL, which needs 2 week.
#08 - Port "apps/snip/https_server" to wolfSSL, which needs 2 week.
#09 - Port "apps/snip/crypto" and "apps/snip/rsa_pkcs1" to wolfSSL, which needs 1 week.
#10 - Write "mbed TLS to wolfSSL API conversion guide" document, which needs 1 week.
#11 - Write "How to use wolfSSL on WICED" document, which needs 1 week.
== インストール
http://www.cypress.com/products/wiced-software から
WICED-Studio-6.0.1.5-IDE-Installer.zipを解凍し、
WICED-Studio-6.0.1.5-IDE-Installer.binを一般ユーザで起動して、
インストーラの支持に従ってインストール。
```
Congratulations!
WICED-Studio has been successfully installed to:
1.IDE:
/home/kiwamu/WICED-Studio-6.0
2.SDK:
/home/kiwamu/Documents/WICED-Studio-6.0
3. Shortcuts created in:
(a) Desktop
(b) /home/kiwamu/Cypress
Press "Done" to quit the installer.
```
とメッセージが表示される。さっそくWICED Studioを起動する:
```
$ /home/kiwamu/WICED-Studio-6.0/eclipse
```
https://community.cypress.com/community/wiced-wifi/wiced-wifi-forums/blog/2017/06/26/example-code-associated-with-cyw943907aeval1f-evk-user-guide
からCY943907AEVAL1F_KitPackage.zipを解凍すると以下のようなツリーが手に入る:
```
$ tree CY943907AEVAL1F_KitPackage
CY943907AEVAL1F_KitPackage
├── apps
│   └── kits
│   └── CYW943907AEVAL1F
│   ├── adc_measure
│   │   ├── adc_measure.c
│   │   ├── adc_measure.h
│   │   ├── adc_measure.mk
│   │   ├── i2c.c
│   │   └── wifi_config_dct.h
│   ├── config_join_ping
│   │   ├── config_join_ping.c
│   │   └── config_join_ping.mk
│   └── publish_subscribe_aws
│   ├── publish_subscribe_aws.mk
│   ├── publish_subscribe.c
│   └── wifi_config_dct.h
└── resources
└── apps
└── adc_measure
├── data.html
└── main.html
```
このツリーを/home/kiwamu/Documents/WICED-Studio-6.0にコピーする:
```
$ cp -r CY943907AEVAL1F_KitPackage/apps/kits /home/kiwamu/Documents/WICED-Studio-6.0/43xxx_Wi-Fi/apps/
$ cp -r CY943907AEVAL1F_KitPackage/resources/apps/adc_measure /home/kiwamu/Documents/WICED-Studio-6.0/43xxx_Wi-Fi/resources/apps/
```
WICED Studioから43xxx_Wi-Fiフォルダを右クリックして、Refreshをクリック。
当該フォルダに"?"がついてるけどいいの?
== ざっくりドキュメントを読む
以下を読むべき:
file:///home/kiwamu/Documents/WICED-Studio-6.0/43xxx_Wi-Fi/doc/WICED-QSG.pdf
== ターゲットボード
ドキュメントによると、以下がサポートボードのように見える。
http://www.cypress.com/documentation/development-kitsboards/cyw943907aeval1f-evaluation-kit
それとも下記から選べばいい?膨大な数あるけど、地雷がないボードはどれだろうか。。。
https://community.cypress.com/community/wiced-wifi/wiced-wifi-partners
発注してもらえた:
https://www.mouser.jp/OrderHistory/OrderDetail.aspx?qs=9C%2fvjDbyW3WpkvWLWtYW5hJx0Cl%2fluJ2kobClpU7S8g=
動作確認のためにボードとPCをUSBケーブルで繋げて、シリアルを読む:
```
$ picocom -b 115200 /dev/ttyUSB1
Waiting for scan results...
# Type BSSID RSSI Rate Chan Security SSID CCode Flag
------------------------------------------------------------------------------------------------------------------
0 Infra A4:12:42:27:45:CF -82 300.0 36 WPA2 AES PSK aterm-bc5c34-a JP PROBE
1 Infra A6:12:42:27:45:CF -82 54.0 36 WEP aterm-bc5c34-aw JP PROBE
2 Infra BC:5C:4C:11:EC:61 -85 450.0 36 WPA2 AES PSK ELECOM-A_5G US BEACON
3 Infra C2:D9:62:80:4A:30 -90 144.4 44 WPA2 AES PSK DIRECT-SPff-UN-JS120 JP BEACON
4 Infra 16:6F:3F:39:0E:2C OFF 130.0 1 WPA2 Mixed PSK 106F3F390E2C BEACON
5 Infra A6:12:42:27:45:CE -76 54.0 1 WEP aterm-bc5c34-gw JP BEACON
6 Infra A6:12:42:98:13:9E -51 300.0 2 WPA2 AES PSK aterm-bbfadc-g PROBE
7 Infra 4C:E6:76:70:5F:D0 -76 300.0 2 WPA2 Mixed PSK 4CE676705FD0 PROBE
8 Infra 52:E6:76:70:5F:D0 -77 300.0 2 WPA AES PSK 4CE676705FD0-1 PROBE
9 Infra 34:3D:C4:BD:A3:40 OFF 144.4 3 WPA2 Mixed PSK Buffalo-G-A340 JP PROBE
10 Infra 90:48:9A:6E:C4:1A -83 130.0 3 WPA2 AES PSK 90489A83E4E6 JP PROBE
11 Infra E4:D5:3D:4D:22:19 -83 130.0 4 WPA2 AES PSK E4D53D51CFB9 JP PROBE
12 Infra 00:90:FE:EE:92:C2 -81 300.0 5 WPA2 AES PSK elecom2g-EE92C0 JP BEACON
13 Infra 9A:F1:99:39:1B:FE OFF 54.0 5 WEP JP BEACON
14 Infra 00:1F:67:3D:29:A1 OFF 130.0 8 Open Wi2premium JP PROBE
15 Infra FC:3F:7C:C0:65:7B OFF 300.0 11 WPA2 AES PSK 504HWa-C0657B PROBE
16 Infra BC:5C:4C:11:EC:64 -68 450.0 11 WPA2 AES PSK ELECOM-A_2G BEACON
17 Infra 00:25:36:77:E5:BD -86 450.0 100 WPA2 AES PSK rs500k-77e5dd-3 JP BEACON
18 Infra 00:1F:67:3D:29:A9 -61 65.0 140 Open Wi2premium JP BEACON
Scan complete in 2652 milliseconds
```
apps/snip/scanがデフォルトで焼き込まれているようだ。
== ビルド
Make Targetウィンドウの43xxx_Wi-Fiを右クリックしてからNewをクリック。
Target nameフィールドに"snip.scan-CYW943907AEVAL1F download run"と入力してOKボタンをクリック。
Make Targetウィンドウのcleanをダブルクリック。
Make Targetウィンドウsnip.scan-CYW943907AEVAL1F download runをダブルクリック。
```
--snip--
Making snip.scan-CYW943907AEVAL1F.bin
snip.scan-CYW943907AEVAL1F
----------------------------------|---------|---------|
| | Static |
Module | Flash | RAM |
----------------------------------+---------+---------|
App | 0 | 470 |
crc | 0 | 1060 |
Interrupt Vectors | 0 | 288 |
libc | 0 | 28744 |
Networking | 0 | 14746 |
NetX-Duo - Interfaces & Stacks | 0 | 16 |
NVRam | 0 | 2210 |
Other | 0 | 52315 |
Packet Buffers | 0 | 74412 |
platform | 0 | 620 |
RAM Initialisation | 32 | 0 |
resources | 0 | 32 |
Ring_Buffer | 0 | 140 |
Startup Stack & Link Script fill | 0 | 131 |
ThreadX | 0 | 12272 |
TLV | 0 | 28 |
WICED | 0 | 5193 |
Wiced_RO_FS | 0 | 570 |
WWD | 0 | 1417 |
----------------------------------+---------+---------|
TOTAL (bytes) | 0 | 194664 |
----------------------------------|---------|---------|
Creating Filesystem BCM94390x_targets.mk ...
Downloading DCT ... build/snip.scan-CYW943907AEVAL1F/DCT.bin @ SFLASH_DCT_LOC=0x00008000
./tools/common/Linux64/mk_wicedfs32 build/snip.scan-CYW943907AEVAL1F/filesystem.bin build/snip.scan-CYW943907AEVAL1F/resources/Staging/
Creating Filesystem Done
Building apps lookup table
make[1]: *** [download_dct] Error 1
make: *** [main_app] Error 2
16:06:03 Build Finished (took 2m:5s.45ms)
```
ビルド自体は完了したっぽい。
なぜかwineを使うので、コンソールからビルドしてみる:
```
$ pwd
/home/kiwamu/Documents/WICED-Studio-6.0/43xxx_Wi-Fi
$ vi make.sh
#!/bin/sh
make HOST_OS=Linux64 $@
$ chmod +x make.sh
$ ./make.sh snip.scan-CYW943907AEVAL1F
```
ボードを入手したのでファームウェアを書き込んでみる:
```
$ ./make.sh test.console-CYW943907AEVAL1F-FreeRTOS-LwIP download run
$ picocom -b 115200 /dev/ttyUSB1
> help
Console Commands:
?
help [<command> [<example_num>]]
- Print help message or command example.
loop <times> <semicolon_separated_commands_list>
- Loops the specified commands for specified number of times.
```
== デバッグ
デバッグシンボル付きでビルド:
```
$ ./make.sh test.wolfssl_test-CYW943907AEVAL1F-FreeRTOS-LwIP-debug download debug
```
xxx Eclipse使いたくない。。。コマンドラインでGDBを使う方法はないか?
== お題: 工数見積り
```
1. Create a time estimate for how long you think the project will take you, based on the following outline.
```
以下に見積る。が、全体について疑問:
```
Totally, I have some questions:
A. Should I replace mbedtls, which is default TLS in WICED SDK, with wolfSSL?
It needs many patches for the original SDK, and much human resource.
(e.g. WICED-Studio-6.0/43xxx_Wi-Fi/WICED/security/BESL/host/WICED/wiced_tls.c)
B. What RTOS should I support? The SDK supports FreeRTOS/NoOS/ThreadX.
I think the SDK uses ThreadX by default.
C. What Network Stack should I support? The SDK supports LwIP/NetX/NetX_Duo.
I think the SDK uses NetX_Duo by default.
D. May I use GitHub issue to report my progress?
```
== お題: wolfSSLをWICED SDKの上でビルド
工数予測: 1 week without any boards
```
2. Get wolfSSL to compile on top of the WICED SDK using the Cypress WICED Studio tools.
If we need to make changes to wolfSSL to allow us to compile wolfSSL with the WICED SDK,
we can add a new #define to the wolfSSL code (for example, something like "WOLFSSL_WICED_SDK").
You can find several of our existing port defines in the "./wolfssl/wolfcrypt/settings.h" file.
I have attached the wolfSSL Porting Guide to this email, which outlines the key areas of wolfSSL
that oftentimes require changes when porting wolfSSL to new platforms.
```
$(NAME)_COMPONENTSでwolfSSLの場所を指定すれば良さそう。
configureは何時やるべき?現状のFreeRTOS実装を参考にしよう。
とりあえず以下をビルドすればいい:
```
wolfssl/wolfcrypt/src/hmac.c
wolfssl/wolfcrypt/src/random.c
wolfssl/wolfcrypt/src/sha256.c
wolfssl/wolfcrypt/src/cpuid.c
wolfssl/wolfcrypt/src/hash.c
wolfssl/wolfcrypt/src/rsa.c
wolfssl/wolfcrypt/src/aes.c
wolfssl/wolfcrypt/src/sha.c
wolfssl/wolfcrypt/src/sha512.c
wolfssl/wolfcrypt/src/sha3.c
wolfssl/wolfcrypt/src/logging.c
wolfssl/wolfcrypt/src/wc_encrypt.c
wolfssl/wolfcrypt/src/wc_port.c
wolfssl/wolfcrypt/src/error.c
wolfssl/wolfcrypt/src/signature.c
wolfssl/wolfcrypt/src/wolfmath.c
wolfssl/wolfcrypt/src/memory.c
wolfssl/wolfcrypt/src/dh.c
wolfssl/wolfcrypt/src/asn.c
wolfssl/wolfcrypt/src/coding.c
wolfssl/wolfcrypt/src/poly1305.c
wolfssl/wolfcrypt/src/md5.c
wolfssl/wolfcrypt/src/chacha.c
wolfssl/wolfcrypt/src/chacha20_poly1305.c
wolfssl/wolfcrypt/src/tfm.c
wolfssl/wolfcrypt/src/ecc.c
wolfssl/src/internal.c
wolfssl/src/wolfio.c
wolfssl/src/keys.c
wolfssl/src/ssl.c
wolfssl/src/tls.c
wolfssl/wolfcrypt/test/test.c
```
Linux amd64でのビルドオプションは以下:
```
$ make clean
$ make V=1
--snip--
libtool: compile: gcc -DHAVE_CONFIG_H -I. -DBUILDING_WOLFSSL -fvisibility=hidden -fvisibility=hidden -DBUILDING_WOLFSSL -D_POSIX_THREADS -DHAVE_THREAD_LS -DNDEBUG -pthread -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT -DWC_RSA_BLINDING -DHAVE_AESGCM -DWOLFSSL_SHA512 -DWOLFSSL_SHA384 -DNO_DSA -DHAVE_ECC -DTFM_ECC256 -DECC_SHAMIR -DWOLFSSL_BASE64_ENCODE -DNO_RC4 -DNO_HC128 -DNO_RABBIT -DWOLFSSL_SHA224 -DWOLFSSL_SHA3 -DHAVE_POLY1305 -DHAVE_ONE_TIME_AUTH -DHAVE_CHACHA -DHAVE_HASHDRBG -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DHAVE_EXTENDED_MASTER -DNO_PSK -DNO_MD4 -DNO_PWDBASED -DUSE_FAST_MATH -DWOLFSSL_X86_64_BUILD -DWC_NO_ASYNC_THREADING -DNO_DES3 -Wall -Wno-unused -O2 -fomit-frame-pointer -DHAVE___UINT128_T -Werror -Wno-pragmas -Wall -Wno-strict-aliasing -Wextra -Wunknown-pragmas --param=ssp-buffer-size=1 -Waddress -Warray-bounds -Wbad-function-cast -Wchar-subscripts -Wcomment -Wfloat-equal -Wformat-security -Wformat=2 -Wmaybe-uninitialized -Wmissing-field-initializers -Wmissing-noreturn -Wmissing-prototypes -Wnested-externs -Wnormalized=id -Woverride-init -Wpointer-arith -Wpointer-sign -Wredundant-decls -Wshadow -Wsign-compare -Wstrict-overflow=1 -Wswitch-enum -Wundef -Wunused -Wunused-result -Wunused-variable -Wwrite-strings -fwrapv -MT wolfcrypt/src/src_libwolfssl_la-hmac.lo -MD -MP -MF wolfcrypt/src/.deps/src_libwolfssl_la-hmac.Tpo -c wolfcrypt/src/hmac.c -fPIC -DPIC -o wolfcrypt/src/.libs/src_libwolfssl_la-hmac.o
```
で、どのdefineがどういった意味なのか?
* FREERTOS: Needed. To use FreeRTOS.
* HAVE_LWIP_NATIVE: NoNeeded. WOLFSSL_LWIP is better.
* NO_FILESYSTEM: Needed. WICED doesn't support dirent.h.
* BUILDING_WOLFSSL: NoNeeded. It just decorates function scopes.
* NDEBUG: NoNeeded. wolfSSL code doesn't menion it.
* TFM_TIMING_RESISTANT: Needed. It gets better security.
* ECC_TIMING_RESISTANT: Needed. It gets better security.
* WC_RSA_BLINDING: Needed. To avoid "For timing resistance / side-channel attack..." warning.
* WOLFSSL_SHA512: Needed. The mbed TLS also supports SHA512.
* WOLFSSL_SHA384: Needed. The mbed TLS also supports SHA384.
* NO_DSA: Needed. DSA is an old algorithm.
* HAVE_ECC: Needed. To use Elliptic-curve cryptography.
* TFM_ECC256: Needed. To get speed on ECC.
* ECC_SHAMIR: Needed. To get speed on ECC.
* WOLFSSL_BASE64_ENCODE: Needed. mbed TLS also provide base64 encode.
* NO_RC4: Needed. mbed TLS doesn't provide RC4.
* NO_HC128: Needed. mbed TLS doesn't provide HC128.
* NO_RABBIT: Needed. mbed TLS doesn't provide RABBIT.
* WOLFSSL_SHA224: Needed. mbed TLS doesn't provide SHA224.
* WOLFSSL_SHA3: Needed. It's a latest hash.
* HAVE_POLY1305: Needed. It's a latest mac.
* HAVE_ONE_TIME_AUTH: Needed.
* HAVE_CHACHA: Needed. It's a latest mac.
* HAVE_HASHDRBG: Needed.
* HAVE_TLS_EXTENSIONS: Needed.
* HAVE_SUPPORTED_CURVES: Needed. To support Elliptic-curve cryptography.
* HAVE_EXTENDED_MASTER: Needed.
* NO_PSK: NoNeeded. mbed TLS supports PSK.
* NO_MD4: NoNeeded. mbed TLS supports MD4.
* NO_PWDBASED: Needed.
* USE_FAST_MATH: Needed.
* WC_NO_ASYNC_THREADING: Needed. If disable, it depends on pthread.
* NO_DES3: NoNeeded. mbed TLS supports DES3.
* NO_MAIN_DRIVER: Needed. To remove main function in test.c.
とりあえずこれでdefineの整理は一旦終了。
== お第: wolfcrypt/test/test.cを移植
工数予測: 1 week without any boards, and more 1 week after getting the board
```
3. Get the wolfCrypt test application (./wolfcrypt/test/test.c) to compile and run
on top of a target embedded device. This lets us verify that the port from step #2
is correct and that the cryptography algorithms work on the target device.
We will work with Cypress Semiconductor to figure out the best prototype board to use
for testing and development.
When compiling test.c, you can define NO_MAIN_DRIVER to exclude the main() function in that file.
This will allow you to call the "wolfcrypt_test()" function from a WICED Studio driver application that is created.
Our end goal is to place these example WICED Studio projects in the "./IDE" directory of the wolfSSL package.
```
test.cはかなりのAPIをたたいている。実際にデバッグするのには時間がかかりそう。
== お第: HTTPSクライアントを作る
工数予測: 1 week after getting the board
```
4. Create a simple TLS example client application that uses wolfSSL with the WICED SDK to make a secure connection.
Ideally, this will also be placed in the "./IDE" directory of the wolfSSL package.
It should be the simplest example client possible, connecting to a web server
(for example "https://www.example.com" and sending a simple HTTP GET message, like our example client application can do now).
```
HTTPS clientの例はなさそう。単純に手作りするか。
file:///home/kiwamu/Documents/WICED-Studio-6.0/43xxx_Wi-Fi/doc/API/group__http__client.html
によると:
```
The HTTP client library on WICED is capable of both secure [with TLS security] and non-secure mode of connection. The library also provides support for various RESTful HTTP methods such as GET, POST and PUT; and has support for various content types [e.g. HTML, Plain, JSON]. The HTTP library is capable of handling content payload that is greater than MTU size.
```
だそうなので、
```
wiced_result_t http_client_init( http_client_t* client, wiced_interface_t interface, http_event_handler_t event_handler, wiced_tls_identity_t* optional_identity )
```
のようにwiced_tls_identity_tをわたせば良さそう。この構造体は以下のような定義:
```
/* psk_key is only used for DTLS. as currently PSK support is only available for DTLS
* TODO : Need to add support for multiple certificate & private keys. ex. supporting RSA & ECDSA signed certificates */
typedef struct
{
union
{
wiced_tls_psk_key_t psk_key;
mbedtls_pk_context private_key;
};
mbedtls_x509_crt certificate;
wiced_tls_sign_certificate_verify custom_sign;
} wiced_tls_identity_t;
```
この構造体は以下のように初期化するものらしい:
```
result = wiced_dct_read_lock( (void**) &dct_security,
WICED_FALSE,
DCT_SECURITY_SECTION,
0,
sizeof( *dct_security ) );
result = wiced_tls_init_identity( &tls_identity,
dct_security->private_key,
strlen( dct_security->private_key ),
(uint8_t*) dct_security->certificate,
strlen( dct_security->certificate ) );
result = wiced_dct_read_unlock( dct_security, WICED_FALSE );
```
DCT(Device Configuration Table (Non-volatile flash storage space))
って単純なストレージなんでしょうか。。。
file:///home/kiwamu/Documents/WICED-Studio-6.0/43xxx_Wi-Fi/doc/API/group__dct.html#ga8a48c1c9301b78369ee89536f0e654d8
以下にmbed TLSを使ったhttps clientの例がある:
https://tls.mbed.org/kb/how-to/mbedtls-tutorial
https://github.com/ARMmbed/mbedtls/blob/development/programs/ssl/ssl_client1.c
上記コードから接続手順は以下のようになることがわかる:
* mbedtls_net_init()でmbedtls_net_contextを初期化
* mbedtls_ssl_init()でmbedtls_ssl_contextを初期化
* mbedtls_ssl_config_init()でmbedtls_ssl_configを初期化
* mbedtls_x509_crt_init()でmbedtls_x509_crtを初期化
* mbedtls_ctr_drbg_init()でmbedtls_ctr_drbg_contextを初期化
* mbedtls_entropy_init()でmbedtls_entropy_contextを初期化
* mbedtls_ctr_drbg_seed()で乱数初期化
* mbedtls_x509_crt_parse()でCA root証明書をロード
* mbedtls_net_connect()でサーバのポート4433に接続
* mbedtls_ssl_config_defaults()でSSL/TLS構造体を設定
* mbedtls_ssl_conf_authmode()で認証モードをOPTIONALに(本当はREQUIREDが良い)
* mbedtls_ssl_conf_ca_chain()でpeer認証に必要なデータを設定
* mbedtls_ssl_conf_rng()で乱数ジェネレータのコールバックを設定
* mbedtls_ssl_conf_dbg()でデバッグ関数コールバックを設定
* mbedtls_ssl_setup()でSSLコンテキストを設定
* mbedtls_ssl_set_hostname()でセーバ名を設定
* mbedtls_ssl_set_bio()でread/writeコールバックを設定
* mbedtls_ssl_handshake()でハンドシェイク
* mbedtls_ssl_get_verify_result()でサーバ証明書を検査
* mbedtls_ssl_write()でGETリクエスト送信
* mbedtls_ssl_read()でレスポンス受信
* mbedtls_ssl_close_notify()でSSL接続クローズ
* mbedtls_x509_crt_free(),mbedtls_ssl_free(),mbedtls_ssl_config_free(),
mbedtls_ctr_drbg_free(),mbedtls_entropy_free()でコンテキスト解放
上記をWICED APIで置き換えると...
* wiced_init()でWICED初期化
* wiced_network_up(WICED_STA_INTERFACE,WICED_USE_EXTERNAL_DHCP_SERVER,NULL)
でAPに接続
(43xxx_Wi-Fi/include/default_wifi_config_dct.hのCLIENT_AP_{SSID,PASSPHRASE}
をaterm-bbfadc-gに修正する必要有り)
* wiced_hostname_lookup()でDNSからIPアドレスを得る
* wiced_tcp_create_socket()でソケット生成
* wiced_tcp_bind()でソケットをバインド(不要?)
* wiced_tls_init_context()でTLSコンテキストを初期化
* wiced_tcp_enable_tls()でTLSを有効化
* wiced_tcp_connect()でサーバのポート4433に接続
* wiced_packet_create_tcp()でパケットを確保
* sprintfでパケットの中身を書き込む
* wiced_packet_set_data_end()でパケットを設定完了
* wiced_tcp_send_packet()でパケットを送信
* wiced_tcp_receive()でパケットを受信
* wiced_packet_get_data()で受信パケットの中身を取り出し
* wiced_packet_delete()で送信パケットと受信パケットを解放
* wiced_tcp_disconnect()で切断
などと考えていたら以下の方が楽そう?
* wiced_init()でWICED初期化
* wiced_network_up(WICED_STA_INTERFACE,WICED_USE_EXTERNAL_DHCP_SERVER,NULL)
でAPに接続
(43xxx_Wi-Fi/include/default_wifi_config_dct.hのCLIENT_AP_{SSID,PASSPHRASE}
を修正する必要有り)
* wiced_hostname_lookup()でDNSからIPアドレスを得る
* wiced_https_get()でGETリクエストをHTTPSで発行
実ボードで試した。動いているようだ。
== お題: `WICED/*`以下にあるAPIをwolfSSLで置き換えた際のテスト手段を考える
以下で見つかるAPIをwolfSSLで置き換えたとする:
```
$ pwd
/home/kiwamu/Documents/WICED-Studio-6.0/43xxx_Wi-Fi
$ git grep mbedtls_ | grep -v mbedtls_open | grep -v "^Binary file" | grep -v "^apps" | lv
```
その場合、当該APIが正常に動作するかどうやって調べるべきだろうか?
ファイル別に調べよう。
* WICED/internal/wiced_cooee.c: wiced_wifi_cooee()
* WICED/network/wiced_tcpip_common.c: wiced_tcp_send_buffer()
* WICED/network/wiced_tcpip_common.c: wiced_tcp_stream_write()
* WICED/security/BESL/host/WICED/wiced_dtls.c: dtls_check_psk_identity()
* WICED/security/BESL/host/WICED/wiced_dtls.c: dtls_check_retransmission()
* WICED/security/BESL/host/WICED/wiced_dtls.c: dtls_event_thread()
* WICED/security/BESL/host/WICED/wiced_dtls.c: dtls_free_peer()
* WICED/security/BESL/host/WICED/wiced_dtls.c: dtls_network_receive()
* WICED/security/BESL/host/WICED/wiced_dtls.c: dtls_network_send()
* WICED/security/BESL/host/WICED/wiced_dtls.c: dtls_server_event_processing_thread()
* WICED/security/BESL/host/WICED/wiced_dtls.c: mbedtls_reset_context()
* WICED/security/BESL/host/WICED/wiced_dtls.c: mbedtls_ssl_copy_context()
* WICED/security/BESL/host/WICED/wiced_dtls.c: mbedtls_timing_get_delay()
* WICED/security/BESL/host/WICED/wiced_dtls.c: mbedtls_timing_set_delay()
* WICED/security/BESL/host/WICED/wiced_dtls.c: wiced_dtls_calculate_overhead()
* WICED/security/BESL/host/WICED/wiced_dtls.c: wiced_dtls_deinit_identity()
* WICED/security/BESL/host/WICED/wiced_dtls.c: wiced_dtls_encrypt_packet()
* WICED/security/BESL/host/WICED/wiced_dtls.c: wiced_dtls_init_identity()
* WICED/security/BESL/host/WICED/wiced_dtls.c: wiced_generic_start_dtls_with_ciphers()
* WICED/security/BESL/host/WICED/wiced_supplicant.c: besl_supplicant_init()
* WICED/security/BESL/host/WICED/wiced_supplicant.c: supplicant_peap_thread()
* WICED/security/BESL/host/WICED/wiced_tls.c: eap_ssl_flush_output()
* WICED/security/BESL/host/WICED/wiced_tls.c: eap_ssl_receive_packet()
* WICED/security/BESL/host/WICED/wiced_tls.c: mbedtls_debug()
* WICED/security/BESL/host/WICED/wiced_tls.c: mbedtls_reset_context()
* WICED/security/BESL/host/WICED/wiced_tls.c: my_verify()
* WICED/security/BESL/host/WICED/wiced_tls.c: ssl_flush_output()
* WICED/security/BESL/host/WICED/wiced_tls.c: ssl_receive_packet()
* WICED/security/BESL/host/WICED/wiced_tls.c: tls_add_alpn_extension()
* WICED/security/BESL/host/WICED/wiced_tls.c: tls_calculate_encrypt_buffer_length()
* WICED/security/BESL/host/WICED/wiced_tls.c: tls_host_create_buffer()
* WICED/security/BESL/host/WICED/wiced_tls.c: tls_host_get_packet_data()
* WICED/security/BESL/host/WICED/wiced_tls.c: tls_host_receive_packet()
* WICED/security/BESL/host/WICED/wiced_tls.c: tls_packetize_buffered_data()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_generic_start_tls_with_ciphers()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_calculate_overhead()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_close_notify()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_deinit_context()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_deinit_identity()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_deinit_root_ca_certificates()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_encrypt_packet()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_init_context()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_init_identity()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_init_root_ca_certificates()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_is_encryption_enabled()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_receive_eap_packet()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_receive_packet()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_reset_context()
* WICED/security/BESL/host/WICED/wiced_tls.c: wiced_tls_set_extension()
* WICED/security/PostgreSQL/fortuna.c: ciph_encrypt()
* WICED/security/PostgreSQL/fortuna.c: ciph_init()
* WICED/security/PostgreSQL/fortuna.c: md_init()
* WICED/security/PostgreSQL/fortuna.c: md_result()
* WICED/security/PostgreSQL/fortuna.c: md_update()
* libraries/protocols/websocket/websocket_handshake.c: wiced_generate_server_websocket_key()
* libraries/utilities/command_console/fs/fs_test.c: sw_calc_file_sha1()
具体的にどのアプリをどうやって動かすと、上記の関数が検査できるのだろうか?
* wiced_wifi_cooee() needs new test application.
* wiced_tcp_send_buffer() called by apps/snip/websocket_server.
* wiced_tcp_stream_write() called by apps/snip/websocket_client.
* dtls_check_psk_identity() called by apps/snip/coap_app.
* dtls_check_retransmission() called by apps/snip/coap_app.
* dtls_event_thread() called by apps/snip/coap_app.
* dtls_free_peer() called by apps/snip/coap_app.
* dtls_network_receive() called by apps/snip/coap_app.
* dtls_network_send() called by apps/snip/coap_app.
* dtls_server_event_processing_thread() called by apps/snip/coap_app.
* mbedtls_reset_context() called by apps/snip/coap_app.
* mbedtls_ssl_copy_context() called by apps/snip/coap_app.
* mbedtls_timing_get_delay() called by apps/snip/coap_app.
* mbedtls_timing_set_delay() called by apps/snip/coap_app.
* wiced_dtls_calculate_overhead() called by apps/snip/coap_app.
* wiced_dtls_deinit_identity() called by apps/snip/coap_app.
* wiced_dtls_encrypt_packet() called by apps/snip/coap_app.
* wiced_dtls_init_identity() called by apps/snip/coap_app.
* wiced_generic_start_dtls_with_ciphers() called by apps/snip/coap_app.
* besl_supplicant_init() called by apps/snip/rfmon join_ent command.
* supplicant_peap_thread() needs new test application.
* eap_ssl_flush_output() called by apps/snip/tcp_server.
* eap_ssl_receive_packet() called by apps/snip/tcp_server.
* mbedtls_debug() used on mbed TLS, which is changed by WICED.
* mbedtls_reset_context() called by apps/snip/tcp_server.
* my_verify() called by apps/snip/tcp_server.
* ssl_flush_output() called by apps/snip/tcp_server.
* ssl_receive_packet() called by apps/snip/tcp_server.
* tls_add_alpn_extension() called by apps/test/http2.
* tls_calculate_encrypt_buffer_length() called by apps/snip/websocket_server.
* tls_host_create_buffer() used on mbed TLS, which is changed by WICED.
* tls_host_get_packet_data() called by apps/snip/tcp_server.
* tls_host_receive_packet() called by apps/snip/tcp_server.
* tls_packetize_buffered_data() called by apps/snip/tcp_server.
* wiced_generic_start_tls_with_ciphers() called by apps/snip/tcp_server.
* wiced_tls_calculate_overhead() called by apps/snip/tcp_server.
* wiced_tls_close_notify() called by apps/snip/tcp_server.
* wiced_tls_deinit_context() called by apps/snip/https_server.
* wiced_tls_deinit_identity() called by apps/test/http2.
* wiced_tls_deinit_root_ca_certificates() called by apps/test/http2.
* wiced_tls_encrypt_packet() called by apps/snip/tcp_server.
* wiced_tls_init_context() called by apps/snip/httpbin_org.
* wiced_tls_init_identity() called by apps/snip/https_server and apps/snip/websocket_server.
* wiced_tls_init_root_ca_certificates() called by apps/snip/httpbin_org.
* wiced_tls_receive_eap_packet() needs new test application.
* wiced_tls_receive_packet() called by apps/test/http2.
* wiced_tls_reset_context() called by apps/test/http2.
* wiced_tls_set_extension() called by apps/snip/httpbin_org.
* ciph_encrypt()/ciph_init()/md_init()/md_result()/md_update() not used yet.
* wiced_generate_server_websocket_key() called by apps/snip/websocket_server and apps/snip/websocket_client.
* sw_calc_file_sha1() needs new test application.
と、ここまで調べたが、広範囲なテストよりapps/snip/https_clientをまずは動かすことに集中したい。
== 先にmakeターゲットでmbed TLSとwolfSSLを切り換え可能にする
以下のようにコマンドをたたいたときにFreeRTOSとLwIPが選択される仕組みを調べる:
```
$ ./make.sh snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP download run
```
tools/makefiles/wiced_config.mkというファイルにしかけがあるようだ。
このファイルは以下のように使われる:
```
$ ./make.sh -r -f ./tools/makefiles/wiced_config.mk MAKEFILES_PATH=./tools/makefiles snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP
```
これでビルド通るようにまずはしてみる:
```
$ ./make.sh clean
$ ./make.sh snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP-mbedtls_open
```
とおった。次は以下でデフォルトmbedtls_openでビルドできるべき:
```
$ ./make.sh snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP
```
これでmakeターゲットはできた。あとは-wolfsslを付けたときのビルドエラーを消してから起動確認すればいい。
== "apps/snip/https_client"をwolfSSLでビルドできるようにする
```
$ ./make.sh snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP-wolfssl
```
とりあえずWICED_MBEDTLSとWOLFSSL_WICEDでTLSを切り換え可能にすることを目指す。
が、WICED_MBEDTLSをMakefileに持ち上げるとビルドエラーになる:
```
$ ./make.sh clean && ./make.sh QUIET= snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP-wolfssl |& lv
```
mbed TLSとwolfSSL間のおおざっぱな設計差異を見つけたい。
が、一度に全部を見わたすのは無理なので、近視眼的に攻めたい。
一旦TLS関連のヘッダを全部無効化した。
file:///home/kiwamu/Dropbox/patches/patch_wiced_no_tls.txt
この状態で libraries/protocols/HTTP/http.c の呼び出しを少しずつ翻訳したい。
=== mbed TLSのhttps通信手順
libraries/protocols/HTTP/http.c#wiced_https_get()を読み解く。
typedef struct mbedtls_ssl_context wiced_tls_workspace_t;
typedef struct mbedtls_ssl_session wiced_tls_session_t;
typedef struct mbedtls_x509_crt wiced_tls_certificate_t;
typedef int (*wiced_tls_sign_certificate_verify)( void* key ,rsa_hash_id_t hash_id, int32_t hashlen, const unsigned char *hash, unsigned char *sign, uint32_t* key_length, wiced_tls_key_type_t type );
typedef struct
{
union
{
wiced_tls_psk_key_t psk_key;
mbedtls_pk_context private_key;
};
mbedtls_x509_crt certificate;
wiced_tls_sign_certificate_verify custom_sign;
} wiced_tls_identity_t;
typedef struct
{
uint32_t context_id;
wiced_tls_workspace_t context;
wiced_tls_session_t* session;
wiced_tls_identity_t* identity;
} wiced_tls_context_t;
wiced_https_get()
=> wiced_tls_context_t *context;
wiced_tls_identity_t *tls_identity = NULL;
tls_identity = ( wiced_tls_identity_t* ) malloc_named ("tls_identity", sizeof( wiced_tls_identity_t ));
wiced_tls_init_identity( tls_identity, dct_security->private_key, strlen( dct_security->private_key ), (uint8_t*) dct_security->certificate, strlen( dct_security->certificate ) );
=> mbedtls_x509_crt_init( &identity->certificate );
mbedtls_x509_crt_parse( &identity->certificate, (const unsigned char *) certificate_data, certificate_length );
mbedtls_pk_init( &identity->private_key );
mbedtls_pk_parse_key( &identity->private_key, (const unsigned char *) private_key, key_length, NULL, 0 );
wiced_tcp_create_socket( &socket, WICED_STA_INTERFACE ) ) != WICED_SUCCESS );
context = MALLOC_OBJECT( "HTTP Client TLS Context", wiced_tls_context_t );
socket.context_malloced = WICED_TRUE;
wiced_tls_init_context( context, tls_identity, peer_cn );
=> context->context.conf = tls_host_malloc ("tls", sizeof(mbedtls_ssl_config));
context->context_id = WICED_TLS_CONTEXT_ID;
context->identity = identity;
((mbedtls_ssl_config*)context->context.conf)->peer_cn = peer_cn;
wiced_tcp_enable_tls( &socket, context );
=> socket->tls_context = context;
wiced_tcp_connect( &socket, address, 443, 20000 );
=> wiced_tcp_start_tls( socket, WICED_TLS_AS_CLIENT, WICED_TLS_DEFAULT_VERIFICATION );
=> wiced_generic_start_tls_with_ciphers( socket->tls_context, socket, type, verification, NULL, TLS_TCP_TRANSPORT );
=> mbedtls_ssl_config* conf = (mbedtls_ssl_config*) tls_context->context.conf;
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_entropy_init( &entropy );
mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ));
mbedtls_ssl_config_defaults( conf, MBEDTLS_SSL_IS_CLIENT, opt_config.transport, MBEDTLS_SSL_PRESET_DEFAULT );
mbedtls_ssl_conf_ca_chain( conf, root_ca_certificates, NULL );
mbedtls_ssl_conf_authmode( conf, verification );
mbedtls_ssl_conf_rng( conf, wiced_crypto_random_ecc, NULL );
mbedtls_ssl_conf_own_cert( conf, &tls_context->identity->certificate, &tls_context->identity->private_key );
mbedtls_ssl_conf_min_version( conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt_config.min_version );
mbedtls_ssl_conf_max_version( conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt_config.max_version );
mbedtls_ssl_setup( &tls_context->context, conf );
mbedtls_reset_context( &tls_context->context );
mbedtls_ssl_set_session( &tls_context->context, tls_context->session );
mbedtls_ssl_set_bio( &tls_context->context, referee, ssl_flush_output, ssl_receive_packet, NULL );
tls_context->context.send_context = referee;
tls_context->context.receive_context = referee;
tls_context->context.read_timeout = TLS_HANDSHAKE_PACKET_TIMEOUT_MS;
mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay );
mbedtls_ssl_handshake( &tls_context->context );
mbedtls_ssl_get_record_expansion( &tls_context->context );
wiced_tcp_send_buffer( &socket, query, (uint16_t) strlen( query ) ) != WICED_SUCCESS );
=> mbedtls_ssl_context* ssl_context = &socket->tls_context->context;
wiced_tls_calculate_encrypt_buffer_length(&socket->tls_context->context,data_length,&enc_output_buf_len );
ssl_context->out_hdr = enc_output_buf;
ssl_context->out_len = ssl_context->out_hdr + 3;
ssl_context->out_msg = ssl_context->out_hdr + sizeof(tls_record_header_t);
ssl_context->out_iv = ssl_context->out_msg;
ssl_context->out_msglen = data_length;
ssl_context->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
memmove( ssl_context->out_msg + (ssl_context->transform_out->ivlen - ssl_context->transform_out->fixed_ivlen), ssl_context->out_msg, ssl_context->out_msglen );
ssl_context->out_msg = ssl_context->out_msg + ssl_context->transform_out->ivlen - ssl_context->transform_out->fixed_ivlen;
mbedtls_ssl_write_record( ssl_context );
wiced_packet_create_tcp( socket, data_length, &packet, &packet_data_ptr, &available_space );
=> wiced_tls_calculate_overhead( &socket->tls_context->context, (*packet)->p->len, &header_space, &footer_pad_space );
=> mbedtls_cipher_get_cipher_mode( &context->transform_out->cipher_ctx_enc );
=> wiced_packet_set_data_start((wiced_packet_t*) packet, packet_data_ptr);
=> wiced_tls_encrypt_packet( &socket->tls_context->context, packet );
=> tls_host_set_packet_start((tls_packet_t*)packet, data);
=> wiced_packet_set_data_start((wiced_packet_t*)packet, start);
wiced_tcp_receive( &socket, &reply_packet, 5000 );
=> wiced_tls_receive_packet( socket, packet, timeout );
mbedtls_ssl_read( &socket->tls_context->context, &data, max_fragment_len );
wiced_packet_get_data( reply_packet, offset, &data, &data_length, &available );
wiced_packet_delete( reply_packet );
wiced_tcp_disconnect( &socket );
wiced_tcp_delete_socket( &socket );
wiced_tls_deinit_identity( tls_identity );
free ( tls_identity );
=== wolfSSLのhttps通信手順
https://os.mbed.com/users/wolfSSL/code/Example-HTTPSClient/
https://os.mbed.com/users/wolfSSL/code/HTTPClient/ を読み解く。
static int SocketReceive(WOLFSSL* ssl, char *buf, int sz, void *sock);
static int SocketSend(WOLFSSL* ssl, char *buf, int sz, void *sock);
static TCPSocketConnection m_sock;
struct WOLFSSL_CTX* ctx;
struct WOLFSSL * ssl;
net_main()
=> HTTPClient::get(url, recvBuff, sizeof(recvBuff));
=> HTTPClient::connect(url, HTTP_GET, NULL, pDataIn, timeout);
WOLFSSL_METHOD *SSLmethod;
SSLmethod = wolfTLSv1_2_client_method();
ctx = wolfSSL_CTX_new((WOLFSSL_METHOD *)SSLmethod);
wolfSSL_CTX_load_verify_locations(ctx, "certs/ca-cert.pem", 0);
wolfSSL_SetIORecv(ctx, SocketReceive) ;
wolfSSL_SetIOSend(ctx, SocketSend) ;
ssl = wolfSSL_new(ctx);
wolfSSL_SetIOReadCtx (ssl, (void *)&m_sock) ;
wolfSSL_SetIOWriteCtx(ssl, (void *)&m_sock) ;
wolfSSL_connect(ssl);
HTTPClient::send("GET / HTTP/1.1\r\nHost: myhost.com\r\n");
=> memcpy(send_buf_p, buf, cp_len) ;
HTTPClient::flush()
=> wolfSSL_write(ssl, buf, len);
m_sock.send_all(buf, len);
HTTPClient::send("\r\n");
HTTPClient::flush();
HTTPClient::recv(buf, CHUNK_SIZE - 1, CHUNK_SIZE - 1, &trfLen);
=> wolfSSL_read(ssl, buf, maxLen);
=== で、WICED+wolfSSLで結局やるべきことは?
コンテキストを何も生成する前に証明書と鍵をどこかに保管し、後からコンテキストに注入する必要がある。そんなことは可能なのか?無理そう。
以下のような構造体に変更して対処できないか:
typedef struct
{
WOLFSSL_CTX* ctx;
wiced_tls_sign_certificate_verify custom_sign; // Not used
} wiced_tls_identity_t;
typedef struct
{
uint32_t context_id;
WOLFSSL* ssl;
wiced_tls_identity_t* identity;
} wiced_tls_context_t;
既存のWICEDコードのフローにあてはめてみる:
* wiced_tls_identity_tの確保/初期化
* server/clientの指定? (wiced_tcp_start_tls()のtype変数で分かる)
* TLSバージョンの指定? (mbed TLSはmix/maxで指定する?)
* PEM certificate群の読み込み (wolfSSL_CTX_load_verify_buffer)
* 秘密鍵の読み込み (wolfSSL_CTX_use_PrivateKey_buffer)
* wiced_tls_context_tの確保/初期化
* xxx peer_cnはどう扱う?
* socket->tls_contextにwiced_tls_context_t *を代入
* ソケット関数登録?
* ハンドシェイク(wolfSSL_connect)
* GETリクエスト送信(wolfSSL_write)
* レスポンス受信(wolfSSL_read)
* 解放(wolfSSL_free)
* 解放(wolfSSL_CTX_free)
xxx 上記のフローを完成させること
xxx このとき、構造体の定義について熟考すること
=== まずはmbed TLSとwolfSSLの対応表を作ることになった
```
Can you create a Google Spreadsheet that contains a list of all mbed TLS API that we will need to convert/port wolfSSL to? This will let me see the scope of our conversion project. It will also let me see the functions that are completed and those that are not completed. We should also track the number of hours each function conversion took.
Once you have created this spreadsheet, please share it with me. My Gmail/Google Docs email is [email protected].
```
作った。以下:
https://docs.google.com/spreadsheets/d/1H1dWnLrYgBLW_xiU65_ILFMseHDo8OejVeFYENDwivs/edit#gid=0
=== mbed TLS依存をifdefで除外して、ビルドを通すようにする
ifdefでmbed TLSを除外して、以下を埋め込む:
```
#ifdef WICED_MBEDTLS /* xxx TODO: support TLS on wolfSSL */
#else
UNUSED_PARAMETER();
printf("xxx TODO: support TLS on wolfSSL at %s, line %d.\n", __FILE__, __LINE__);
return WICED_ERROR;
#endif
```
```
$ ./make clean && ./make.sh snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP-wolfssl
```
これでwolfSSLを有効にしてもビルドは通る。なおかつmbed TLS版は実行可能なことを確かめた。
```
$ ./make.sh snip.https_client-CYW943907AEVAL1F-FreeRTOS-LwIP
```
コミットした:
https://gitlab.com/masterq/WICED-Studio-6.0-wolfSSL/commit/07b8a388574ad443ee658ee123d3f067b7d80fdc
上記のpatchでwolfSSL入りsnip.https_clientを実行すると以下のエラーになる:
```
Resolved Server IP: XXX.XXX.XXX.XXX
Read the certificate Key from DCT
xxx TODO: support TLS on wolfSSL at WICED/security/BESL/host/WICED/wiced_tls.c, line 1302.
xxx TODO: support TLS on wolfSSL at WICED/security/BESL/host/WICED/wiced_tls.c, line 1314.
xxx TODO: support TLS on wolfSSL at WICED/security/BESL/host/WICED/wiced_tls.c, line 1343.
http_get: Get failed: 4
```
上記それぞれのエラー箇所は以下の関数:
* wiced_generic_start_tls_with_ciphers()
* wiced_tls_close_notify()
* wiced_tls_deinit_context()
その理由は以下のように関数呼び出しされるため:
wiced_https_get()
=> wiced_tls_init_identity( tls_identity, dct_security->private_key, strlen( dct_security->private_key ), (uint8_t*) dct_security->certificate, strlen( dct_security->certificate ) );
=> wiced_tcp_create_socket( &socket, WICED_STA_INTERFACE ) ) != WICED_SUCCESS );
=> wiced_tls_init_context() は呼ばれない
=> wiced_tcp_enable_tls( &socket, context );
=> wiced_tcp_connect( &socket, address, 443, 20000 );
=> wiced_tcp_start_tls( socket, WICED_TLS_AS_CLIENT, WICED_TLS_DEFAULT_VERIFICATION );
=> wiced_generic_start_tls_with_ciphers( socket->tls_context, socket, type, verification, NULL, TLS_TCP_TRANSPORT );
なんと。デフォルトではwiced_tls_identity_tは確保されないんだ。すると少し楽ができるかもしれない。
== "apps/snip/https_client"をwolfSSLで実行可能にする
はじめにwiced_generic_start_tls_with_ciphers()を実装する。
wiced_generic_start_tls_with_ciphers()では何をすべきか?
v wolfSSL_Init()をlazyに初期化すべき。スレッド対策はしなくて良いのでは
v wiced_tcp_start_tls()ではじめてclient/serverの判別がつくので、WOLFSSL_CTXの生成はこの関数最初ですべき
v server側は後で考えるために、TODOメモを残す
v WOLFSSL_CTXはどこに格納すべき?
v wiced_tls_identity_tがないので、鍵と証明書は不要
v 元コードではNULLポインタの先をmbedtls_ssl_conf_own_cert()で辿ってるけどいいのか?たぶん読んでリストに繋ぐけどmbed TLS側から使っていないだけっぽい
v wiced_tls_init_root_ca_certificates()はroot_ca_certificatesを初期化していないので、TODOメモを残すだけで証明書検査は不要
v とりあえず wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
v wolfSSL_SetIORecv()/wolfSSL_SetIOSend()
v ssl_flush_output()を作る
* ssl_receive_packet()をnetwork_tcp_receive()で作る エラーでは-1を返す
* ssl_receive_packet()はsizeを要求するが、network_tcp_receive()は任意長のパケットを返す。どうすれば。。。
v WOLFSSLを生成
v wolfSSL_SetIOReadCtx()/wolfSSL_SetIOWriteCtx()
v clientならwolfSSL_connect()もしてしまう
v エラーケースでWOLFSSL_CTX/WOLFSSLを解放
xxx 検討中
他にこの段階でわかっているやるべきことは:
xxx wolfSSL_free()をどこかで呼ぶ
xxx wolfSSL_CTX_free()をどこかで呼ぶ
xxx wolfSSL_Cleanup()は放置
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment