Skip to content

Commit 94ea184

Browse files
authored
Merge pull request #481 from night1rider/Zephyr-fixes
Replace deprecated VeriSign CA with Amazon Root CA 1 + Starfield G2
2 parents 9cfac07 + 2cea52b commit 94ea184

3 files changed

Lines changed: 225 additions & 3 deletions

File tree

.github/workflows/ubuntu-check-curl.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ jobs:
1111

1212
runs-on: ubuntu-22.04
1313
timeout-minutes: 5
14+
# Serialize with every other workflow that runs awsiot.test against
15+
# AWS IoT under the hard-coded "demoDevice" client ID. Without this,
16+
# parallel runs from sibling workflows clobber each other's MQTT
17+
# connections.
18+
concurrency:
19+
group: wolfmqtt-awsiot-external
20+
cancel-in-progress: false
1421

1522
steps:
1623
- name: Install dependencies

.github/workflows/ubuntu-check.yml

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ jobs:
1111

1212
runs-on: ubuntu-22.04
1313
timeout-minutes: 5
14+
# Serialize across all workflows that exercise the hard-coded
15+
# "demoDevice" MQTT client ID against AWS IoT. Parallel runs from
16+
# different workflows (ubuntu-check, ubuntu-check-curl, this file's
17+
# aws-ca-regression) otherwise collide on the AWS side and produce
18+
# spurious "MQTT Connect/Subscribe: Error (Network) (-8)" failures.
19+
concurrency:
20+
group: wolfmqtt-awsiot-external
21+
cancel-in-progress: false
1422

