Compare commits
60 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1fe4894800 | ||
![]() |
028e33728d | ||
![]() |
978d6020d4 | ||
![]() |
f95facc254 | ||
![]() |
d5e9c6d1aa | ||
![]() |
cbb4493876 | ||
![]() |
1f9c1f9088 | ||
![]() |
812ff13425 | ||
![]() |
7fd3c7ff3e | ||
![]() |
22ddeeb19b | ||
![]() |
1f1f81fde5 | ||
![]() |
f6aa0fd5ad | ||
![]() |
a5f4e412cc | ||
![]() |
bcceea1c47 | ||
![]() |
b8539a88d7 | ||
![]() |
32d1c55066 | ||
![]() |
a6462552cd | ||
![]() |
a7bcbfba2a | ||
![]() |
adaac3066c | ||
![]() |
7e3c21c396 | ||
![]() |
92647716ca | ||
![]() |
c19e7ba506 | ||
![]() |
9854b229f7 | ||
![]() |
efdfbe8cbb | ||
![]() |
65c4d634f5 | ||
![]() |
f40b9c47e1 | ||
![]() |
f250f7f2d2 | ||
![]() |
2472e517a5 | ||
![]() |
4707ea4b48 | ||
![]() |
dd58b5b345 | ||
![]() |
61d2538f91 | ||
![]() |
c42d5c10b0 | ||
![]() |
b21d20e688 | ||
![]() |
c7a30e716b | ||
![]() |
1cf0fac337 | ||
![]() |
ac7ffaef41 | ||
![]() |
7debbabdd2 | ||
![]() |
5d8fe824ee | ||
![]() |
fa0c4ee5e2 | ||
![]() |
376c339c95 | ||
![]() |
9964401199 | ||
![]() |
3d8ff7d341 | ||
![]() |
4bb4e14682 | ||
![]() |
915535aacf | ||
![]() |
159267684a | ||
![]() |
e9d418fbb1 | ||
![]() |
9464307cb5 | ||
![]() |
dd942735e3 | ||
![]() |
93dc91994a | ||
![]() |
4f3c4c8729 | ||
![]() |
226307d0bd | ||
![]() |
f20f619947 | ||
![]() |
d01c2e1f27 | ||
![]() |
e858f5e4c3 | ||
![]() |
2bf648ee58 | ||
![]() |
5e3809b5da | ||
![]() |
7bc9b735bf | ||
![]() |
57aa984d5f | ||
![]() |
1d4ca8e943 | ||
![]() |
8476eebf80 |
28 changed files with 1293 additions and 446 deletions
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Write some steps to reproduce the behavior. Be sure to include the vant hardware required, if any.
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen. A reproducible sketch is especially helpful.
|
||||
|
||||
**Screenshots/Serial Output**
|
||||
If applicable, add screenshots or serial logs to help explain your problem.
|
||||
|
||||
**Context (please complete the following information):**
|
||||
- Device Type [e.g. ESP32]
|
||||
- Arduino Core Version [e.g. Adafruit SAMD core 1.5.3]
|
||||
- Relevant Library Versions [PubSubClient, etc.]
|
||||
- SSLClient Version [e.g. v1.2.0]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
14
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
name: Question
|
||||
about: Ask for clarification on this project
|
||||
title: ''
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your question related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Description
|
||||
|
||||
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
## Type of change
|
||||
|
||||
Please uncheck options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
- [ ] I have made the appropriate changes to documentation already
|
||||
|
||||
# How Has This Been Tested?
|
||||
|
||||
Please describe the tests that you ran to verify your changes, including relevant hardware setups. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||
|
||||
- [ ] Test A
|
||||
- [ ] Test B
|
||||
|
||||
**Test Configuration**:
|
||||
* Device type:
|
||||
* SSLClient version:
|
||||
* Arduino core version:
|
||||
* Additional library versions:
|
||||
* Hardware:
|
281
.github/workflows/ci.yml
vendored
Normal file
281
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,281 @@
|
|||
name: CI
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
branches-ignore:
|
||||
- gh-pages
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS: "https://adafruit.github.io/arduino-board-index/package_adafruit_index.json https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json"
|
||||
|
||||
jobs:
|
||||
build-examples-arduino:
|
||||
name: Arduino ${{ matrix.example }} for ${{ matrix.board.fqbn }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
example:
|
||||
- EthernetHTTPS
|
||||
- EthernetMultiHTTPS
|
||||
- EthernetMQTT
|
||||
- EthernetAWSIoT
|
||||
board:
|
||||
# Arduino Zero
|
||||
- arduino-platform: arduino:samd
|
||||
fqbn: arduino:samd:mzero_bl
|
||||
# Adafruit Feather M0
|
||||
- arduino-platform: arduino:samd adafruit:samd
|
||||
fqbn: adafruit:samd:adafruit_feather_m0
|
||||
# Arduino Due
|
||||
- arduino-platform: arduino:sam
|
||||
fqbn: arduino:sam:arduino_due_x
|
||||
# ESP32
|
||||
- arduino-platform: esp32:esp32
|
||||
fqbn: esp32:esp32:d32
|
||||
include:
|
||||
# STM32 Nucleo 144
|
||||
- board:
|
||||
arduino-platform: STM32:stm32
|
||||
fqbn: STM32:stm32:Nucleo_144:pnum=NUCLEO_F767ZI
|
||||
pio-platform: nucleo_f767zi
|
||||
example: stm32/EthernetHTTPSstm32
|
||||
steps:
|
||||
# Setup pyserial for esptool.py
|
||||
- name: Setup Python
|
||||
if: matrix.board.arduino-platform == 'esp32:esp32'
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
- name: Install Pyserial
|
||||
if: matrix.board.arduino-platform == 'esp32:esp32'
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyserial
|
||||
|
||||
# Setup Arduino-CLI
|
||||
- name: Install Arduino CLI
|
||||
uses: arduino/setup-arduino-cli@v1.1.1
|
||||
|
||||
# Install Dependencies
|
||||
- name: Install Core(s)
|
||||
run: arduino-cli core install ${{ matrix.board.arduino-platform }} -v
|
||||
- name: Install EthernetLarge
|
||||
run: git clone https://github.com/OPEnSLab-OSU/EthernetLarge.git ~/Arduino/libraries/EthernetLarge
|
||||
- name: Install Other Libraries
|
||||
run: arduino-cli lib install "STM32duino STM32Ethernet" PubSubClient -v
|
||||
|
||||
# Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: SSLClient
|
||||
|
||||
# Compile
|
||||
- name: Compile Sketch
|
||||
run: arduino-cli compile -v --libraries . --warnings all --fqbn ${{ matrix.board.fqbn }} SSLClient/examples/${{ matrix.example }}
|
||||
|
||||
build-examples-platformio:
|
||||
name: PIO ${{ matrix.example }} for ${{ matrix.board.pio-platform }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Copy of the above matrix (no anchors :( )
|
||||
example:
|
||||
- EthernetHTTPS
|
||||
- EthernetMultiHTTPS
|
||||
- EthernetMQTT
|
||||
- EthernetAWSIoT
|
||||
board:
|
||||
# Arduino Zero
|
||||
- pio-platform: zeroUSB
|
||||
# Adafruit Feather M0
|
||||
- pio-platform: adafruit_feather_m0
|
||||
# Arduino Due
|
||||
- pio-platform: dueUSB
|
||||
# ESP32
|
||||
- pio-platform: lolin32
|
||||
# Teensy 4.0
|
||||
- pio-platform: teensy40
|
||||
# Teensy 3.6
|
||||
- pio-platform: teensy36
|
||||
# Teensy 3.5
|
||||
- pio-platform: teensy35
|
||||
# Teensy 3.1/3.2
|
||||
- pio-platform: teensy31
|
||||
# Teensy 3.0
|
||||
- pio-platform: teensy30
|
||||
include:
|
||||
# STM32 Nucleo 144
|
||||
- board:
|
||||
pio-platform: nucleo_f767zi
|
||||
example: stm32/EthernetHTTPSstm32
|
||||
# TIVA-C
|
||||
- board:
|
||||
pio-platform: lptm4c1294ncpdt
|
||||
extra-flags: -O "lib_deps=SPI"
|
||||
example: tivac/EthernetHTTPStivac
|
||||
steps:
|
||||
# Setup python for platformio
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
|
||||
# Setup PlatformIO
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyserial platformio
|
||||
|
||||
# Install Dependencies
|
||||
- name: Install Libraries
|
||||
run: |
|
||||
pio lib -g install "stm32duino/STM32duino LwIP"
|
||||
pio lib -g install stm32duino/STM32Ethernet
|
||||
pio lib -g install PubSubClient
|
||||
pio lib -g install https://github.com/OPEnSLab-OSU/EthernetLarge.git
|
||||
|
||||
# Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Compile
|
||||
- name: Compile Sketch
|
||||
run: pio ci -l . -b ${{ matrix.board.pio-platform }} ${{ matrix.board.extra-flags }} ${{ github.workspace }}/examples/${{ matrix.example }}
|
||||
|
||||
compile-archives:
|
||||
name: Compile Archives
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-examples-arduino, build-examples-platformio]
|
||||
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
include:
|
||||
# Adafruit Feather M0
|
||||
- board:
|
||||
arduino-platform: arduino:samd adafruit:samd
|
||||
fqbn: adafruit:samd:adafruit_feather_m0
|
||||
arch: cortex-m0plus
|
||||
example: EthernetHTTPS
|
||||
# Arduino Due
|
||||
- board:
|
||||
arduino-platform: arduino:sam
|
||||
fqbn: arduino:sam:arduino_due_x
|
||||
arch: cortex-m3
|
||||
example: EthernetHTTPS
|
||||
# ESP32
|
||||
- board:
|
||||
arduino-platform: esp32:esp32
|
||||
fqbn: esp32:esp32:d32
|
||||
arch: esp32
|
||||
example: EthernetHTTPS
|
||||
# STM32
|
||||
- board:
|
||||
arduino-platform: STM32:stm32
|
||||
fqbn: STM32:stm32:Nucleo_144:pnum=NUCLEO_F767ZI
|
||||
arch: cortex-m7
|
||||
example: stm32/EthernetHTTPSstm32
|
||||
steps:
|
||||
# Setup pyserial for esptool.py
|
||||
- name: Setup Python
|
||||
if: matrix.board.arduino-platform == 'esp32:esp32'
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
- name: Install Pyserial
|
||||
if: matrix.board.arduino-platform == 'esp32:esp32'
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyserial
|
||||
|
||||
# Setup Arduino-CLI
|
||||
- name: Install Arduino CLI
|
||||
uses: arduino/setup-arduino-cli@v1.1.1
|
||||
|
||||
# Install Dependencies
|
||||
- name: Install Core(s)
|
||||
run: arduino-cli core install ${{ matrix.board.arduino-platform }} -v
|
||||
- name: Install EthernetLarge
|
||||
run: git clone https://github.com/OPEnSLab-OSU/EthernetLarge.git ~/Arduino/libraries/EthernetLarge
|
||||
- name: Install Other Libraries
|
||||
run: arduino-cli lib install "STM32duino STM32Ethernet" PubSubClient -v
|
||||
|
||||
# Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: SSLClient
|
||||
|
||||
# Compile with dot-a-linkage
|
||||
- name: Compile with Archive
|
||||
run: |
|
||||
echo "dot_a_linkage=true" >> SSLClient/library.properties
|
||||
arduino-cli compile -v --build-path ${{ github.workspace }}/build --libraries . --warnings all --fqbn ${{ matrix.board.fqbn }} SSLClient/examples/${{ matrix.example }}
|
||||
|
||||
# Upload as an artifact
|
||||
- name: Emit Compiled SSLClient
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.board.arch }}
|
||||
path: build/libraries/SSLClient/SSLClient.a
|
||||
|
||||
generate-release:
|
||||
name: Generate Release
|
||||
runs-on: ubuntu-latest
|
||||
needs: compile-archives
|
||||
steps:
|
||||
# Checkout
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Build the release changelog
|
||||
- name: Build Changelog
|
||||
id: build_changelog
|
||||
uses: heineiuo/create-changelogs@master
|
||||
|
||||
# Create a release
|
||||
- name: Publish Release
|
||||
id: publish_release
|
||||
uses: actions/create-release@v1
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ github.ref }}
|
||||
body: ${{ steps.build_changelog.outputs.changelogs }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Create SSLClient-precompiled
|
||||
- name: Convert Library to Precompiled Format
|
||||
run: |
|
||||
echo "precompiled=true" >> library.properties
|
||||
rm -rf .git
|
||||
find src/ -iname "*.c" -delete
|
||||
find src/ -iname "*.cpp" -delete
|
||||
|
||||
# Download all the artifacts
|
||||
- name: Add Precompiled Artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: src
|
||||
|
||||
# Zip the result
|
||||
- name: Generate SSLClient-precompiled
|
||||
run: zip -r SSLClient-precompiled.zip .
|
||||
|
||||
# Upload SSLClient-precompiled.zip to the release created
|
||||
- name: Upload SSLClient-precompiled
|
||||
uses: actions/upload-release-asset@v1
|
||||
with:
|
||||
upload_url: ${{ steps.publish_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
||||
asset_path: ./SSLClient-precompiled.zip
|
||||
asset_name: SSLClient-precompiled.zip
|
||||
asset_content_type: application/zip
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
26
.github/workflows/docs.yml
vendored
Normal file
26
.github/workflows/docs.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
name: Documentation
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
documentation:
|
||||
name: Documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Build Documentation
|
||||
uses: mattnotmitt/doxygen-action@v1
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: JamesIves/github-pages-deploy-action@3.7.1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BRANCH: gh-pages # The branch the action should deploy to.
|
||||
FOLDER: docs # The folder the action should deploy.
|
||||
CLEAN: true # Automatically remove deleted files from the deploy branch
|
105
.travis.yml
105
.travis.yml
|
@ -1,105 +0,0 @@
|
|||
language: c
|
||||
env:
|
||||
global:
|
||||
# You can uncomment this to explicitly choose an (old) version of the Arduino IDE
|
||||
#- ARDUINO_IDE_VERSION="1.8.7"
|
||||
- ADDITIONAL_URLS="https://adafruit.github.io/arduino-board-index/package_adafruit_index.json,https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json,https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json"
|
||||
- DOXYFILE=$TRAVIS_BUILD_DIR/.travis/Doxyfile
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- ~/arduino_ide
|
||||
- ~/.arduino15/packages/
|
||||
|
||||
# Blacklist
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
# Install dependencies
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- doxygen
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: "Build"
|
||||
name: "Feather M0"
|
||||
env: CORE="adafruit:samd" BOARD="adafruit:samd:adafruit_feather_m0"
|
||||
- name: "Arduino Zero"
|
||||
env: CORE="arduino:samd" BOARD="arduino:samd:mzero_bl"
|
||||
- name: "ESP32"
|
||||
env: CORE="esp32:esp32" BOARD="esp32:esp32:d32"
|
||||
- name: "STM32"
|
||||
env: CORE="STM32:stm32" BOARD="STM32:stm32:Nucleo_144:pnum=NUCLEO_F767ZI"
|
||||
script:
|
||||
- arduino-cli compile --warnings all --fqbn $BOARD $PWD/examples/stm32/EthernetHTTPSstm32
|
||||
|
||||
- stage: "Documentation"
|
||||
if: branch = master
|
||||
install: skip
|
||||
script:
|
||||
- doxygen $DOXYFILE
|
||||
deploy:
|
||||
provider: pages
|
||||
skip_cleanup: true
|
||||
local_dir: docs
|
||||
github_token: $GITHUB_TOKEN
|
||||
|
||||
- stage: "Deploy"
|
||||
if: tag is present
|
||||
env: CORE="arduino:samd esp32:esp32 STM32:stm32"
|
||||
script: skip
|
||||
before_deploy:
|
||||
- mkdir tmp-bin
|
||||
- cp library.properties library.properties.old
|
||||
- echo "dot_a_linkage=true" >> library.properties
|
||||
- rm -rf /tmp/arduino-sketch*
|
||||
# cortex-m0plus
|
||||
- arduino-cli compile --fqbn arduino:samd:mzero_bl $PWD/examples/EthernetHTTPS
|
||||
- mkdir tmp-bin/cortex-m0plus
|
||||
- cp "$(find /tmp/ -maxdepth 1 -type d -name "arduino-sketch*" -print | head -n 1)/libraries/SSLClient/SSLClient.a" tmp-bin/cortex-m0plus/SSLClient.a
|
||||
- rm -rf /tmp/arduino-sketch*
|
||||
# cortex-m7
|
||||
- arduino-cli compile --fqbn STM32:stm32:Nucleo_144:pnum=NUCLEO_F767ZI $PWD/examples/stm32/EthernetHTTPSstm32
|
||||
- mkdir tmp-bin/cortex-m7
|
||||
- cp "$(find /tmp/ -maxdepth 1 -type d -name "arduino-sketch*" -print | head -n 1)/libraries/SSLClient/SSLClient.a" tmp-bin/cortex-m7/SSLClient.a
|
||||
- rm -rf /tmp/arduino-sketch*
|
||||
# esp32
|
||||
- arduino-cli compile --fqbn esp32:esp32:d32 $PWD/examples/EthernetHTTPS
|
||||
- mkdir tmp-bin/esp32
|
||||
- cp "$(find /tmp/ -maxdepth 1 -type d -name "arduino-sketch*" -print | head -n 1)/libraries/SSLClient/SSLClient.a" tmp-bin/esp32/SSLClient.a
|
||||
# bundle it up!
|
||||
- mv library.properties.old library.properties
|
||||
- echo "precompiled=true" >> library.properties
|
||||
- mv tmp-bin/* src/
|
||||
- rm -rf tmp-bin
|
||||
- rm -rf .git
|
||||
- find src/ -iname "*.c" -delete
|
||||
- find src/ -iname "*.cpp" -delete
|
||||
- zip -r SSLClient-precompiled.zip .
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key: $GITHUB_TOKEN
|
||||
skip_cleanup: true
|
||||
file: "SSLClient-precompiled.zip"
|
||||
on:
|
||||
tags: true
|
||||
|
||||
install:
|
||||
- curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/bin sudo sh
|
||||
- arduino-cli core update-index --additional-urls $ADDITIONAL_URLS
|
||||
- arduino-cli core install arduino:samd -v
|
||||
- arduino-cli core install $CORE -v --additional-urls $ADDITIONAL_URLS
|
||||
- mkdir -p $HOME/Arduino/libraries
|
||||
- rm -rf $HOME/Arduino/libraries/EthernetLarge
|
||||
- git clone https://github.com/OPEnSLab-OSU/EthernetLarge.git $HOME/Arduino/libraries/EthernetLarge
|
||||
- arduino-cli lib install "STM32duino STM32Ethernet"
|
||||
- arduino-cli lib install "PubSubClient"
|
||||
- ln -s $PWD $HOME/Arduino/libraries/.
|
||||
|
||||
script:
|
||||
- arduino-cli compile --warnings all --fqbn $BOARD $PWD/examples/EthernetHTTPS
|
||||
- arduino-cli compile --warnings all --fqbn $BOARD $PWD/examples/EthernetMultiHTTPS
|
||||
- arduino-cli compile --warnings all --fqbn $BOARD $PWD/examples/EthernetMQTT
|
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at open.sensing@oregonstate.edu. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
19
CONTRIBUTING.md
Normal file
19
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Contributing
|
||||
|
||||
Thank you for contributing to SSLClient! This library is a single-person effort, so help is always appreciated.
|
||||
|
||||
There is no formal style guide, however this project does attempt to provide detailed documentation through the README and [Doxygen block comments](https://www.doxygen.nl/manual/docblocks.html) which are highly encouraged. If you get stuck or have a question, please feel free to [submit an issue](https://github.com/OPEnSLab-OSU/SSLClient/issues/new?assignees=&labels=question&template=question.md&title=). Below are some resources to get you started:
|
||||
* **TLS**
|
||||
* [How does SSL work? (StackOverflow)](https://security.stackexchange.com/questions/20803/how-does-ssl-tls-work)
|
||||
* [What happens in a TLS handshake? (Cloudflare)](https://www.cloudflare.com/learning/ssl/what-happens-in-a-tls-handshake/)
|
||||
* [What is mTLS? (wott.io)](https://wott.io/blog/tutorials/2019/09/09/what-is-mtls)
|
||||
* **BearSSL**
|
||||
* [BearSSL Homepage](https://bearssl.org/)
|
||||
* [BearSSL TLS API Overview](https://bearssl.org/api1.html) (SSLClient uses the Generic I/O version ot the API).
|
||||
* [BearSSL Certificate API Overview](https://bearssl.org/x509.html) (SSLClient uses the Minimal Engine)
|
||||
* [BearSSL Doxygen](https://bearssl.org/apidoc/index.html)
|
||||
* **SSLClient**
|
||||
* [README](./README.md)
|
||||
* [Trust Anchors Overview](./TrustAnchors.md)
|
||||
* [Known ESP32 Issue with PubSubClient](https://github.com/OPEnSLab-OSU/SSLClient/issues/9)
|
||||
* [Known ESP8266 Issue with any TLS Connection](https://github.com/OPEnSLab-OSU/SSLClient/issues/5)
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = SSLClient
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = v1.6.2
|
||||
PROJECT_NUMBER = v1.6.11
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
98
README.md
98
README.md
|
@ -1,22 +1,20 @@
|
|||
# SSLClient
|
||||
|
||||
[](https://travis-ci.org/OPEnSLab-OSU/SSLClient)
|
||||

|
||||
|
||||
**SSLClient requires at least 110kb flash and 7kb RAM, and will not compile otherwise. This means that most Arduino boards are not supported. Check your board's specifications before attempting to use this library.**
|
||||
SSLClient adds [TLS 1.2](https://www.websecurity.symantec.com/security-topics/what-is-ssl-tls-https) functionality to any network library implementing the [Arduino Client interface](https://www.arduino.cc/en/Reference/ClientConstructor), including the Arduino [EthernetClient](https://www.arduino.cc/en/Reference/EthernetClient) and [WiFiClient](https://www.arduino.cc/en/Reference/WiFiClient) classes. SSLClient was created to integrate TLS seamlessly with the Arduino infrastructure using [BearSSL](https://bearssl.org/) as an underlying TLS engine. Unlike [ArduinoBearSSL](https://github.com/arduino-libraries/ArduinoBearSSL), SSLClient is completly self-contained, and does not require any additional hardware (other than a network connection).
|
||||
|
||||
SSLClient officially supports SAMD21, SAM3X, ESP32, TIVA C, STM32F7, and Teensy >= 3.0; but it should work on any board with at least 110kB flash and 7kB RAM. SSClient does not currently support ESP8266 (see [this issue](https://github.com/OPEnSLab-OSU/SSLClient/issues/5#issuecomment-569968546)) or AVR due to memory constraints on both platforms.
|
||||
|
||||
You can also view this README in [doxygen](https://openslab-osu.github.io/SSLClient/index.html).
|
||||
|
||||
SSLClient is a simple library to add [TLS 1.2](https://www.websecurity.symantec.com/security-topics/what-is-ssl-tls-https) functionality to any network library implementing the [Arduino Client interface](https://www.arduino.cc/en/Reference/ClientConstructor), including the Arduino [EthernetClient](https://www.arduino.cc/en/Reference/EthernetClient) and [WiFiClient](https://www.arduino.cc/en/Reference/WiFiClient) classes (though it is better to prefer WiFClient.connectSSL if implemented). In other words, SSLClient implements encrypted communication through TLS on devices that do not otherwise support it.
|
||||
|
||||
SSLClient has been tested on the SAMD21, ESP32, TIVA C, and STM32. SSClient does not currently support the ESP8266 (see [this issue](https://github.com/OPEnSLab-OSU/SSLClient/issues/5#issuecomment-569968546)).
|
||||
|
||||
## Overview
|
||||
|
||||
Using SSLClient should be similar to using any other Arduino-based Client class, since this library was developed around compatibility with [EthernetClient](https://www.arduino.cc/en/Reference/EthernetClient). There are a few extra things, however, that you will need to get started:
|
||||
Using SSLClient is similar to using any other Arduino-based Client class, as this library was developed around compatibility with [EthernetClient](https://www.arduino.cc/en/Reference/EthernetClient). There are a few extra things, however, that you will need to get started:
|
||||
|
||||
1. **Board and Network Peripheral** - Your board should have a lot of resources (>110kb flash and >7kb RAM), and your network peripheral should have a large internal buffer (>7kb). This library was tested with the [Adafruit Feather M0](https://www.adafruit.com/product/2772) (256K flash, 32K RAM) and the [Adafruit Ethernet Featherwing](https://www.adafruit.com/product/3201) (16kb Buffer), and we still had to modify the Arduino Ethernet library to support larger internal buffers per socket (see the [Implementation Gotchas](#sslclient-with-ethernet)).
|
||||
2. **Trust Anchors** - You will need a header containing array of trust anchors ([example](./readme/cert.h)), which are used to verify the SSL connection later on. **This file must generated for every project.** Check out [TrustAnchors.md](./TrustAnchors.md) on how to generate this file for your project, and for more information about what a trust anchor is.
|
||||
3. **Network Peripheral Driver Implementing `Client`** - Examples include `EthernetClient`, `WiFiClient`, and so on—SSLClient will run on top of any network driver exposing the `Client` interface. We tested this library using [EthernetClient](https://www.arduino.cc/en/Reference/EthernetClient).
|
||||
1. **Board and Network Peripheral** - Your board should have a lot of resources (>110kB flash and >7kB RAM), and your network peripheral should have a large internal buffer (>7kB). This library was tested with the [Adafruit Feather M0](https://www.adafruit.com/product/2772) (256K flash, 32K RAM) and the [Adafruit Ethernet Featherwing](https://www.adafruit.com/product/3201) (16kB Buffer), and we still had to modify the Arduino Ethernet library to support larger internal buffers per socket (see the [Implementation Gotchas](#sslclient-with-ethernet)).
|
||||
2. **Trust Anchors** - You will need a header containing array of trust anchors ([example](./readme/cert.h)), which are used to verify the SSL connection later on. **This file must generated for every project.** Check out [TrustAnchors.md](./TrustAnchors.md#generating-trust-anchors) on how to generate this file for your project, and for more information about what a trust anchor is.
|
||||
3. **Network Peripheral Driver Implementing `Client`** - Examples include `EthernetClient`, `WiFiClient`, and so on—SSLClient will run on top of any network driver exposing the `Client` interface.
|
||||
4. **Analog Pin** - Used for generating random data at the start of the connection (see the [Implementation Gotchas](#implementation-gotchas)).
|
||||
|
||||
Once all those are ready, you can create an SSLClient object like this:
|
||||
|
@ -51,14 +49,10 @@ client.flush();
|
|||
// read and print the data
|
||||
...
|
||||
```
|
||||
**Note**: `client.connect("www.arduino.cc", 443)` can take 5-15 seconds to finish. This an unavoidable consequence of the SSL protocol, and is detailed in [Implementation Notes](#resources).
|
||||
**Note**: `client.connect("www.arduino.cc", 443)` can take 5-15 seconds to finish on some low-power devices. This an unavoidable consequence of the SSL protocol, and is detailed more in [Implementation Gotchas](#resources).
|
||||
|
||||
For more information on SSLClient, check out the [examples](./examples), [API documentation](https://openslab-osu.github.io/SSLClient/html/index.html), or the rest of this README.
|
||||
|
||||
## How It Works
|
||||
|
||||
SSLClient was created to integrate SSL seamlessly with the Arduino infrastructure, and so it does just that: implementing the brilliant [BearSSL](https://bearssl.org/) as a proxy in front of any Arduino socket library. BearSSL is designed with low flash footprint in mind, and as a result does little verification of improper programming, relying on the developer to ensure the code is correct. Since SSLClient is built specifically for the Arduino ecosystem, most of SSLClient's code adds those programming checks back in, making debugging a fast and simple process.
|
||||
|
||||
## Other Features
|
||||
|
||||
### Logging
|
||||
|
@ -70,7 +64,7 @@ SSLClient client(baseClient, TAs, (size_t)2, A7, 1, SSLClient::SSL_INFO);
|
|||
Logging is always outputted through the [Arduino Serial interface](https://www.arduino.cc/reference/en/language/functions/communication/serial/), so you'll need to setup Serial before you can view the SSL logs. Log levels are enumerated in ::DebugLevel. The log level is set to `SSL_WARN` by default.
|
||||
|
||||
### Errors
|
||||
When SSLClient encounters an error, it will attempt to terminate the SSL session gracefully if possible, and then close the socket. Simple error information can be found from SSLClient::getWriteError(), which will return a value from the ::Error enum. For more detailed diagnostics, you can look at the serial logs, which will be displayed if the log level is at `SSL_ERROR` or lower.
|
||||
When SSLClient encounters an error, it will attempt to terminate the SSL session gracefully if possible, and then close the socket. Simple error information can be found from SSLClient::getWriteError, which will return a value from the ::Error enum. For more detailed diagnostics, you can look at the serial logs, which will be displayed if the log level is at `SSL_ERROR` or lower.
|
||||
|
||||
### Write Buffering
|
||||
As you may have noticed in the documentation for SSLClient::write, calling this function does not actually write to the network. Instead, you must call SSLClient::available or SSLClient::flush, which will detect that the buffer is ready and write to the network (see SSLClient::write for details).
|
||||
|
@ -90,7 +84,7 @@ client.write("Connection: close\r\n");
|
|||
while (!client.available()) { /* ... */ }
|
||||
// ...
|
||||
```
|
||||
Notice that every single write() call immediately writes to the network, which is fine with most network clients. With SSL, however, if we are encrypting and writing to the network every write() call, this will result in a lot of small encryption tasks. Encryption takes a lot of time and code, so to reduce the overhead of an SSL connection, SSLClient::write implicitly buffers until the developer states that they are waiting for data to be received with SSLClient::available. A simple example can be found below:
|
||||
Notice that every single `client.write()` call immediately writes to the network. This behavior is fine for most network clients; with SSL, however, it results in many small encryption tasks that consume resources. To reduce the overhead of an SSL connection, SSLClient::write implicitly buffers until the developer states that they are waiting for data to be received with SSLClient::available. A simple example can be found below:
|
||||
|
||||
```C++
|
||||
EthernetClient baseClient;
|
||||
|
@ -111,18 +105,18 @@ while (!client.available()) { /* ... */ }
|
|||
If you would like to trigger a network write manually without using the SSLClient::available, you can also call SSLClient::flush, which will write all data and return when finished.
|
||||
|
||||
### Session Caching
|
||||
As detailed in the [resources section](#resources), SSL handshakes take an extended period (1-4sec) to negotiate. To remedy this problem, BearSSL is able to keep a [SSL session cache](https://bearssl.org/api1.html#session-cache) of the clients it has connected to. If BearSSL successfully resumes an SSL session, it can reduce connection time to 100-500ms.
|
||||
As detailed in the [resources section](#resources), SSL handshakes take an extended period (1-4sec) to negotiate. BearSSL is able to keep a [SSL session cache](https://bearssl.org/api1.html#session-cache) of the clients it has connected to which can drastically reduce this time: if BearSSL successfully resumes an SSL session, connection time is typically 100-500ms.
|
||||
|
||||
In order to use SSL session resumption:
|
||||
* The website you are connecting to must support it. Support is widespread, but you can verify easily using the [SSLLabs tool](https://www.ssllabs.com/ssltest/).
|
||||
* The website you are connecting to must support it. Support is widespread, and you can verify it using [SSLLabs](https://www.ssllabs.com/ssltest/).
|
||||
* You must reuse the same SSLClient object (SSL Sessions are stored in the object itself).
|
||||
* You must reconnect to the exact same server.
|
||||
* You must reconnect to the exact same server (detailed below).
|
||||
|
||||
SSLClient automatically stores an IP address and hostname in each session, ensuring that if you call `connect("www.google.com")` SSLClient will use the SSL session with that hostname. However, because some websites have multiple servers on a single IP address (github.com being an example), you may find that even if you are connecting to the same host the connection does not resume. This is a flaw in the SSL session protocol — though it has been resolved in TLS 1.3, the lack of widespread adoption of the new protocol prevents it from being used here. SSL sessions can also expire based on server criteria, which will result in a standard 4-10 second connection.
|
||||
> NOTE: SSLClient automatically stores an IP address and hostname in each session, ensuring that if you call `connect("www.google.com")` SSLClient will use the same SSL session for that hostname. Unfortunately some websites have multiple servers on a single IP address (github.com being an example), so you may find that even if you are connecting to the same host the connection will not resume. This is a flaw in the SSL session protocol—though it has been resolved in TLS 1.3, the lack of widespread adoption of the new protocol prevents it from being resolved here.
|
||||
>
|
||||
> SSL sessions can also expire based on server criteria (ex. timeout), which will result in a standard 4-10 second connection.
|
||||
|
||||
You can test whether or not a website can resume SSL Sessions using the [Session Example](./examples/Session_Example/Session_Example.ino) included with this library. Because of all the confounding factors of SSL Sessions, it is generally prudent while programming to assume the session will always fail to resume.
|
||||
|
||||
SSL sessions take a lot of memory to store, so by default SSLClient will only store one at a time. You can change this behavior by adding the following to your SSLClient declaration:
|
||||
SSL sessions take memory to store, so by default SSLClient will only store one at a time. You can change this behavior by adding the following to your SSLClient declaration:
|
||||
```C++
|
||||
EthernetClient baseClient;
|
||||
SSLClient client(baseClient, TAs, (size_t)2, A7, SomeNumber);
|
||||
|
@ -138,7 +132,7 @@ If you need to clear a session, you can do so using the SSLSession::removeSessio
|
|||
|
||||
### mTLS
|
||||
|
||||
As of `v1.6.0`, SSLClient supports [mutual TLS authentication](https://developers.cloudflare.com/access/service-auth/mtls/). mTLS is a varient of TLS that verifys both the server and device identities before a connection, and is commonly used in IoT protocols as a secure layer (MQTT over TLS, HTTPS over TLS, etc.).
|
||||
As of `v1.6.0`, SSLClient supports [mutual TLS authentication](https://developers.cloudflare.com/access/service-auth/mtls/). mTLS is a varient of TLS that verifies both the server and device identities before a connection, and is commonly used in IoT protocols as a secure layer (MQTT over TLS, HTTP over TLS, etc.).
|
||||
|
||||
To use mTLS with SSLClient you will need to a client certificate and client private key associated with the server you are attempting to connect to. Depending on your use case, you will either generate these yourself (ex. [Mosquito MQTT setup](http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/)), or have them generated for you (ex. [AWS IoT Certificate Generation](https://docs.aws.amazon.com/iot/latest/developerguide/create-device-certificate.html)). Given this cryptographic information, you can modify the standard SSLClient connection sketch to enable mTLS authentication:
|
||||
```C++
|
||||
|
@ -175,14 +169,19 @@ void setup() {
|
|||
}
|
||||
...
|
||||
```
|
||||
Note that both the above client information *as well as* the correct trust anchors associated with the server are needed for the connection to succeed. Additionally, the certificate must be formatted correctly (according to [BearSSL's specification](https://bearssl.org/apidoc/bearssl__pem_8h.html)) in order for mTLS to work. If the certificate is improperly formatted, SSLClient will attempt to make a regular TLS connection instead of an mTLS one, and fail to connect as a result. Because of this, if you are seeing errors similar to `"peer did not send certificate chain"` on your server, check that your certificate and key are formatted correctly (see https://github.com/OPEnSLab-OSU/SSLClient/issues/7#issuecomment-593704969). For more information on SSLClient's mTLS functionality, please see the [SSLClientParameters documentation](https://openslab-osu.github.io/SSLClient/class_s_s_l_client_parameters.html).
|
||||
|
||||
> NOTE: Certificates are finicky, and it is easy to make mistakes when generating a certificate chain yourself. If SSLClient raises an error that says `Expected server name not found in chain`, double check that the common name, distinguished name, and issuer name are being set correctly (check out [this article](https://medium.com/@superseb/get-your-certificate-chain-right-4b117a9c0fce) for how to do that).
|
||||
|
||||
The client certificate must be formatted correctly (according to [BearSSL's specification](https://bearssl.org/apidoc/bearssl__pem_8h.html)) in order for mTLS to work. If the certificate is improperly formatted, SSLClient will attempt to make a regular TLS connection instead of an mTLS one, and fail to connect as a result. Because of this, if you are seeing errors similar to `"peer did not send certificate chain"` on your server, check that your certificate and key are formatted correctly (see https://github.com/OPEnSLab-OSU/SSLClient/issues/7#issuecomment-593704969). For more information on SSLClient's mTLS functionality, please see the [SSLClientParameters documentation](https://openslab-osu.github.io/SSLClient/class_s_s_l_client_parameters.html).
|
||||
|
||||
Note that both the above client certificate information *as well as* the correct trust anchors associated with the server are needed for the connection to succeed. Trust anchors will typically be generated from the CA used to generate the server certificate. More information on generating trust anchors can be found in [TrustAnchors.md](./TrustAnchors.md).
|
||||
|
||||
## Implementation Gotchas
|
||||
|
||||
Some ideas that didn't quite fit in the API documentation.
|
||||
|
||||
### SSLClient with Ethernet
|
||||
If you are using the [Arduino Ethernet library](https://github.com/arduino-libraries/Ethernet), you will need to modify the library to support the large buffer sizes required by SSL (detailed in [resources](#resources)). You can either modify the library yourself, or use [this fork of the Ethernet library with the modification](https://github.com/OPEnSLab-OSU/EthernetLarge). To use the fork, simply install the library using the "add a .zip library" button in Arduino, and replace `#include "Ethernet.h"` with `#include "EthernetLarge.h"` in your sketch. Alternatively if for some reason this solution does not work, you can apply the modification using the instructions below.
|
||||
If you are using the [Arduino Ethernet library](https://github.com/arduino-libraries/Ethernet) you will need to modify the library to support the large buffer sizes required by SSL (detailed in [resources](#resources)). You can either modify the library yourself, or use [this fork of the Ethernet library with the modification](https://github.com/OPEnSLab-OSU/EthernetLarge). To use the fork: download a zipped copy of the fork through GiThub, use the "add a .zip library" button in Arduino to install the library, and replace `#include "Ethernet.h"` with `#include "EthernetLarge.h"` in your sketch. Alternatively if for some reason this solution does not work, you can apply the modification manually using the instructions below.
|
||||
|
||||
#### Manual Modification
|
||||
|
||||
|
@ -236,24 +235,39 @@ SSLClient uses BearSSL's [minimal x509 verification engine](https://bearssl.org/
|
|||
|
||||
BearSSL also features a [known certificate validation engine](https://bearssl.org/x509.html#the-known-key-engine), which only allows for a single domain in exchange for a significantly reduced resource usage (flash and CPU time). This functionality is planned to be implemented in the future.
|
||||
|
||||
#### Time
|
||||
The minimal x509 verification engine requires an accurate source of time to properly verify the creation and expiration dates of a certificate. As most embedded devices do not have a reliable source of time, by default SSLClient opts to use the compilation timestamp ([`__DATE__` and `__TIME__`](https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html)) as the "current time" during the verification process. While this approach reduces the complexity of using SSLClient, it is inherently insecure, and can cause errors if certificates are redeployed (see [#27](https://github.com/OPEnSLab-OSU/SSLClient/issues/27)): to accommodate these edge cases, SSLClient::setVerificationTime can be used to update the timestamp before connecting, resolving the above issues.
|
||||
|
||||
### Resources
|
||||
The SSL protocol recommends a device support many different encryption algorithms, as well as protocols for SSL itself. The complexity of both of those components results in many medium sized components forming an extremely large whole. Additionally, most embedded processors lack the sophisticated math hardware commonly found in a modern CPU, and as a result require more instructions to create the encryption algorithms SSL requires. This not only increases size but makes the algorithms slow and memory intensive.
|
||||
The SSL/TLS protocol recommends a device support many different encryption and handshake algorithms. The complexity of these components results in many medium-footprint algorithms forming an extremely large whole. Compilation size of the [EthernetHTTPS](examples/EthernetHTTPS/EthernetHTTPS.ino) example in SSLClient `v1.6.11` for various boards is shown below:
|
||||
|
||||
To illustrate this, I will run some tests on various domains below. I haven't yet, but I will.
|
||||
| Board | Size
|
||||
| :--- | :--- |
|
||||
| Arduino Zero | <pre>`RAM: [=== ] 33.7% (used 11052 bytes from 32768 bytes)`<br/>`Flash: [=== ] 34.7% (used 90988 bytes from 262144 bytes)`</pre> |
|
||||
| Arduino Due | <pre>`RAM: [= ] 11.7% (used 11548 bytes from 98304 bytes)`<br/>`Flash: [== ] 16.7% (used 87572 bytes from 524288 bytes)`</pre> |
|
||||
| Adafruit Feather M0 | <pre>`RAM: [==== ] 40.4% (used 13240 bytes from 32768 bytes)`<br/>`Flash: [==== ] 40.0% (used 104800 bytes from 262144 bytes)`</pre> |
|
||||
| ESP32 (Lolin32) | <pre>`RAM: [= ] 6.9% (used 22476 bytes from 327680 bytes)`<br/>`Flash: [== ] 24.0% (used 314956 bytes from 1310720 bytes)`</pre> |
|
||||
| Teensy 3.0 | <pre>`RAM: [======== ] 78.2% (used 12812 bytes from 16384 bytes)`<br/>`Flash: [======== ] 79.8% (used 104532 bytes from 131072 bytes)`</pre> |
|
||||
| Teensy 3.1 | <pre>`RAM: [== ] 19.9% (used 13020 bytes from 65536 bytes)`<br/>`Flash: [==== ] 40.6% (used 106332 bytes from 262144 bytes)`</pre> |
|
||||
| Teensy 3.5 | <pre>`RAM: [ ] 5.0% (used 12996 bytes from 262136 bytes)`<br/>`Flash: [== ] 20.1% (used 105476 bytes from 524288 bytes)`</pre>
|
||||
| Teensy 3.6 | <pre>`RAM: [ ] 5.0% (used 13060 bytes from 262144 bytes)`<br/>`Flash: [= ] 10.2% (used 106828 bytes from 1048576 bytes)`</pre> |
|
||||
| Teensy 4.0 | <pre>`RAM: [=== ] 25.9% (used 135860 bytes from 524288 bytes)`<br/>`Flash: [= ] 5.7% (used 115344 bytes from 2031616 bytes)`</pre> |
|
||||
|
||||
If flash footprint is becoming a problem, there are numerous debugging strings (~3kb estimated) that can be removed from `SSLClient.h`, `SSLClientImpl.h`, and `SSLClientImpl.cpp`. I have not figured out a way to configure compilation of these strings, so you will need to modify the library to remove them yourself.
|
||||
In addition to the above, most embedded processors lack the sophisticated math hardware commonly found in a modern CPU, which results in slow and memory intensive execution of these algorithms. Because of this, it is recommended that SSLClient have 8kb of memory available on the stack during a connection, and 4-10 seconds should be allowed for the connection to complete. Note that this requirement is based on the SAMD21—more powerful processors (such as the ESP32) will see faster connection times.
|
||||
|
||||
> NOTE: If flash footprint is becoming a problem, there are numerous debugging strings (~3kB estimated) that can be removed from `SSLClient.h`, `SSLClientImpl.h`, and `SSLClientImpl.cpp`. Unfortunately I have not figured out a way to configure compilation of these strings, so you will need to modify the library to remove them yourself.
|
||||
|
||||
### Read Buffer Overflow
|
||||
SSL is a buffered protocol, and since most microcontrollers have limited resources (see [Resources](#resources)), SSLClient is limited in the size of its buffers. A common problem I encountered with SSL connections is buffer overflow, caused by the server sending too much data at once. This problem is caused by the microcontroller being unable to copy and decrypt data faster than it is being received, forcing some data to be discarded. This usually puts BearSSL in an unrecoverable state, forcing SSLClient to close the connection with a write error. If you are experiencing frequent timeout problems, this could be the reason why.
|
||||
SSL is a buffered protocol, and since most microcontrollers have limited resources (see [Resources](#resources)), SSLClient is limited in the size of its buffers. A common problem I encountered with SSL connections is buffer overflow caused by the server sending too much data at once. This problem is caused by the microcontroller being unable to copy and decrypt data faster than it is being received—forcing some data to be discarded. This usually puts BearSSL in an unrecoverable state, forcing SSLClient to close the connection with a write error. If you are experiencing frequent timeout problems this could be the reason why.
|
||||
|
||||
In order to remedy this problem, the device must be able to read the data faster than it is being received, or alternatively have a cache large enough to store the entire payload. Since SSL's encryption forces the device to read slowly, this means we must increase the cache size. Depending on your platform, there are a number of ways this can be done:
|
||||
* Sometimes your communication shield will have an internal buffer, which can be expanded through the driver code. This is the case with the Arduino Ethernet library (in the form of the MAX_SOCK_NUM and ETHERNET_LARGE_BUFFERS macros), however the library must be modified for the change to take effect.
|
||||
* SSLClient has an internal buffer SSLClientImpl::m_iobuf, which can be expanded. BearSSL limits the amount of data that can be processed based on the stage in the SSL handshake, and so this will change will have limited usefulness.
|
||||
* In some cases, a website will send so much data that even with the above solutions, SSLClient will be unable to keep up (a website with a lot of HTML is an example). In these cases you will have to find another method of retrieving the data you need.
|
||||
* If none of the above are viable, it is possible to implement your own Client class which has an internal buffer much larger than both the driver and BearSSL. This would require in-depth knowledge of programming and the communication shield you are working with, as well as a microcontroller with a significant amount of RAM.
|
||||
In order to remedy this problem, the device must be able to read the data faster than it is being received or have a cache large enough to store the entire payload. Since the device is typically already reading as fast as it can, we must increase the cache size in order to resolve this issue. Depending on your platform there are a number of ways this can be done:
|
||||
* Sometimes your communication shield will have an internal buffer which can be expanded through the driver code: this is the case with the Arduino Ethernet library (in the form of the `MAX_SOCK_NUM` and `ETHERNET_LARGE_BUFFERS` macros show [here](#manual-modification)), but mileage may vary with other drivers.
|
||||
* SSLClient has an internal buffer SSLClient::m_iobuf which can be expanded. Unfortunately, BearSSL limits the amount of data that can be put into the buffer based on the stage in the SSL handshake, and so increasing the buffer will have limited usefulness.
|
||||
* In some cases, a website will send so much data that even with the above solutions SSLClient will be unable to keep up. In these cases you will have to find another method of retrieving the data you need.
|
||||
* If none of the above are viable, it is possible to implement your own Client class which has an internal buffer much larger than both the driver and BearSSL. This implementation would require in-depth knowledge of communication shield you are working with and a microcontroller with a significant amount of RAM, but would be the most robust solution available.
|
||||
|
||||
### Cipher Support
|
||||
By default, SSLClient supports only TLS1.2 and the ciphers listed in [this file](./src/TLS12_only_profile.c) under `suites[]`, and the list is relatively small to keep the connection secure and the flash footprint down. These ciphers should work for most applications, however if for some reason you would like to use an older version of TLS or a different cipher, you can change the BearSSL profile being used by SSLClient to an [alternate one with support for older protocols](./src/bearssl/src/ssl/ssl_client_full.c). To do this, edit `SSLClientImpl::SSLClientImpl` to change these lines:
|
||||
By default, SSLClient supports only TLS1.2 and the ciphers listed in [this file](./src/TLS12_only_profile.c) under `suites[]`, and the list is relatively small to keep the connection secure and the flash footprint down. These ciphers should work for most applications, however if for some reason you would like to use an older version of TLS or a different cipher you can change the BearSSL profile being used by SSLClient to an [alternate one with support for older protocols](./src/bearssl/src/ssl/ssl_client_full.c). To do this, edit `SSLClientImpl::SSLClientImpl` to change these lines:
|
||||
```C++
|
||||
br_client_init_TLS12_only(&m_sslctx, &m_x509ctx, m_trust_anchors, m_trust_anchors_num);
|
||||
// comment the above line and uncomment the line below if you're having trouble connecting over SSL
|
||||
|
@ -266,3 +280,13 @@ to this:
|
|||
br_ssl_client_init_full(&m_sslctx, &m_x509ctx, m_trust_anchors, m_trust_anchors_num);
|
||||
```
|
||||
If for some unfortunate reason you need SSL 3.0 or SSL 2.0, you will need to modify the BearSSL profile to enable support. Check out the [BearSSL profiles documentation](https://bearssl.org/api1.html#profiles) and I wish you the best of luck.
|
||||
|
||||
### Security
|
||||
Unlike BearSSL, SSLClient is not rigorously vetted to be secure. If your project has security requirements I recommend you utilize BearSSL directly.
|
||||
|
||||
### Known Issues
|
||||
* In some drivers (Ethernet), calls to `Client::flush` will hang if internet is available but there is no route to the destination. Unfortunately SSLClient cannot correct for this without modifying the driver itself, and as a result the recommended solution is ensuring you choose a driver with built-in timeouts to prevent freezing. [More information here](https://github.com/OPEnSLab-OSU/SSLClient/issues/13#issuecomment-643855923).
|
||||
* Previous to SSLClient `v1.6.11`, `SSLClient::write` would sometimes call `br_ssl_engine_sendapp_ack` with zero bytes, which resulted in a variety of issues including (but not limited to) and infinite recursion loop on the esp32 ([#9](https://github.com/OPEnSLab-OSU/SSLClient/issues/9), [#30](https://github.com/OPEnSLab-OSU/SSLClient/issues/30)).
|
||||
* Previous to SSLClient `v1.6.7`, calls to `SSLClient::stop` would sometimes hang the device. More information in issue https://github.com/OPEnSLab-OSU/SSLClient/issues/13.
|
||||
* Previous to SSLClient `v1.6.6`, calls to `SSLClient::connect` would fail if the driver indicated that a socket was already opened (`Client::connected` returned true). This behavior created unintentional permanent failures when `Client::stop` would fail to close the socket, and as a result was downgraded to a warning in v1.6.6.
|
||||
* Previous to SSLClient `v1.6.3`, calling `SSLClient::write` with more than 2kB of total data before flushing the write buffer would cause a buffer overflow.
|
|
@ -1,4 +1,5 @@
|
|||
# Trust Anchors
|
||||
## Background
|
||||
|
||||
SSLClient uses BearSSL's [minimal x509 verification engine](https://bearssl.org/x509.html#the-minimal-engine) to verify the certificate of an SSL connection. This engine requires the developer create a trust anchor array using values stored in trusted root certificates. In short, these trust anchor arrays allow BearSSL to verify that the server being connected to is who they say they are, and not someone malicious. You can read more about certificates and why they are important [here](https://www.globalsign.com/en/ssl-information-center/what-is-an-ssl-certificate/).
|
||||
|
||||
|
@ -36,12 +37,18 @@ static const br_x509_trust_anchor TAs[] = {
|
|||
```
|
||||
A full example of a trust anchor header can be found in [this file](./readme/cert.h). Full documentation for the format of these variables can be found in the [BearSSL documentation for br_x509_trust_anchor](https://bearssl.org/apidoc/structbr__x509__trust__anchor.html).
|
||||
|
||||
|
||||
|
||||
## Generating Trust Anchors
|
||||
|
||||
Typically a trust anchor header file is generated using [brssl](https://bearssl.org/gitweb/?p=BearSSL;a=tree;f=tools;h=0fa053e41d6bf88a28472f3b22dde41b21f14292;hb=dda1f8a0c46e15b4a235163470ff700b2f13dcc5), a command-line utility included in BearSSL. As it is a fairly involded process to get brssl working, SSLClient provides a number of alternative tools to make the generation process a bit easier.
|
||||
|
||||
**Note:** When working with certificates (particularly in complicated mTLS setups), it can easily become confusing which certificate does what. If you aren't sure what certificate to put into the Trust Anchor tool, remember that Trust Anchors *only care about the verifying the server*: in other words, the certificate that goes into a Trust Anchor generation tool should be the certificate used to generate the server's certificate (usually a CA). Trust Anchors will never contain any information about client certificates, which should be passed into [SSLClientParams](https://github.com/OPEnSLab-OSU/SSLClient#mtls) instead.
|
||||
|
||||
### HTTPS
|
||||
|
||||
For HTTPS, there a couple of tools you can use. Ordered from easiest to hardest:
|
||||
* [This website, written to simplify the creation of trust anchor headers](https://openslab-osu.github.io/bearssl-certificate-utility/). Simply plug and play.
|
||||
* This website, written to simplify the creation of trust anchor headers: https://openslab-osu.github.io/bearssl-certificate-utility/. Simply plug and play.
|
||||
* [pycert_bearssl](./tools/pycert_bearssl/pycert_bearssl.py), a command line utility based on a [pycert](https://learn.adafruit.com/introducing-the-adafruit-wiced-feather-wifi/pycert-dot-py). You will need to install Python 3, and follow the instructions in the [pycert_bearssl.py file](./tools/pycert_bearssl/pycert_bearssl.py). You'll want to use the `pycert_bearssl.py download` command once the utility is set up.
|
||||
* The `brssl` command line utility, included in the [BearSSL source](https://bearssl.org/gitweb/?p=BearSSL;a=blob_plain;f=tools/brssl.h;hb=HEAD). You will need to compile this file yourself.
|
||||
|
||||
|
|
74
examples/EthernetAWSIoT/AWS_Root_CA.h
Normal file
74
examples/EthernetAWSIoT/AWS_Root_CA.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
#ifndef _CERTIFICATES_H_
|
||||
#define _CERTIFICATES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* This file is auto-generated by the pycert_bearssl tool. Do not change it manually.
|
||||
* Certificates are BearSSL br_x509_trust_anchor format. Included certs:
|
||||
*
|
||||
* Index: 0
|
||||
* Label: Amazon Root CA 1
|
||||
* Subject: CN=Amazon Root CA 1,O=Amazon,C=US
|
||||
*/
|
||||
|
||||
#define TAs_NUM 1
|
||||
|
||||
static const unsigned char TA_DN0[] = {
|
||||
0x30, 0x39, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x06, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x19, 0x30, 0x17,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6d, 0x61, 0x7a, 0x6f,
|
||||
0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_N0[] = {
|
||||
0xb2, 0x78, 0x80, 0x71, 0xca, 0x78, 0xd5, 0xe3, 0x71, 0xaf, 0x47, 0x80,
|
||||
0x50, 0x74, 0x7d, 0x6e, 0xd8, 0xd7, 0x88, 0x76, 0xf4, 0x99, 0x68, 0xf7,
|
||||
0x58, 0x21, 0x60, 0xf9, 0x74, 0x84, 0x01, 0x2f, 0xac, 0x02, 0x2d, 0x86,
|
||||
0xd3, 0xa0, 0x43, 0x7a, 0x4e, 0xb2, 0xa4, 0xd0, 0x36, 0xba, 0x01, 0xbe,
|
||||
0x8d, 0xdb, 0x48, 0xc8, 0x07, 0x17, 0x36, 0x4c, 0xf4, 0xee, 0x88, 0x23,
|
||||
0xc7, 0x3e, 0xeb, 0x37, 0xf5, 0xb5, 0x19, 0xf8, 0x49, 0x68, 0xb0, 0xde,
|
||||
0xd7, 0xb9, 0x76, 0x38, 0x1d, 0x61, 0x9e, 0xa4, 0xfe, 0x82, 0x36, 0xa5,
|
||||
0xe5, 0x4a, 0x56, 0xe4, 0x45, 0xe1, 0xf9, 0xfd, 0xb4, 0x16, 0xfa, 0x74,
|
||||
0xda, 0x9c, 0x9b, 0x35, 0x39, 0x2f, 0xfa, 0xb0, 0x20, 0x50, 0x06, 0x6c,
|
||||
0x7a, 0xd0, 0x80, 0xb2, 0xa6, 0xf9, 0xaf, 0xec, 0x47, 0x19, 0x8f, 0x50,
|
||||
0x38, 0x07, 0xdc, 0xa2, 0x87, 0x39, 0x58, 0xf8, 0xba, 0xd5, 0xa9, 0xf9,
|
||||
0x48, 0x67, 0x30, 0x96, 0xee, 0x94, 0x78, 0x5e, 0x6f, 0x89, 0xa3, 0x51,
|
||||
0xc0, 0x30, 0x86, 0x66, 0xa1, 0x45, 0x66, 0xba, 0x54, 0xeb, 0xa3, 0xc3,
|
||||
0x91, 0xf9, 0x48, 0xdc, 0xff, 0xd1, 0xe8, 0x30, 0x2d, 0x7d, 0x2d, 0x74,
|
||||
0x70, 0x35, 0xd7, 0x88, 0x24, 0xf7, 0x9e, 0xc4, 0x59, 0x6e, 0xbb, 0x73,
|
||||
0x87, 0x17, 0xf2, 0x32, 0x46, 0x28, 0xb8, 0x43, 0xfa, 0xb7, 0x1d, 0xaa,
|
||||
0xca, 0xb4, 0xf2, 0x9f, 0x24, 0x0e, 0x2d, 0x4b, 0xf7, 0x71, 0x5c, 0x5e,
|
||||
0x69, 0xff, 0xea, 0x95, 0x02, 0xcb, 0x38, 0x8a, 0xae, 0x50, 0x38, 0x6f,
|
||||
0xdb, 0xfb, 0x2d, 0x62, 0x1b, 0xc5, 0xc7, 0x1e, 0x54, 0xe1, 0x77, 0xe0,
|
||||
0x67, 0xc8, 0x0f, 0x9c, 0x87, 0x23, 0xd6, 0x3f, 0x40, 0x20, 0x7f, 0x20,
|
||||
0x80, 0xc4, 0x80, 0x4c, 0x3e, 0x3b, 0x24, 0x26, 0x8e, 0x04, 0xae, 0x6c,
|
||||
0x9a, 0xc8, 0xaa, 0x0d,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_E0[] = {
|
||||
0x01, 0x00, 0x01,
|
||||
};
|
||||
|
||||
static const br_x509_trust_anchor TAs[] = {
|
||||
{
|
||||
{ (unsigned char *)TA_DN0, sizeof TA_DN0 },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ .rsa = {
|
||||
(unsigned char *)TA_RSA_N0, sizeof TA_RSA_N0,
|
||||
(unsigned char *)TA_RSA_E0, sizeof TA_RSA_E0,
|
||||
} }
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* ifndef _CERTIFICATES_H_ */
|
167
examples/EthernetAWSIoT/EthernetAWSIoT.ino
Normal file
167
examples/EthernetAWSIoT/EthernetAWSIoT.ino
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
Connect to AWS IOT using SSLClient and Wiz850io Ethernet Mdoule
|
||||
AWS_Root_CA.h is the trust anchor created using the Root CA from:
|
||||
https://www.amazontrust.com/repository/AmazonRootCA1.pem
|
||||
You can re-create it again using the python file present
|
||||
in SSLClient/tools/pycert_bearssl/pycert_bearssl.py
|
||||
python pycert_bearssl.py convert --no-search <certificate PEM file>
|
||||
refer: https://github.com/OPEnSLab-OSU/SSLClient/issues/17#issuecomment-700143405
|
||||
|
||||
Circuit:
|
||||
Ethernet shield WIZ850io:
|
||||
CS 10
|
||||
MOSI 11
|
||||
MISO 12
|
||||
SCK 13
|
||||
|
||||
created 10 October 2020
|
||||
by Ram Rohit Gannavarapu
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <EthernetLarge.h>
|
||||
#include <SSLClient.h>
|
||||
#include <PubSubClient.h>
|
||||
#include "AWS_Root_CA.h" // This file is created using AmazonRootCA1.pem from https://www.amazontrust.com/repository/AmazonRootCA1.pem
|
||||
|
||||
#define THING_NAME "<Thing_Name>"
|
||||
#define MQTT_PACKET_SIZE 1024
|
||||
|
||||
void MQTTPublish(const char *topic, char *payload);
|
||||
void updateThing();
|
||||
|
||||
const char my_cert[] = \
|
||||
"-----BEGIN CERTIFICATE-----\n" \
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" \
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" \
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" \
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
const char my_key[] = \
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n" \
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" \
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" \
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" \
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
|
||||
SSLClientParameters mTLS = SSLClientParameters::fromPEM(my_cert, sizeof my_cert, my_key, sizeof my_key);
|
||||
|
||||
const char* mqttServer = "xxxxxxxxxxxx-ats.iot.us-east-1.amazonaws.com";
|
||||
const char publishShadowUpdate[] = "$aws/things/" THING_NAME "/shadow/update";
|
||||
char publishPayload[MQTT_PACKET_SIZE];
|
||||
char *subscribeTopic[5] =
|
||||
{
|
||||
"$aws/things/" THING_NAME "/shadow/update/accepted",
|
||||
"$aws/things/" THING_NAME "/shadow/update/rejected",
|
||||
"$aws/things/" THING_NAME "/shadow/update/delta",
|
||||
"$aws/things/" THING_NAME "/shadow/get/accepted",
|
||||
"$aws/things/" THING_NAME "/shadow/get/rejected"
|
||||
};
|
||||
|
||||
void callback(char* topic, byte* payload, unsigned int length)
|
||||
{
|
||||
Serial.print("Message arrived [");
|
||||
Serial.print(topic);
|
||||
Serial.print("] ");
|
||||
for (int i=0;i<length;i++)
|
||||
{
|
||||
Serial.print((char)payload[i]);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
EthernetClient ethClient;
|
||||
SSLClient ethClientSSL(ethClient, TAs, (size_t)TAs_NUM, A5);
|
||||
PubSubClient mqtt(mqttServer, 8883, callback, ethClientSSL);
|
||||
|
||||
// Enter a MAC address for your controller below.
|
||||
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
|
||||
byte mac[] = {
|
||||
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
|
||||
};
|
||||
|
||||
void reconnect()
|
||||
{
|
||||
while (!mqtt.connected())
|
||||
{
|
||||
Serial.print("Attempting MQTT connection...");
|
||||
if (mqtt.connect("arduinoClient"))
|
||||
{
|
||||
Serial.println("connected");
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
// Serial.println(subscribeTopic[i]);
|
||||
mqtt.subscribe(subscribeTopic[i]);
|
||||
}
|
||||
Serial.println("Started updateThing ");
|
||||
updateThing();
|
||||
Serial.println("Done updateThing ");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("failed, rc=");
|
||||
Serial.print(mqtt.state());
|
||||
Serial.println(" try again in 5 seconds");
|
||||
delay(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// You can use Ethernet.init(pin) to configure the CS pin
|
||||
Ethernet.init(10); // Most Arduino shields
|
||||
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for native USB port only
|
||||
}
|
||||
ethClientSSL.setMutualAuthParams(mTLS);
|
||||
mqtt.setBufferSize(MQTT_PACKET_SIZE);
|
||||
|
||||
// start the Ethernet connection:
|
||||
Serial.println("Initialize Ethernet with DHCP:");
|
||||
if (Ethernet.begin(mac) == 0) {
|
||||
Serial.println("Failed to configure Ethernet using DHCP");
|
||||
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
|
||||
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
|
||||
} else if (Ethernet.linkStatus() == LinkOFF) {
|
||||
Serial.println("Ethernet cable is not connected.");
|
||||
}
|
||||
// no point in carrying on, so do nothing forevermore:
|
||||
while (true) {
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
// print your local IP address:
|
||||
Serial.print("My IP address: ");
|
||||
Serial.println(Ethernet.localIP());
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!mqtt.connected())
|
||||
{
|
||||
reconnect();
|
||||
}
|
||||
mqtt.loop();
|
||||
}
|
||||
|
||||
|
||||
void updateThing()
|
||||
{
|
||||
strcpy(publishPayload, "{\"state\": {\"reported\": {\"powerState\":\"ON\"}}}");
|
||||
MQTTPublish(publishShadowUpdate, publishPayload);
|
||||
|
||||
}
|
||||
|
||||
void MQTTPublish(const char *topic, char *payload)
|
||||
{
|
||||
mqtt.publish(topic, payload);
|
||||
Serial.print("Published [");
|
||||
Serial.print(topic);
|
||||
Serial.print("] ");
|
||||
Serial.println(payload);
|
||||
}
|
|
@ -10,49 +10,47 @@ extern "C"
|
|||
* Certificates are BearSSL br_x509_trust_anchor format. Included certs:
|
||||
*
|
||||
* Index: 0
|
||||
* Label: AddTrust External CA Root
|
||||
* Subject: C=SE,O=AddTrust AB,OU=AddTrust External TTP Network,CN=AddTrust External CA Root
|
||||
* Label: Baltimore CyberTrust Root
|
||||
* Subject: C=IE,O=Baltimore,OU=CyberTrust,CN=Baltimore CyberTrust Root
|
||||
* Domain(s): www.arduino.cc
|
||||
*/
|
||||
|
||||
#define TAs_NUM 1
|
||||
|
||||
static const unsigned char TA_DN0[] = {
|
||||
0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41,
|
||||
0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
|
||||
0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65,
|
||||
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
|
||||
0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41,
|
||||
0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31,
|
||||
0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79,
|
||||
0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69,
|
||||
0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_N0[] = {
|
||||
0xb7, 0xf7, 0x1a, 0x33, 0xe6, 0xf2, 0x00, 0x04, 0x2d, 0x39, 0xe0, 0x4e,
|
||||
0x5b, 0xed, 0x1f, 0xbc, 0x6c, 0x0f, 0xcd, 0xb5, 0xfa, 0x23, 0xb6, 0xce,
|
||||
0xde, 0x9b, 0x11, 0x33, 0x97, 0xa4, 0x29, 0x4c, 0x7d, 0x93, 0x9f, 0xbd,
|
||||
0x4a, 0xbc, 0x93, 0xed, 0x03, 0x1a, 0xe3, 0x8f, 0xcf, 0xe5, 0x6d, 0x50,
|
||||
0x5a, 0xd6, 0x97, 0x29, 0x94, 0x5a, 0x80, 0xb0, 0x49, 0x7a, 0xdb, 0x2e,
|
||||
0x95, 0xfd, 0xb8, 0xca, 0xbf, 0x37, 0x38, 0x2d, 0x1e, 0x3e, 0x91, 0x41,
|
||||
0xad, 0x70, 0x56, 0xc7, 0xf0, 0x4f, 0x3f, 0xe8, 0x32, 0x9e, 0x74, 0xca,
|
||||
0xc8, 0x90, 0x54, 0xe9, 0xc6, 0x5f, 0x0f, 0x78, 0x9d, 0x9a, 0x40, 0x3c,
|
||||
0x0e, 0xac, 0x61, 0xaa, 0x5e, 0x14, 0x8f, 0x9e, 0x87, 0xa1, 0x6a, 0x50,
|
||||
0xdc, 0xd7, 0x9a, 0x4e, 0xaf, 0x05, 0xb3, 0xa6, 0x71, 0x94, 0x9c, 0x71,
|
||||
0xb3, 0x50, 0x60, 0x0a, 0xc7, 0x13, 0x9d, 0x38, 0x07, 0x86, 0x02, 0xa8,
|
||||
0xe9, 0xa8, 0x69, 0x26, 0x18, 0x90, 0xab, 0x4c, 0xb0, 0x4f, 0x23, 0xab,
|
||||
0x3a, 0x4f, 0x84, 0xd8, 0xdf, 0xce, 0x9f, 0xe1, 0x69, 0x6f, 0xbb, 0xd7,
|
||||
0x42, 0xd7, 0x6b, 0x44, 0xe4, 0xc7, 0xad, 0xee, 0x6d, 0x41, 0x5f, 0x72,
|
||||
0x5a, 0x71, 0x08, 0x37, 0xb3, 0x79, 0x65, 0xa4, 0x59, 0xa0, 0x94, 0x37,
|
||||
0xf7, 0x00, 0x2f, 0x0d, 0xc2, 0x92, 0x72, 0xda, 0xd0, 0x38, 0x72, 0xdb,
|
||||
0x14, 0xa8, 0x45, 0xc4, 0x5d, 0x2a, 0x7d, 0xb7, 0xb4, 0xd6, 0xc4, 0xee,
|
||||
0xac, 0xcd, 0x13, 0x44, 0xb7, 0xc9, 0x2b, 0xdd, 0x43, 0x00, 0x25, 0xfa,
|
||||
0x61, 0xb9, 0x69, 0x6a, 0x58, 0x23, 0x11, 0xb7, 0xa7, 0x33, 0x8f, 0x56,
|
||||
0x75, 0x59, 0xf5, 0xcd, 0x29, 0xd7, 0x46, 0xb7, 0x0a, 0x2b, 0x65, 0xb6,
|
||||
0xd3, 0x42, 0x6f, 0x15, 0xb2, 0xb8, 0x7b, 0xfb, 0xef, 0xe9, 0x5d, 0x53,
|
||||
0xd5, 0x34, 0x5a, 0x27,
|
||||
0xa3, 0x04, 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a,
|
||||
0xb5, 0x79, 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3,
|
||||
0x5b, 0x8e, 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09,
|
||||
0x05, 0x6d, 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88,
|
||||
0xda, 0x12, 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52,
|
||||
0x7b, 0x88, 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a,
|
||||
0x09, 0xe7, 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d,
|
||||
0x2d, 0xe5, 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea,
|
||||
0xf5, 0xab, 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f,
|
||||
0x0c, 0xd5, 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70,
|
||||
0xf0, 0x8f, 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33,
|
||||
0x7a, 0x77, 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13,
|
||||
0xd2, 0xc0, 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc,
|
||||
0xb4, 0xdd, 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5,
|
||||
0x63, 0xe0, 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea,
|
||||
0xeb, 0xd4, 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69,
|
||||
0xbc, 0xf9, 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9,
|
||||
0x90, 0x2c, 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98,
|
||||
0x21, 0x5c, 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86,
|
||||
0x3a, 0x6b, 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78,
|
||||
0x8d, 0x76, 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90,
|
||||
0xdc, 0x27, 0x1a, 0x39,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_E0[] = {
|
||||
|
|
|
@ -10,19 +10,59 @@ extern "C"
|
|||
* Certificates are BearSSL br_x509_trust_anchor format. Included certs:
|
||||
*
|
||||
* Index: 0
|
||||
* Label: Baltimore CyberTrust Root
|
||||
* Subject: C=IE,O=Baltimore,OU=CyberTrust,CN=Baltimore CyberTrust Root
|
||||
* Domain(s): www.arduino.cc
|
||||
*
|
||||
* Index: 1
|
||||
* Label: DigiCert High Assurance EV Root CA
|
||||
* Subject: C=US,O=DigiCert Inc,OU=www.digicert.com,CN=DigiCert High Assurance EV Root CA
|
||||
* Domain(s): www.cloudflare.com
|
||||
*
|
||||
* Index: 1
|
||||
* Label: AddTrust External CA Root
|
||||
* Subject: C=SE,O=AddTrust AB,OU=AddTrust External TTP Network,CN=AddTrust External CA Root
|
||||
* Domain(s): www.arduino.cc
|
||||
*/
|
||||
|
||||
#define TAs_NUM 2
|
||||
|
||||
static const unsigned char TA_DN0[] = {
|
||||
0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31,
|
||||
0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79,
|
||||
0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69,
|
||||
0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_N0[] = {
|
||||
0xa3, 0x04, 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a,
|
||||
0xb5, 0x79, 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3,
|
||||
0x5b, 0x8e, 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09,
|
||||
0x05, 0x6d, 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88,
|
||||
0xda, 0x12, 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52,
|
||||
0x7b, 0x88, 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a,
|
||||
0x09, 0xe7, 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d,
|
||||
0x2d, 0xe5, 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea,
|
||||
0xf5, 0xab, 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f,
|
||||
0x0c, 0xd5, 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70,
|
||||
0xf0, 0x8f, 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33,
|
||||
0x7a, 0x77, 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13,
|
||||
0xd2, 0xc0, 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc,
|
||||
0xb4, 0xdd, 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5,
|
||||
0x63, 0xe0, 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea,
|
||||
0xeb, 0xd4, 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69,
|
||||
0xbc, 0xf9, 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9,
|
||||
0x90, 0x2c, 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98,
|
||||
0x21, 0x5c, 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86,
|
||||
0x3a, 0x6b, 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78,
|
||||
0x8d, 0x76, 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90,
|
||||
0xdc, 0x27, 0x1a, 0x39,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_E0[] = {
|
||||
0x01, 0x00, 0x01,
|
||||
};
|
||||
|
||||
static const unsigned char TA_DN1[] = {
|
||||
0x30, 0x6c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x0c, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49,
|
||||
|
@ -35,7 +75,7 @@ static const unsigned char TA_DN0[] = {
|
|||
0x43, 0x41,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_N0[] = {
|
||||
static const unsigned char TA_RSA_N1[] = {
|
||||
0xc6, 0xcc, 0xe5, 0x73, 0xe6, 0xfb, 0xd4, 0xbb, 0xe5, 0x2d, 0x2d, 0x32,
|
||||
0xa6, 0xdf, 0xe5, 0x81, 0x3f, 0xc9, 0xcd, 0x25, 0x49, 0xb6, 0x71, 0x2a,
|
||||
0xc3, 0xd5, 0x94, 0x34, 0x67, 0xa2, 0x0a, 0x1c, 0xb0, 0x5f, 0x69, 0xa6,
|
||||
|
@ -60,48 +100,6 @@ static const unsigned char TA_RSA_N0[] = {
|
|||
0x38, 0xb8, 0x4b, 0xcb,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_E0[] = {
|
||||
0x01, 0x00, 0x01,
|
||||
};
|
||||
|
||||
static const unsigned char TA_DN1[] = {
|
||||
0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41,
|
||||
0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
|
||||
0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65,
|
||||
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
|
||||
0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41,
|
||||
0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_N1[] = {
|
||||
0xb7, 0xf7, 0x1a, 0x33, 0xe6, 0xf2, 0x00, 0x04, 0x2d, 0x39, 0xe0, 0x4e,
|
||||
0x5b, 0xed, 0x1f, 0xbc, 0x6c, 0x0f, 0xcd, 0xb5, 0xfa, 0x23, 0xb6, 0xce,
|
||||
0xde, 0x9b, 0x11, 0x33, 0x97, 0xa4, 0x29, 0x4c, 0x7d, 0x93, 0x9f, 0xbd,
|
||||
0x4a, 0xbc, 0x93, 0xed, 0x03, 0x1a, 0xe3, 0x8f, 0xcf, 0xe5, 0x6d, 0x50,
|
||||
0x5a, 0xd6, 0x97, 0x29, 0x94, 0x5a, 0x80, 0xb0, 0x49, 0x7a, 0xdb, 0x2e,
|
||||
0x95, 0xfd, 0xb8, 0xca, 0xbf, 0x37, 0x38, 0x2d, 0x1e, 0x3e, 0x91, 0x41,
|
||||
0xad, 0x70, 0x56, 0xc7, 0xf0, 0x4f, 0x3f, 0xe8, 0x32, 0x9e, 0x74, 0xca,
|
||||
0xc8, 0x90, 0x54, 0xe9, 0xc6, 0x5f, 0x0f, 0x78, 0x9d, 0x9a, 0x40, 0x3c,
|
||||
0x0e, 0xac, 0x61, 0xaa, 0x5e, 0x14, 0x8f, 0x9e, 0x87, 0xa1, 0x6a, 0x50,
|
||||
0xdc, 0xd7, 0x9a, 0x4e, 0xaf, 0x05, 0xb3, 0xa6, 0x71, 0x94, 0x9c, 0x71,
|
||||
0xb3, 0x50, 0x60, 0x0a, 0xc7, 0x13, 0x9d, 0x38, 0x07, 0x86, 0x02, 0xa8,
|
||||
0xe9, 0xa8, 0x69, 0x26, 0x18, 0x90, 0xab, 0x4c, 0xb0, 0x4f, 0x23, 0xab,
|
||||
0x3a, 0x4f, 0x84, 0xd8, 0xdf, 0xce, 0x9f, 0xe1, 0x69, 0x6f, 0xbb, 0xd7,
|
||||
0x42, 0xd7, 0x6b, 0x44, 0xe4, 0xc7, 0xad, 0xee, 0x6d, 0x41, 0x5f, 0x72,
|
||||
0x5a, 0x71, 0x08, 0x37, 0xb3, 0x79, 0x65, 0xa4, 0x59, 0xa0, 0x94, 0x37,
|
||||
0xf7, 0x00, 0x2f, 0x0d, 0xc2, 0x92, 0x72, 0xda, 0xd0, 0x38, 0x72, 0xdb,
|
||||
0x14, 0xa8, 0x45, 0xc4, 0x5d, 0x2a, 0x7d, 0xb7, 0xb4, 0xd6, 0xc4, 0xee,
|
||||
0xac, 0xcd, 0x13, 0x44, 0xb7, 0xc9, 0x2b, 0xdd, 0x43, 0x00, 0x25, 0xfa,
|
||||
0x61, 0xb9, 0x69, 0x6a, 0x58, 0x23, 0x11, 0xb7, 0xa7, 0x33, 0x8f, 0x56,
|
||||
0x75, 0x59, 0xf5, 0xcd, 0x29, 0xd7, 0x46, 0xb7, 0x0a, 0x2b, 0x65, 0xb6,
|
||||
0xd3, 0x42, 0x6f, 0x15, 0xb2, 0xb8, 0x7b, 0xfb, 0xef, 0xe9, 0x5d, 0x53,
|
||||
0xd5, 0x34, 0x5a, 0x27,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_E1[] = {
|
||||
0x01, 0x00, 0x01,
|
||||
};
|
||||
|
|
|
@ -10,49 +10,47 @@ extern "C"
|
|||
* Certificates are BearSSL br_x509_trust_anchor format. Included certs:
|
||||
*
|
||||
* Index: 0
|
||||
* Label: AddTrust External CA Root
|
||||
* Subject: C=SE,O=AddTrust AB,OU=AddTrust External TTP Network,CN=AddTrust External CA Root
|
||||
* Label: Baltimore CyberTrust Root
|
||||
* Subject: C=IE,O=Baltimore,OU=CyberTrust,CN=Baltimore CyberTrust Root
|
||||
* Domain(s): www.arduino.cc
|
||||
*/
|
||||
|
||||
#define TAs_NUM 1
|
||||
|
||||
static const unsigned char TA_DN0[] = {
|
||||
0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41,
|
||||
0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
|
||||
0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65,
|
||||
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
|
||||
0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41,
|
||||
0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31,
|
||||
0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79,
|
||||
0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69,
|
||||
0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_N0[] = {
|
||||
0xb7, 0xf7, 0x1a, 0x33, 0xe6, 0xf2, 0x00, 0x04, 0x2d, 0x39, 0xe0, 0x4e,
|
||||
0x5b, 0xed, 0x1f, 0xbc, 0x6c, 0x0f, 0xcd, 0xb5, 0xfa, 0x23, 0xb6, 0xce,
|
||||
0xde, 0x9b, 0x11, 0x33, 0x97, 0xa4, 0x29, 0x4c, 0x7d, 0x93, 0x9f, 0xbd,
|
||||
0x4a, 0xbc, 0x93, 0xed, 0x03, 0x1a, 0xe3, 0x8f, 0xcf, 0xe5, 0x6d, 0x50,
|
||||
0x5a, 0xd6, 0x97, 0x29, 0x94, 0x5a, 0x80, 0xb0, 0x49, 0x7a, 0xdb, 0x2e,
|
||||
0x95, 0xfd, 0xb8, 0xca, 0xbf, 0x37, 0x38, 0x2d, 0x1e, 0x3e, 0x91, 0x41,
|
||||
0xad, 0x70, 0x56, 0xc7, 0xf0, 0x4f, 0x3f, 0xe8, 0x32, 0x9e, 0x74, 0xca,
|
||||
0xc8, 0x90, 0x54, 0xe9, 0xc6, 0x5f, 0x0f, 0x78, 0x9d, 0x9a, 0x40, 0x3c,
|
||||
0x0e, 0xac, 0x61, 0xaa, 0x5e, 0x14, 0x8f, 0x9e, 0x87, 0xa1, 0x6a, 0x50,
|
||||
0xdc, 0xd7, 0x9a, 0x4e, 0xaf, 0x05, 0xb3, 0xa6, 0x71, 0x94, 0x9c, 0x71,
|
||||
0xb3, 0x50, 0x60, 0x0a, 0xc7, 0x13, 0x9d, 0x38, 0x07, 0x86, 0x02, 0xa8,
|
||||
0xe9, 0xa8, 0x69, 0x26, 0x18, 0x90, 0xab, 0x4c, 0xb0, 0x4f, 0x23, 0xab,
|
||||
0x3a, 0x4f, 0x84, 0xd8, 0xdf, 0xce, 0x9f, 0xe1, 0x69, 0x6f, 0xbb, 0xd7,
|
||||
0x42, 0xd7, 0x6b, 0x44, 0xe4, 0xc7, 0xad, 0xee, 0x6d, 0x41, 0x5f, 0x72,
|
||||
0x5a, 0x71, 0x08, 0x37, 0xb3, 0x79, 0x65, 0xa4, 0x59, 0xa0, 0x94, 0x37,
|
||||
0xf7, 0x00, 0x2f, 0x0d, 0xc2, 0x92, 0x72, 0xda, 0xd0, 0x38, 0x72, 0xdb,
|
||||
0x14, 0xa8, 0x45, 0xc4, 0x5d, 0x2a, 0x7d, 0xb7, 0xb4, 0xd6, 0xc4, 0xee,
|
||||
0xac, 0xcd, 0x13, 0x44, 0xb7, 0xc9, 0x2b, 0xdd, 0x43, 0x00, 0x25, 0xfa,
|
||||
0x61, 0xb9, 0x69, 0x6a, 0x58, 0x23, 0x11, 0xb7, 0xa7, 0x33, 0x8f, 0x56,
|
||||
0x75, 0x59, 0xf5, 0xcd, 0x29, 0xd7, 0x46, 0xb7, 0x0a, 0x2b, 0x65, 0xb6,
|
||||
0xd3, 0x42, 0x6f, 0x15, 0xb2, 0xb8, 0x7b, 0xfb, 0xef, 0xe9, 0x5d, 0x53,
|
||||
0xd5, 0x34, 0x5a, 0x27,
|
||||
0xa3, 0x04, 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a,
|
||||
0xb5, 0x79, 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3,
|
||||
0x5b, 0x8e, 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09,
|
||||
0x05, 0x6d, 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88,
|
||||
0xda, 0x12, 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52,
|
||||
0x7b, 0x88, 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a,
|
||||
0x09, 0xe7, 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d,
|
||||
0x2d, 0xe5, 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea,
|
||||
0xf5, 0xab, 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f,
|
||||
0x0c, 0xd5, 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70,
|
||||
0xf0, 0x8f, 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33,
|
||||
0x7a, 0x77, 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13,
|
||||
0xd2, 0xc0, 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc,
|
||||
0xb4, 0xdd, 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5,
|
||||
0x63, 0xe0, 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea,
|
||||
0xeb, 0xd4, 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69,
|
||||
0xbc, 0xf9, 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9,
|
||||
0x90, 0x2c, 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98,
|
||||
0x21, 0x5c, 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86,
|
||||
0x3a, 0x6b, 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78,
|
||||
0x8d, 0x76, 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90,
|
||||
0xdc, 0x27, 0x1a, 0x39,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_E0[] = {
|
||||
|
|
|
@ -10,49 +10,47 @@ extern "C"
|
|||
* Certificates are BearSSL br_x509_trust_anchor format. Included certs:
|
||||
*
|
||||
* Index: 0
|
||||
* Label: AddTrust External CA Root
|
||||
* Subject: C=SE,O=AddTrust AB,OU=AddTrust External TTP Network,CN=AddTrust External CA Root
|
||||
* Label: Baltimore CyberTrust Root
|
||||
* Subject: C=IE,O=Baltimore,OU=CyberTrust,CN=Baltimore CyberTrust Root
|
||||
* Domain(s): www.arduino.cc
|
||||
*/
|
||||
|
||||
#define TAs_NUM 1
|
||||
|
||||
static const unsigned char TA_DN0[] = {
|
||||
0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x53, 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x0b, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41,
|
||||
0x42, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d,
|
||||
0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65,
|
||||
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74,
|
||||
0x20, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41,
|
||||
0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
|
||||
0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31,
|
||||
0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79,
|
||||
0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69,
|
||||
0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_N0[] = {
|
||||
0xb7, 0xf7, 0x1a, 0x33, 0xe6, 0xf2, 0x00, 0x04, 0x2d, 0x39, 0xe0, 0x4e,
|
||||
0x5b, 0xed, 0x1f, 0xbc, 0x6c, 0x0f, 0xcd, 0xb5, 0xfa, 0x23, 0xb6, 0xce,
|
||||
0xde, 0x9b, 0x11, 0x33, 0x97, 0xa4, 0x29, 0x4c, 0x7d, 0x93, 0x9f, 0xbd,
|
||||
0x4a, 0xbc, 0x93, 0xed, 0x03, 0x1a, 0xe3, 0x8f, 0xcf, 0xe5, 0x6d, 0x50,
|
||||
0x5a, 0xd6, 0x97, 0x29, 0x94, 0x5a, 0x80, 0xb0, 0x49, 0x7a, 0xdb, 0x2e,
|
||||
0x95, 0xfd, 0xb8, 0xca, 0xbf, 0x37, 0x38, 0x2d, 0x1e, 0x3e, 0x91, 0x41,
|
||||
0xad, 0x70, 0x56, 0xc7, 0xf0, 0x4f, 0x3f, 0xe8, 0x32, 0x9e, 0x74, 0xca,
|
||||
0xc8, 0x90, 0x54, 0xe9, 0xc6, 0x5f, 0x0f, 0x78, 0x9d, 0x9a, 0x40, 0x3c,
|
||||
0x0e, 0xac, 0x61, 0xaa, 0x5e, 0x14, 0x8f, 0x9e, 0x87, 0xa1, 0x6a, 0x50,
|
||||
0xdc, 0xd7, 0x9a, 0x4e, 0xaf, 0x05, 0xb3, 0xa6, 0x71, 0x94, 0x9c, 0x71,
|
||||
0xb3, 0x50, 0x60, 0x0a, 0xc7, 0x13, 0x9d, 0x38, 0x07, 0x86, 0x02, 0xa8,
|
||||
0xe9, 0xa8, 0x69, 0x26, 0x18, 0x90, 0xab, 0x4c, 0xb0, 0x4f, 0x23, 0xab,
|
||||
0x3a, 0x4f, 0x84, 0xd8, 0xdf, 0xce, 0x9f, 0xe1, 0x69, 0x6f, 0xbb, 0xd7,
|
||||
0x42, 0xd7, 0x6b, 0x44, 0xe4, 0xc7, 0xad, 0xee, 0x6d, 0x41, 0x5f, 0x72,
|
||||
0x5a, 0x71, 0x08, 0x37, 0xb3, 0x79, 0x65, 0xa4, 0x59, 0xa0, 0x94, 0x37,
|
||||
0xf7, 0x00, 0x2f, 0x0d, 0xc2, 0x92, 0x72, 0xda, 0xd0, 0x38, 0x72, 0xdb,
|
||||
0x14, 0xa8, 0x45, 0xc4, 0x5d, 0x2a, 0x7d, 0xb7, 0xb4, 0xd6, 0xc4, 0xee,
|
||||
0xac, 0xcd, 0x13, 0x44, 0xb7, 0xc9, 0x2b, 0xdd, 0x43, 0x00, 0x25, 0xfa,
|
||||
0x61, 0xb9, 0x69, 0x6a, 0x58, 0x23, 0x11, 0xb7, 0xa7, 0x33, 0x8f, 0x56,
|
||||
0x75, 0x59, 0xf5, 0xcd, 0x29, 0xd7, 0x46, 0xb7, 0x0a, 0x2b, 0x65, 0xb6,
|
||||
0xd3, 0x42, 0x6f, 0x15, 0xb2, 0xb8, 0x7b, 0xfb, 0xef, 0xe9, 0x5d, 0x53,
|
||||
0xd5, 0x34, 0x5a, 0x27,
|
||||
0xa3, 0x04, 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a,
|
||||
0xb5, 0x79, 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3,
|
||||
0x5b, 0x8e, 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09,
|
||||
0x05, 0x6d, 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88,
|
||||
0xda, 0x12, 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52,
|
||||
0x7b, 0x88, 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a,
|
||||
0x09, 0xe7, 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d,
|
||||
0x2d, 0xe5, 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea,
|
||||
0xf5, 0xab, 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f,
|
||||
0x0c, 0xd5, 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70,
|
||||
0xf0, 0x8f, 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33,
|
||||
0x7a, 0x77, 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13,
|
||||
0xd2, 0xc0, 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc,
|
||||
0xb4, 0xdd, 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5,
|
||||
0x63, 0xe0, 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea,
|
||||
0xeb, 0xd4, 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69,
|
||||
0xbc, 0xf9, 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9,
|
||||
0x90, 0x2c, 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98,
|
||||
0x21, 0x5c, 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86,
|
||||
0x3a, 0x6b, 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78,
|
||||
0x8d, 0x76, 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90,
|
||||
0xdc, 0x27, 0x1a, 0x39,
|
||||
};
|
||||
|
||||
static const unsigned char TA_RSA_E0[] = {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
name=SSLClient
|
||||
version=1.6.2
|
||||
version=1.6.11
|
||||
author=Noah Koontz <koontzn@oregonstate.edu>
|
||||
maintainer=OPEnS Lab
|
||||
sentence=Arduino library to add TLS functionality to any Client class
|
||||
paragraph=including the Arduino EthernetClient and WiFiClient classes (though it is better to prefer WiFClient.connectSSL if implemented). In other words, SSLClient implements encrypted communication through SSL on devices that do not otherwise support it.
|
||||
category=Communication
|
||||
url=https://github.com/OPEnSLab-OSU/SSLClient
|
||||
architectures=samd,tivac,stm32,esp32
|
||||
architectures=samd,sam,tivac,stm32,esp32
|
||||
includes=SSLClient.h
|
||||
|
|
|
@ -33,7 +33,8 @@ SSLClient::SSLClient( Client& client,
|
|||
, m_analog_pin(analog_pin)
|
||||
, m_debug(debug)
|
||||
, m_is_connected(false)
|
||||
, m_write_idx(0) {
|
||||
, m_write_idx(0)
|
||||
, m_br_last_state(0) {
|
||||
|
||||
setTimeout(30*1000);
|
||||
// zero the iobuf just in case it's still garbage
|
||||
|
@ -51,10 +52,8 @@ SSLClient::SSLClient( Client& client,
|
|||
int SSLClient::connect(IPAddress ip, uint16_t port) {
|
||||
const char* func_name = __func__;
|
||||
// connection check
|
||||
if (get_arduino_client().connected()) {
|
||||
m_error("Cannot have two connections at the same time! Please create another SSLClient instance.", func_name);
|
||||
return 0;
|
||||
}
|
||||
if (get_arduino_client().connected())
|
||||
m_warn("Arduino client is already connected? Continuing anyway...", func_name);
|
||||
// reset indexs for saftey
|
||||
m_write_idx = 0;
|
||||
// Warning for security
|
||||
|
@ -74,10 +73,8 @@ int SSLClient::connect(IPAddress ip, uint16_t port) {
|
|||
int SSLClient::connect(const char *host, uint16_t port) {
|
||||
const char* func_name = __func__;
|
||||
// connection check
|
||||
if (get_arduino_client().connected()) {
|
||||
m_error("Cannot have two connections at the same time! Please create another SSLClient instance.", func_name);
|
||||
return 0;
|
||||
}
|
||||
if (get_arduino_client().connected())
|
||||
m_warn("Arduino client is already connected? Continuing anyway...", func_name);
|
||||
// reset indexs for saftey
|
||||
m_write_idx = 0;
|
||||
// first we need our hidden client member to negotiate the socket for us,
|
||||
|
@ -95,41 +92,48 @@ int SSLClient::connect(const char *host, uint16_t port) {
|
|||
/* see SSLClient.h*/
|
||||
size_t SSLClient::write(const uint8_t *buf, size_t size) {
|
||||
const char* func_name = __func__;
|
||||
// super debug
|
||||
if (m_debug >= DebugLevel::SSL_DUMP) Serial.write(buf, size);
|
||||
// check if the socket is still open and such
|
||||
if (!m_soft_connected(func_name) || !buf || !size) return 0;
|
||||
// wait until bearssl is ready to send
|
||||
if (m_run_until(BR_SSL_SENDAPP) < 0) {
|
||||
m_error("Failed while waiting for the engine to enter BR_SSL_SENDAPP", func_name);
|
||||
return 0;
|
||||
}
|
||||
// add to the bearssl io buffer, simply appending whatever we want to write
|
||||
size_t alen;
|
||||
unsigned char *br_buf = br_ssl_engine_sendapp_buf(&m_sslctx.eng, &alen);
|
||||
size_t cur_idx = 0;
|
||||
bool did_overflow = false;
|
||||
if (alen == 0) {
|
||||
m_error("BearSSL returned zero length buffer for sending, did an internal error occur?", func_name);
|
||||
return 0;
|
||||
}
|
||||
// while there are still elements to write
|
||||
while (cur_idx < size) {
|
||||
// run until the ssl socket is ready to write, unless we've already written
|
||||
// to the buffer in which we conclude it's already safe to write
|
||||
if(m_write_idx == 0) {
|
||||
// if we're about to fill the buffer, we need to send the data and then wait
|
||||
// for another oppurtinity to send
|
||||
// so we only send the smallest of the buffer size or our data size - how much we've already sent
|
||||
const size_t cpamount = size - cur_idx >= alen - m_write_idx ? alen - m_write_idx : size - cur_idx;
|
||||
memcpy(br_buf + m_write_idx, buf + cur_idx, cpamount);
|
||||
// increment write idx
|
||||
m_write_idx += cpamount;
|
||||
// increment the buffer pointer
|
||||
cur_idx += cpamount;
|
||||
// if we filled the buffer, reset m_write_idx, and mark the data for sending
|
||||
if(m_write_idx == alen) {
|
||||
// indicate to bearssl that we are done writing
|
||||
br_ssl_engine_sendapp_ack(&m_sslctx.eng, m_write_idx);
|
||||
// reset the write index
|
||||
m_write_idx = 0;
|
||||
// write to the socket immediatly
|
||||
if (m_run_until(BR_SSL_SENDAPP) < 0) {
|
||||
m_error("Failed while waiting for the engine to enter BR_SSL_SENDAPP", func_name);
|
||||
return 0;
|
||||
}
|
||||
// reset the buffer pointer
|
||||
br_ssl_engine_sendapp_buf(&m_sslctx.eng, &alen);
|
||||
br_buf = br_ssl_engine_sendapp_buf(&m_sslctx.eng, &alen);
|
||||
}
|
||||
// if we're about to fill the buffer, we need to send the data and then wait
|
||||
// for another oppurtinity to send
|
||||
// so we only send the smallest of the buffer size or our data size - how much we've already sent
|
||||
const size_t cpamount = m_write_idx + (size - cur_idx) > alen ? alen : size - cur_idx;
|
||||
memcpy(br_buf + m_write_idx, buf + cur_idx, cpamount);
|
||||
// if we filled the buffer, reset m_write_idx, and mark the data for sending
|
||||
// or if we've overflowed since we're writing to the network already we may as well finish
|
||||
if (cpamount == alen || did_overflow) {
|
||||
m_write_idx = 0;
|
||||
br_ssl_engine_sendapp_ack(&m_sslctx.eng, alen);
|
||||
did_overflow = true;
|
||||
}
|
||||
// else increment
|
||||
else m_write_idx += cpamount;
|
||||
// increment the buffer pointer
|
||||
cur_idx += cpamount;
|
||||
}
|
||||
// works oky
|
||||
return size;
|
||||
|
@ -185,29 +189,37 @@ int SSLClient::peek() {
|
|||
|
||||
/* see SSLClient.h */
|
||||
void SSLClient::flush() {
|
||||
if (m_write_idx > 0)
|
||||
if(m_run_until(BR_SSL_RECVAPP) < 0) m_error("Could not flush write buffer!", __func__);
|
||||
if (m_write_idx > 0) {
|
||||
if(m_run_until(BR_SSL_RECVAPP) < 0) {
|
||||
m_error("Could not flush write buffer!", __func__);
|
||||
int error = br_ssl_engine_last_error(&m_sslctx.eng);
|
||||
if(error != BR_ERR_OK)
|
||||
m_print_br_error(error, SSL_ERROR);
|
||||
if (getWriteError())
|
||||
m_print_ssl_error(getWriteError(), SSL_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* see SSLClient.h */
|
||||
void SSLClient::stop() {
|
||||
// tell the SSL connection to gracefully close
|
||||
br_ssl_engine_close(&m_sslctx.eng);
|
||||
// Disabled to prevent close_notify from hanging SSLClient
|
||||
// br_ssl_engine_close(&m_sslctx.eng);
|
||||
// if the engine isn't closed, and the socket is still open
|
||||
const auto state = br_ssl_engine_current_state(&m_sslctx.eng);
|
||||
while (getWriteError() == SSL_OK
|
||||
&& m_is_connected
|
||||
&& state != BR_SSL_CLOSED
|
||||
auto state = br_ssl_engine_current_state(&m_sslctx.eng);
|
||||
if (state != BR_SSL_CLOSED
|
||||
&& state != 0
|
||||
&& m_run_until(BR_SSL_SENDAPP | BR_SSL_RECVAPP) == 0) {
|
||||
&& connected()) {
|
||||
/*
|
||||
* Discard any incoming application data.
|
||||
*/
|
||||
size_t len;
|
||||
|
||||
if (br_ssl_engine_recvapp_buf(&m_sslctx.eng, &len) != nullptr) {
|
||||
br_ssl_engine_recvapp_ack(&m_sslctx.eng, len);
|
||||
}
|
||||
// run SSL to finish any existing transactions
|
||||
flush();
|
||||
}
|
||||
// close the ethernet socket
|
||||
get_arduino_client().flush();
|
||||
|
@ -293,6 +305,11 @@ void SSLClient::setMutualAuthParams(const SSLClientParameters& params) {
|
|||
}
|
||||
}
|
||||
|
||||
/* see SSLClient.h */
|
||||
void SSLClient::setVerificationTime(uint32_t days, uint32_t seconds) {
|
||||
br_x509_minimal_set_time(&m_x509ctx, days, seconds);
|
||||
}
|
||||
|
||||
bool SSLClient::m_soft_connected(const char* func_name) {
|
||||
// check if the socket is still open and such
|
||||
if (getWriteError()) {
|
||||
|
@ -367,7 +384,7 @@ int SSLClient::m_run_until(const unsigned target) {
|
|||
const unsigned long start = millis();
|
||||
for (;;) {
|
||||
unsigned state = m_update_engine();
|
||||
// error check
|
||||
// error check
|
||||
if (state == BR_SSL_CLOSED || getWriteError() != SSL_OK) {
|
||||
if (state == BR_SSL_CLOSED) {
|
||||
m_warn("Terminating because the ssl engine closed", func_name);
|
||||
|
@ -389,17 +406,7 @@ int SSLClient::m_run_until(const unsigned target) {
|
|||
if (state != lastState || lastState == 0) {
|
||||
lastState = state;
|
||||
m_info("m_run changed state:", func_name);
|
||||
if(m_debug == DebugLevel::SSL_INFO) {
|
||||
m_info("State: ", func_name);
|
||||
if(state == 0) Serial.println(" Invalid");
|
||||
else if (state & BR_SSL_CLOSED) Serial.println(" Connection closed");
|
||||
else {
|
||||
if (state & BR_SSL_SENDREC) Serial.println(" SENDREC");
|
||||
if (state & BR_SSL_RECVREC) Serial.println(" RECVREC");
|
||||
if (state & BR_SSL_SENDAPP) Serial.println(" SENDAPP");
|
||||
if (state & BR_SSL_RECVAPP) Serial.println(" RECVAPP");
|
||||
}
|
||||
}
|
||||
m_print_br_state(state, DebugLevel::SSL_INFO);
|
||||
}
|
||||
if (state & BR_SSL_RECVREC) {
|
||||
size_t len;
|
||||
|
@ -457,6 +464,11 @@ unsigned SSLClient::m_update_engine() {
|
|||
for(;;) {
|
||||
// get the state
|
||||
unsigned state = br_ssl_engine_current_state(&m_sslctx.eng);
|
||||
// debug
|
||||
if (m_br_last_state == 0 || state != m_br_last_state) {
|
||||
m_br_last_state = state;
|
||||
m_print_br_state(state, DebugLevel::SSL_INFO);
|
||||
}
|
||||
if (state & BR_SSL_CLOSED) return state;
|
||||
/*
|
||||
* If there is some record data to send, do it. This takes
|
||||
|
@ -469,6 +481,7 @@ unsigned SSLClient::m_update_engine() {
|
|||
|
||||
buf = br_ssl_engine_sendrec_buf(&m_sslctx.eng, &len);
|
||||
wlen = get_arduino_client().write(buf, len);
|
||||
get_arduino_client().flush();
|
||||
if (wlen <= 0) {
|
||||
// if the arduino client encountered an error
|
||||
if (get_arduino_client().getWriteError() || !get_arduino_client().connected()) {
|
||||
|
@ -626,68 +639,84 @@ void SSLClient::m_print_ssl_error(const int ssl_error, const DebugLevel level) c
|
|||
|
||||
/* See SSLClient.h */
|
||||
void SSLClient::m_print_br_error(const unsigned br_error_code, const DebugLevel level) const {
|
||||
if (level > m_debug) return;
|
||||
m_print_prefix(__func__, level);
|
||||
switch (br_error_code) {
|
||||
case BR_ERR_BAD_PARAM: Serial.println("Caller-provided parameter is incorrect."); break;
|
||||
case BR_ERR_BAD_STATE: Serial.println("Operation requested by the caller cannot be applied with the current context state (e.g. reading data while outgoing data is waiting to be sent)."); break;
|
||||
case BR_ERR_UNSUPPORTED_VERSION: Serial.println("Incoming protocol or record version is unsupported."); break;
|
||||
case BR_ERR_BAD_VERSION: Serial.println("Incoming record version does not match the expected version."); break;
|
||||
case BR_ERR_BAD_LENGTH: Serial.println("Incoming record length is invalid."); break;
|
||||
case BR_ERR_TOO_LARGE: Serial.println("Incoming record is too large to be processed, or buffer is too small for the handshake message to send."); break;
|
||||
case BR_ERR_BAD_MAC: Serial.println("Decryption found an invalid padding, or the record MAC is not correct."); break;
|
||||
case BR_ERR_NO_RANDOM: Serial.println("No initial entropy was provided, and none can be obtained from the OS."); break;
|
||||
case BR_ERR_UNKNOWN_TYPE: Serial.println("Incoming record type is unknown."); break;
|
||||
case BR_ERR_UNEXPECTED: Serial.println("Incoming record or message has wrong type with regards to the current engine state."); break;
|
||||
case BR_ERR_BAD_CCS: Serial.println("ChangeCipherSpec message from the peer has invalid contents."); break;
|
||||
case BR_ERR_BAD_ALERT: Serial.println("Alert message from the peer has invalid contents (odd length)."); break;
|
||||
case BR_ERR_BAD_HANDSHAKE: Serial.println("Incoming handshake message decoding failed."); break;
|
||||
case BR_ERR_OVERSIZED_ID: Serial.println("ServerHello contains a session ID which is larger than 32 bytes."); break;
|
||||
case BR_ERR_BAD_CIPHER_SUITE: Serial.println("Server wants to use a cipher suite that we did not claim to support. This is also reported if we tried to advertise a cipher suite that we do not support."); break;
|
||||
case BR_ERR_BAD_COMPRESSION: Serial.println("Server wants to use a compression that we did not claim to support."); break;
|
||||
case BR_ERR_BAD_FRAGLEN: Serial.println("Server's max fragment length does not match client's."); break;
|
||||
case BR_ERR_BAD_SECRENEG: Serial.println("Secure renegotiation failed."); break;
|
||||
case BR_ERR_EXTRA_EXTENSION: Serial.println("Server sent an extension type that we did not announce, or used the same extension type several times in a single ServerHello."); break;
|
||||
case BR_ERR_BAD_SNI: Serial.println("Invalid Server Name Indication contents (when used by the server, this extension shall be empty)."); break;
|
||||
case BR_ERR_BAD_HELLO_DONE: Serial.println("Invalid ServerHelloDone from the server (length is not 0)."); break;
|
||||
case BR_ERR_LIMIT_EXCEEDED: Serial.println("Internal limit exceeded (e.g. server's public key is too large)."); break;
|
||||
case BR_ERR_BAD_FINISHED: Serial.println("Finished message from peer does not match the expected value."); break;
|
||||
case BR_ERR_RESUME_MISMATCH: Serial.println("Session resumption attempt with distinct version or cipher suite."); break;
|
||||
case BR_ERR_INVALID_ALGORITHM: Serial.println("Unsupported or invalid algorithm (ECDHE curve, signature algorithm, hash function)."); break;
|
||||
case BR_ERR_BAD_SIGNATURE: Serial.println("Invalid signature in ServerKeyExchange or CertificateVerify message."); break;
|
||||
case BR_ERR_WRONG_KEY_USAGE: Serial.println("Peer's public key does not have the proper type or is not allowed for the requested operation."); break;
|
||||
case BR_ERR_NO_CLIENT_AUTH: Serial.println("Client did not send a certificate upon request, or the client certificate could not be validated."); break;
|
||||
case BR_ERR_IO: Serial.println("I/O error or premature close on transport stream."); break;
|
||||
case BR_ERR_X509_INVALID_VALUE: Serial.println("Invalid value in an ASN.1 structure."); break;
|
||||
case BR_ERR_X509_TRUNCATED: Serial.println("Truncated certificate or other ASN.1 object."); break;
|
||||
case BR_ERR_X509_EMPTY_CHAIN: Serial.println("Empty certificate chain (no certificate at all)."); break;
|
||||
case BR_ERR_X509_INNER_TRUNC: Serial.println("Decoding error: inner element extends beyond outer element size."); break;
|
||||
case BR_ERR_X509_BAD_TAG_CLASS: Serial.println("Decoding error: unsupported tag class (application or private)."); break;
|
||||
case BR_ERR_X509_BAD_TAG_VALUE: Serial.println("Decoding error: unsupported tag value."); break;
|
||||
case BR_ERR_X509_INDEFINITE_LENGTH: Serial.println("Decoding error: indefinite length."); break;
|
||||
case BR_ERR_X509_EXTRA_ELEMENT: Serial.println("Decoding error: extraneous element."); break;
|
||||
case BR_ERR_X509_UNEXPECTED: Serial.println("Decoding error: unexpected element."); break;
|
||||
case BR_ERR_X509_NOT_CONSTRUCTED: Serial.println("Decoding error: expected constructed element, but is primitive."); break;
|
||||
case BR_ERR_X509_NOT_PRIMITIVE: Serial.println("Decoding error: expected primitive element, but is constructed."); break;
|
||||
case BR_ERR_X509_PARTIAL_BYTE: Serial.println("Decoding error: BIT STRING length is not multiple of 8."); break;
|
||||
case BR_ERR_X509_BAD_BOOLEAN: Serial.println("Decoding error: BOOLEAN value has invalid length."); break;
|
||||
case BR_ERR_X509_OVERFLOW: Serial.println("Decoding error: value is off-limits."); break;
|
||||
case BR_ERR_X509_BAD_DN: Serial.println("Invalid distinguished name."); break;
|
||||
case BR_ERR_X509_BAD_TIME: Serial.println("Invalid date/time representation."); break;
|
||||
case BR_ERR_X509_UNSUPPORTED: Serial.println("Certificate contains unsupported features that cannot be ignored."); break;
|
||||
case BR_ERR_X509_LIMIT_EXCEEDED: Serial.println("Key or signature size exceeds internal limits."); break;
|
||||
case BR_ERR_X509_WRONG_KEY_TYPE: Serial.println("Key type does not match that which was expected."); break;
|
||||
case BR_ERR_X509_BAD_SIGNATURE: Serial.println("Signature is invalid."); break;
|
||||
case BR_ERR_X509_TIME_UNKNOWN: Serial.println("Validation time is unknown."); break;
|
||||
case BR_ERR_X509_EXPIRED: Serial.println("Certificate is expired or not yet valid."); break;
|
||||
case BR_ERR_X509_DN_MISMATCH: Serial.println("Issuer/Subject DN mismatch in the chain."); break;
|
||||
case BR_ERR_X509_BAD_SERVER_NAME: Serial.println("Expected server name was not found in the chain."); break;
|
||||
case BR_ERR_X509_CRITICAL_EXTENSION: Serial.println("Unknown critical extension in certificate."); break;
|
||||
case BR_ERR_X509_NOT_CA: Serial.println("Not a CA, or path length constraint violation."); break;
|
||||
case BR_ERR_X509_FORBIDDEN_KEY_USAGE: Serial.println("Key Usage extension prohibits intended usage."); break;
|
||||
case BR_ERR_X509_WEAK_PUBLIC_KEY: Serial.println("Public key found in certificate is too small."); break;
|
||||
case BR_ERR_X509_NOT_TRUSTED: Serial.println("Chain could not be linked to a trust anchor."); break;
|
||||
case 296: Serial.println("Server denied access (did you setup mTLS correctly?)"); break;
|
||||
default: Serial.print("Unknown error code: "); Serial.println(br_error_code); break;
|
||||
}
|
||||
if (level > m_debug) return;
|
||||
m_print_prefix(__func__, level);
|
||||
switch (br_error_code) {
|
||||
case BR_ERR_BAD_PARAM: Serial.println("Caller-provided parameter is incorrect."); break;
|
||||
case BR_ERR_BAD_STATE: Serial.println("Operation requested by the caller cannot be applied with the current context state (e.g. reading data while outgoing data is waiting to be sent)."); break;
|
||||
case BR_ERR_UNSUPPORTED_VERSION: Serial.println("Incoming protocol or record version is unsupported."); break;
|
||||
case BR_ERR_BAD_VERSION: Serial.println("Incoming record version does not match the expected version."); break;
|
||||
case BR_ERR_BAD_LENGTH: Serial.println("Incoming record length is invalid."); break;
|
||||
case BR_ERR_TOO_LARGE: Serial.println("Incoming record is too large to be processed, or buffer is too small for the handshake message to send."); break;
|
||||
case BR_ERR_BAD_MAC: Serial.println("Decryption found an invalid padding, or the record MAC is not correct."); break;
|
||||
case BR_ERR_NO_RANDOM: Serial.println("No initial entropy was provided, and none can be obtained from the OS."); break;
|
||||
case BR_ERR_UNKNOWN_TYPE: Serial.println("Incoming record type is unknown."); break;
|
||||
case BR_ERR_UNEXPECTED: Serial.println("Incoming record or message has wrong type with regards to the current engine state."); break;
|
||||
case BR_ERR_BAD_CCS: Serial.println("ChangeCipherSpec message from the peer has invalid contents."); break;
|
||||
case BR_ERR_BAD_ALERT: Serial.println("Alert message from the peer has invalid contents (odd length)."); break;
|
||||
case BR_ERR_BAD_HANDSHAKE: Serial.println("Incoming handshake message decoding failed."); break;
|
||||
case BR_ERR_OVERSIZED_ID: Serial.println("ServerHello contains a session ID which is larger than 32 bytes."); break;
|
||||
case BR_ERR_BAD_CIPHER_SUITE: Serial.println("Server wants to use a cipher suite that we did not claim to support. This is also reported if we tried to advertise a cipher suite that we do not support."); break;
|
||||
case BR_ERR_BAD_COMPRESSION: Serial.println("Server wants to use a compression that we did not claim to support."); break;
|
||||
case BR_ERR_BAD_FRAGLEN: Serial.println("Server's max fragment length does not match client's."); break;
|
||||
case BR_ERR_BAD_SECRENEG: Serial.println("Secure renegotiation failed."); break;
|
||||
case BR_ERR_EXTRA_EXTENSION: Serial.println("Server sent an extension type that we did not announce, or used the same extension type several times in a single ServerHello."); break;
|
||||
case BR_ERR_BAD_SNI: Serial.println("Invalid Server Name Indication contents (when used by the server, this extension shall be empty)."); break;
|
||||
case BR_ERR_BAD_HELLO_DONE: Serial.println("Invalid ServerHelloDone from the server (length is not 0)."); break;
|
||||
case BR_ERR_LIMIT_EXCEEDED: Serial.println("Internal limit exceeded (e.g. server's public key is too large)."); break;
|
||||
case BR_ERR_BAD_FINISHED: Serial.println("Finished message from peer does not match the expected value."); break;
|
||||
case BR_ERR_RESUME_MISMATCH: Serial.println("Session resumption attempt with distinct version or cipher suite."); break;
|
||||
case BR_ERR_INVALID_ALGORITHM: Serial.println("Unsupported or invalid algorithm (ECDHE curve, signature algorithm, hash function)."); break;
|
||||
case BR_ERR_BAD_SIGNATURE: Serial.println("Invalid signature in ServerKeyExchange or CertificateVerify message."); break;
|
||||
case BR_ERR_WRONG_KEY_USAGE: Serial.println("Peer's public key does not have the proper type or is not allowed for the requested operation."); break;
|
||||
case BR_ERR_NO_CLIENT_AUTH: Serial.println("Client did not send a certificate upon request, or the client certificate could not be validated."); break;
|
||||
case BR_ERR_IO: Serial.println("I/O error or premature close on transport stream."); break;
|
||||
case BR_ERR_X509_INVALID_VALUE: Serial.println("Invalid value in an ASN.1 structure."); break;
|
||||
case BR_ERR_X509_TRUNCATED: Serial.println("Truncated certificate or other ASN.1 object."); break;
|
||||
case BR_ERR_X509_EMPTY_CHAIN: Serial.println("Empty certificate chain (no certificate at all)."); break;
|
||||
case BR_ERR_X509_INNER_TRUNC: Serial.println("Decoding error: inner element extends beyond outer element size."); break;
|
||||
case BR_ERR_X509_BAD_TAG_CLASS: Serial.println("Decoding error: unsupported tag class (application or private)."); break;
|
||||
case BR_ERR_X509_BAD_TAG_VALUE: Serial.println("Decoding error: unsupported tag value."); break;
|
||||
case BR_ERR_X509_INDEFINITE_LENGTH: Serial.println("Decoding error: indefinite length."); break;
|
||||
case BR_ERR_X509_EXTRA_ELEMENT: Serial.println("Decoding error: extraneous element."); break;
|
||||
case BR_ERR_X509_UNEXPECTED: Serial.println("Decoding error: unexpected element."); break;
|
||||
case BR_ERR_X509_NOT_CONSTRUCTED: Serial.println("Decoding error: expected constructed element, but is primitive."); break;
|
||||
case BR_ERR_X509_NOT_PRIMITIVE: Serial.println("Decoding error: expected primitive element, but is constructed."); break;
|
||||
case BR_ERR_X509_PARTIAL_BYTE: Serial.println("Decoding error: BIT STRING length is not multiple of 8."); break;
|
||||
case BR_ERR_X509_BAD_BOOLEAN: Serial.println("Decoding error: BOOLEAN value has invalid length."); break;
|
||||
case BR_ERR_X509_OVERFLOW: Serial.println("Decoding error: value is off-limits."); break;
|
||||
case BR_ERR_X509_BAD_DN: Serial.println("Invalid distinguished name."); break;
|
||||
case BR_ERR_X509_BAD_TIME: Serial.println("Invalid date/time representation."); break;
|
||||
case BR_ERR_X509_UNSUPPORTED: Serial.println("Certificate contains unsupported features that cannot be ignored."); break;
|
||||
case BR_ERR_X509_LIMIT_EXCEEDED: Serial.println("Key or signature size exceeds internal limits."); break;
|
||||
case BR_ERR_X509_WRONG_KEY_TYPE: Serial.println("Key type does not match that which was expected."); break;
|
||||
case BR_ERR_X509_BAD_SIGNATURE: Serial.println("Signature is invalid."); break;
|
||||
case BR_ERR_X509_TIME_UNKNOWN: Serial.println("Validation time is unknown."); break;
|
||||
case BR_ERR_X509_EXPIRED: Serial.println("Certificate is expired or not yet valid."); break;
|
||||
case BR_ERR_X509_DN_MISMATCH: Serial.println("Issuer/Subject DN mismatch in the chain."); break;
|
||||
case BR_ERR_X509_BAD_SERVER_NAME: Serial.println("Expected server name was not found in the chain."); break;
|
||||
case BR_ERR_X509_CRITICAL_EXTENSION: Serial.println("Unknown critical extension in certificate."); break;
|
||||
case BR_ERR_X509_NOT_CA: Serial.println("Not a CA, or path length constraint violation."); break;
|
||||
case BR_ERR_X509_FORBIDDEN_KEY_USAGE: Serial.println("Key Usage extension prohibits intended usage."); break;
|
||||
case BR_ERR_X509_WEAK_PUBLIC_KEY: Serial.println("Public key found in certificate is too small."); break;
|
||||
case BR_ERR_X509_NOT_TRUSTED: Serial.println("Chain could not be linked to a trust anchor. See https://github.com/OPEnSLab-OSU/SSLClient/blob/master/TrustAnchors.md"); break;
|
||||
case 296: Serial.println("Server denied access (did you setup mTLS correctly?)"); break;
|
||||
default: Serial.print("Unknown error code: "); Serial.println(br_error_code); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SSLClient::m_print_br_state(const unsigned state, const DebugLevel level) const {
|
||||
const char* func_name = __func__;
|
||||
if (level > m_debug) return;
|
||||
m_print_prefix(func_name, level);
|
||||
m_info("State: ", func_name);
|
||||
if(state == 0) Serial.println(" Invalid");
|
||||
else if (state & BR_SSL_CLOSED) Serial.println(" Connection closed");
|
||||
else {
|
||||
if (state & BR_SSL_SENDREC) Serial.println(" SENDREC");
|
||||
if (state & BR_SSL_RECVREC) Serial.println(" RECVREC");
|
||||
if (state & BR_SSL_SENDAPP) Serial.println(" SENDAPP");
|
||||
if (state & BR_SSL_RECVAPP) Serial.println(" RECVAPP");
|
||||
}
|
||||
}
|
|
@ -72,6 +72,8 @@ public:
|
|||
SSL_WARN = 2,
|
||||
/** Output errors, warnings, and internal information (very verbose) */
|
||||
SSL_INFO = 3,
|
||||
/** In addition to the above logs, dumps every byte in SSLClient::write to the Serial monitor */
|
||||
SSL_DUMP = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -369,6 +371,19 @@ public:
|
|||
*/
|
||||
unsigned int getTimeout() const { return m_timeout; }
|
||||
|
||||
/**
|
||||
* @brief Change the time used during x509 verification to a different value.
|
||||
*
|
||||
* This function directly calls br_x509_minimal_set_time to change the validation
|
||||
* time used by the minimal verification engine. You can use this function if the default value
|
||||
* of the compile time is causing issues. See https://bearssl.org/apidoc/bearssl__x509_8h.html#a7f3558b1999ce904084d578700b1002c
|
||||
* for more information what this function does and how to use it.
|
||||
*
|
||||
* @param days Days are counted in a proleptic Gregorian calendar since January 1st, 0 AD.
|
||||
* @param seconds Seconds are counted since midnight, from 0 to 86400 (a count of 86400 is possible only if a leap second happened).
|
||||
*/
|
||||
void setVerificationTime(uint32_t days, uint32_t seconds);
|
||||
|
||||
private:
|
||||
/** @brief Returns an instance of m_client that is polymorphic and can be used by SSLClientImpl */
|
||||
Client& get_arduino_client() { return m_client; }
|
||||
|
@ -394,6 +409,9 @@ private:
|
|||
/** @brief Print the text string associated with a BearSSL error code */
|
||||
void m_print_br_error(const unsigned br_error_code, const DebugLevel level) const;
|
||||
|
||||
/** @brief Print the text string associated with the BearSSL state */
|
||||
void m_print_br_state(const unsigned br_state, const DebugLevel level) const;
|
||||
|
||||
/** @brief debugging print function, only prints if m_debug is true */
|
||||
template<typename T>
|
||||
void m_print(const T str, const char* func_name, const DebugLevel level) const {
|
||||
|
@ -453,6 +471,8 @@ private:
|
|||
// so we can send our records all at once to prevent
|
||||
// weird timing issues
|
||||
size_t m_write_idx;
|
||||
// store the last BearSSL state so we can print changes to the console
|
||||
unsigned m_br_last_state;
|
||||
};
|
||||
|
||||
#endif /** SSLClient_H_ */
|
|
@ -1,11 +1,10 @@
|
|||
#include "SSLClientParameters.h"
|
||||
|
||||
// fix for non-exception arduino platforms
|
||||
#ifdef ADAFRUIT_FEATHER_M0
|
||||
// fix for non-exception arduino platforms (Feather and Teensy 4.0)
|
||||
namespace std {
|
||||
void __throw_length_error(char const*) {}
|
||||
void __attribute__((weak)) __throw_length_error(char const*) {}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct ssl_pem_decode_state {
|
||||
std::vector<char>* vect;
|
||||
|
@ -81,7 +80,7 @@ static br_skey_decoder_context make_key_from_der(const std::vector<char>& der) {
|
|||
SSLClientParameters::SSLClientParameters(const char* cert, const size_t cert_len, const char* key, const size_t key_len, bool is_der)
|
||||
: m_cert(is_der ? std::vector<char>(cert, cert + cert_len) : make_vector_pem(cert, cert_len))
|
||||
, m_cert_struct{ const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(m_cert.data())), m_cert.size() }
|
||||
, m_key_struct{ make_key_from_der( is_der ? std::vector<char>(key, key + key_len) : make_vector_pem(key, key_len) ) } {}
|
||||
, m_key_struct( make_key_from_der( is_der ? std::vector<char>(key, key + key_len) : make_vector_pem(key, key_len) ) ) {}
|
||||
|
||||
/* See SSLClientParams.h */
|
||||
SSLClientParameters SSLClientParameters::fromPEM(const char* cert_pem, const size_t cert_len, const char* key_pem, const size_t key_len) {
|
||||
|
|
|
@ -221,7 +221,8 @@ br_client_init_TLS12_only(br_ssl_client_context *cc,
|
|||
//* Alternate: set implementations explicitly.
|
||||
// br_ssl_client_set_rsapub(cc, &br_rsa_i31_public);
|
||||
br_ssl_engine_set_rsavrfy(&cc->eng, &br_rsa_i15_pkcs1_vrfy);
|
||||
br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15);
|
||||
// br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15);
|
||||
br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_fast_256);
|
||||
br_ssl_engine_set_ecdsa(&cc->eng, &br_ecdsa_i15_vrfy_asn1);
|
||||
//*/
|
||||
|
||||
|
@ -439,7 +440,7 @@ br_client_init_TLS12_only(br_ssl_client_context *cc,
|
|||
// br_x509_minimal_set_ecdsa(xc,
|
||||
// &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1);
|
||||
br_x509_minimal_set_ecdsa(xc,
|
||||
&br_ec_prime_fast_256,
|
||||
br_ssl_engine_get_ec(&cc->eng),
|
||||
br_ssl_engine_get_ecdsa(&cc->eng));
|
||||
|
||||
/*
|
||||
|
|
1
tools/pycert_bearssl/.gitignore
vendored
Normal file
1
tools/pycert_bearssl/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
__pycache__
|
20
tools/pycert_bearssl/ca.crt
Normal file
20
tools/pycert_bearssl/ca.crt
Normal file
|
@ -0,0 +1,20 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDRTCCAi2gAwIBAgIUCn8+KWh0IuIhfze2cfetSV+clcIwDQYJKoZIhvcNAQEL
|
||||
BQAwMjELMAkGA1UEBhMCREUxEDAOBgNVBAgMB1NhY2hzZW4xETAPBgNVBAoMCFpl
|
||||
bnRyYWxlMB4XDTIwMDQyMDE4MTc0MloXDTI1MDQyMDE4MTc0MlowMjELMAkGA1UE
|
||||
BhMCREUxEDAOBgNVBAgMB1NhY2hzZW4xETAPBgNVBAoMCFplbnRyYWxlMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAumwRj1qO7pDmbeMG8F3i29v9aM2t
|
||||
wDWz4q9uR8RD2YbDza39yNdRd1p2rbITd7YEic74qWwcuNoLiqOOGdf37L2XGVE/
|
||||
UPv6lrLIrY7ttvKBv4x86WVHUlv3zYDmfdOBvk9hWH7rX6oXc6pg7QjFPhn5qeEV
|
||||
LaRKB92O2IqPyDO84eyB2fgh2/5gKA5SsL56i2iHCYnLIvctXiKHXOA2NTDjvkEA
|
||||
tTRacs4kIcyXd5NSg7upA1oGp4e8Dvv5MCcSxlFyb3qOdF1VbeAIiPPMIzOxkxzC
|
||||
dDgtMFnJviuycOQD0INfEa+vRlxL146TUO2xP8llzMSPgygA+zMBPJI3wwIDAQAB
|
||||
o1MwUTAdBgNVHQ4EFgQUCDqS169brBVfcbjpzo/DVWpyjEswHwYDVR0jBBgwFoAU
|
||||
CDqS169brBVfcbjpzo/DVWpyjEswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
|
||||
AQsFAAOCAQEAqvcCisHUynfNjL6iqOb8ZMkrVb7Xy5deQUj0U0evYKVZc4/kkXKH
|
||||
aD5g5e5mU+9NlXO9yvoSy7tHDdy1AkFrnd/F2m+e1jBnXhLutbrKWcyusOS8uC8f
|
||||
f9f/Z0CckOh1VKU6BDhjX6t2Fn8RoGIkiEdo0QXMqlZwEQC1nTqaSpwF2pJD6J7n
|
||||
3x+QCmVcN6k6speAC9+hGckpSYSWEOmSd0vOz3JBLstkDmQmqDw2KqzgcPIVlKME
|
||||
lgojxziwdIWNBrjSo7fRi9rB5SnzbhQUFvgMB83MLuUbjTYDThXMmw7Wr1uefZKC
|
||||
0qLGE2thUbWmBv4l+1UshfU9VcLRe8zGLA==
|
||||
-----END CERTIFICATE-----
|
|
@ -32,6 +32,12 @@ DN_PRE = "TA_DN"
|
|||
RSA_N_PRE = "TA_RSA_N"
|
||||
# RSA public key exponent prefix
|
||||
RSA_E_PRE = "TA_RSA_E"
|
||||
# EC public key number prefix
|
||||
EC_CURVE_PRE = "TA_EC_CURVE"
|
||||
# EC curve type enum prefix
|
||||
EC_CURVE_NAME_PRE = "BR_EC_"
|
||||
# CA flag
|
||||
CA_FLAG = "BR_X509_TA_CA"
|
||||
|
||||
|
||||
# Template that defines the C header output format.
|
||||
|
@ -81,7 +87,7 @@ static const {ray_type} {ray_name}[] = {{
|
|||
{ray_data}
|
||||
}};"""
|
||||
|
||||
# Template that defines a single root certificate entry in the BearSSL trust
|
||||
# Template that defines a single root RSA certificate entry in the BearSSL trust
|
||||
# anchor list
|
||||
# This takes in a few named parameters:
|
||||
# - ta_dn_name: The name of the static byte array containing the distunguished
|
||||
|
@ -91,7 +97,7 @@ static const {ray_type} {ray_name}[] = {{
|
|||
CROOTCA_TEMPLATE = """\
|
||||
{{
|
||||
{{ (unsigned char *){ta_dn_name}, sizeof {ta_dn_name} }},
|
||||
BR_X509_TA_CA,
|
||||
{ca_flag},
|
||||
{{
|
||||
BR_KEYTYPE_RSA,
|
||||
{{ .rsa = {{
|
||||
|
@ -101,6 +107,25 @@ CROOTCA_TEMPLATE = """\
|
|||
}}
|
||||
}},"""
|
||||
|
||||
# Template that defines a single root EC certificate entry in the BearSSL trust
|
||||
# anchor list
|
||||
# This takes in a few named parameters:
|
||||
# - ta_dn_name: The name of the static byte array containing the distunguished
|
||||
# name of the certificate.
|
||||
# - ec_number_name: Varible name of the static array containing ec public key
|
||||
# - ec_curve_name: Varible name of the enum that describes curve type
|
||||
CROOTCA_EC_TEMPLATE = """\
|
||||
{{
|
||||
{{ (unsigned char *){ta_dn_name}, sizeof {ta_dn_name} }},
|
||||
BR_X509_TA_CA,
|
||||
{{
|
||||
BR_KEYTYPE_EC,
|
||||
{{ .ec = {{{ec_curve_name}, (unsigned char *){ec_number_name}, sizeof {ec_number_name}}}
|
||||
}}
|
||||
}}
|
||||
}},"""
|
||||
|
||||
|
||||
# Template that defines a description of the certificate, so that the header
|
||||
# file can be slightly more human readable
|
||||
# This takes in a few named parameters:
|
||||
|
@ -112,7 +137,8 @@ CROOTCA_TEMPLATE = """\
|
|||
CCERT_DESC_TEMPLATE = """\
|
||||
* Index: {cert_num}
|
||||
* Label: {cert_label}
|
||||
* Subject: {cert_subject}"""
|
||||
* Subject: {cert_subject}
|
||||
* Type: {cert_type}"""
|
||||
|
||||
def PEM_split(cert_pem):
|
||||
"""Split a certificate / certificate chain in PEM format into multiple
|
||||
|
@ -205,12 +231,17 @@ def decribe_cert_object(cert, cert_num, domain=None):
|
|||
label = com[b'OU'].decode("utf-8")
|
||||
elif b'O' in com:
|
||||
label = com[b'O'].decode("utf-8")
|
||||
if cert.get_issuer() == cert.get_subject():
|
||||
cert_type = "Certificate Authority"
|
||||
else:
|
||||
cert_type = "End Entity"
|
||||
# return the formated string
|
||||
crypto = cert.to_cryptography()
|
||||
out_str = CCERT_DESC_TEMPLATE.format(
|
||||
cert_num=cert_num,
|
||||
cert_label=label,
|
||||
cert_subject=crypto.subject.rfc4514_string(),
|
||||
cert_type=cert_type
|
||||
)
|
||||
# if domain, then add domain entry
|
||||
if domain is not None:
|
||||
|
@ -256,6 +287,8 @@ def x509_to_header(x509Certs, cert_var, cert_length_var, output_file, keep_dupes
|
|||
cert_desc.append(decribe_cert_object(cert, cert_index))
|
||||
else:
|
||||
cert_desc.append(decribe_cert_object(cert, cert_index, domain=domains[i]))
|
||||
# detect if the cert is a CA
|
||||
is_ca = cert.get_issuer() == cert.get_subject()
|
||||
# build static arrays containing all the keys of the certificate
|
||||
# start with distinguished name
|
||||
# get the distinguished name in bytes
|
||||
|
@ -267,23 +300,45 @@ def x509_to_header(x509Certs, cert_var, cert_length_var, output_file, keep_dupes
|
|||
# next, the RSA public numbers
|
||||
pubkey = cert.get_pubkey()
|
||||
numbers = pubkey.to_cryptography_key().public_numbers()
|
||||
# starting with the modulous
|
||||
n_bytes_str = bytes_to_c_data(numbers.n.to_bytes(pubkey.bits() // 8, byteorder="big"))
|
||||
static_arrays.append(CRAY_TEMPLATE.format(
|
||||
ray_type="unsigned char",
|
||||
ray_name=RSA_N_PRE + str(cert_index),
|
||||
ray_data=n_bytes_str))
|
||||
# and then the exponent
|
||||
e_bytes_str = bytes_to_c_data(numbers.e.to_bytes(math.ceil(numbers.e.bit_length() / 8), byteorder="big"))
|
||||
static_arrays.append(CRAY_TEMPLATE.format(
|
||||
ray_type="unsigned char",
|
||||
ray_name=RSA_E_PRE + str(cert_index),
|
||||
ray_data=e_bytes_str))
|
||||
# format the root certificate entry
|
||||
CAs.append(CROOTCA_TEMPLATE.format(
|
||||
ta_dn_name=DN_PRE + str(cert_index),
|
||||
rsa_number_name=RSA_N_PRE + str(cert_index),
|
||||
rsa_exp_name=RSA_E_PRE + str(cert_index)))
|
||||
numbers_typename = type(numbers).__name__
|
||||
if 'RSA' in numbers_typename:
|
||||
# starting with the modulous
|
||||
n_bytes_str = bytes_to_c_data(numbers.n.to_bytes(pubkey.bits() // 8, byteorder="big"))
|
||||
static_arrays.append(CRAY_TEMPLATE.format(
|
||||
ray_type="unsigned char",
|
||||
ray_name=RSA_N_PRE + str(cert_index),
|
||||
ray_data=n_bytes_str))
|
||||
# and then the exponent
|
||||
e_bytes_str = bytes_to_c_data(numbers.e.to_bytes(math.ceil(numbers.e.bit_length() / 8), byteorder="big"))
|
||||
static_arrays.append(CRAY_TEMPLATE.format(
|
||||
ray_type="unsigned char",
|
||||
ray_name=RSA_E_PRE + str(cert_index),
|
||||
ray_data=e_bytes_str))
|
||||
# format the root certificate entry
|
||||
CAs.append(CROOTCA_TEMPLATE.format(
|
||||
ta_dn_name=DN_PRE + str(cert_index),
|
||||
ca_flag=CA_FLAG if is_ca else "0",
|
||||
rsa_number_name=RSA_N_PRE + str(cert_index),
|
||||
rsa_exp_name=RSA_E_PRE + str(cert_index)))
|
||||
elif 'Elliptic' in numbers_typename:
|
||||
# starting with the modulous
|
||||
curve_bytes = b'\x04' + numbers.x.to_bytes(pubkey.bits() // 8, byteorder="big") + numbers.y.to_bytes(
|
||||
pubkey.bits() // 8, byteorder="big")
|
||||
curve_str = bytes_to_c_data(curve_bytes)
|
||||
curve_name = numbers.curve.name
|
||||
static_arrays.append(CRAY_TEMPLATE.format(
|
||||
ray_type="unsigned char",
|
||||
ray_name=EC_CURVE_PRE + str(cert_index),
|
||||
ray_data=curve_str))
|
||||
# and then the exponent
|
||||
CAs.append(CROOTCA_EC_TEMPLATE.format(
|
||||
ta_dn_name=DN_PRE + str(cert_index),
|
||||
ca_flag=CA_FLAG if is_ca else "0",
|
||||
ec_number_name=EC_CURVE_PRE + str(cert_index),
|
||||
ec_curve_name=EC_CURVE_NAME_PRE + curve_name
|
||||
))
|
||||
else:
|
||||
raise Exception(f'Unknown public key type {numbers_typename}')
|
||||
# concatonate it all into the big header file template
|
||||
# cert descriptions
|
||||
cert_desc_out = '\n * \n'.join(cert_desc)
|
||||
|
@ -301,3 +356,5 @@ def x509_to_header(x509Certs, cert_var, cert_length_var, output_file, keep_dupes
|
|||
cert_length=str(len(CAs)),
|
||||
cert_data=cert_data_out,
|
||||
))
|
||||
|
||||
return len(cert_ser)
|
54
tools/pycert_bearssl/certificates.h
Normal file
54
tools/pycert_bearssl/certificates.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef _CERTIFICATES_H_
|
||||
#define _CERTIFICATES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* This file is auto-generated by the pycert_bearssl tool. Do not change it manually.
|
||||
* Certificates are BearSSL br_x509_trust_anchor format. Included certs:
|
||||
*
|
||||
* Index: 0
|
||||
* Label: GlobalSign
|
||||
* Subject: OU=GlobalSign ECC Root CA - R4,O=GlobalSign,CN=GlobalSign
|
||||
*/
|
||||
|
||||
#define TAs_NUM 1
|
||||
|
||||
static const unsigned char TA_DN0[] = {
|
||||
0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
|
||||
0x1b, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20,
|
||||
0x45, 0x43, 0x43, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20,
|
||||
0x2d, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
|
||||
0x0a, 0x13, 0x0a, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
|
||||
0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e,
|
||||
};
|
||||
|
||||
static const unsigned char TA_EC_CURVE0[] = {
|
||||
0x04, 0xb8, 0xc6, 0x79, 0xd3, 0x8f, 0x6c, 0x25, 0x0e, 0x9f, 0x2e, 0x39,
|
||||
0x19, 0x1c, 0x03, 0xa4, 0xae, 0x9a, 0xe5, 0x39, 0x07, 0x09, 0x16, 0xca,
|
||||
0x63, 0xb1, 0xb9, 0x86, 0xf8, 0x8a, 0x57, 0xc1, 0x57, 0xce, 0x42, 0xfa,
|
||||
0x73, 0xa1, 0xf7, 0x65, 0x42, 0xff, 0x1e, 0xc1, 0x00, 0xb2, 0x6e, 0x73,
|
||||
0x0e, 0xff, 0xc7, 0x21, 0xe5, 0x18, 0xa4, 0xaa, 0xd9, 0x71, 0x3f, 0xa8,
|
||||
0xd4, 0xb9, 0xce, 0x8c, 0x1d,
|
||||
};
|
||||
|
||||
static const br_x509_trust_anchor TAs[] = {
|
||||
{
|
||||
{ (unsigned char *)TA_DN0, sizeof TA_DN0 },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_EC,
|
||||
{ .ec = {BR_EC_secp256r1, (unsigned char *)TA_EC_CURVE0, sizeof TA_EC_CURVE0}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* ifndef _CERTIFICATES_H_ */
|
|
@ -86,7 +86,11 @@ def download(port, cert_var, cert_length_var, output, use_store, keep_dupes, dom
|
|||
# append cert to array
|
||||
down_certs.append(cert)
|
||||
# Combine PEMs and write output header.
|
||||
cert_util.x509_to_header(down_certs, cert_var, cert_length_var, output, keep_dupes, domains=domain)
|
||||
try:
|
||||
cert_util.x509_to_header(down_certs, cert_var, cert_length_var, output, keep_dupes, domains=domain)
|
||||
except Exception as E:
|
||||
click.echo(f'Recieved error when converting certificate to header: {E}')
|
||||
exit(1)
|
||||
|
||||
|
||||
@pycert_bearssl.command(short_help='Convert PEM certs into a C header.')
|
||||
|
@ -132,6 +136,10 @@ def convert(cert_var, cert_length_var, output, use_store, keep_dupes, no_search,
|
|||
else:
|
||||
click.echo('Loaded certificate {0}'.format(c.name))
|
||||
cert_objs.append(cert_parsed)
|
||||
|
||||
if no_search and cert_parsed.get_subject() != cert_parsed.get_issuer():
|
||||
click.echo(f'Warning: certificate {c.name} is an end entity certificate (not a CA). '
|
||||
'SSLClient may fail to validate if the server certificate changes.')
|
||||
# find a root certificate for each
|
||||
root_certs = []
|
||||
if no_search:
|
||||
|
@ -144,8 +152,12 @@ def convert(cert_var, cert_length_var, output, use_store, keep_dupes, no_search,
|
|||
else:
|
||||
root_certs.append(cert_dict[cn_hash])
|
||||
# Combine PEMs and write output header.
|
||||
cert_util.x509_to_header(root_certs, cert_var, cert_length_var, output, keep_dupes)
|
||||
|
||||
try:
|
||||
written = cert_util.x509_to_header(root_certs, cert_var, cert_length_var, output, keep_dupes)
|
||||
click.echo(f'Wrote {written} trust anchors to {output.name}')
|
||||
except Exception as E:
|
||||
click.echo(f'Recieved error when converting certificate to header: {E}')
|
||||
exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pycert_bearssl()
|
Loading…
Add table
Reference in a new issue