Arduinoスケッチに安全に秘匿値を埋め込む

Arduinoスケッチを描いていると、WiFiのSSIDやパスワードといった秘匿値をデバイスに渡してやらないといけないことが多々ありますよね。

インターネットにあるスケッチをみていると、たいてい、

const char* password = "PASSWORD";

のようにソースコードにハードコードされているわけなのですが、githubなどでスケッチを公開するときに、誤って秘匿値をさらしてしまう危険性があります。

そこで、環境変数を経由して、コンパイル時に秘匿値を渡す方法を紹介します。

使うツールは、`Make`です。Arduino IDEからのコンパイルではコンパイラオプションが渡せないので、この方法は使えません。Arduinoをインストールしていると、`arduino` (MacOSの場合は、`Arduino.app/Contents/MacOS/Arduino` )というコマンドラインツールが同梱されているので、これを利用します。

https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc

ちなみに、公式レポジトリには、`arduino-cli` というgolang製のツールも用意されていますが、今回はこれは使いません。

1. Makefileを定義する

ARDUINO := /Applications/Arduino.app/Contents/MacOS/Arduino
BUILD_DIR := build
BOARD := espressif:esp32:m5stack-core-esp32
PORT := /dev/cu.SLAB_USBtoUART
BAUD := 115200
SKETCH = $(shell basename "$$PWD").ino

.PHONY: all

all:
	$(ARDUINO) --pref build.path=$(BUILD_DIR) --board $(BOARD) --port $(PORT) --upload $(SKETCH)

私はm5stackを使っているので、このような設定なっていますが、BOARDやPORTは、お持ちのデバイスに合わせて適切に設定してください。デバイスが開発マシンにつながっていれば、`make` でバイナリをuploadすることができるはずです。

ちなみに、Serial 通信の内容は、

screen /dev/tty.${FOO} 115200

で確認できる(あと送信も可能)ので、Arduino IDEを立ち上げなくても、好きなエディタとTerminalで開発ができます。

2. マクロを定義する

たとえば、`MYSECRET`というマクロなら、

#ifdef MYSECRET
const char *secret = MYSECRET
#else
const char *secret = "MYSECRET"
#endif

といった感じで、定数マクロを利用したい場所に格納します。

3. コンパイラオプションを追加する

さて、次に、秘匿値を環境変数から受け取り、コンパイラオプションとして渡しましょう。

Platforms.txt をみると、

build.extra_flags=-DESP32 -DCORE_DEBUG_LEVEL={build.code_debug} {build.defines}

とあるので、`build.defines`が今回使用するオプションです。Makefileに、自分の定義したい、DEFINEマクロを記述し、

DEFINES := "-DMYSECRET=\"$$MYSECRET\""

allタスクのコマンドを、以下のように変更します。

$(ARDUINO) --pref build.path=$(BUILD_DIR) --pref build.defines=$(DEFINES) --board $(BOARD) --port $(PORT) --upload $(SKETCH)

そして、環境変数に値をセットして、make。

MYSECRET=password make

無事に、渡せたでしょうか?

もしうまくいかない場合は、`build/build.options.json`の中身を確認してみてください。このファイルの`customBuildProperties`には、環境変数が展開された形で、コンパイラオプションが書き込まれているはずです。ここで空白が渡っていたりした場合、うまく環境変数を設定できていない可能性があります。

また、もちろん`build`ディレクトリはSCMに含めないでくださいね。

環境変数を毎回指定するのは大変なので、あとは、`dotenv`, `direnv` `envchain`などお好みの環境変数管理ツールを利用して、makeコマンドに渡してください。

Happy Hacking!

この記事が気に入ったらサポートをしてみませんか?