1523
steps:
1624
- name: Install dependencies
@@ -123,3 +131,126 @@ jobs:
123131
run: |
124132
cat test-suite.log
125133
cat scripts/*.log
134+
135+
aws-ca-regression:
136+
# Exercises examples/aws/awsiot.c trust-anchor handling in three
137+
# configurations. Uses the real AWS IoT ATS endpoint hard-coded in
138+
# the demo, so this job needs external network access (same as the
139+
# `build` job's `make check`).
140+
#
141+
# `needs: build` serializes AWS IoT access within this workflow.
142+
# The repo-wide `concurrency:` group below serializes against other
143+
# workflows (e.g. ubuntu-check-curl) that also run awsiot.test
144+
# against the same hard-coded "demoDevice" client ID. Without both,
145+
# parallel jobs cause AWS IoT to drop connections with "MQTT
146+
# Connect/Subscribe: Error (Network) (-8)".
147+
needs: build
148+
concurrency:
149+
group: wolfmqtt-awsiot-external
150+
cancel-in-progress: false
151+
#
152+
# case 1: default bundle (Amazon Root CA 1 + Starfield G2), wolfSSL
153+
# built WITHOUT WOLFSSL_NO_ASN_STRICT. Strict ASN parsing
154+
# drops Starfield G2 (serial=0); the verify callback's
155+
# accept-anyway branch keeps the test passing. Expect PASS.
156+
#
157+
# case 2: default bundle, wolfSSL built WITH WOLFSSL_NO_ASN_STRICT.
158+
# Full bundle loads, chain verifies cleanly, callback
159+
# never has to mask an error. Expect PASS.
160+
#
161+
# case 3: legacy VeriSign G5 bundle (via
162+
# -DWOLFMQTT_AWSIOT_LEGACY_VERISIGN_CA), wolfSSL built WITH
163+
# WOLFSSL_NO_ASN_STRICT. The strict callback rejects the
164+
# unanchored chain. Expect FAIL.
165+
runs-on: ubuntu-22.04
166+
timeout-minutes: 10
167+
steps:
168+
- name: Install dependencies
169+
run: |
170+
export DEBIAN_FRONTEND=noninteractive
171+
sudo apt-get update
172+
sudo apt-get install -y mosquitto bubblewrap
173+
- name: Setup mosquitto broker
174+
run: |
175+
sudo service mosquitto stop
176+
sleep 1
177+
178+
# --- case 1: wolfSSL built with DEFAULT strict ASN parsing ---
179+
- uses: actions/checkout@master
180+
with:
181+
repository: wolfssl/wolfssl
182+
path: wolfssl
183+
- name: wolfssl autogen (strict ASN default)
184+
working-directory: ./wolfssl
185+
run: ./autogen.sh
186+
- name: wolfssl configure (strict ASN default)
187+
working-directory: ./wolfssl
188+
run: ./configure --enable-enckeys
189+
- name: wolfssl make
190+
working-directory: ./wolfssl
191+
run: make
192+
- name: wolfssl make install
193+
working-directory: ./wolfssl
194+
run: sudo make install
195+
196+
- uses: actions/checkout@master
197+
- name: wolfmqtt autogen
198+
run: ./autogen.sh
199+
- name: case 1 - wolfmqtt configure (default bundle, strict ASN)
200+
run: ./configure --enable-tls --enable-examples
201+
- name: case 1 - wolfmqtt make
202+
run: make
203+
- name: case 1 - awsiot.test expect PASS
204+
run: ./scripts/awsiot.test
205+
206+
# --- cases 2 + 3: wolfSSL rebuilt with WOLFSSL_NO_ASN_STRICT ---
207+
# The wolfmqtt checkout above wiped the workspace, so the wolfssl
208+
# source tree is gone even though /usr/local/lib/libwolfssl.* is
209+
# still installed. Re-checkout to get a fresh source tree for the
210+
# NO_ASN_STRICT rebuild.
211+
- uses: actions/checkout@master
212+
with:
213+
repository: wolfssl/wolfssl
214+
path: wolfssl
215+
- name: wolfssl autogen (NO_ASN_STRICT build)
216+
working-directory: ./wolfssl
217+
run: ./autogen.sh
218+
- name: wolfssl configure with -DWOLFSSL_NO_ASN_STRICT
219+
working-directory: ./wolfssl
220+
run: ./configure --enable-enckeys CFLAGS=-DWOLFSSL_NO_ASN_STRICT
221+
- name: wolfssl rebuild
222+
working-directory: ./wolfssl
223+
run: make
224+
- name: wolfssl reinstall
225+
working-directory: ./wolfssl
226+
run: sudo make install
227+
228+
- name: case 2 - wolfmqtt configure (default bundle, WOLFSSL_NO_ASN_STRICT)
229+
run: |
230+
make clean
231+
./configure --enable-tls --enable-examples
232+
- name: case 2 - wolfmqtt make
233+
run: make
234+
- name: case 2 - awsiot.test expect PASS
235+
run: ./scripts/awsiot.test
236+
237+
- name: case 3 - wolfmqtt configure (legacy VeriSign, WOLFSSL_NO_ASN_STRICT)
238+
run: |
239+
make clean
240+
./configure --enable-tls --enable-examples \
241+
CPPFLAGS=-DWOLFMQTT_AWSIOT_LEGACY_VERISIGN_CA
242+
- name: case 3 - wolfmqtt make
243+
run: make
244+
- name: case 3 - awsiot.test expect FAIL
245+
run: |
246+
if ./scripts/awsiot.test; then
247+
echo "case 3 unexpectedly PASSED - legacy VeriSign should not verify AWS IoT chain"
248+
exit 1
249+
fi
250+
echo "case 3 FAILED as expected (legacy VeriSign trust anchor rejected)"
251+
252+
- name: Show logs on failure
253+
if: failure() || cancelled()
254+
run: |
255+
cat test-suite.log || true
256+
cat scripts/*.log || true

examples/aws/awsiot.c

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,27 @@ static int mTestDone = 0;
7676

7777
#define AWSIOT_PUBLISH_MSG_SZ 400
7878

79-
/* Demo Certificates */
79+
/* Demo Certificates
80+
*
81+
* Default: Amazon Root CA 1 + Starfield Services Root CA G2, the trust
82+
* anchors AWS IoT documents for ATS endpoints. Sources:
83+
* https://www.amazontrust.com/repository/AmazonRootCA1.pem
84+
* https://www.amazontrust.com/repository/SFSRootCAG2.pem
85+
*
86+
* Note: Starfield Services Root CA G2 has serialNumber=0, so wolfSSL's
87+
* default strict ASN parser drops it. Builds that need real chain
88+
* verification against AWS IoT must define WOLFSSL_NO_ASN_STRICT.
89+
*
90+
* Regression toggle: define WOLFMQTT_AWSIOT_LEGACY_VERISIGN_CA at build
91+
* time to restore the pre-fix VeriSign Class 3 G5 root. That CA was
92+
* deprecated by AWS IoT Core (see AWS server-authentication docs) and
93+
* no longer verifies any AWS IoT chain; the toggle exists so the test
94+
* can assert that strict verification rejects the old anchor.
95+
*/
96+
#ifdef WOLFMQTT_AWSIOT_LEGACY_VERISIGN_CA
8097
WOLFMQTT_EXAMPLE_CERT const char* root_ca =
98+
/* VeriSign Class 3 Public Primary Certification Authority - G5
99+
* (deprecated by AWS IoT Core; preserved only for regression testing). */
81100
"-----BEGIN CERTIFICATE-----\n"
82101
"MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\n"
83102
"yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL\n"
@@ -106,6 +125,55 @@ WOLFMQTT_EXAMPLE_CERT const char* root_ca =
106125
"4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N\n"
107126
"hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\n"
108127
"-----END CERTIFICATE-----";
128+
#else
129+
WOLFMQTT_EXAMPLE_CERT const char* root_ca =
130+
/* Amazon Root CA 1 */
131+
"-----BEGIN CERTIFICATE-----\n"
132+
"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n"
133+
"ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n"
134+
"b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n"
135+
"MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n"
136+
"b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n"
137+
"ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n"
138+
"9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n"
139+
"IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n"
140+
"VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n"
141+
"93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n"
142+
"jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
143+
"AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n"
144+
"A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n"
145+
"U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n"
146+
"N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n"
147+
"o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n"
148+
"5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n"
149+
"rqXRfboQnoZsG4q5WTP468SQvvG5\n"
150+
"-----END CERTIFICATE-----\n"
151+
/* Starfield Services Root Certificate Authority - G2 */
152+
"-----BEGIN CERTIFICATE-----\n"
153+
"MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx\n"
154+
"EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n"
155+
"HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs\n"
156+
"ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5\n"
157+
"MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD\n"
158+
"VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy\n"
159+
"ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy\n"
160+
"dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI\n"
161+
"hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p\n"
162+
"OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2\n"
163+
"8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K\n"
164+
"Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe\n"
165+
"hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk\n"
166+
"6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw\n"
167+
"DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q\n"
168+
"AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI\n"
169+
"bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB\n"
170+
"ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z\n"
171+
"qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd\n"
172+
"iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn\n"
173+
"0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN\n"
174+
"sSi6\n"
175+
"-----END CERTIFICATE-----";
176+
#endif /* WOLFMQTT_AWSIOT_LEGACY_VERISIGN_CA */
109177

