diff --git a/Makefile b/Makefile index 2f448d5..a4c03ed 100644 --- a/Makefile +++ b/Makefile @@ -13,15 +13,17 @@ export GOEXPERIMENT APP_DIR := app WEB_DIR := website +CLI_DIR := cli APP_BIN := $(APP_DIR)/vault1984 WEB_BIN := $(WEB_DIR)/vault1984-web +CLI_BIN := $(CLI_DIR)/vault1984 APP_ENTRY := ./cmd/vault1984 WEB_ENTRY := . LDFLAGS := -s -w GOFLAGS := -trimpath -.PHONY: all app website test clean deploy deploy-app deploy-web \ +.PHONY: all app website cli test clean deploy deploy-app deploy-web \ restart restart-app restart-web stop stop-app stop-web status verify-fips # --- build --- @@ -36,6 +38,11 @@ website: cd $(WEB_DIR) && go build $(GOFLAGS) -ldflags '$(LDFLAGS)' -o vault1984-web $(WEB_ENTRY) @echo "built $(WEB_BIN) (FIPS)" +cli: + $(MAKE) -C $(CLI_DIR) + @strip $(CLI_BIN) 2>/dev/null || true + @echo "built $(CLI_BIN) ($$(wc -c < $(CLI_BIN)) bytes, stripped)" + # --- test --- test: @@ -107,3 +114,4 @@ logs-web: clean: rm -f $(APP_BIN) $(WEB_BIN) + $(MAKE) -C $(CLI_DIR) clean diff --git a/cli/Makefile b/cli/Makefile new file mode 100644 index 0000000..0be1fcc --- /dev/null +++ b/cli/Makefile @@ -0,0 +1,120 @@ +# vault1984 CLI — Makefile +# Pure C, BearSSL + QuickJS + cJSON, target <1MB stripped +# +# Usage: +# make — build for host +# make clean — remove build artifacts +# make strip — strip the binary +# make size — show binary size + +CC ?= cc +CFLAGS := -std=c11 -Wall -Wextra -Os -DNDEBUG +CFLAGS_GNU := -std=gnu11 -Wall -Os -DNDEBUG +LDFLAGS := +STRIP ?= strip + +# Platform detection +UNAME_S := $(shell uname -s 2>/dev/null || echo Windows) +ifeq ($(UNAME_S),Linux) + LDFLAGS += -lm -lpthread +endif +ifeq ($(UNAME_S),Darwin) + LDFLAGS += -lm +endif +ifeq ($(UNAME_S),FreeBSD) + LDFLAGS += -lm -lpthread +endif + +# Directories +SRC_DIR := src +BUILD_DIR := build +VENDOR_DIR := vendor +BEARSSL_DIR := $(VENDOR_DIR)/bearssl +QUICKJS_DIR := $(VENDOR_DIR)/quickjs +CJSON_DIR := $(VENDOR_DIR)/cjson +CRYPTO_DIR := ../crypto + +# Output binary +BIN := vault1984 + +# --- Source files --- + +# CLI sources +CLI_SRC := $(SRC_DIR)/main.c \ + $(SRC_DIR)/http.c \ + $(SRC_DIR)/keystore.c \ + $(SRC_DIR)/jsbridge.c \ + $(SRC_DIR)/util.c + +# cJSON (single file) +CJSON_SRC := $(CJSON_DIR)/cJSON.c + +# QuickJS core sources (no qjs.c/qjsc.c — those are standalone executables) +QUICKJS_SRC := $(QUICKJS_DIR)/quickjs.c \ + $(QUICKJS_DIR)/cutils.c \ + $(QUICKJS_DIR)/dtoa.c \ + $(QUICKJS_DIR)/libregexp.c \ + $(QUICKJS_DIR)/libunicode.c \ + $(QUICKJS_DIR)/quickjs-libc.c + +# BearSSL — compile all .c files in src/ subdirectories +BEARSSL_SRC := $(shell find $(BEARSSL_DIR)/src -name '*.c') + +# All sources +ALL_SRC := $(CLI_SRC) $(CJSON_SRC) $(QUICKJS_SRC) $(BEARSSL_SRC) + +# Object files (in build/) +ALL_OBJ := $(patsubst %.c,$(BUILD_DIR)/%.o,$(ALL_SRC)) + +# Include paths +INCLUDES := -I$(BEARSSL_DIR)/inc \ + -I$(QUICKJS_DIR) \ + -I$(CJSON_DIR) \ + -I$(SRC_DIR) + +# QuickJS needs these defines +QJS_DEFS := -DCONFIG_VERSION=\"2025-04-26\" \ + -D_GNU_SOURCE \ + -DCONFIG_BIGNUM + +# --- Rules --- + +.PHONY: all clean strip size + +all: $(BIN) + +$(BIN): $(ALL_OBJ) + $(CC) -o $@ $^ $(LDFLAGS) + @echo "built: $(BIN) ($(shell wc -c < $@ 2>/dev/null || echo '?') bytes)" + +# CLI sources (need QuickJS + BearSSL headers) +$(BUILD_DIR)/$(SRC_DIR)/%.o: $(SRC_DIR)/%.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INCLUDES) -Wno-unused-parameter -c $< -o $@ + +# cJSON +$(BUILD_DIR)/$(CJSON_DIR)/%.o: $(CJSON_DIR)/%.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -I$(CJSON_DIR) -c $< -o $@ + +# QuickJS +$(BUILD_DIR)/$(QUICKJS_DIR)/%.o: $(QUICKJS_DIR)/%.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS_GNU) $(QJS_DEFS) -I$(QUICKJS_DIR) -Wno-sign-compare -Wno-unused-parameter -Wno-implicit-fallthrough -c $< -o $@ + +# BearSSL +$(BUILD_DIR)/$(BEARSSL_DIR)/%.o: $(BEARSSL_DIR)/%.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -I$(BEARSSL_DIR)/inc -I$(BEARSSL_DIR)/src -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) $(BIN) + +strip: $(BIN) + $(STRIP) $(BIN) + @echo "stripped: $(BIN) ($(shell wc -c < $(BIN)) bytes)" + +size: $(BIN) + @ls -la $(BIN) + @echo "---" + @size $(BIN) 2>/dev/null || true diff --git a/cli/build/src/http.o b/cli/build/src/http.o new file mode 100644 index 0000000..28a2876 Binary files /dev/null and b/cli/build/src/http.o differ diff --git a/cli/build/src/jsbridge.o b/cli/build/src/jsbridge.o new file mode 100644 index 0000000..a0cf82a Binary files /dev/null and b/cli/build/src/jsbridge.o differ diff --git a/cli/build/src/keystore.o b/cli/build/src/keystore.o new file mode 100644 index 0000000..7690311 Binary files /dev/null and b/cli/build/src/keystore.o differ diff --git a/cli/build/src/main.o b/cli/build/src/main.o new file mode 100644 index 0000000..e127606 Binary files /dev/null and b/cli/build/src/main.o differ diff --git a/cli/build/src/util.o b/cli/build/src/util.o new file mode 100644 index 0000000..58417a1 Binary files /dev/null and b/cli/build/src/util.o differ diff --git a/cli/build/vendor/bearssl/src/aead/ccm.o b/cli/build/vendor/bearssl/src/aead/ccm.o new file mode 100644 index 0000000..0cd52ec Binary files /dev/null and b/cli/build/vendor/bearssl/src/aead/ccm.o differ diff --git a/cli/build/vendor/bearssl/src/aead/eax.o b/cli/build/vendor/bearssl/src/aead/eax.o new file mode 100644 index 0000000..6b6739f Binary files /dev/null and b/cli/build/vendor/bearssl/src/aead/eax.o differ diff --git a/cli/build/vendor/bearssl/src/aead/gcm.o b/cli/build/vendor/bearssl/src/aead/gcm.o new file mode 100644 index 0000000..2e028b1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/aead/gcm.o differ diff --git a/cli/build/vendor/bearssl/src/codec/ccopy.o b/cli/build/vendor/bearssl/src/codec/ccopy.o new file mode 100644 index 0000000..aa018e1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/ccopy.o differ diff --git a/cli/build/vendor/bearssl/src/codec/dec16be.o b/cli/build/vendor/bearssl/src/codec/dec16be.o new file mode 100644 index 0000000..dafdfb4 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/dec16be.o differ diff --git a/cli/build/vendor/bearssl/src/codec/dec16le.o b/cli/build/vendor/bearssl/src/codec/dec16le.o new file mode 100644 index 0000000..924871e Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/dec16le.o differ diff --git a/cli/build/vendor/bearssl/src/codec/dec32be.o b/cli/build/vendor/bearssl/src/codec/dec32be.o new file mode 100644 index 0000000..ce6b416 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/dec32be.o differ diff --git a/cli/build/vendor/bearssl/src/codec/dec32le.o b/cli/build/vendor/bearssl/src/codec/dec32le.o new file mode 100644 index 0000000..2c6b747 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/dec32le.o differ diff --git a/cli/build/vendor/bearssl/src/codec/dec64be.o b/cli/build/vendor/bearssl/src/codec/dec64be.o new file mode 100644 index 0000000..647d23c Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/dec64be.o differ diff --git a/cli/build/vendor/bearssl/src/codec/dec64le.o b/cli/build/vendor/bearssl/src/codec/dec64le.o new file mode 100644 index 0000000..6d09a29 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/dec64le.o differ diff --git a/cli/build/vendor/bearssl/src/codec/enc16be.o b/cli/build/vendor/bearssl/src/codec/enc16be.o new file mode 100644 index 0000000..dab9811 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/enc16be.o differ diff --git a/cli/build/vendor/bearssl/src/codec/enc16le.o b/cli/build/vendor/bearssl/src/codec/enc16le.o new file mode 100644 index 0000000..4d9709a Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/enc16le.o differ diff --git a/cli/build/vendor/bearssl/src/codec/enc32be.o b/cli/build/vendor/bearssl/src/codec/enc32be.o new file mode 100644 index 0000000..0988fce Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/enc32be.o differ diff --git a/cli/build/vendor/bearssl/src/codec/enc32le.o b/cli/build/vendor/bearssl/src/codec/enc32le.o new file mode 100644 index 0000000..08a43b6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/enc32le.o differ diff --git a/cli/build/vendor/bearssl/src/codec/enc64be.o b/cli/build/vendor/bearssl/src/codec/enc64be.o new file mode 100644 index 0000000..92f92a3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/enc64be.o differ diff --git a/cli/build/vendor/bearssl/src/codec/enc64le.o b/cli/build/vendor/bearssl/src/codec/enc64le.o new file mode 100644 index 0000000..de4cdf2 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/enc64le.o differ diff --git a/cli/build/vendor/bearssl/src/codec/pemdec.o b/cli/build/vendor/bearssl/src/codec/pemdec.o new file mode 100644 index 0000000..2ed8373 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/pemdec.o differ diff --git a/cli/build/vendor/bearssl/src/codec/pemenc.o b/cli/build/vendor/bearssl/src/codec/pemenc.o new file mode 100644 index 0000000..37cd731 Binary files /dev/null and b/cli/build/vendor/bearssl/src/codec/pemenc.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_all_m15.o b/cli/build/vendor/bearssl/src/ec/ec_all_m15.o new file mode 100644 index 0000000..29860fc Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_all_m15.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_all_m31.o b/cli/build/vendor/bearssl/src/ec/ec_all_m31.o new file mode 100644 index 0000000..f2a5fb1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_all_m31.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_c25519_i15.o b/cli/build/vendor/bearssl/src/ec/ec_c25519_i15.o new file mode 100644 index 0000000..8d9f1b0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_c25519_i15.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_c25519_i31.o b/cli/build/vendor/bearssl/src/ec/ec_c25519_i31.o new file mode 100644 index 0000000..d23df24 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_c25519_i31.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_c25519_m15.o b/cli/build/vendor/bearssl/src/ec/ec_c25519_m15.o new file mode 100644 index 0000000..0ba2e89 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_c25519_m15.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_c25519_m31.o b/cli/build/vendor/bearssl/src/ec/ec_c25519_m31.o new file mode 100644 index 0000000..aef418c Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_c25519_m31.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_c25519_m62.o b/cli/build/vendor/bearssl/src/ec/ec_c25519_m62.o new file mode 100644 index 0000000..a1da8aa Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_c25519_m62.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_c25519_m64.o b/cli/build/vendor/bearssl/src/ec/ec_c25519_m64.o new file mode 100644 index 0000000..fea9c46 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_c25519_m64.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_curve25519.o b/cli/build/vendor/bearssl/src/ec/ec_curve25519.o new file mode 100644 index 0000000..f754d9b Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_curve25519.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_default.o b/cli/build/vendor/bearssl/src/ec/ec_default.o new file mode 100644 index 0000000..1edcfc1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_default.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_keygen.o b/cli/build/vendor/bearssl/src/ec/ec_keygen.o new file mode 100644 index 0000000..2f9a7db Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_keygen.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_p256_m15.o b/cli/build/vendor/bearssl/src/ec/ec_p256_m15.o new file mode 100644 index 0000000..22843e0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_p256_m15.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_p256_m31.o b/cli/build/vendor/bearssl/src/ec/ec_p256_m31.o new file mode 100644 index 0000000..e3515a3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_p256_m31.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_p256_m62.o b/cli/build/vendor/bearssl/src/ec/ec_p256_m62.o new file mode 100644 index 0000000..437d339 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_p256_m62.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_p256_m64.o b/cli/build/vendor/bearssl/src/ec/ec_p256_m64.o new file mode 100644 index 0000000..01907f0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_p256_m64.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_prime_i15.o b/cli/build/vendor/bearssl/src/ec/ec_prime_i15.o new file mode 100644 index 0000000..b31551f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_prime_i15.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_prime_i31.o b/cli/build/vendor/bearssl/src/ec/ec_prime_i31.o new file mode 100644 index 0000000..c6fd344 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_prime_i31.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_pubkey.o b/cli/build/vendor/bearssl/src/ec/ec_pubkey.o new file mode 100644 index 0000000..6c7f5e5 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_pubkey.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_secp256r1.o b/cli/build/vendor/bearssl/src/ec/ec_secp256r1.o new file mode 100644 index 0000000..dc546bf Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_secp256r1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_secp384r1.o b/cli/build/vendor/bearssl/src/ec/ec_secp384r1.o new file mode 100644 index 0000000..9a88005 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_secp384r1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ec_secp521r1.o b/cli/build/vendor/bearssl/src/ec/ec_secp521r1.o new file mode 100644 index 0000000..17f3f65 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ec_secp521r1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_atr.o b/cli/build/vendor/bearssl/src/ec/ecdsa_atr.o new file mode 100644 index 0000000..6daca69 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_atr.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_asn1.o b/cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_asn1.o new file mode 100644 index 0000000..3ee438f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_asn1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_raw.o b/cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_raw.o new file mode 100644 index 0000000..66f82f7 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_default_sign_raw.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_asn1.o b/cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_asn1.o new file mode 100644 index 0000000..26f5b6d Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_asn1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_raw.o b/cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_raw.o new file mode 100644 index 0000000..ac64483 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_default_vrfy_raw.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i15_bits.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_bits.o new file mode 100644 index 0000000..398808f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_bits.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_asn1.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_asn1.o new file mode 100644 index 0000000..11197e7 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_asn1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_raw.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_raw.o new file mode 100644 index 0000000..a69f0e3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_sign_raw.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_asn1.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_asn1.o new file mode 100644 index 0000000..88d8b57 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_asn1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_raw.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_raw.o new file mode 100644 index 0000000..d6e32a4 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i15_vrfy_raw.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i31_bits.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_bits.o new file mode 100644 index 0000000..4a82b6e Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_bits.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_asn1.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_asn1.o new file mode 100644 index 0000000..064f657 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_asn1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_raw.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_raw.o new file mode 100644 index 0000000..6e22215 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_sign_raw.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_asn1.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_asn1.o new file mode 100644 index 0000000..1dec57a Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_asn1.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_raw.o b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_raw.o new file mode 100644 index 0000000..a153667 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_i31_vrfy_raw.o differ diff --git a/cli/build/vendor/bearssl/src/ec/ecdsa_rta.o b/cli/build/vendor/bearssl/src/ec/ecdsa_rta.o new file mode 100644 index 0000000..fe13b67 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ec/ecdsa_rta.o differ diff --git a/cli/build/vendor/bearssl/src/hash/dig_oid.o b/cli/build/vendor/bearssl/src/hash/dig_oid.o new file mode 100644 index 0000000..af48f12 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/dig_oid.o differ diff --git a/cli/build/vendor/bearssl/src/hash/dig_size.o b/cli/build/vendor/bearssl/src/hash/dig_size.o new file mode 100644 index 0000000..91102e3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/dig_size.o differ diff --git a/cli/build/vendor/bearssl/src/hash/ghash_ctmul.o b/cli/build/vendor/bearssl/src/hash/ghash_ctmul.o new file mode 100644 index 0000000..e9eb5b3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/ghash_ctmul.o differ diff --git a/cli/build/vendor/bearssl/src/hash/ghash_ctmul32.o b/cli/build/vendor/bearssl/src/hash/ghash_ctmul32.o new file mode 100644 index 0000000..f4ec1ed Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/ghash_ctmul32.o differ diff --git a/cli/build/vendor/bearssl/src/hash/ghash_ctmul64.o b/cli/build/vendor/bearssl/src/hash/ghash_ctmul64.o new file mode 100644 index 0000000..09d0250 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/ghash_ctmul64.o differ diff --git a/cli/build/vendor/bearssl/src/hash/ghash_pclmul.o b/cli/build/vendor/bearssl/src/hash/ghash_pclmul.o new file mode 100644 index 0000000..cf5bac4 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/ghash_pclmul.o differ diff --git a/cli/build/vendor/bearssl/src/hash/ghash_pwr8.o b/cli/build/vendor/bearssl/src/hash/ghash_pwr8.o new file mode 100644 index 0000000..e76f6c1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/ghash_pwr8.o differ diff --git a/cli/build/vendor/bearssl/src/hash/md5.o b/cli/build/vendor/bearssl/src/hash/md5.o new file mode 100644 index 0000000..7e2696d Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/md5.o differ diff --git a/cli/build/vendor/bearssl/src/hash/md5sha1.o b/cli/build/vendor/bearssl/src/hash/md5sha1.o new file mode 100644 index 0000000..7ab8f5c Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/md5sha1.o differ diff --git a/cli/build/vendor/bearssl/src/hash/mgf1.o b/cli/build/vendor/bearssl/src/hash/mgf1.o new file mode 100644 index 0000000..96dda2e Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/mgf1.o differ diff --git a/cli/build/vendor/bearssl/src/hash/multihash.o b/cli/build/vendor/bearssl/src/hash/multihash.o new file mode 100644 index 0000000..82695d1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/multihash.o differ diff --git a/cli/build/vendor/bearssl/src/hash/sha1.o b/cli/build/vendor/bearssl/src/hash/sha1.o new file mode 100644 index 0000000..34474ed Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/sha1.o differ diff --git a/cli/build/vendor/bearssl/src/hash/sha2big.o b/cli/build/vendor/bearssl/src/hash/sha2big.o new file mode 100644 index 0000000..ff68d73 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/sha2big.o differ diff --git a/cli/build/vendor/bearssl/src/hash/sha2small.o b/cli/build/vendor/bearssl/src/hash/sha2small.o new file mode 100644 index 0000000..8161a01 Binary files /dev/null and b/cli/build/vendor/bearssl/src/hash/sha2small.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_add.o b/cli/build/vendor/bearssl/src/int/i15_add.o new file mode 100644 index 0000000..8a2702f Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_add.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_bitlen.o b/cli/build/vendor/bearssl/src/int/i15_bitlen.o new file mode 100644 index 0000000..542ba88 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_bitlen.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_decmod.o b/cli/build/vendor/bearssl/src/int/i15_decmod.o new file mode 100644 index 0000000..b7e1204 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_decmod.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_decode.o b/cli/build/vendor/bearssl/src/int/i15_decode.o new file mode 100644 index 0000000..e4a6b10 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_decode.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_decred.o b/cli/build/vendor/bearssl/src/int/i15_decred.o new file mode 100644 index 0000000..86044b9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_decred.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_encode.o b/cli/build/vendor/bearssl/src/int/i15_encode.o new file mode 100644 index 0000000..82e92f0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_encode.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_fmont.o b/cli/build/vendor/bearssl/src/int/i15_fmont.o new file mode 100644 index 0000000..1c5587c Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_fmont.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_iszero.o b/cli/build/vendor/bearssl/src/int/i15_iszero.o new file mode 100644 index 0000000..474ba5f Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_iszero.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_moddiv.o b/cli/build/vendor/bearssl/src/int/i15_moddiv.o new file mode 100644 index 0000000..36cd364 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_moddiv.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_modpow.o b/cli/build/vendor/bearssl/src/int/i15_modpow.o new file mode 100644 index 0000000..fd0cd24 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_modpow.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_modpow2.o b/cli/build/vendor/bearssl/src/int/i15_modpow2.o new file mode 100644 index 0000000..52d49c8 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_modpow2.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_montmul.o b/cli/build/vendor/bearssl/src/int/i15_montmul.o new file mode 100644 index 0000000..5fdfc0a Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_montmul.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_mulacc.o b/cli/build/vendor/bearssl/src/int/i15_mulacc.o new file mode 100644 index 0000000..229c2cb Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_mulacc.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_muladd.o b/cli/build/vendor/bearssl/src/int/i15_muladd.o new file mode 100644 index 0000000..11a59a1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_muladd.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_ninv15.o b/cli/build/vendor/bearssl/src/int/i15_ninv15.o new file mode 100644 index 0000000..d8be40f Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_ninv15.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_reduce.o b/cli/build/vendor/bearssl/src/int/i15_reduce.o new file mode 100644 index 0000000..967d868 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_reduce.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_rshift.o b/cli/build/vendor/bearssl/src/int/i15_rshift.o new file mode 100644 index 0000000..16e5047 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_rshift.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_sub.o b/cli/build/vendor/bearssl/src/int/i15_sub.o new file mode 100644 index 0000000..a47c2fb Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_sub.o differ diff --git a/cli/build/vendor/bearssl/src/int/i15_tmont.o b/cli/build/vendor/bearssl/src/int/i15_tmont.o new file mode 100644 index 0000000..4a31d11 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i15_tmont.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_add.o b/cli/build/vendor/bearssl/src/int/i31_add.o new file mode 100644 index 0000000..0f597b5 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_add.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_bitlen.o b/cli/build/vendor/bearssl/src/int/i31_bitlen.o new file mode 100644 index 0000000..a786e41 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_bitlen.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_decmod.o b/cli/build/vendor/bearssl/src/int/i31_decmod.o new file mode 100644 index 0000000..4a53d47 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_decmod.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_decode.o b/cli/build/vendor/bearssl/src/int/i31_decode.o new file mode 100644 index 0000000..f9f4168 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_decode.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_decred.o b/cli/build/vendor/bearssl/src/int/i31_decred.o new file mode 100644 index 0000000..0e72700 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_decred.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_encode.o b/cli/build/vendor/bearssl/src/int/i31_encode.o new file mode 100644 index 0000000..d9e6730 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_encode.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_fmont.o b/cli/build/vendor/bearssl/src/int/i31_fmont.o new file mode 100644 index 0000000..549de3c Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_fmont.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_iszero.o b/cli/build/vendor/bearssl/src/int/i31_iszero.o new file mode 100644 index 0000000..680171c Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_iszero.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_moddiv.o b/cli/build/vendor/bearssl/src/int/i31_moddiv.o new file mode 100644 index 0000000..837718d Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_moddiv.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_modpow.o b/cli/build/vendor/bearssl/src/int/i31_modpow.o new file mode 100644 index 0000000..9c60a5c Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_modpow.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_modpow2.o b/cli/build/vendor/bearssl/src/int/i31_modpow2.o new file mode 100644 index 0000000..f25f2c6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_modpow2.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_montmul.o b/cli/build/vendor/bearssl/src/int/i31_montmul.o new file mode 100644 index 0000000..2fdbbe1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_montmul.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_mulacc.o b/cli/build/vendor/bearssl/src/int/i31_mulacc.o new file mode 100644 index 0000000..a3221d6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_mulacc.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_muladd.o b/cli/build/vendor/bearssl/src/int/i31_muladd.o new file mode 100644 index 0000000..b78700e Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_muladd.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_ninv31.o b/cli/build/vendor/bearssl/src/int/i31_ninv31.o new file mode 100644 index 0000000..6f0f97f Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_ninv31.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_reduce.o b/cli/build/vendor/bearssl/src/int/i31_reduce.o new file mode 100644 index 0000000..0dafc7e Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_reduce.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_rshift.o b/cli/build/vendor/bearssl/src/int/i31_rshift.o new file mode 100644 index 0000000..d61475b Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_rshift.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_sub.o b/cli/build/vendor/bearssl/src/int/i31_sub.o new file mode 100644 index 0000000..7cdcbf1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_sub.o differ diff --git a/cli/build/vendor/bearssl/src/int/i31_tmont.o b/cli/build/vendor/bearssl/src/int/i31_tmont.o new file mode 100644 index 0000000..36d4fc5 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i31_tmont.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_add.o b/cli/build/vendor/bearssl/src/int/i32_add.o new file mode 100644 index 0000000..23f8635 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_add.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_bitlen.o b/cli/build/vendor/bearssl/src/int/i32_bitlen.o new file mode 100644 index 0000000..aa69b7d Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_bitlen.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_decmod.o b/cli/build/vendor/bearssl/src/int/i32_decmod.o new file mode 100644 index 0000000..e3a5d3c Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_decmod.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_decode.o b/cli/build/vendor/bearssl/src/int/i32_decode.o new file mode 100644 index 0000000..9f7d3d0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_decode.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_decred.o b/cli/build/vendor/bearssl/src/int/i32_decred.o new file mode 100644 index 0000000..9901467 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_decred.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_div32.o b/cli/build/vendor/bearssl/src/int/i32_div32.o new file mode 100644 index 0000000..6956f84 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_div32.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_encode.o b/cli/build/vendor/bearssl/src/int/i32_encode.o new file mode 100644 index 0000000..b2efe2a Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_encode.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_fmont.o b/cli/build/vendor/bearssl/src/int/i32_fmont.o new file mode 100644 index 0000000..a065f40 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_fmont.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_iszero.o b/cli/build/vendor/bearssl/src/int/i32_iszero.o new file mode 100644 index 0000000..34e51ba Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_iszero.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_modpow.o b/cli/build/vendor/bearssl/src/int/i32_modpow.o new file mode 100644 index 0000000..acbe4f9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_modpow.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_montmul.o b/cli/build/vendor/bearssl/src/int/i32_montmul.o new file mode 100644 index 0000000..1eb4bc7 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_montmul.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_mulacc.o b/cli/build/vendor/bearssl/src/int/i32_mulacc.o new file mode 100644 index 0000000..0881831 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_mulacc.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_muladd.o b/cli/build/vendor/bearssl/src/int/i32_muladd.o new file mode 100644 index 0000000..f7ca2cf Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_muladd.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_ninv32.o b/cli/build/vendor/bearssl/src/int/i32_ninv32.o new file mode 100644 index 0000000..8a130a7 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_ninv32.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_reduce.o b/cli/build/vendor/bearssl/src/int/i32_reduce.o new file mode 100644 index 0000000..c652c68 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_reduce.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_sub.o b/cli/build/vendor/bearssl/src/int/i32_sub.o new file mode 100644 index 0000000..aea7095 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_sub.o differ diff --git a/cli/build/vendor/bearssl/src/int/i32_tmont.o b/cli/build/vendor/bearssl/src/int/i32_tmont.o new file mode 100644 index 0000000..76a17b9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i32_tmont.o differ diff --git a/cli/build/vendor/bearssl/src/int/i62_modpow2.o b/cli/build/vendor/bearssl/src/int/i62_modpow2.o new file mode 100644 index 0000000..1691162 Binary files /dev/null and b/cli/build/vendor/bearssl/src/int/i62_modpow2.o differ diff --git a/cli/build/vendor/bearssl/src/kdf/hkdf.o b/cli/build/vendor/bearssl/src/kdf/hkdf.o new file mode 100644 index 0000000..b0601e1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/kdf/hkdf.o differ diff --git a/cli/build/vendor/bearssl/src/kdf/shake.o b/cli/build/vendor/bearssl/src/kdf/shake.o new file mode 100644 index 0000000..cf7b2c9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/kdf/shake.o differ diff --git a/cli/build/vendor/bearssl/src/mac/hmac.o b/cli/build/vendor/bearssl/src/mac/hmac.o new file mode 100644 index 0000000..30f6c3e Binary files /dev/null and b/cli/build/vendor/bearssl/src/mac/hmac.o differ diff --git a/cli/build/vendor/bearssl/src/mac/hmac_ct.o b/cli/build/vendor/bearssl/src/mac/hmac_ct.o new file mode 100644 index 0000000..8f97c89 Binary files /dev/null and b/cli/build/vendor/bearssl/src/mac/hmac_ct.o differ diff --git a/cli/build/vendor/bearssl/src/rand/aesctr_drbg.o b/cli/build/vendor/bearssl/src/rand/aesctr_drbg.o new file mode 100644 index 0000000..fe7243a Binary files /dev/null and b/cli/build/vendor/bearssl/src/rand/aesctr_drbg.o differ diff --git a/cli/build/vendor/bearssl/src/rand/hmac_drbg.o b/cli/build/vendor/bearssl/src/rand/hmac_drbg.o new file mode 100644 index 0000000..301a876 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rand/hmac_drbg.o differ diff --git a/cli/build/vendor/bearssl/src/rand/sysrng.o b/cli/build/vendor/bearssl/src/rand/sysrng.o new file mode 100644 index 0000000..831098c Binary files /dev/null and b/cli/build/vendor/bearssl/src/rand/sysrng.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_keygen.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_keygen.o new file mode 100644 index 0000000..c0eb810 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_keygen.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_modulus.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_modulus.o new file mode 100644 index 0000000..91373c4 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_modulus.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_decrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_decrypt.o new file mode 100644 index 0000000..bccb30b Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_decrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_encrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_encrypt.o new file mode 100644 index 0000000..66c08f6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_oaep_encrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_sign.o new file mode 100644 index 0000000..fe4bb3b Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_vrfy.o new file mode 100644 index 0000000..71c7367 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_pkcs1_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_priv.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_priv.o new file mode 100644 index 0000000..706dd4d Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_priv.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_privexp.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_privexp.o new file mode 100644 index 0000000..a182640 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_privexp.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_pss_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_pss_sign.o new file mode 100644 index 0000000..4fe3f68 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_pss_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_pss_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_pss_vrfy.o new file mode 100644 index 0000000..668487c Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_pss_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_pub.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_pub.o new file mode 100644 index 0000000..894509c Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_pub.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_default_pubexp.o b/cli/build/vendor/bearssl/src/rsa/rsa_default_pubexp.o new file mode 100644 index 0000000..c095702 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_default_pubexp.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_keygen.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_keygen.o new file mode 100644 index 0000000..fb1b15a Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_keygen.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_modulus.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_modulus.o new file mode 100644 index 0000000..def8c4c Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_modulus.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_decrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_decrypt.o new file mode 100644 index 0000000..6885915 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_decrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_encrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_encrypt.o new file mode 100644 index 0000000..039d16f Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_oaep_encrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_sign.o new file mode 100644 index 0000000..f45cc78 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.o new file mode 100644 index 0000000..c66e10f Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_priv.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_priv.o new file mode 100644 index 0000000..5e14774 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_priv.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_privexp.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_privexp.o new file mode 100644 index 0000000..9e54404 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_privexp.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_sign.o new file mode 100644 index 0000000..5bcf8f1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_vrfy.o new file mode 100644 index 0000000..a7740a8 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pss_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_pub.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pub.o new file mode 100644 index 0000000..c9d68bb Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pub.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i15_pubexp.o b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pubexp.o new file mode 100644 index 0000000..31f80d4 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i15_pubexp.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen.o new file mode 100644 index 0000000..14cccd8 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen_inner.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen_inner.o new file mode 100644 index 0000000..e981666 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_keygen_inner.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_modulus.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_modulus.o new file mode 100644 index 0000000..2c71d63 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_modulus.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_decrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_decrypt.o new file mode 100644 index 0000000..53eb495 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_decrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_encrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_encrypt.o new file mode 100644 index 0000000..e11ac7d Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_oaep_encrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_sign.o new file mode 100644 index 0000000..155091a Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.o new file mode 100644 index 0000000..84eaefe Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_priv.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_priv.o new file mode 100644 index 0000000..6fadd84 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_priv.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_privexp.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_privexp.o new file mode 100644 index 0000000..38bf5bd Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_privexp.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_sign.o new file mode 100644 index 0000000..0b137f6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_vrfy.o new file mode 100644 index 0000000..63b17d3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pss_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_pub.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pub.o new file mode 100644 index 0000000..e92d6cb Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pub.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i31_pubexp.o b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pubexp.o new file mode 100644 index 0000000..403ec4f Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i31_pubexp.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_decrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_decrypt.o new file mode 100644 index 0000000..bdb6881 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_decrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_encrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_encrypt.o new file mode 100644 index 0000000..554537f Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_oaep_encrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_sign.o new file mode 100644 index 0000000..f9b9b7d Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.o new file mode 100644 index 0000000..0cdaeab Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_priv.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_priv.o new file mode 100644 index 0000000..991422a Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_priv.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_sign.o new file mode 100644 index 0000000..3b5a96a Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_vrfy.o new file mode 100644 index 0000000..9a46da0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pss_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i32_pub.o b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pub.o new file mode 100644 index 0000000..8b4be3b Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i32_pub.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_keygen.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_keygen.o new file mode 100644 index 0000000..9e0cb61 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_keygen.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_decrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_decrypt.o new file mode 100644 index 0000000..e1d48e3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_decrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_encrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_encrypt.o new file mode 100644 index 0000000..b35c68c Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_oaep_encrypt.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_sign.o new file mode 100644 index 0000000..290d468 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.o new file mode 100644 index 0000000..6324b56 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_priv.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_priv.o new file mode 100644 index 0000000..c9b62dd Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_priv.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_sign.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_sign.o new file mode 100644 index 0000000..87ee5b3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_sign.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_vrfy.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_vrfy.o new file mode 100644 index 0000000..988752a Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pss_vrfy.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_i62_pub.o b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pub.o new file mode 100644 index 0000000..02d0485 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_i62_pub.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_oaep_pad.o b/cli/build/vendor/bearssl/src/rsa/rsa_oaep_pad.o new file mode 100644 index 0000000..17022f3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_oaep_pad.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_oaep_unpad.o b/cli/build/vendor/bearssl/src/rsa/rsa_oaep_unpad.o new file mode 100644 index 0000000..ce19d65 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_oaep_unpad.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_pad.o b/cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_pad.o new file mode 100644 index 0000000..c216eac Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_pad.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_unpad.o b/cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_unpad.o new file mode 100644 index 0000000..a9198c8 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_pkcs1_sig_unpad.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_pad.o b/cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_pad.o new file mode 100644 index 0000000..95089c5 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_pad.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_unpad.o b/cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_unpad.o new file mode 100644 index 0000000..01b9de2 Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_pss_sig_unpad.o differ diff --git a/cli/build/vendor/bearssl/src/rsa/rsa_ssl_decrypt.o b/cli/build/vendor/bearssl/src/rsa/rsa_ssl_decrypt.o new file mode 100644 index 0000000..c05128f Binary files /dev/null and b/cli/build/vendor/bearssl/src/rsa/rsa_ssl_decrypt.o differ diff --git a/cli/build/vendor/bearssl/src/settings.o b/cli/build/vendor/bearssl/src/settings.o new file mode 100644 index 0000000..99b7833 Binary files /dev/null and b/cli/build/vendor/bearssl/src/settings.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/prf.o b/cli/build/vendor/bearssl/src/ssl/prf.o new file mode 100644 index 0000000..eecd342 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/prf.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/prf_md5sha1.o b/cli/build/vendor/bearssl/src/ssl/prf_md5sha1.o new file mode 100644 index 0000000..b6972a3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/prf_md5sha1.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/prf_sha256.o b/cli/build/vendor/bearssl/src/ssl/prf_sha256.o new file mode 100644 index 0000000..7ea4acb Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/prf_sha256.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/prf_sha384.o b/cli/build/vendor/bearssl/src/ssl/prf_sha384.o new file mode 100644 index 0000000..e61581d Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/prf_sha384.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_ec.o b/cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_ec.o new file mode 100644 index 0000000..fc00ab5 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_ec.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_rsa.o b/cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_rsa.o new file mode 100644 index 0000000..1ca024f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_ccert_single_rsa.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_client.o b/cli/build/vendor/bearssl/src/ssl/ssl_client.o new file mode 100644 index 0000000..c9542fe Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_client.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_client_default_rsapub.o b/cli/build/vendor/bearssl/src/ssl/ssl_client_default_rsapub.o new file mode 100644 index 0000000..0ef21f9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_client_default_rsapub.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_client_full.o b/cli/build/vendor/bearssl/src/ssl/ssl_client_full.o new file mode 100644 index 0000000..90f3bb9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_client_full.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine.o new file mode 100644 index 0000000..5770fa9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aescbc.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aescbc.o new file mode 100644 index 0000000..0c965c6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aescbc.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesccm.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesccm.o new file mode 100644 index 0000000..e5f2a68 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesccm.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesgcm.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesgcm.o new file mode 100644 index 0000000..150e2d0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_aesgcm.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_chapol.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_chapol.o new file mode 100644 index 0000000..3b02352 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_chapol.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_descbc.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_descbc.o new file mode 100644 index 0000000..a66301b Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_descbc.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ec.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ec.o new file mode 100644 index 0000000..fc2a5df Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ec.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ecdsa.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ecdsa.o new file mode 100644 index 0000000..a478c16 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_ecdsa.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_rsavrfy.o b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_rsavrfy.o new file mode 100644 index 0000000..f1ead26 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_engine_default_rsavrfy.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_hashes.o b/cli/build/vendor/bearssl/src/ssl/ssl_hashes.o new file mode 100644 index 0000000..d878c1f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_hashes.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_hs_client.o b/cli/build/vendor/bearssl/src/ssl/ssl_hs_client.o new file mode 100644 index 0000000..c9a1946 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_hs_client.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_hs_server.o b/cli/build/vendor/bearssl/src/ssl/ssl_hs_server.o new file mode 100644 index 0000000..8b9f710 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_hs_server.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_io.o b/cli/build/vendor/bearssl/src/ssl/ssl_io.o new file mode 100644 index 0000000..f215faa Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_io.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_keyexport.o b/cli/build/vendor/bearssl/src/ssl/ssl_keyexport.o new file mode 100644 index 0000000..2e9696f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_keyexport.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_lru.o b/cli/build/vendor/bearssl/src/ssl/ssl_lru.o new file mode 100644 index 0000000..7542c1d Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_lru.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_rec_cbc.o b/cli/build/vendor/bearssl/src/ssl/ssl_rec_cbc.o new file mode 100644 index 0000000..f5c76c4 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_rec_cbc.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_rec_ccm.o b/cli/build/vendor/bearssl/src/ssl/ssl_rec_ccm.o new file mode 100644 index 0000000..77a50eb Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_rec_ccm.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_rec_chapol.o b/cli/build/vendor/bearssl/src/ssl/ssl_rec_chapol.o new file mode 100644 index 0000000..5b47779 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_rec_chapol.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_rec_gcm.o b/cli/build/vendor/bearssl/src/ssl/ssl_rec_gcm.o new file mode 100644 index 0000000..d63eeb5 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_rec_gcm.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_scert_single_ec.o b/cli/build/vendor/bearssl/src/ssl/ssl_scert_single_ec.o new file mode 100644 index 0000000..c8f194f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_scert_single_ec.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_scert_single_rsa.o b/cli/build/vendor/bearssl/src/ssl/ssl_scert_single_rsa.o new file mode 100644 index 0000000..3422d7f Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_scert_single_rsa.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server.o b/cli/build/vendor/bearssl/src/ssl/ssl_server.o new file mode 100644 index 0000000..29fbda1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_full_ec.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_full_ec.o new file mode 100644 index 0000000..2ac9b49 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_full_ec.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_full_rsa.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_full_rsa.o new file mode 100644 index 0000000..c6cc34c Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_full_rsa.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_mine2c.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_mine2c.o new file mode 100644 index 0000000..43a2d81 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_mine2c.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_mine2g.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_mine2g.o new file mode 100644 index 0000000..a63d724 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_mine2g.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_minf2c.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_minf2c.o new file mode 100644 index 0000000..217a778 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_minf2c.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_minf2g.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_minf2g.o new file mode 100644 index 0000000..3ebd60d Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_minf2g.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_minr2g.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_minr2g.o new file mode 100644 index 0000000..7aff9a8 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_minr2g.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_minu2g.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_minu2g.o new file mode 100644 index 0000000..d0f81ad Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_minu2g.o differ diff --git a/cli/build/vendor/bearssl/src/ssl/ssl_server_minv2g.o b/cli/build/vendor/bearssl/src/ssl/ssl_server_minv2g.o new file mode 100644 index 0000000..30897b9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/ssl/ssl_server_minv2g.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_big_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/aes_big_cbcdec.o new file mode 100644 index 0000000..7bfd706 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_big_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_big_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/aes_big_cbcenc.o new file mode 100644 index 0000000..7802add Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_big_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_big_ctr.o b/cli/build/vendor/bearssl/src/symcipher/aes_big_ctr.o new file mode 100644 index 0000000..0eba1ce Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_big_ctr.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_big_ctrcbc.o b/cli/build/vendor/bearssl/src/symcipher/aes_big_ctrcbc.o new file mode 100644 index 0000000..45cc5d2 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_big_ctrcbc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_big_dec.o b/cli/build/vendor/bearssl/src/symcipher/aes_big_dec.o new file mode 100644 index 0000000..8a0c7a1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_big_dec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_big_enc.o b/cli/build/vendor/bearssl/src/symcipher/aes_big_enc.o new file mode 100644 index 0000000..9e08b20 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_big_enc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_common.o b/cli/build/vendor/bearssl/src/symcipher/aes_common.o new file mode 100644 index 0000000..fb02958 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_common.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct.o new file mode 100644 index 0000000..7470d68 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct64.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct64.o new file mode 100644 index 0000000..e4ee9a3 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct64.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcdec.o new file mode 100644 index 0000000..8e3aec9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcenc.o new file mode 100644 index 0000000..236230c Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctr.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctr.o new file mode 100644 index 0000000..fdeb9d0 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctr.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctrcbc.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctrcbc.o new file mode 100644 index 0000000..92a8bba Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_ctrcbc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct64_dec.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_dec.o new file mode 100644 index 0000000..dcc7d1f Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_dec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct64_enc.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_enc.o new file mode 100644 index 0000000..ffb624c Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct64_enc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcdec.o new file mode 100644 index 0000000..1ec830c Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcenc.o new file mode 100644 index 0000000..f75ce68 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct_ctr.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct_ctr.o new file mode 100644 index 0000000..cdef65a Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct_ctr.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct_ctrcbc.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct_ctrcbc.o new file mode 100644 index 0000000..c904ad6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct_ctrcbc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct_dec.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct_dec.o new file mode 100644 index 0000000..aa6f36d Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct_dec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_ct_enc.o b/cli/build/vendor/bearssl/src/symcipher/aes_ct_enc.o new file mode 100644 index 0000000..eb68bc9 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_ct_enc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_pwr8.o b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8.o new file mode 100644 index 0000000..875a37e Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcdec.o new file mode 100644 index 0000000..b880376 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcenc.o new file mode 100644 index 0000000..a6dec4c Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctr.o b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctr.o new file mode 100644 index 0000000..ea0724d Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctr.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctrcbc.o b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctrcbc.o new file mode 100644 index 0000000..30ad0f4 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_pwr8_ctrcbc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_small_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/aes_small_cbcdec.o new file mode 100644 index 0000000..daa032f Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_small_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_small_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/aes_small_cbcenc.o new file mode 100644 index 0000000..9a0e3a6 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_small_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_small_ctr.o b/cli/build/vendor/bearssl/src/symcipher/aes_small_ctr.o new file mode 100644 index 0000000..44dcbde Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_small_ctr.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_small_ctrcbc.o b/cli/build/vendor/bearssl/src/symcipher/aes_small_ctrcbc.o new file mode 100644 index 0000000..dc27787 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_small_ctrcbc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_small_dec.o b/cli/build/vendor/bearssl/src/symcipher/aes_small_dec.o new file mode 100644 index 0000000..d892900 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_small_dec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_small_enc.o b/cli/build/vendor/bearssl/src/symcipher/aes_small_enc.o new file mode 100644 index 0000000..c16fd1b Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_small_enc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_x86ni.o b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni.o new file mode 100644 index 0000000..db4918b Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcdec.o new file mode 100644 index 0000000..5db5adf Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcenc.o new file mode 100644 index 0000000..2264104 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctr.o b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctr.o new file mode 100644 index 0000000..499b2e8 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctr.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctrcbc.o b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctrcbc.o new file mode 100644 index 0000000..e0c2fbe Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/aes_x86ni_ctrcbc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/chacha20_ct.o b/cli/build/vendor/bearssl/src/symcipher/chacha20_ct.o new file mode 100644 index 0000000..ec36860 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/chacha20_ct.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/chacha20_sse2.o b/cli/build/vendor/bearssl/src/symcipher/chacha20_sse2.o new file mode 100644 index 0000000..88534f1 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/chacha20_sse2.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/des_ct.o b/cli/build/vendor/bearssl/src/symcipher/des_ct.o new file mode 100644 index 0000000..41939f7 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/des_ct.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/des_ct_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/des_ct_cbcdec.o new file mode 100644 index 0000000..feb8df2 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/des_ct_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/des_ct_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/des_ct_cbcenc.o new file mode 100644 index 0000000..2f7a494 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/des_ct_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/des_support.o b/cli/build/vendor/bearssl/src/symcipher/des_support.o new file mode 100644 index 0000000..3fc8bda Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/des_support.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/des_tab.o b/cli/build/vendor/bearssl/src/symcipher/des_tab.o new file mode 100644 index 0000000..fcfa80e Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/des_tab.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/des_tab_cbcdec.o b/cli/build/vendor/bearssl/src/symcipher/des_tab_cbcdec.o new file mode 100644 index 0000000..792c143 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/des_tab_cbcdec.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/des_tab_cbcenc.o b/cli/build/vendor/bearssl/src/symcipher/des_tab_cbcenc.o new file mode 100644 index 0000000..fcafd0d Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/des_tab_cbcenc.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul.o b/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul.o new file mode 100644 index 0000000..8f9bcf7 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul32.o b/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul32.o new file mode 100644 index 0000000..2147cad Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmul32.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmulq.o b/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmulq.o new file mode 100644 index 0000000..11568af Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/poly1305_ctmulq.o differ diff --git a/cli/build/vendor/bearssl/src/symcipher/poly1305_i15.o b/cli/build/vendor/bearssl/src/symcipher/poly1305_i15.o new file mode 100644 index 0000000..1306b35 Binary files /dev/null and b/cli/build/vendor/bearssl/src/symcipher/poly1305_i15.o differ diff --git a/cli/build/vendor/bearssl/src/x509/asn1enc.o b/cli/build/vendor/bearssl/src/x509/asn1enc.o new file mode 100644 index 0000000..335d162 Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/asn1enc.o differ diff --git a/cli/build/vendor/bearssl/src/x509/encode_ec_pk8der.o b/cli/build/vendor/bearssl/src/x509/encode_ec_pk8der.o new file mode 100644 index 0000000..4e77650 Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/encode_ec_pk8der.o differ diff --git a/cli/build/vendor/bearssl/src/x509/encode_ec_rawder.o b/cli/build/vendor/bearssl/src/x509/encode_ec_rawder.o new file mode 100644 index 0000000..1696a1b Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/encode_ec_rawder.o differ diff --git a/cli/build/vendor/bearssl/src/x509/encode_rsa_pk8der.o b/cli/build/vendor/bearssl/src/x509/encode_rsa_pk8der.o new file mode 100644 index 0000000..83bc9ba Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/encode_rsa_pk8der.o differ diff --git a/cli/build/vendor/bearssl/src/x509/encode_rsa_rawder.o b/cli/build/vendor/bearssl/src/x509/encode_rsa_rawder.o new file mode 100644 index 0000000..d364e70 Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/encode_rsa_rawder.o differ diff --git a/cli/build/vendor/bearssl/src/x509/skey_decoder.o b/cli/build/vendor/bearssl/src/x509/skey_decoder.o new file mode 100644 index 0000000..04bf5cc Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/skey_decoder.o differ diff --git a/cli/build/vendor/bearssl/src/x509/x509_decoder.o b/cli/build/vendor/bearssl/src/x509/x509_decoder.o new file mode 100644 index 0000000..05797dc Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/x509_decoder.o differ diff --git a/cli/build/vendor/bearssl/src/x509/x509_knownkey.o b/cli/build/vendor/bearssl/src/x509/x509_knownkey.o new file mode 100644 index 0000000..ad1f175 Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/x509_knownkey.o differ diff --git a/cli/build/vendor/bearssl/src/x509/x509_minimal.o b/cli/build/vendor/bearssl/src/x509/x509_minimal.o new file mode 100644 index 0000000..9ae0923 Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/x509_minimal.o differ diff --git a/cli/build/vendor/bearssl/src/x509/x509_minimal_full.o b/cli/build/vendor/bearssl/src/x509/x509_minimal_full.o new file mode 100644 index 0000000..eb7cc2c Binary files /dev/null and b/cli/build/vendor/bearssl/src/x509/x509_minimal_full.o differ diff --git a/cli/build/vendor/cjson/cJSON.o b/cli/build/vendor/cjson/cJSON.o new file mode 100644 index 0000000..7de17c1 Binary files /dev/null and b/cli/build/vendor/cjson/cJSON.o differ diff --git a/cli/build/vendor/quickjs/cutils.o b/cli/build/vendor/quickjs/cutils.o new file mode 100644 index 0000000..eaa5f69 Binary files /dev/null and b/cli/build/vendor/quickjs/cutils.o differ diff --git a/cli/build/vendor/quickjs/dtoa.o b/cli/build/vendor/quickjs/dtoa.o new file mode 100644 index 0000000..9e701f2 Binary files /dev/null and b/cli/build/vendor/quickjs/dtoa.o differ diff --git a/cli/build/vendor/quickjs/libregexp.o b/cli/build/vendor/quickjs/libregexp.o new file mode 100644 index 0000000..e07a324 Binary files /dev/null and b/cli/build/vendor/quickjs/libregexp.o differ diff --git a/cli/build/vendor/quickjs/libunicode.o b/cli/build/vendor/quickjs/libunicode.o new file mode 100644 index 0000000..247a394 Binary files /dev/null and b/cli/build/vendor/quickjs/libunicode.o differ diff --git a/cli/build/vendor/quickjs/quickjs-libc.o b/cli/build/vendor/quickjs/quickjs-libc.o new file mode 100644 index 0000000..17c2bf8 Binary files /dev/null and b/cli/build/vendor/quickjs/quickjs-libc.o differ diff --git a/cli/build/vendor/quickjs/quickjs.o b/cli/build/vendor/quickjs/quickjs.o new file mode 100644 index 0000000..e71b22a Binary files /dev/null and b/cli/build/vendor/quickjs/quickjs.o differ diff --git a/cli/src/http.c b/cli/src/http.c new file mode 100644 index 0000000..e9c7264 --- /dev/null +++ b/cli/src/http.c @@ -0,0 +1,342 @@ +/* + * vault1984 CLI — HTTP/HTTPS client using BearSSL + * + * Supports both plain HTTP and HTTPS (TLS via BearSSL). + * URL scheme determines protocol: http:// = plain, https:// = TLS. + * + * Trust anchors: TODO — currently no certificate validation. + */ + +#define _POSIX_C_SOURCE 200809L + +#include "http.h" + +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#pragma comment(lib, "ws2_32.lib") +#define SOCKCLOSE(s) closesocket(s) +typedef int socklen_t; +#else +#include +#include +#include +#include +#define SOCKET int +#define INVALID_SOCKET (-1) +#define SOCKCLOSE(s) close(s) +#endif + +#include "bearssl.h" + +/* --- socket connect --- */ + +static SOCKET tcp_connect(const char *host, const char *port) { +#ifdef _WIN32 + WSADATA wsa; + WSAStartup(MAKEWORD(2, 2), &wsa); +#endif + + struct addrinfo hints, *res, *p; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + int err = getaddrinfo(host, port, &hints, &res); + if (err != 0) { + fprintf(stderr, "error: DNS lookup failed for %s: %s\n", host, gai_strerror(err)); + return INVALID_SOCKET; + } + + SOCKET fd = INVALID_SOCKET; + for (p = res; p; p = p->ai_next) { + fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (fd == INVALID_SOCKET) continue; + if (connect(fd, p->ai_addr, p->ai_addrlen) == 0) break; + SOCKCLOSE(fd); + fd = INVALID_SOCKET; + } + freeaddrinfo(res); + + if (fd == INVALID_SOCKET) { + fprintf(stderr, "error: cannot connect to %s:%s\n", host, port); + } + return fd; +} + +/* --- BearSSL I/O callbacks --- */ + +static int sock_read(void *ctx, unsigned char *buf, size_t len) { + SOCKET fd = *(SOCKET *)ctx; + int n; + for (;;) { + n = (int)recv(fd, (char *)buf, (int)len, 0); + if (n <= 0) { + if (n < 0 && errno == EINTR) continue; + return -1; + } + return n; + } +} + +static int sock_write(void *ctx, const unsigned char *buf, size_t len) { + SOCKET fd = *(SOCKET *)ctx; + int n; + for (;;) { + n = (int)send(fd, (const char *)buf, (int)len, 0); + if (n <= 0) { + if (n < 0 && errno == EINTR) continue; + return -1; + } + return n; + } +} + +/* --- plain socket send/recv wrappers --- */ + +static int plain_send_all(SOCKET fd, const char *data, size_t len) { + size_t sent = 0; + while (sent < len) { + int n = (int)send(fd, data + sent, (int)(len - sent), 0); + if (n <= 0) { + if (n < 0 && errno == EINTR) continue; + return -1; + } + sent += (size_t)n; + } + return 0; +} + +static int plain_recv_all(SOCKET fd, char **out_buf, size_t *out_len) { + size_t cap = 8192; + size_t len = 0; + char *buf = malloc(cap); + if (!buf) return -1; + + for (;;) { + if (len + 1024 > cap) { + cap *= 2; + char *tmp = realloc(buf, cap); + if (!tmp) { free(buf); return -1; } + buf = tmp; + } + int n = (int)recv(fd, buf + len, (int)(cap - len - 1), 0); + if (n <= 0) break; + len += (size_t)n; + } + buf[len] = '\0'; + *out_buf = buf; + *out_len = len; + return 0; +} + +/* --- URL parsing --- */ + +struct parsed_url { + char host[256]; + char port[8]; + char path[1024]; + int use_tls; +}; + +static int parse_url(const char *url, struct parsed_url *out) { + memset(out, 0, sizeof(*out)); + + if (strncmp(url, "https://", 8) == 0) { + out->use_tls = 1; + url += 8; + } else if (strncmp(url, "http://", 7) == 0) { + out->use_tls = 0; + url += 7; + } else { + fprintf(stderr, "error: URL must start with http:// or https://\n"); + return -1; + } + + /* host[:port]/path */ + const char *slash = strchr(url, '/'); + const char *colon = strchr(url, ':'); + + if (colon && (!slash || colon < slash)) { + size_t hlen = (size_t)(colon - url); + if (hlen >= sizeof(out->host)) return -1; + memcpy(out->host, url, hlen); + out->host[hlen] = '\0'; + + colon++; + const char *pend = slash ? slash : (url + strlen(url)); + size_t plen = (size_t)(pend - colon); + if (plen >= sizeof(out->port)) return -1; + memcpy(out->port, colon, plen); + out->port[plen] = '\0'; + } else { + const char *hend = slash ? slash : (url + strlen(url)); + size_t hlen = (size_t)(hend - url); + if (hlen >= sizeof(out->host)) return -1; + memcpy(out->host, url, hlen); + out->host[hlen] = '\0'; + strcpy(out->port, out->use_tls ? "443" : "80"); + } + + if (slash) { + snprintf(out->path, sizeof(out->path), "%s", slash); + } else { + strcpy(out->path, "/"); + } + + return 0; +} + +/* --- parse HTTP response --- */ + +static int parse_response(char *resp_buf, size_t resp_len, struct v84_response *resp) { + if (resp_len < 12 || strncmp(resp_buf, "HTTP/", 5) != 0) { + fprintf(stderr, "error: invalid HTTP response\n"); + free(resp_buf); + return -1; + } + + const char *sp = strchr(resp_buf, ' '); + if (!sp) { free(resp_buf); return -1; } + resp->status = atoi(sp + 1); + + const char *body = strstr(resp_buf, "\r\n\r\n"); + if (body) { + body += 4; + resp->body_len = resp_len - (size_t)(body - resp_buf); + resp->body = malloc(resp->body_len + 1); + if (resp->body) { + memcpy(resp->body, body, resp->body_len); + resp->body[resp->body_len] = '\0'; + } + } else { + resp->body = malloc(1); + if (resp->body) resp->body[0] = '\0'; + resp->body_len = 0; + } + + free(resp_buf); + return 0; +} + +/* --- HTTP GET (plain) --- */ + +static int http_get_plain(const struct parsed_url *pu, const char *bearer_token, + struct v84_response *resp) { + SOCKET fd = tcp_connect(pu->host, pu->port); + if (fd == INVALID_SOCKET) return -1; + + char request[2048]; + int reqlen = snprintf(request, sizeof(request), + "GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "Authorization: Bearer %s\r\n" + "Connection: close\r\n" + "Accept: application/json\r\n" + "\r\n", + pu->path, pu->host, bearer_token); + + if (plain_send_all(fd, request, (size_t)reqlen) != 0) { + fprintf(stderr, "error: send failed\n"); + SOCKCLOSE(fd); + return -1; + } + + char *resp_buf = NULL; + size_t resp_len = 0; + if (plain_recv_all(fd, &resp_buf, &resp_len) != 0) { + fprintf(stderr, "error: recv failed\n"); + SOCKCLOSE(fd); + return -1; + } + + SOCKCLOSE(fd); + return parse_response(resp_buf, resp_len, resp); +} + +/* --- HTTPS GET (BearSSL TLS) --- */ + +static int http_get_tls(const struct parsed_url *pu, const char *bearer_token, + struct v84_response *resp) { + SOCKET fd = tcp_connect(pu->host, pu->port); + if (fd == INVALID_SOCKET) return -1; + + br_ssl_client_context sc; + br_x509_minimal_context xc; + unsigned char iobuf[BR_SSL_BUFSIZE_BIDI]; + + /* + * TODO: load system CA bundle for production certificate validation. + * For now: no trust anchors = no validation. + */ + br_x509_minimal_init(&xc, &br_sha256_vtable, NULL, 0); + br_x509_minimal_set_rsa(&xc, &br_rsa_i31_pkcs1_vrfy); + br_x509_minimal_set_ecdsa(&xc, &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); + + br_ssl_client_init_full(&sc, &xc, NULL, 0); + br_ssl_engine_set_buffer(&sc.eng, iobuf, sizeof(iobuf), 1); + br_ssl_client_reset(&sc, pu->host, 0); + + br_sslio_context ioc; + br_sslio_init(&ioc, &sc.eng, sock_read, &fd, sock_write, &fd); + + char request[2048]; + int reqlen = snprintf(request, sizeof(request), + "GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "Authorization: Bearer %s\r\n" + "Connection: close\r\n" + "Accept: application/json\r\n" + "\r\n", + pu->path, pu->host, bearer_token); + + if (br_sslio_write_all(&ioc, request, (size_t)reqlen) != 0) { + fprintf(stderr, "error: TLS write failed\n"); + int err = br_ssl_engine_last_error(&sc.eng); + if (err) fprintf(stderr, " BearSSL error: %d\n", err); + SOCKCLOSE(fd); + return -1; + } + br_sslio_flush(&ioc); + + size_t resp_cap = 8192; + size_t resp_len = 0; + char *resp_buf = malloc(resp_cap); + if (!resp_buf) { SOCKCLOSE(fd); return -1; } + + for (;;) { + if (resp_len + 1024 > resp_cap) { + resp_cap *= 2; + char *tmp = realloc(resp_buf, resp_cap); + if (!tmp) { free(resp_buf); SOCKCLOSE(fd); return -1; } + resp_buf = tmp; + } + int n = br_sslio_read(&ioc, resp_buf + resp_len, resp_cap - resp_len - 1); + if (n <= 0) break; + resp_len += (size_t)n; + } + resp_buf[resp_len] = '\0'; + + SOCKCLOSE(fd); + return parse_response(resp_buf, resp_len, resp); +} + +/* --- public API --- */ + +int http_get(const char *url, const char *bearer_token, struct v84_response *resp) { + memset(resp, 0, sizeof(*resp)); + + struct parsed_url pu; + if (parse_url(url, &pu) != 0) return -1; + + if (pu.use_tls) { + return http_get_tls(&pu, bearer_token, resp); + } else { + return http_get_plain(&pu, bearer_token, resp); + } +} diff --git a/cli/src/http.h b/cli/src/http.h new file mode 100644 index 0000000..ef8ff1e --- /dev/null +++ b/cli/src/http.h @@ -0,0 +1,19 @@ +/* + * vault1984 CLI — HTTPS client (BearSSL) + */ + +#ifndef V84_HTTP_H +#define V84_HTTP_H + +#include + +struct v84_response { + int status; /* HTTP status code */ + char *body; /* response body (malloc'd, caller frees) */ + size_t body_len; +}; + +/* Perform HTTPS GET with Bearer auth. Returns 0 on success, -1 on error. */ +int http_get(const char *url, const char *bearer_token, struct v84_response *resp); + +#endif diff --git a/cli/src/jsbridge.c b/cli/src/jsbridge.c new file mode 100644 index 0000000..850d5ea --- /dev/null +++ b/cli/src/jsbridge.c @@ -0,0 +1,593 @@ +/* + * vault1984 CLI — QuickJS bridge to BearSSL + * + * Registers native functions into the QuickJS runtime so that + * crypto/crypto.js and crypto/totp.js can call BearSSL primitives. + * + * Native functions exposed to JS: + * native_aes_gcm_encrypt(key, plaintext) → Uint8Array (nonce || ct || tag) + * native_aes_gcm_decrypt(key, iv, ct) → Uint8Array (plaintext) + * native_hkdf_sha256(ikm, salt, info, len) → Uint8Array + * native_hmac_sha1(key, data) → Uint8Array + * native_base64_encode(bytes) → string + * native_base64_decode(string) → Uint8Array + * native_encode_utf8(string) → Uint8Array + * native_decode_utf8(bytes) → string + * native_random_bytes(n) → Uint8Array + */ + +#define _POSIX_C_SOURCE 200809L + +#include "jsbridge.h" +#include "util.h" + +#include +#include +#include + +#include "quickjs.h" +#include "bearssl.h" + +static JSRuntime *rt = NULL; +static JSContext *ctx = NULL; + +/* --- helper: JS Uint8Array ↔ C buffer --- */ + +static int js_get_uint8array(JSContext *ctx, JSValueConst val, + uint8_t **out, size_t *out_len) { + size_t offset, len; + size_t bpp; + JSValue buf = JS_GetTypedArrayBuffer(ctx, val, &offset, &len, &bpp); + if (JS_IsException(buf)) return -1; + + size_t buf_size; + uint8_t *ptr = JS_GetArrayBuffer(ctx, &buf_size, buf); + JS_FreeValue(ctx, buf); + if (!ptr) return -1; + + *out = ptr + offset; + *out_len = len; + return 0; +} + +static JSValue js_new_uint8array(JSContext *ctx, const uint8_t *data, size_t len) { + JSValue ab = JS_NewArrayBufferCopy(ctx, data, len); + if (JS_IsException(ab)) return ab; + + JSValue global = JS_GetGlobalObject(ctx); + JSValue u8ctor = JS_GetPropertyStr(ctx, global, "Uint8Array"); + JSValue result = JS_CallConstructor(ctx, u8ctor, 1, &ab); + JS_FreeValue(ctx, u8ctor); + JS_FreeValue(ctx, global); + JS_FreeValue(ctx, ab); + return result; +} + +/* --- native_random_bytes(n) --- */ + +static JSValue js_random_bytes(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + int n; + if (JS_ToInt32(ctx, &n, argv[0]) || n <= 0 || n > 4096) + return JS_ThrowRangeError(ctx, "invalid length"); + + uint8_t *buf = malloc((size_t)n); + br_hmac_drbg_context drbg; + br_hmac_drbg_init(&drbg, &br_sha256_vtable, "vault1984-seed", 14); + + /* Seed with system RNG */ + uint8_t seed[32]; + br_prng_seeder seeder = br_prng_seeder_system(NULL); + if (seeder) { + seeder(&drbg.vtable); + } + br_hmac_drbg_generate(&drbg, buf, (size_t)n); + + JSValue result = js_new_uint8array(ctx, buf, (size_t)n); + free(buf); + return result; +} + +/* --- native_aes_gcm_encrypt(key, plaintext) → nonce(12) || ciphertext || tag(16) --- */ + +static JSValue js_aes_gcm_encrypt(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + uint8_t *key, *pt; + size_t key_len, pt_len; + + if (js_get_uint8array(ctx, argv[0], &key, &key_len) != 0) + return JS_ThrowTypeError(ctx, "key must be Uint8Array"); + if (js_get_uint8array(ctx, argv[1], &pt, &pt_len) != 0) + return JS_ThrowTypeError(ctx, "plaintext must be Uint8Array"); + if (key_len != 16 && key_len != 32) + return JS_ThrowRangeError(ctx, "key must be 16 or 32 bytes"); + + /* Generate random 12-byte nonce */ + uint8_t nonce[12]; + br_hmac_drbg_context drbg; + br_hmac_drbg_init(&drbg, &br_sha256_vtable, "vault1984-nonce", 15); + br_prng_seeder seeder = br_prng_seeder_system(NULL); + if (seeder) seeder(&drbg.vtable); + br_hmac_drbg_generate(&drbg, nonce, 12); + + /* AES-GCM encrypt */ + size_t out_len = 12 + pt_len + 16; /* nonce + ciphertext + tag */ + uint8_t *out = malloc(out_len); + memcpy(out, nonce, 12); + memcpy(out + 12, pt, pt_len); + + br_aes_ct64_ctr_keys aes_ctx; + br_aes_ct64_ctr_init(&aes_ctx, key, key_len); + + br_gcm_context gcm; + br_gcm_init(&gcm, &aes_ctx.vtable, br_ghash_ctmul64); + br_gcm_reset(&gcm, nonce, 12); + br_gcm_flip(&gcm); + br_gcm_run(&gcm, 1, out + 12, pt_len); /* encrypt in place */ + br_gcm_get_tag(&gcm, out + 12 + pt_len); /* append 16-byte tag */ + + JSValue result = js_new_uint8array(ctx, out, out_len); + free(out); + return result; +} + +/* --- native_aes_gcm_decrypt(key, iv, ct_with_tag) → plaintext --- */ + +static JSValue js_aes_gcm_decrypt(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + uint8_t *key, *iv, *ct; + size_t key_len, iv_len, ct_len; + + if (js_get_uint8array(ctx, argv[0], &key, &key_len) != 0) + return JS_ThrowTypeError(ctx, "key must be Uint8Array"); + if (js_get_uint8array(ctx, argv[1], &iv, &iv_len) != 0) + return JS_ThrowTypeError(ctx, "iv must be Uint8Array"); + if (js_get_uint8array(ctx, argv[2], &ct, &ct_len) != 0) + return JS_ThrowTypeError(ctx, "ciphertext must be Uint8Array"); + + if (key_len != 16 && key_len != 32) + return JS_ThrowRangeError(ctx, "key must be 16 or 32 bytes"); + if (iv_len != 12) + return JS_ThrowRangeError(ctx, "iv must be 12 bytes"); + if (ct_len < 16) + return JS_ThrowRangeError(ctx, "ciphertext too short (need tag)"); + + size_t pt_len = ct_len - 16; + uint8_t *buf = malloc(ct_len); + memcpy(buf, ct, ct_len); + + br_aes_ct64_ctr_keys aes_ctx; + br_aes_ct64_ctr_init(&aes_ctx, key, key_len); + + br_gcm_context gcm; + br_gcm_init(&gcm, &aes_ctx.vtable, br_ghash_ctmul64); + br_gcm_reset(&gcm, iv, 12); + br_gcm_flip(&gcm); + br_gcm_run(&gcm, 0, buf, pt_len); /* decrypt in place */ + + if (!br_gcm_check_tag(&gcm, buf + pt_len)) { + free(buf); + return JS_ThrowInternalError(ctx, "AES-GCM tag verification failed"); + } + + JSValue result = js_new_uint8array(ctx, buf, pt_len); + free(buf); + return result; +} + +/* --- native_aes_gcm_decrypt_blob(key, nonce_ct_tag) → plaintext --- */ + +static JSValue js_aes_gcm_decrypt_blob(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + uint8_t *key, *data; + size_t key_len, data_len; + + if (js_get_uint8array(ctx, argv[0], &key, &key_len) != 0) + return JS_ThrowTypeError(ctx, "key must be Uint8Array"); + if (js_get_uint8array(ctx, argv[1], &data, &data_len) != 0) + return JS_ThrowTypeError(ctx, "data must be Uint8Array"); + + if (key_len != 16 && key_len != 32) + return JS_ThrowRangeError(ctx, "key must be 16 or 32 bytes"); + if (data_len < 28) /* 12 nonce + 0 pt + 16 tag minimum */ + return JS_ThrowRangeError(ctx, "data too short"); + + uint8_t *iv = data; + uint8_t *ct = data + 12; + size_t ct_len = data_len - 12; + size_t pt_len = ct_len - 16; + + uint8_t *buf = malloc(ct_len); + memcpy(buf, ct, ct_len); + + br_aes_ct64_ctr_keys aes_ctx; + br_aes_ct64_ctr_init(&aes_ctx, key, key_len); + + br_gcm_context gcm; + br_gcm_init(&gcm, &aes_ctx.vtable, br_ghash_ctmul64); + br_gcm_reset(&gcm, iv, 12); + br_gcm_flip(&gcm); + br_gcm_run(&gcm, 0, buf, pt_len); + + if (!br_gcm_check_tag(&gcm, buf + pt_len)) { + free(buf); + return JS_ThrowInternalError(ctx, "AES-GCM tag verification failed"); + } + + JSValue result = js_new_uint8array(ctx, buf, pt_len); + free(buf); + return result; +} + +/* --- native_hkdf_sha256(ikm, salt, info, length) → Uint8Array --- */ + +static JSValue js_hkdf_sha256(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + uint8_t *ikm, *info; + size_t ikm_len, info_len; + + if (js_get_uint8array(ctx, argv[0], &ikm, &ikm_len) != 0) + return JS_ThrowTypeError(ctx, "ikm must be Uint8Array"); + + /* salt can be null */ + uint8_t *salt = NULL; + size_t salt_len = 0; + if (!JS_IsNull(argv[1]) && !JS_IsUndefined(argv[1])) { + if (js_get_uint8array(ctx, argv[1], &salt, &salt_len) != 0) + return JS_ThrowTypeError(ctx, "salt must be Uint8Array or null"); + } + + if (js_get_uint8array(ctx, argv[2], &info, &info_len) != 0) + return JS_ThrowTypeError(ctx, "info must be Uint8Array"); + + int length; + if (JS_ToInt32(ctx, &length, argv[3]) || length <= 0 || length > 255 * 32) + return JS_ThrowRangeError(ctx, "invalid output length"); + + /* BearSSL HKDF */ + br_hkdf_context hkdf; + br_hkdf_init(&hkdf, &br_sha256_vtable, salt, salt_len); + br_hkdf_inject(&hkdf, ikm, ikm_len); + br_hkdf_flip(&hkdf); + + uint8_t *out = malloc((size_t)length); + br_hkdf_produce(&hkdf, info, info_len, out, (size_t)length); + + JSValue result = js_new_uint8array(ctx, out, (size_t)length); + free(out); + return result; +} + +/* --- native_hmac_sha1(key, data) → Uint8Array(20) --- */ + +static JSValue js_hmac_sha1(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + uint8_t *key, *data; + size_t key_len, data_len; + + if (js_get_uint8array(ctx, argv[0], &key, &key_len) != 0) + return JS_ThrowTypeError(ctx, "key must be Uint8Array"); + if (js_get_uint8array(ctx, argv[1], &data, &data_len) != 0) + return JS_ThrowTypeError(ctx, "data must be Uint8Array"); + + br_hmac_key_context kc; + br_hmac_key_init(&kc, &br_sha1_vtable, key, key_len); + + br_hmac_context hmac; + br_hmac_init(&hmac, &kc, 0); /* 0 = full output length (20 for SHA-1) */ + br_hmac_update(&hmac, data, data_len); + + uint8_t out[20]; + br_hmac_out(&hmac, out); + + return js_new_uint8array(ctx, out, 20); +} + +/* --- native_base64_encode(Uint8Array) → string --- */ + +static JSValue js_base64_encode(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + uint8_t *data; + size_t len; + if (js_get_uint8array(ctx, argv[0], &data, &len) != 0) + return JS_ThrowTypeError(ctx, "argument must be Uint8Array"); + + size_t out_len = ((len + 2) / 3) * 4 + 1; + char *out = malloc(out_len); + base64_encode(data, len, out, out_len); + + JSValue result = JS_NewString(ctx, out); + free(out); + return result; +} + +/* --- native_base64_decode(string) → Uint8Array --- */ + +static JSValue js_base64_decode_fn(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + const char *str = JS_ToCString(ctx, argv[0]); + if (!str) return JS_ThrowTypeError(ctx, "argument must be string"); + + size_t max_len = strlen(str); + uint8_t *out = malloc(max_len); + size_t out_len = 0; + + if (base64_decode(str, out, max_len, &out_len) != 0) { + JS_FreeCString(ctx, str); + free(out); + return JS_ThrowInternalError(ctx, "base64 decode failed"); + } + + JS_FreeCString(ctx, str); + JSValue result = js_new_uint8array(ctx, out, out_len); + free(out); + return result; +} + +/* --- native_encode_utf8(string) → Uint8Array --- */ + +static JSValue js_encode_utf8(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + size_t len; + const char *str = JS_ToCStringLen(ctx, &len, argv[0]); + if (!str) return JS_ThrowTypeError(ctx, "argument must be string"); + + JSValue result = js_new_uint8array(ctx, (const uint8_t *)str, len); + JS_FreeCString(ctx, str); + return result; +} + +/* --- native_decode_utf8(Uint8Array) → string --- */ + +static JSValue js_decode_utf8(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) { + uint8_t *data; + size_t len; + if (js_get_uint8array(ctx, argv[0], &data, &len) != 0) + return JS_ThrowTypeError(ctx, "argument must be Uint8Array"); + + return JS_NewStringLen(ctx, (const char *)data, len); +} + +/* --- load a JS file from disk --- */ + +static int load_js_file(JSContext *ctx, const char *filename) { + FILE *f = fopen(filename, "rb"); + if (!f) { + /* Try common relative paths */ + static const char *prefixes[] = { + "../", /* running from cli/ */ + "./", /* running from repo root */ + "../../", /* running from cli/build/ */ + NULL + }; + char alt[1024]; + for (int i = 0; prefixes[i] && !f; i++) { + snprintf(alt, sizeof(alt), "%s%s", prefixes[i], filename); + f = fopen(alt, "rb"); + } + } + if (!f) { + fprintf(stderr, "error: cannot open %s\n", filename); + return -1; + } + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + + char *buf = malloc((size_t)size + 1); + fread(buf, 1, (size_t)size, f); + fclose(f); + buf[size] = '\0'; + + JSValue val = JS_Eval(ctx, buf, (size_t)size, filename, JS_EVAL_TYPE_GLOBAL); + free(buf); + + if (JS_IsException(val)) { + JSValue exc = JS_GetException(ctx); + const char *msg = JS_ToCString(ctx, exc); + fprintf(stderr, "error: JS eval %s: %s\n", filename, msg ? msg : "unknown"); + if (msg) JS_FreeCString(ctx, msg); + JS_FreeValue(ctx, exc); + JS_FreeValue(ctx, val); + return -1; + } + + JS_FreeValue(ctx, val); + return 0; +} + +/* --- public API --- */ + +int jsbridge_init(void) { + rt = JS_NewRuntime(); + if (!rt) { + fprintf(stderr, "error: cannot create JS runtime\n"); + return -1; + } + + ctx = JS_NewContext(rt); + if (!ctx) { + fprintf(stderr, "error: cannot create JS context\n"); + JS_FreeRuntime(rt); + rt = NULL; + return -1; + } + + /* Register native functions */ + JSValue global = JS_GetGlobalObject(ctx); + + #define REG(name, func, nargs) \ + JS_SetPropertyStr(ctx, global, name, \ + JS_NewCFunction(ctx, func, name, nargs)) + + REG("native_aes_gcm_encrypt", js_aes_gcm_encrypt, 2); + REG("native_aes_gcm_decrypt", js_aes_gcm_decrypt, 3); + REG("native_aes_gcm_decrypt_blob", js_aes_gcm_decrypt_blob, 2); + REG("native_hkdf_sha256", js_hkdf_sha256, 4); + REG("native_hmac_sha1", js_hmac_sha1, 2); + REG("native_base64_encode", js_base64_encode, 1); + REG("native_base64_decode", js_base64_decode_fn, 1); + REG("native_encode_utf8", js_encode_utf8, 1); + REG("native_decode_utf8", js_decode_utf8, 1); + REG("native_random_bytes", js_random_bytes, 1); + + #undef REG + + JS_FreeValue(ctx, global); + + /* Load shared crypto modules */ + if (load_js_file(ctx, "crypto/crypto.js") != 0) return -1; + if (load_js_file(ctx, "crypto/totp.js") != 0) return -1; + + return 0; +} + +void jsbridge_cleanup(void) { + if (ctx) { JS_FreeContext(ctx); ctx = NULL; } + if (rt) { JS_FreeRuntime(rt); rt = NULL; } +} + +char *jsbridge_totp(const char *seed_b32) { + if (!ctx) return NULL; + + JSValue global = JS_GetGlobalObject(ctx); + JSValue v84 = JS_GetPropertyStr(ctx, global, "vault1984"); + JSValue totp_obj = JS_GetPropertyStr(ctx, v84, "totp"); + JSValue fn = JS_GetPropertyStr(ctx, totp_obj, "generate_totp"); + + JSValue args[1] = { JS_NewString(ctx, seed_b32) }; + JSValue result = JS_Call(ctx, fn, JS_UNDEFINED, 1, args); + + char *out = NULL; + if (!JS_IsException(result)) { + const char *str = JS_ToCString(ctx, result); + if (str) { + out = strdup(str); + JS_FreeCString(ctx, str); + } + } else { + JSValue exc = JS_GetException(ctx); + const char *msg = JS_ToCString(ctx, exc); + fprintf(stderr, "error: totp: %s\n", msg ? msg : "unknown"); + if (msg) JS_FreeCString(ctx, msg); + JS_FreeValue(ctx, exc); + } + + JS_FreeValue(ctx, args[0]); + JS_FreeValue(ctx, result); + JS_FreeValue(ctx, fn); + JS_FreeValue(ctx, totp_obj); + JS_FreeValue(ctx, v84); + JS_FreeValue(ctx, global); + return out; +} + +char *jsbridge_eval(const char *code) { + if (!ctx) return NULL; + JSValue val = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); + if (JS_IsException(val)) { + JSValue exc = JS_GetException(ctx); + const char *msg = JS_ToCString(ctx, exc); + fprintf(stderr, "JS error: %s\n", msg ? msg : "unknown"); + if (msg) JS_FreeCString(ctx, msg); + JS_FreeValue(ctx, exc); + JS_FreeValue(ctx, val); + return NULL; + } + const char *str = JS_ToCString(ctx, val); + char *out = str ? strdup(str) : NULL; + if (str) JS_FreeCString(ctx, str); + JS_FreeValue(ctx, val); + return out; +} + +char *jsbridge_l2_encrypt(const unsigned char *l2_key, size_t key_len, + const char *entry_id, const char *field_label, + const char *plaintext) { + if (!ctx) return NULL; + + /* Call vault1984.crypto.l2_encrypt_field(key, entry_id, label, plaintext) */ + JSValue global = JS_GetGlobalObject(ctx); + JSValue v84 = JS_GetPropertyStr(ctx, global, "vault1984"); + JSValue crypto_obj = JS_GetPropertyStr(ctx, v84, "crypto"); + JSValue fn = JS_GetPropertyStr(ctx, crypto_obj, "l2_encrypt_field"); + + JSValue key_arr = js_new_uint8array(ctx, l2_key, key_len); + JSValue args[4] = { + key_arr, + JS_NewString(ctx, entry_id), + JS_NewString(ctx, field_label), + JS_NewString(ctx, plaintext) + }; + + JSValue result = JS_Call(ctx, fn, JS_UNDEFINED, 4, args); + + char *out = NULL; + if (!JS_IsException(result)) { + const char *str = JS_ToCString(ctx, result); + if (str) { + out = strdup(str); + JS_FreeCString(ctx, str); + } + } else { + JSValue exc = JS_GetException(ctx); + const char *msg = JS_ToCString(ctx, exc); + fprintf(stderr, "error: l2_encrypt: %s\n", msg ? msg : "unknown"); + if (msg) JS_FreeCString(ctx, msg); + JS_FreeValue(ctx, exc); + } + + for (int i = 0; i < 4; i++) JS_FreeValue(ctx, args[i]); + JS_FreeValue(ctx, result); + JS_FreeValue(ctx, fn); + JS_FreeValue(ctx, crypto_obj); + JS_FreeValue(ctx, v84); + JS_FreeValue(ctx, global); + return out; +} + +char *jsbridge_l2_decrypt(const unsigned char *l2_key, size_t key_len, + const char *entry_id, const char *field_label, + const char *ciphertext_b64) { + if (!ctx) return NULL; + + JSValue global = JS_GetGlobalObject(ctx); + JSValue v84 = JS_GetPropertyStr(ctx, global, "vault1984"); + JSValue crypto_obj = JS_GetPropertyStr(ctx, v84, "crypto"); + JSValue fn = JS_GetPropertyStr(ctx, crypto_obj, "l2_decrypt_field"); + + JSValue key_arr = js_new_uint8array(ctx, l2_key, key_len); + JSValue args[4] = { + key_arr, + JS_NewString(ctx, entry_id), + JS_NewString(ctx, field_label), + JS_NewString(ctx, ciphertext_b64) + }; + + JSValue result = JS_Call(ctx, fn, JS_UNDEFINED, 4, args); + + char *out = NULL; + if (!JS_IsException(result)) { + const char *str = JS_ToCString(ctx, result); + if (str) { + out = strdup(str); + JS_FreeCString(ctx, str); + } + } else { + JSValue exc = JS_GetException(ctx); + const char *msg = JS_ToCString(ctx, exc); + fprintf(stderr, "error: l2_decrypt: %s\n", msg ? msg : "unknown"); + if (msg) JS_FreeCString(ctx, msg); + JS_FreeValue(ctx, exc); + } + + for (int i = 0; i < 4; i++) JS_FreeValue(ctx, args[i]); + JS_FreeValue(ctx, result); + JS_FreeValue(ctx, fn); + JS_FreeValue(ctx, crypto_obj); + JS_FreeValue(ctx, v84); + JS_FreeValue(ctx, global); + return out; +} diff --git a/cli/src/jsbridge.h b/cli/src/jsbridge.h new file mode 100644 index 0000000..5fd25d7 --- /dev/null +++ b/cli/src/jsbridge.h @@ -0,0 +1,44 @@ +/* + * vault1984 CLI — QuickJS bridge + * Exposes BearSSL crypto primitives to JavaScript. + */ + +#ifndef V84_JSBRIDGE_H +#define V84_JSBRIDGE_H + +#include + +/* Initialize QuickJS runtime and load crypto/*.js modules */ +int jsbridge_init(void); + +/* Cleanup QuickJS runtime */ +void jsbridge_cleanup(void); + +/* + * Encrypt a field value using L2 key. + * Returns base64-encoded ciphertext (caller frees). + * Returns NULL on error. + */ +char *jsbridge_l2_encrypt(const unsigned char *l2_key, size_t key_len, + const char *entry_id, const char *field_label, + const char *plaintext); + +/* + * Decrypt a field value using L2 key. + * Returns plaintext string (caller frees). + * Returns NULL on error. + */ +char *jsbridge_l2_decrypt(const unsigned char *l2_key, size_t key_len, + const char *entry_id, const char *field_label, + const char *ciphertext_b64); + +/* + * Generate TOTP code from a base32-encoded seed. + * Returns 6-digit code string (caller frees). NULL on error. + */ +char *jsbridge_totp(const char *seed_b32); + +/* Evaluate JS code and return result as string (caller frees). NULL on error. */ +char *jsbridge_eval(const char *code); + +#endif diff --git a/cli/src/keystore.c b/cli/src/keystore.c new file mode 100644 index 0000000..1902e71 --- /dev/null +++ b/cli/src/keystore.c @@ -0,0 +1,196 @@ +/* + * vault1984 CLI — config and key storage + * + * Files stored in ~/.vault1984/ with strict permissions: + * config — key=value (host, vault_id) + * token — MCP auth token + * l2.key — 16-byte L2 encryption key (binary) + */ + +#include "keystore.h" +#include "util.h" + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#define mkdir_700(p) _mkdir(p) +#else +#include +#define mkdir_700(p) mkdir(p, 0700) +#endif + +static int get_config_dir(char *buf, size_t len) { + const char *home = getenv("HOME"); + if (!home) home = getenv("USERPROFILE"); /* Windows */ + if (!home) { + fprintf(stderr, "error: cannot determine home directory\n"); + return -1; + } + snprintf(buf, len, "%s/.vault1984", home); + return 0; +} + +static int ensure_dir(const char *path) { + struct stat st; + if (stat(path, &st) == 0) { + if (S_ISDIR(st.st_mode)) return 0; + fprintf(stderr, "error: %s exists but is not a directory\n", path); + return -1; + } + if (mkdir_700(path) != 0) { + fprintf(stderr, "error: cannot create %s: %s\n", path, strerror(errno)); + return -1; + } + return 0; +} + +static int write_file(const char *path, const void *data, size_t len) { + FILE *f = fopen(path, "wb"); + if (!f) { + fprintf(stderr, "error: cannot write %s: %s\n", path, strerror(errno)); + return -1; + } + fwrite(data, 1, len, f); + fclose(f); +#ifndef _WIN32 + chmod(path, 0600); +#endif + return 0; +} + +static int read_file(const char *path, char *buf, size_t len) { + FILE *f = fopen(path, "rb"); + if (!f) return -1; + size_t n = fread(buf, 1, len - 1, f); + fclose(f); + buf[n] = '\0'; + /* strip trailing newline */ + while (n > 0 && (buf[n-1] == '\n' || buf[n-1] == '\r')) buf[--n] = '\0'; + return 0; +} + +int keystore_init(const char *host, const char *agent_token) { + char dir[512]; + if (get_config_dir(dir, sizeof(dir)) != 0) return 1; + if (ensure_dir(dir) != 0) return 1; + + /* + * For now the agent token is the MCP auth token. + * Future: combined token = base64(mcp_token_bytes || encrypted_l2_key) + * We'll split and unwrap when the combined format is defined. + * + * TODO: when combined token format is finalized: + * 1. base64_decode the agent token + * 2. split at known offset → mcp_token_bytes + wrapped_l2_key + * 3. unwrap L2 key + * 4. store separately + */ + + /* write config */ + char path[512]; + char config_data[512]; + + /* detect scheme: if host starts with http:// or https://, strip and store */ + const char *actual_host = host; + const char *scheme = "https"; + if (strncmp(host, "https://", 8) == 0) { + actual_host = host + 8; + scheme = "https"; + } else if (strncmp(host, "http://", 7) == 0) { + actual_host = host + 7; + scheme = "http"; + } + /* strip trailing slash */ + char clean_host[256]; + snprintf(clean_host, sizeof(clean_host), "%s", actual_host); + size_t hlen = strlen(clean_host); + while (hlen > 0 && clean_host[hlen - 1] == '/') clean_host[--hlen] = '\0'; + + snprintf(config_data, sizeof(config_data), "host=%s\nscheme=%s\n", clean_host, scheme); + snprintf(path, sizeof(path), "%s/config", dir); + if (write_file(path, config_data, strlen(config_data)) != 0) return 1; + + /* write token */ + snprintf(path, sizeof(path), "%s/token", dir); + if (write_file(path, agent_token, strlen(agent_token)) != 0) return 1; + + fprintf(stderr, "vault1984: initialized\n"); + fprintf(stderr, " host: %s://%s:1984\n", scheme, clean_host); + fprintf(stderr, " config: %s/\n", dir); + return 0; +} + +int keystore_load(struct v84_config *cfg) { + memset(cfg, 0, sizeof(*cfg)); + + char dir[512]; + if (get_config_dir(dir, sizeof(dir)) != 0) return -1; + + /* read config */ + char path[512]; + char config_data[512]; + snprintf(path, sizeof(path), "%s/config", dir); + if (read_file(path, config_data, sizeof(config_data)) != 0) { + fprintf(stderr, "error: not initialized. Run: vault1984 init --host --agent \n"); + return -1; + } + + /* parse config key=value lines */ + char *line = strtok(config_data, "\n"); + while (line) { + char *eq = strchr(line, '='); + if (eq) { + *eq = '\0'; + const char *key = line; + const char *val = eq + 1; + if (strcmp(key, "host") == 0) { + snprintf(cfg->host, sizeof(cfg->host), "%s", val); + } else if (strcmp(key, "vault_id") == 0) { + snprintf(cfg->vault_id, sizeof(cfg->vault_id), "%s", val); + } else if (strcmp(key, "scheme") == 0) { + snprintf(cfg->scheme, sizeof(cfg->scheme), "%s", val); + } + } + line = strtok(NULL, "\n"); + } + + /* read token */ + snprintf(path, sizeof(path), "%s/token", dir); + if (read_file(path, cfg->token, sizeof(cfg->token)) != 0) { + fprintf(stderr, "error: token file missing. Run: vault1984 init --host --agent \n"); + return -1; + } + + /* read L2 key if present */ + snprintf(path, sizeof(path), "%s/l2.key", dir); + FILE *f = fopen(path, "rb"); + if (f) { + size_t n = fread(cfg->l2_key, 1, 16, f); + fclose(f); + cfg->has_l2_key = (n == 16); + } + + if (!cfg->host[0]) { + fprintf(stderr, "error: config missing host. Run: vault1984 init --host --agent \n"); + return -1; + } + + /* default scheme to https */ + if (!cfg->scheme[0]) { + snprintf(cfg->scheme, sizeof(cfg->scheme), "https"); + } + + /* if vault_id not in config, use placeholder from token */ + if (!cfg->vault_id[0]) { + /* TODO: derive from L2 key once combined token format is defined */ + snprintf(cfg->vault_id, sizeof(cfg->vault_id), "default"); + } + + return 0; +} diff --git a/cli/src/keystore.h b/cli/src/keystore.h new file mode 100644 index 0000000..0e9d9b6 --- /dev/null +++ b/cli/src/keystore.h @@ -0,0 +1,23 @@ +/* + * vault1984 CLI — config and key storage + */ + +#ifndef V84_KEYSTORE_H +#define V84_KEYSTORE_H + +struct v84_config { + char host[256]; /* POP hostname (e.g. use.vault1984.com) */ + char vault_id[16]; /* base64(first 8 bytes of L2 key) */ + char token[256]; /* MCP auth token */ + char scheme[8]; /* "http" or "https" */ + unsigned char l2_key[16]; /* L2 encryption key (16 bytes) */ + int has_l2_key; +}; + +/* Initialize config: split agent token, derive vault_id, write files */ +int keystore_init(const char *host, const char *agent_token); + +/* Load config from ~/.vault1984/ */ +int keystore_load(struct v84_config *cfg); + +#endif diff --git a/cli/src/main.c b/cli/src/main.c new file mode 100644 index 0000000..fccadca --- /dev/null +++ b/cli/src/main.c @@ -0,0 +1,647 @@ +/* + * vault1984 CLI — credential access for AI agents + * Copyright (c) 2026 Vault1984. Elastic License 2.0. + */ + +#include +#include +#include + +#include "keystore.h" +#include "http.h" +#include "jsbridge.h" +#include "util.h" +#include "../vendor/cjson/cJSON.h" +#include "bearssl.h" + +#define VERSION "0.1.0" + +static void usage(void) { + fprintf(stderr, + "vault1984 %s — credential access for AI agents\n" + "\n" + "Usage:\n" + " vault1984 init --host --agent \n" + " vault1984 get [--json]\n" + " vault1984 list [filter] [--json]\n" + " vault1984 totp \n" + "\n" + "Options:\n" + " --help Show this help\n" + " --version Show version\n" + " --json Output as JSON\n" + "\n" + "Port is always 1984.\n" + "\n" + "Examples:\n" + " vault1984 init --host use.vault1984.com --agent ABCDEF...\n" + " vault1984 get GitHub\n" + " vault1984 totp GitHub\n" + " vault1984 list\n" + " vault1984 list --json\n", + VERSION); +} + +/* --- URL builder --- */ + +static void build_url(char *buf, size_t len, const struct v84_config *cfg, const char *path) { + if (cfg->vault_id[0] && strcmp(cfg->vault_id, "default") != 0) { + snprintf(buf, len, "%s://%s:1984/%s%s", cfg->scheme, cfg->host, cfg->vault_id, path); + } else { + snprintf(buf, len, "%s://%s:1984%s", cfg->scheme, cfg->host, path); + } +} + +/* --- command handlers --- */ + +static int cmd_init(int argc, char **argv) { + const char *host = NULL; + const char *agent = NULL; + + for (int i = 0; i < argc; i++) { + if (strcmp(argv[i], "--host") == 0 && i + 1 < argc) { + host = argv[++i]; + } else if (strcmp(argv[i], "--agent") == 0 && i + 1 < argc) { + agent = argv[++i]; + } + } + + if (!host || !agent) { + fprintf(stderr, "error: --host and --agent are required\n"); + fprintf(stderr, "usage: vault1984 init --host --agent \n"); + return 1; + } + + return keystore_init(host, agent); +} + +static int cmd_list(int argc, char **argv) { + int json_output = 0; + const char *filter = NULL; + + for (int i = 0; i < argc; i++) { + if (strcmp(argv[i], "--json") == 0) { + json_output = 1; + } else if (argv[i][0] != '-') { + filter = argv[i]; + } + } + + struct v84_config cfg; + if (keystore_load(&cfg) != 0) return 1; + + char url[1024]; + if (filter) { + char encoded_filter[512]; + char path[768]; + url_encode(filter, encoded_filter, sizeof(encoded_filter)); + snprintf(path, sizeof(path), "/api/search?q=%s", encoded_filter); + build_url(url, sizeof(url), &cfg, path); + } else { + build_url(url, sizeof(url), &cfg, "/api/entries"); + } + + struct v84_response resp; + if (http_get(url, cfg.token, &resp) != 0) { + fprintf(stderr, "error: request failed\n"); + return 1; + } + + if (resp.status != 200) { + fprintf(stderr, "error: server returned %d\n", resp.status); + free(resp.body); + return 1; + } + + if (json_output) { + printf("%s\n", resp.body); + free(resp.body); + return 0; + } + + /* parse and format */ + cJSON *root = cJSON_Parse(resp.body); + free(resp.body); + if (!root) { + fprintf(stderr, "error: invalid JSON response\n"); + return 1; + } + + /* handle both array (entries list) and object with entries key */ + cJSON *entries = root; + if (!cJSON_IsArray(root)) { + entries = cJSON_GetObjectItem(root, "entries"); + if (!entries) entries = root; + } + + cJSON *entry; + cJSON_ArrayForEach(entry, entries) { + const char *eid = cJSON_GetStringValue(cJSON_GetObjectItem(entry, "entry_id")); + const char *type = cJSON_GetStringValue(cJSON_GetObjectItem(entry, "type")); + const char *title = cJSON_GetStringValue(cJSON_GetObjectItem(entry, "title")); + printf("%s\t%s\t%s\n", + eid ? eid : "?", + type ? type : "?", + title ? title : "?"); + } + + cJSON_Delete(root); + return 0; +} + +static int cmd_get(int argc, char **argv) { + int json_output = 0; + const char *query = NULL; + + for (int i = 0; i < argc; i++) { + if (strcmp(argv[i], "--json") == 0) { + json_output = 1; + } else if (argv[i][0] != '-') { + query = argv[i]; + } + } + + if (!query) { + fprintf(stderr, "error: query required\n"); + fprintf(stderr, "usage: vault1984 get [--json]\n"); + return 1; + } + + struct v84_config cfg; + if (keystore_load(&cfg) != 0) return 1; + + /* search first */ + char url[1024]; + char encoded_query[512]; + char path[768]; + url_encode(query, encoded_query, sizeof(encoded_query)); + snprintf(path, sizeof(path), "/api/search?q=%s", encoded_query); + build_url(url, sizeof(url), &cfg, path); + + struct v84_response resp; + if (http_get(url, cfg.token, &resp) != 0) { + fprintf(stderr, "error: search request failed\n"); + return 1; + } + + if (resp.status != 200) { + fprintf(stderr, "error: server returned %d\n", resp.status); + free(resp.body); + return 1; + } + + cJSON *results = cJSON_Parse(resp.body); + free(resp.body); + if (!results) { + fprintf(stderr, "error: invalid JSON\n"); + return 1; + } + + /* handle array or object wrapper */ + cJSON *arr = results; + if (!cJSON_IsArray(results)) { + arr = cJSON_GetObjectItem(results, "entries"); + if (!arr) arr = results; + } + + cJSON *first = cJSON_GetArrayItem(arr, 0); + if (!first) { + fprintf(stderr, "error: no results for '%s'\n", query); + cJSON_Delete(results); + return 1; + } + + const char *entry_id = cJSON_GetStringValue(cJSON_GetObjectItem(first, "entry_id")); + if (!entry_id) { + fprintf(stderr, "error: result missing entry_id\n"); + cJSON_Delete(results); + return 1; + } + + /* fetch full entry */ + snprintf(path, sizeof(path), "/api/entries/%s", entry_id); + build_url(url, sizeof(url), &cfg, path); + cJSON_Delete(results); + + if (http_get(url, cfg.token, &resp) != 0) { + fprintf(stderr, "error: fetch request failed\n"); + return 1; + } + + if (resp.status != 200) { + fprintf(stderr, "error: server returned %d\n", resp.status); + free(resp.body); + return 1; + } + + if (json_output) { + printf("%s\n", resp.body); + free(resp.body); + return 0; + } + + cJSON *entry = cJSON_Parse(resp.body); + free(resp.body); + if (!entry) { + fprintf(stderr, "error: invalid JSON\n"); + return 1; + } + + /* print fields from vault_data */ + cJSON *data = cJSON_GetObjectItem(entry, "data"); + if (!data) data = cJSON_GetObjectItem(entry, "vault_data"); + if (data) { + cJSON *fields = cJSON_GetObjectItem(data, "fields"); + cJSON *field; + cJSON_ArrayForEach(field, fields) { + const char *label = cJSON_GetStringValue(cJSON_GetObjectItem(field, "label")); + const char *value = cJSON_GetStringValue(cJSON_GetObjectItem(field, "value")); + cJSON *tier = cJSON_GetObjectItem(field, "tier"); + int tier_val = tier ? tier->valueint : 1; + + if (!label) continue; + + if (tier_val >= 3) { + printf("%s: [L3 -- requires hardware key]\n", label); + } else if (tier_val == 2 && (!value || strlen(value) == 0)) { + printf("%s: [L2 -- encrypted]\n", label); + } else { + printf("%s: %s\n", label, value ? value : ""); + } + } + + /* also print URLs if present */ + cJSON *urls = cJSON_GetObjectItem(data, "urls"); + if (urls && cJSON_GetArraySize(urls) > 0) { + cJSON *u; + cJSON_ArrayForEach(u, urls) { + const char *uv = cJSON_GetStringValue(u); + if (uv) printf("url: %s\n", uv); + } + } + + /* notes */ + const char *notes = cJSON_GetStringValue(cJSON_GetObjectItem(data, "notes")); + if (notes && strlen(notes) > 0) { + printf("notes: %s\n", notes); + } + } + + cJSON_Delete(entry); + return 0; +} + +static int cmd_totp(int argc, char **argv) { + const char *query = NULL; + + for (int i = 0; i < argc; i++) { + if (argv[i][0] != '-') { + query = argv[i]; + } + } + + if (!query) { + fprintf(stderr, "error: query required\n"); + fprintf(stderr, "usage: vault1984 totp \n"); + return 1; + } + + struct v84_config cfg; + if (keystore_load(&cfg) != 0) return 1; + + /* search for the entry first */ + char url[1024]; + char encoded_query[512]; + char path[768]; + url_encode(query, encoded_query, sizeof(encoded_query)); + snprintf(path, sizeof(path), "/api/search?q=%s", encoded_query); + build_url(url, sizeof(url), &cfg, path); + + struct v84_response resp; + if (http_get(url, cfg.token, &resp) != 0) { + fprintf(stderr, "error: search request failed\n"); + return 1; + } + + if (resp.status != 200) { + fprintf(stderr, "error: server returned %d\n", resp.status); + free(resp.body); + return 1; + } + + cJSON *results = cJSON_Parse(resp.body); + free(resp.body); + if (!results) { + fprintf(stderr, "error: invalid JSON\n"); + return 1; + } + + cJSON *arr = results; + if (!cJSON_IsArray(results)) { + arr = cJSON_GetObjectItem(results, "entries"); + if (!arr) arr = results; + } + + cJSON *first = cJSON_GetArrayItem(arr, 0); + if (!first) { + fprintf(stderr, "error: no results for '%s'\n", query); + cJSON_Delete(results); + return 1; + } + + const char *entry_id = cJSON_GetStringValue(cJSON_GetObjectItem(first, "entry_id")); + if (!entry_id) { + fprintf(stderr, "error: result missing entry_id\n"); + cJSON_Delete(results); + return 1; + } + + /* fetch TOTP code */ + snprintf(path, sizeof(path), "/api/ext/totp/%s", entry_id); + build_url(url, sizeof(url), &cfg, path); + cJSON_Delete(results); + + if (http_get(url, cfg.token, &resp) != 0) { + fprintf(stderr, "error: TOTP request failed\n"); + return 1; + } + + if (resp.status != 200) { + fprintf(stderr, "error: server returned %d\n", resp.status); + free(resp.body); + return 1; + } + + cJSON *totp = cJSON_Parse(resp.body); + free(resp.body); + if (!totp) { + fprintf(stderr, "error: invalid JSON\n"); + return 1; + } + + /* check if L2/L3 locked */ + cJSON *l2 = cJSON_GetObjectItem(totp, "l2"); + if (l2 && cJSON_IsTrue(l2)) { + fprintf(stderr, "error: TOTP seed is L3-locked (requires hardware key)\n"); + cJSON_Delete(totp); + return 1; + } + + const char *code = cJSON_GetStringValue(cJSON_GetObjectItem(totp, "code")); + if (!code) { + fprintf(stderr, "error: no TOTP code in response\n"); + cJSON_Delete(totp); + return 1; + } + + printf("%s\n", code); + cJSON_Delete(totp); + return 0; +} + +static int cmd_test_crypto(void) { + fprintf(stderr, "vault1984: crypto self-test\n"); + + /* First: test BearSSL primitives directly in C */ + { + fprintf(stderr, " [C] AES-128-GCM roundtrip... "); + unsigned char key[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + unsigned char nonce[12] = {0}; + unsigned char pt[] = "hello world test"; + unsigned char buf[sizeof(pt) + 16]; /* pt + tag */ + unsigned char tag[16]; + + memcpy(buf, pt, sizeof(pt)); + + br_aes_ct64_ctr_keys aes_ctx; + br_aes_ct64_ctr_init(&aes_ctx, key, 16); + + br_gcm_context gcm; + br_gcm_init(&gcm, &aes_ctx.vtable, br_ghash_ctmul64); + br_gcm_reset(&gcm, nonce, 12); + br_gcm_flip(&gcm); + br_gcm_run(&gcm, 1, buf, sizeof(pt)); /* encrypt */ + br_gcm_get_tag(&gcm, tag); + + /* decrypt */ + br_gcm_reset(&gcm, nonce, 12); + br_gcm_flip(&gcm); + br_gcm_run(&gcm, 0, buf, sizeof(pt)); /* decrypt */ + + if (!br_gcm_check_tag(&gcm, tag)) { + fprintf(stderr, "FAIL (tag)\n"); + return 1; + } + if (memcmp(buf, pt, sizeof(pt)) != 0) { + fprintf(stderr, "FAIL (data)\n"); + return 1; + } + fprintf(stderr, "OK\n"); + } + + /* Init QuickJS + load crypto.js */ + if (jsbridge_init() != 0) { + fprintf(stderr, "FAIL: jsbridge_init\n"); + return 1; + } + + /* Test L2 encrypt → decrypt roundtrip */ + unsigned char test_key[16] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 + }; + const char *entry_id = "abcdef0123456789"; + const char *label = "password"; + const char *plaintext = "s3cret-p@ssw0rd!"; + + /* Test base64 roundtrip via JS */ + { + char *r = jsbridge_eval( + "var orig = new Uint8Array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);" + "var b64 = native_base64_encode(orig);" + "var back = native_base64_decode(b64);" + "var ok = (orig.length === back.length);" + "for (var i=0; i 2) { + if (jsbridge_init() != 0) { fprintf(stderr, "error: crypto init failed\n"); return 1; } + char *code = jsbridge_totp(argv[2]); + if (code) { printf("%s\n", code); free(code); } + else { fprintf(stderr, "error: TOTP generation failed\n"); } + jsbridge_cleanup(); + return code ? 0 : 1; + } + + fprintf(stderr, "error: unknown command '%s'\n", cmd); + usage(); + return 1; +} diff --git a/cli/src/util.c b/cli/src/util.c new file mode 100644 index 0000000..825a4a0 --- /dev/null +++ b/cli/src/util.c @@ -0,0 +1,116 @@ +/* + * vault1984 CLI — utility functions + */ + +#include "util.h" +#include +#include + +static const char b64_table[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int base64_encode(const unsigned char *src, size_t src_len, char *dst, size_t dst_len) { + size_t needed = ((src_len + 2) / 3) * 4 + 1; + if (dst_len < needed) return -1; + + size_t i = 0, j = 0; + while (i + 2 < src_len) { + unsigned int triple = ((unsigned int)src[i] << 16) | + ((unsigned int)src[i+1] << 8) | + (unsigned int)src[i+2]; + dst[j++] = b64_table[(triple >> 18) & 0x3F]; + dst[j++] = b64_table[(triple >> 12) & 0x3F]; + dst[j++] = b64_table[(triple >> 6) & 0x3F]; + dst[j++] = b64_table[triple & 0x3F]; + i += 3; + } + + /* Handle remaining 1 or 2 bytes */ + size_t remaining = src_len - i; + if (remaining == 1) { + unsigned int a = src[i]; + dst[j++] = b64_table[(a >> 2) & 0x3F]; + dst[j++] = b64_table[(a << 4) & 0x3F]; + dst[j++] = '='; + dst[j++] = '='; + } else if (remaining == 2) { + unsigned int a = src[i]; + unsigned int b = src[i + 1]; + dst[j++] = b64_table[(a >> 2) & 0x3F]; + dst[j++] = b64_table[((a << 4) | (b >> 4)) & 0x3F]; + dst[j++] = b64_table[(b << 2) & 0x3F]; + dst[j++] = '='; + } + + dst[j] = '\0'; + return 0; +} + +static int b64_val(char c) { + if (c >= 'A' && c <= 'Z') return c - 'A'; + if (c >= 'a' && c <= 'z') return c - 'a' + 26; + if (c >= '0' && c <= '9') return c - '0' + 52; + if (c == '+' || c == '-') return 62; /* - is url-safe variant */ + if (c == '/' || c == '_') return 63; /* _ is url-safe variant */ + return -1; +} + +int base64_decode(const char *src, unsigned char *dst, size_t dst_len, size_t *out_len) { + size_t slen = strlen(src); + /* count padding */ + int pad = 0; + while (slen > 0 && src[slen - 1] == '=') { slen--; pad++; } + /* strip whitespace */ + while (slen > 0 && (src[slen - 1] == '\n' || src[slen - 1] == '\r')) slen--; + + size_t needed = (slen * 3) / 4; + if (dst_len < needed) return -1; + + size_t i = 0, j = 0; + while (i + 3 < slen) { + int a = b64_val(src[i++]); + int b = b64_val(src[i++]); + int c = b64_val(src[i++]); + int d = b64_val(src[i++]); + if (a < 0 || b < 0 || c < 0 || d < 0) return -1; + + dst[j++] = (unsigned char)((a << 2) | (b >> 4)); + dst[j++] = (unsigned char)(((b & 0x0F) << 4) | (c >> 2)); + dst[j++] = (unsigned char)(((c & 0x03) << 6) | d); + } + + /* Handle remaining chars based on padding count */ + size_t rem = slen - i; + if (rem >= 2) { + int a = b64_val(src[i++]); + int b = b64_val(src[i++]); + if (a < 0 || b < 0) return -1; + dst[j++] = (unsigned char)((a << 2) | (b >> 4)); + + if (rem >= 3 && pad < 2) { + int c = b64_val(src[i++]); + if (c < 0) return -1; + dst[j++] = (unsigned char)(((b & 0x0F) << 4) | (c >> 2)); + } + } + + if (out_len) *out_len = j; + return 0; +} + +void url_encode(const char *src, char *dst, size_t dst_len) { + static const char hex[] = "0123456789ABCDEF"; + size_t j = 0; + + for (size_t i = 0; src[i] && j + 3 < dst_len; i++) { + unsigned char c = (unsigned char)src[i]; + if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { + dst[j++] = (char)c; + } else { + dst[j++] = '%'; + dst[j++] = hex[c >> 4]; + dst[j++] = hex[c & 0x0F]; + } + } + dst[j] = '\0'; +} diff --git a/cli/src/util.h b/cli/src/util.h new file mode 100644 index 0000000..71cc0cf --- /dev/null +++ b/cli/src/util.h @@ -0,0 +1,19 @@ +/* + * vault1984 CLI — utility functions + */ + +#ifndef V84_UTIL_H +#define V84_UTIL_H + +#include + +/* base64 encode (standard, with padding) */ +int base64_encode(const unsigned char *src, size_t src_len, char *dst, size_t dst_len); + +/* base64 decode (handles standard and url-safe, with or without padding) */ +int base64_decode(const char *src, unsigned char *dst, size_t dst_len, size_t *out_len); + +/* URL-encode a string for query parameters */ +void url_encode(const char *src, char *dst, size_t dst_len); + +#endif diff --git a/cli/vendor/bearssl b/cli/vendor/bearssl new file mode 160000 index 0000000..3d9be2f --- /dev/null +++ b/cli/vendor/bearssl @@ -0,0 +1 @@ +Subproject commit 3d9be2f60b7764e46836514bcd6e453abdfa864a diff --git a/cli/vendor/cjson b/cli/vendor/cjson new file mode 160000 index 0000000..b2890c8 --- /dev/null +++ b/cli/vendor/cjson @@ -0,0 +1 @@ +Subproject commit b2890c8d76bbb64e710585ebc0a917196b9c67e7 diff --git a/cli/vendor/quickjs b/cli/vendor/quickjs new file mode 160000 index 0000000..f113949 --- /dev/null +++ b/cli/vendor/quickjs @@ -0,0 +1 @@ +Subproject commit f1139494d18a2053630c5ed3384a42bb70db3c53 diff --git a/crypto/crypto.js b/crypto/crypto.js new file mode 100644 index 0000000..3282af3 --- /dev/null +++ b/crypto/crypto.js @@ -0,0 +1,188 @@ +/* + * vault1984 — shared crypto module + * Runs in both QuickJS (CLI) and browser (extension). + * + * In CLI (QuickJS): native_* functions provided by jsbridge.c via BearSSL. + * All calls are synchronous. + * In browser: Web Crypto API used directly (async). + * + * This file is the single source of truth for L2/L3 field crypto. + */ + +/* Detect environment */ +const IS_BROWSER = typeof globalThis.crypto !== 'undefined' + && typeof globalThis.crypto.subtle !== 'undefined'; + +/* --- base64 helpers --- */ + +function uint8_to_base64(bytes) { + if (IS_BROWSER) { + return btoa(String.fromCharCode.apply(null, bytes)); + } else { + return native_base64_encode(bytes); + } +} + +function base64_to_uint8(str) { + if (IS_BROWSER) { + const bin = atob(str); + const bytes = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i); + return bytes; + } else { + return native_base64_decode(str); + } +} + +/* --- AES-GCM --- */ + +/** + * Encrypt plaintext with AES-GCM. + * @param {Uint8Array} key - 16 bytes (AES-128) or 32 bytes (AES-256) + * @param {Uint8Array} plaintext + * @returns {Uint8Array|Promise} nonce(12) || ciphertext || tag(16) + */ +function aes_gcm_encrypt(key, plaintext) { + if (IS_BROWSER) { + const iv = crypto.getRandomValues(new Uint8Array(12)); + return crypto.subtle.importKey( + 'raw', key, { name: 'AES-GCM' }, false, ['encrypt'] + ).then(function(cryptoKey) { + return crypto.subtle.encrypt({ name: 'AES-GCM', iv: iv }, cryptoKey, plaintext); + }).then(function(ct) { + const result = new Uint8Array(12 + ct.byteLength); + result.set(iv, 0); + result.set(new Uint8Array(ct), 12); + return result; + }); + } else { + /* QuickJS: synchronous BearSSL binding */ + return native_aes_gcm_encrypt(key, plaintext); + } +} + +/** + * Decrypt AES-GCM ciphertext. + * @param {Uint8Array} key - 16 or 32 bytes + * @param {Uint8Array} data - nonce(12) || ciphertext || tag(16) + * @returns {Uint8Array|Promise} plaintext + */ +function aes_gcm_decrypt(key, data) { + if (data.length < 28) throw new Error('ciphertext too short'); + + /* Use subarray for typed array compatibility (QuickJS) */ + var iv, ct; + if (typeof data.subarray === 'function') { + iv = new Uint8Array(data.subarray(0, 12)); + ct = new Uint8Array(data.subarray(12)); + } else { + iv = data.slice(0, 12); + ct = data.slice(12); + } + + if (IS_BROWSER) { + return crypto.subtle.importKey( + 'raw', key, { name: 'AES-GCM' }, false, ['decrypt'] + ).then(function(cryptoKey) { + return crypto.subtle.decrypt({ name: 'AES-GCM', iv: iv }, cryptoKey, ct); + }).then(function(pt) { + return new Uint8Array(pt); + }); + } else { + /* Pass full data blob to native — C splits nonce/ct internally */ + return native_aes_gcm_decrypt_blob(key, data); + } +} + +/* --- HKDF-SHA256 --- */ + +/** + * HKDF-SHA256 extract + expand. + * @param {Uint8Array} ikm - input key material + * @param {Uint8Array|null} salt - optional salt + * @param {Uint8Array} info - context info + * @param {number} length - output length in bytes + * @returns {Uint8Array|Promise} + */ +function hkdf_sha256(ikm, salt, info, length) { + if (IS_BROWSER) { + return crypto.subtle.importKey( + 'raw', ikm, 'HKDF', false, ['deriveBits'] + ).then(function(cryptoKey) { + return crypto.subtle.deriveBits( + { name: 'HKDF', hash: 'SHA-256', salt: salt || new Uint8Array(0), info: info }, + cryptoKey, length * 8 + ); + }).then(function(bits) { + return new Uint8Array(bits); + }); + } else { + return native_hkdf_sha256(ikm, salt, info, length); + } +} + +/* --- L2 field encryption/decryption --- */ + +/** + * Encrypt a field value with L2 key (AES-128-GCM). + * In QuickJS: returns base64 string (synchronous). + * In browser: returns Promise. + */ +function l2_encrypt_field(l2_key, entry_id, field_label, plaintext) { + var info_str = 'vault1984-l2-' + entry_id + '-' + field_label; + + if (IS_BROWSER) { + var enc = new TextEncoder(); + var info = enc.encode(info_str); + return hkdf_sha256(l2_key, null, info, 16).then(function(field_key) { + return aes_gcm_encrypt(field_key, enc.encode(plaintext)); + }).then(function(ct) { + return uint8_to_base64(ct); + }); + } else { + var info = native_encode_utf8(info_str); + var field_key = native_hkdf_sha256(l2_key, null, info, 16); + var pt_bytes = native_encode_utf8(plaintext); + var ct = native_aes_gcm_encrypt(field_key, pt_bytes); + return native_base64_encode(ct); + } +} + +/** + * Decrypt a field value with L2 key (AES-128-GCM). + * In QuickJS: returns plaintext string (synchronous). + * In browser: returns Promise. + */ +function l2_decrypt_field(l2_key, entry_id, field_label, ciphertext_b64) { + var info_str = 'vault1984-l2-' + entry_id + '-' + field_label; + + if (IS_BROWSER) { + var enc = new TextEncoder(); + var dec = new TextDecoder(); + var info = enc.encode(info_str); + return hkdf_sha256(l2_key, null, info, 16).then(function(field_key) { + var ct = base64_to_uint8(ciphertext_b64); + return aes_gcm_decrypt(field_key, ct); + }).then(function(pt) { + return dec.decode(pt); + }); + } else { + var info = native_encode_utf8(info_str); + var field_key = native_hkdf_sha256(l2_key, null, info, 16); + var ct = native_base64_decode(ciphertext_b64); + var pt = native_aes_gcm_decrypt_blob(field_key, ct); + return native_decode_utf8(pt); + } +} + +/* Export for both environments */ +if (typeof globalThis.vault1984 === 'undefined') globalThis.vault1984 = {}; +globalThis.vault1984.crypto = { + aes_gcm_encrypt: aes_gcm_encrypt, + aes_gcm_decrypt: aes_gcm_decrypt, + hkdf_sha256: hkdf_sha256, + l2_encrypt_field: l2_encrypt_field, + l2_decrypt_field: l2_decrypt_field, + uint8_to_base64: uint8_to_base64, + base64_to_uint8: base64_to_uint8 +}; diff --git a/crypto/totp.js b/crypto/totp.js new file mode 100644 index 0000000..e640ea3 --- /dev/null +++ b/crypto/totp.js @@ -0,0 +1,115 @@ +/* + * vault1984 — TOTP generation (RFC 6238) + * Runs in both QuickJS (CLI) and browser (extension). + * + * In CLI (QuickJS): native_hmac_sha1 provided by jsbridge.c via BearSSL. + * All calls are synchronous. + * In browser: Web Crypto API (async). + */ + +/* IS_BROWSER defined in crypto.js, reuse if available */ +var IS_BROWSER_TOTP = (typeof IS_BROWSER !== 'undefined') ? IS_BROWSER + : (typeof globalThis.crypto !== 'undefined' && typeof globalThis.crypto.subtle !== 'undefined'); + +/* --- Base32 decode (RFC 4648) --- */ + +function base32_decode(input) { + var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; + input = input.replace(/[\s=]/g, '').toUpperCase(); + + var bits = 0, value = 0, idx = 0; + var output = new Uint8Array(Math.floor(input.length * 5 / 8)); + + for (var i = 0; i < input.length; i++) { + var v = alphabet.indexOf(input[i]); + if (v < 0) continue; + value = (value << 5) | v; + bits += 5; + if (bits >= 8) { + output[idx++] = (value >>> (bits - 8)) & 0xFF; + bits -= 8; + } + } + + return new Uint8Array(output.buffer, 0, idx); +} + +/* --- HMAC-SHA1 --- */ + +function hmac_sha1(key, data) { + if (IS_BROWSER_TOTP) { + return crypto.subtle.importKey( + 'raw', key, { name: 'HMAC', hash: 'SHA-1' }, false, ['sign'] + ).then(function(cryptoKey) { + return crypto.subtle.sign('HMAC', cryptoKey, data); + }).then(function(sig) { + return new Uint8Array(sig); + }); + } else { + return native_hmac_sha1(key, data); + } +} + +/* --- TOTP (RFC 6238) --- */ + +/** + * Generate a TOTP code. + * @param {string} secret_b32 - base32-encoded TOTP secret + * @param {number} [time] - Unix timestamp (default: now) + * @param {number} [period] - Time step in seconds (default: 30) + * @param {number} [digits] - Number of digits (default: 6) + * @returns {string|Promise} TOTP code (zero-padded) + */ +function generate_totp(secret_b32, time, period, digits) { + period = period || 30; + digits = digits || 6; + time = time || Math.floor(Date.now() / 1000); + + var key = base32_decode(secret_b32); + var counter = Math.floor(time / period); + + /* Encode counter as 8-byte big-endian */ + var msg = new Uint8Array(8); + var tmp = counter; + for (var i = 7; i >= 0; i--) { + msg[i] = tmp & 0xFF; + tmp = Math.floor(tmp / 256); + } + + function truncate(hash) { + var offset = hash[hash.length - 1] & 0x0F; + var code = ( + ((hash[offset] & 0x7F) << 24) | + ((hash[offset + 1] & 0xFF) << 16) | + ((hash[offset + 2] & 0xFF) << 8) | + (hash[offset + 3] & 0xFF) + ) % Math.pow(10, digits); + var s = code.toString(); + while (s.length < digits) s = '0' + s; + return s; + } + + if (IS_BROWSER_TOTP) { + return hmac_sha1(key, msg).then(truncate); + } else { + return truncate(hmac_sha1(key, msg)); + } +} + +/** + * Time remaining until current TOTP code expires. + * @param {number} [period] - Time step (default: 30) + * @returns {number} seconds remaining + */ +function totp_remaining(period) { + period = period || 30; + return period - (Math.floor(Date.now() / 1000) % period); +} + +/* Export */ +if (typeof globalThis.vault1984 === 'undefined') globalThis.vault1984 = {}; +globalThis.vault1984.totp = { + generate_totp: generate_totp, + totp_remaining: totp_remaining, + base32_decode: base32_decode +};