110178
#if 0
111179
static const char* device_pub_key =
@@ -214,9 +282,21 @@ static int mqtt_aws_tls_verify_cb(int preverify, WOLFSSL_X509_STORE_CTX* store)
214282
PRINTF(" Subject's domain name is %s", store->domain);
215283

216284
if (store->error != 0) {
217-
/* Allowing to continue */
218-
/* Should check certificate and return 0 if not okay */
285+
#ifdef WOLFSSL_NO_ASN_STRICT
286+
/* With WOLFSSL_NO_ASN_STRICT the full AWS IoT trust bundle
287+
* (Amazon Root CA 1 + Starfield Services Root CA G2) loads and
288+
* a real chain must verify. Treat any error as a hard failure
289+
* so regressions in the trust bundle or the server chain are
290+
* caught by scripts/awsiot.test instead of being masked. */
291+
PRINTF(" Rejecting cert: verification must succeed under"
292+
" WOLFSSL_NO_ASN_STRICT");
293+
return 0;
294+
#else
295+
/* Strict ASN parsing drops Starfield Services Root CA G2
296+
* (serialNumber=0), so chain verification can legitimately
297+
* fail here. Keep the demo running. */
219298
PRINTF(" Allowing cert anyways");
299+
#endif
220300
}
221301

222302
return 1;
@@ -227,6 +307,10 @@ static int mqtt_aws_tls_cb(MqttClient* client)
227307
{
228308
int rc = WOLFSSL_FAILURE;
229309

310+
#ifdef DEBUG_WOLFSSL
311+
wolfSSL_Debugging_ON();
312+
#endif
313+
230314
/* Use highest available and allow downgrade. If wolfSSL is built with
231315
* old TLS support, it is possible for a server to force a downgrade to
232316
* an insecure version. */

0 commit comments

Comments
 (0)