[AsyncWebServer_STM32][NUCLEO-F767ZI] Attempting to read XML file

Post here first, or if you can't find a relevant section!
Post Reply
exdes
Posts: 11
Joined: Fri May 07, 2021 6:16 pm

[AsyncWebServer_STM32][NUCLEO-F767ZI] Attempting to read XML file

Post by exdes »

Hello all,
I am attempting to read the weather feed from Environment Canada using the AsyncWebServer_STM32 library. My code is based on the WebClient example included in the library. I only made the minimum changes necessary.

This is a file that is periodically updated by Environment Canada and made available at this location:
https://dd.weather.gc.ca/citypage_weath ... 0573_e.xml

This is the output when running the code:

Code: Select all

Start WebClient on NUCLEO_F767ZI with LAN8742A built-in Ethernet
AsyncWebServer_STM32 v1.3.0
You're connected to the network, IP = 192.168.2.122

Starting connection to server...
Connected to server
HTTP/1.1 301 Moved Permanently
Date: Mon, 10 May 2021 19:28:09 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; preload
Location: https://dd.weather.gc.ca/citypage_weather/xml/ON/s0000573_e.xml
Content-Length: 271
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://dd.weather.gc.ca/citypage_weather/xml/ON/s0000573_e.xml">here</a>.</p>
</body></html>

Disconnecting from server...
The code is as follows:

Code: Select all

#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
#include <WiFiServer.h>

/****************************************************************************************************************************
  WebClient.h - Dead simple AsyncWebServer for STM32 LAN8720 or built-in LAN8742A Ethernet

  For STM32 with LAN8720 (STM32F4/F7) or built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)

  AsyncWebServer_STM32 is a library for the STM32 with LAN8720 or built-in LAN8742A Ethernet WebServer

  Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer)
  Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_STM32
  Licensed under MIT license

  Version: 1.3.0

  Version Modified By   Date      Comments
  ------- -----------  ---------- -----------
  1.2.3   K Hoang      02/09/2020 Initial coding for STM32 for built-in Ethernet (Nucleo-144, DISCOVERY, etc).
                                  Bump up version to v1.2.3 to sync with ESPAsyncWebServer v1.2.3
  1.2.4   K Hoang      05/09/2020 Add back MD5/SHA1 authentication feature.
  1.2.5   K Hoang      28/12/2020 Suppress all possible compiler warnings. Add examples.
  1.2.6   K Hoang      22/03/2021 Fix dependency on STM32AsyncTCP Library
  1.3.0   K Hoang      14/04/2021 Add support to LAN8720 using STM32F4 or STM32F7
 *****************************************************************************************************************************/
/*
   Currently support
   1) STM32 boards with built-in Ethernet (to use USE_BUILTIN_ETHERNET = true) such as :
      - Nucleo-144 (F429ZI, F767ZI)
      - Discovery (STM32F746G-DISCOVERY)
      - STM32 boards (STM32F/L/H/G/WB/MP1) with 32K+ Flash, with Built-in Ethernet,
      - See How To Use Built-in Ethernet at (https://github.com/khoih-prog/EthernetWebServer_STM32/issues/1)
   2) STM32F/L/H/G/WB/MP1 boards (with 64+K Flash) running ENC28J60 shields (to use USE_BUILTIN_ETHERNET = false)
   3) STM32F/L/H/G/WB/MP1 boards (with 64+K Flash) running W5x00 shields
   4) STM32F4 and STM32F7 boards (with 64+K Flash) running LAN8720 shields
*/

#include "defines.h"

char server[] = "dd.weather.gc.ca";

// Initialize the Web client object
EthernetClient client;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial);

  Serial.print("\nStart WebClient on "); Serial.print(BOARD_NAME);
  Serial.print(" with "); Serial.println(SHIELD_TYPE);
  Serial.println(ASYNC_WEBSERVER_STM32_VERSION);

  // start the ethernet connection and the server
  // Use random mac
  uint16_t index = millis() % NUMBER_OF_MAC;

  // Use Static IP
  // Use DHCP dynamic IP and random mac
  Ethernet.begin(mac[index]);

  // you're connected now, so print out the data
  Serial.print(F("You're connected to the network, IP = "));
  Serial.println(Ethernet.localIP());

  Serial.println();
  Serial.println(F("Starting connection to server..."));

  // if you get a connection, report back via serial
  if (client.connect(server, 80))
  {
    Serial.println(F("Connected to server"));
    // Make a HTTP request
    client.println(F("GET /citypage_weather/xml/ON/s0000573_e.xml HTTP/1.1"));
    client.println(F("Host: dd.weather.gc.ca"));
    client.println(F("Connection: close"));
    client.println();
  }
}

void printoutData(void)
{
  // if there are incoming bytes available
  // from the server, read them and print them
  while (client.available())
  {
    char c = client.read();
    Serial.write(c);
  }
}

void loop()
{
  printoutData();

  // if the server's disconnected, stop the client
  if (!client.connected())
  {
    Serial.println();
    Serial.println(F("Disconnecting from server..."));
    client.stop();

    // do nothing forevermore
    while (true);
  }
}
The reply tells us that the location has moved, but it is definitely at the specified location.

Any ideas what I could be doing wrong?
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: [AsyncWebServer_STM32][NUCLEO-F767ZI] Attempting to read XML file

Post by fpiSTM »

I think it is related to:

Code: Select all

HTTP/1.1 301 Moved Permanently
As stated here:
https://en.wikipedia.org/wiki/HTTP_301
The 301 redirect is considered a best practice for upgrading users from HTTP to HTTPS.
So this means your code try to access using http and not https.
exdes
Posts: 11
Joined: Fri May 07, 2021 6:16 pm

Re: [AsyncWebServer_STM32][NUCLEO-F767ZI] Attempting to read XML file from Environment Canada

Post by exdes »

So I assume that I would need to use the SSL version of the web client for this site? Please bear with my ignorance on this topic, I'm doing my best to come up to speed as I go along. I have used an example from the library EthernetWebServer_SSL_STM32 and adapted it for my own application as a starting point. I used the tool at:

https://openslab-osu.github.io/bearssl- ... e-utility/

to generate the certificate for the site.

The formatting and references of the trustanchor.h file are consistent with the original 'Arduino' example. It seems that the certificate is not matching - please see the serial output below:

Code: Select all

Start EthernetMultiHTTPS_STM32 on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library
EthernetWebServer_SSL_STM32 v1.3.0
[ETHERNET_WEBSERVER] Board : NUCLEO_F767ZI , setCsPin: 10

Using mac index = 7
Connected! IP address: 192.168.2.122
Connecting to dd.weather.gc.ca...
(EthernetSSLClient)(SSL_WARN)(m_run_until): Terminating because the ssl engine closed
(EthernetSSLClient)(SSL_ERROR)(m_start_ssl): Failed to initlalize the SSL layer
(EthernetSSLClient)(SSL_ERROR)(m_print_br_error): Issuer/Subject DN mismatch in the chain.
connection failed
(EthernetSSLClient)(SSL_ERROR)(available): Cannot operate on a closed SSL connection.
(EthernetSSLClient)(SSL_ERROR)(m_print_br_error): Issuer/Subject DN mismatch in the chain.

Disconnecting.

Received 0 bytes in 0.0100 s, rate = 0.00 kbytes/second
Code as follows:

Code: Select all

/****************************************************************************************************************************
  WebClientMulti_SSL.ino - Dead simple SSL WebClient for Ethernet shields

  For STM32F/L/H/G/WB/MP1 with built-in Ethernet LAN8742A (Nucleo-144, DISCOVERY, etc) or W5x00/ENC28J60 shield/module
  
  EthernetWebServer_SSL_STM32 is a library for STM32 using the Ethernet shields to run WebServer and Client with/without SSL

  Use SSLClient Library code from https://github.com/OPEnSLab-OSU/SSLClient
  
  Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer_SSL_STM32
  Licensed under MIT license
 *****************************************************************************************************************************/

// This sample sketch connects to SSL website (https://www.arduino.cc/asciilogo.txt)
// and  (https://www.cloudflare.com/cdn-cgi/trace)
// Generate trustachors.h at https://openslab-osu.github.io/bearssl-certificate-utility/

#include "defines.h"

// You must have SSL Certificates here
#include "trustanchors.h"

// The domain we want to query
char server1[] = "dd.weather.gc.ca";
char query1[] = "GET /citypage_weather/xml/ON/s0000573_e.xml HTTP/1.1";

//char server1[] = "www.arduino.cc";
//char query1[] = "GET /asciilogo.txt HTTP/1.1";

//char server1[] = "media.flaticon.com";
//char query1[]  = "GET /dist/min/img/logo/flaticon_negative.svg HTTP/1.1";


const uint16_t  server_port = 443;

// Initialize the SSL client library
// Arguments: EthernetClient, our trust anchors
EthernetClient    client;
EthernetSSLClient sslClient(client, TAs, (size_t)TAs_NUM);

// Variables to measure the speed
unsigned long beginMicros, endMicros;
unsigned long byteCount = 0;
unsigned long loopCount = 0;

bool printWebData = true;  // set to false for better speed measurement


void connectSSL() 
{
  char* server;
  char* query;
  
    server  = server1;
    query   = query1;
  Serial.print("Connecting to ");
  Serial.print(server);
  Serial.println("...");

  // if you get a connection, report back via serial:
  auto start = millis();
  
  if (sslClient.connect(server, server_port)) 
  {
    auto time = millis() - start;
    
    Serial.print("Took: ");
    Serial.println(time);
    
    // Make a HTTP request:
    sslClient.println(query);     
    sslClient.println("User-Agent: SSLClientOverEthernet");
    sslClient.print("Host: ");
    sslClient.println(server);
    sslClient.println("Connection: close");
    sslClient.println();
    sslClient.flush();
  } 
  else 
  {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  
  beginMicros = micros();
}

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial);

  Serial.print("\nStart EthernetMultiHTTPS_STM32 on " + String(BOARD_NAME));
  Serial.println(" with " + String(SHIELD_TYPE));
  Serial.println(ETHERNET_WEBSERVER_SSL_STM32_VERSION);

#if USE_ETHERNET_WRAPPER

  EthernetInit();

#else

#if USE_ETHERNET
  ET_LOGWARN(F("=========== USE_ETHERNET ==========="));
#elif USE_ETHERNET2
  ET_LOGWARN(F("=========== USE_ETHERNET2 ==========="));
#elif USE_ETHERNET3
  ET_LOGWARN(F("=========== USE_ETHERNET3 ==========="));
#elif USE_ETHERNET_LARGE
  ET_LOGWARN(F("=========== USE_ETHERNET_LARGE ==========="));
#elif USE_ETHERNET_ESP8266
  ET_LOGWARN(F("=========== USE_ETHERNET_ESP8266 ==========="));
#else
//  ET_LOGWARN(F("========================="));
#endif


#if defined(ESP8266)
  // For ESP8266, change for other boards if necessary
#ifndef USE_THIS_SS_PIN
#define USE_THIS_SS_PIN   D2    // For ESP8266
#endif

  ET_LOGWARN1(F("ESP8266 setCsPin:"), USE_THIS_SS_PIN);

#if ( USE_ETHERNET || USE_ETHERNET_LARGE || USE_ETHERNET2 || USE_ETHERNET_ENC )
  // For ESP8266
  // Pin                D0(GPIO16)    D1(GPIO5)    D2(GPIO4)    D3(GPIO0)    D4(GPIO2)    D8
  // Ethernet           0                 X            X            X            X        0
  // Ethernet2          X                 X            X            X            X        0
  // Ethernet3          X                 X            X            X            X        0
  // EthernetLarge      X                 X            X            X            X        0
  // Ethernet_ESP8266   0                 0            0            0            0        0
  // D2 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs
  // Must use library patch for Ethernet, EthernetLarge libraries
  Ethernet.init (USE_THIS_SS_PIN);

#elif USE_ETHERNET3
  // Use  MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer
#ifndef ETHERNET3_MAX_SOCK_NUM
#define ETHERNET3_MAX_SOCK_NUM      4
#endif

  Ethernet.setCsPin (USE_THIS_SS_PIN);
  Ethernet.init (ETHERNET3_MAX_SOCK_NUM);

#elif USE_CUSTOM_ETHERNET

  // You have to add initialization for your Custom Ethernet here
  // This is just an example to setCSPin to USE_THIS_SS_PIN, and can be not correct and enough
  Ethernet.init(USE_THIS_SS_PIN);

#endif  //( USE_ETHERNET || USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE )

#elif defined(ESP32)

#ifndef USE_THIS_SS_PIN
#define USE_THIS_SS_PIN   22    // For ESP32
#endif

  ET_LOGWARN1(F("ESP32 setCsPin:"), USE_THIS_SS_PIN);

  // For other boards, to change if necessary
#if ( USE_ETHERNET || USE_ETHERNET_LARGE || USE_ETHERNET2 || USE_ETHERNET_ENC )
  // Must use library patch for Ethernet, EthernetLarge libraries
  // ESP32 => GPIO2,4,5,13,15,21,22 OK with Ethernet, Ethernet2, EthernetLarge
  // ESP32 => GPIO2,4,5,15,21,22 OK with Ethernet3

  //Ethernet.setCsPin (USE_THIS_SS_PIN);
  Ethernet.init (USE_THIS_SS_PIN);

#elif USE_ETHERNET3
  // Use  MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer
#ifndef ETHERNET3_MAX_SOCK_NUM
#define ETHERNET3_MAX_SOCK_NUM      4
#endif

  Ethernet.setCsPin (USE_THIS_SS_PIN);
  Ethernet.init (ETHERNET3_MAX_SOCK_NUM);

#elif USE_CUSTOM_ETHERNET

  // You have to add initialization for your Custom Ethernet here
  // This is just an example to setCSPin to USE_THIS_SS_PIN, and can be not correct and enough
  Ethernet.init(USE_THIS_SS_PIN);

#endif  //( USE_ETHERNET || USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE )

#else   //defined(ESP8266)
  // unknown board, do nothing, use default SS = 10
#ifndef USE_THIS_SS_PIN
  // Select USE_THIS_SS_PIN as follows
  //  10    // Most Arduino shields
  //   5    // MKR ETH shield
  //   0    // Teensy 2.0
  //  20    // Teensy++ 2.0
  //  15    // ESP8266 with Adafruit Featherwing Ethernet
  //  33    // ESP32 with Adafruit Featherwing Ethernet
#define USE_THIS_SS_PIN   10    // For other boards
#endif

  ET_LOGWARN3(F("Board :"), BOARD_NAME, F(", setCsPin:"), USE_THIS_SS_PIN);

  // For other boards, to change if necessary
#if ( USE_ETHERNET || USE_ETHERNET_LARGE || USE_ETHERNET2  || USE_ETHERNET_ENC )
  // Must use library patch for Ethernet, Ethernet2, EthernetLarge libraries

  Ethernet.init (USE_THIS_SS_PIN);

#elif USE_ETHERNET3
  // Use  MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer
#ifndef ETHERNET3_MAX_SOCK_NUM
#define ETHERNET3_MAX_SOCK_NUM      4
#endif

  Ethernet.setCsPin (USE_THIS_SS_PIN);
  Ethernet.init (ETHERNET3_MAX_SOCK_NUM);

#elif USE_CUSTOM_ETHERNET

  // You have to add initialization for your Custom Ethernet here
  // This is just an example to setCSPin to USE_THIS_SS_PIN, and can be not correct and enough
  Ethernet.init(USE_THIS_SS_PIN);

#endif  //( USE_ETHERNET || USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE )

#endif    //defined(ESP8266)


#endif  //USE_ETHERNET_WRAPPER


  // start the ethernet connection and the server:
  // Use DHCP dynamic IP and random mac
  uint16_t index = millis() % NUMBER_OF_MAC;
  // Use Static IP
  //Ethernet.begin(mac[index], ip);
  Ethernet.begin(mac[index]);
  Serial.println("");
  Serial.print(F("Using mac index = "));
  Serial.println(index);

  Serial.print(F("Connected! IP address: "));
  Serial.println(Ethernet.localIP());

  // give the Ethernet shield a second to initialize:
  delay(2000);

  // connect!
  connectSSL();
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and print them:
  int len = sslClient.available();

  if (len > 0)
  {
    byte buffer[80];

    if (len > 80)
      len = 80;

    sslClient.read(buffer, len);

    if (printWebData)
    {
      Serial.write(buffer, len); // show in the serial monitor (slows some boards)
    }

    byteCount = byteCount + len;
  }

  // if the server's disconnected, stop the sslClient:
  if (!sslClient.connected())
  {
    endMicros = micros();

    Serial.println();
    Serial.println("Disconnecting.\n");
    sslClient.stop();

    Serial.print("Received ");
    Serial.print(byteCount);
    Serial.print(" bytes in ");
    float seconds = (float)(endMicros - beginMicros) / 1000000.0;
    Serial.print(seconds, 4);
    float rate = (float)byteCount / seconds / 1000.0;
    Serial.print(" s, rate = ");
    Serial.print(rate);
    Serial.print(" kbytes/second");
    Serial.println();


	while(1);
  }
}
And the trustachors.h file:

Code: Select all

#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:    Entrust Root Certification Authority - G2
 * Subject:  CN=Entrust Root Certification Authority - G2,OU=(c) 2009 Entrust\, Inc. - for authorized use only,OU=See www.entrust.net/legal-terms,O=Entrust\, Inc.,C=US
 * Domain(s): dd.weather.gc.ca
 */

#define TAs_NUM 1

static const unsigned char TA_DN0[] = {
    0x30, 0x81, 0xbe, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
    0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04,
    0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20,
    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
    0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65,
    0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c,
    0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39,
    0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29,
    0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73,
    0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f,
    0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
    0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x32, 0x30,
    0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6e, 0x74, 0x72,
    0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72,
    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
    0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47,
    0x32,
};

static const unsigned char TA_RSA_N0[] = {
    0xba, 0x84, 0xb6, 0x72, 0xdb, 0x9e, 0x0c, 0x6b, 0xe2, 0x99, 0xe9, 0x30,
    0x01, 0xa7, 0x76, 0xea, 0x32, 0xb8, 0x95, 0x41, 0x1a, 0xc9, 0xda, 0x61,
    0x4e, 0x58, 0x72, 0xcf, 0xfe, 0xf6, 0x82, 0x79, 0xbf, 0x73, 0x61, 0x06,
    0x0a, 0xa5, 0x27, 0xd8, 0xb3, 0x5f, 0xd3, 0x45, 0x4e, 0x1c, 0x72, 0xd6,
    0x4e, 0x32, 0xf2, 0x72, 0x8a, 0x0f, 0xf7, 0x83, 0x19, 0xd0, 0x6a, 0x80,
    0x80, 0x00, 0x45, 0x1e, 0xb0, 0xc7, 0xe7, 0x9a, 0xbf, 0x12, 0x57, 0x27,
    0x1c, 0xa3, 0x68, 0x2f, 0x0a, 0x87, 0xbd, 0x6a, 0x6b, 0x0e, 0x5e, 0x65,
    0xf3, 0x1c, 0x77, 0xd5, 0xd4, 0x85, 0x8d, 0x70, 0x21, 0xb4, 0xb3, 0x32,
    0xe7, 0x8b, 0xa2, 0xd5, 0x86, 0x39, 0x02, 0xb1, 0xb8, 0xd2, 0x47, 0xce,
    0xe4, 0xc9, 0x49, 0xc4, 0x3b, 0xa7, 0xde, 0xfb, 0x54, 0x7d, 0x57, 0xbe,
    0xf0, 0xe8, 0x6e, 0xc2, 0x79, 0xb2, 0x3a, 0x0b, 0x55, 0xe2, 0x50, 0x98,
    0x16, 0x32, 0x13, 0x5c, 0x2f, 0x78, 0x56, 0xc1, 0xc2, 0x94, 0xb3, 0xf2,
    0x5a, 0xe4, 0x27, 0x9a, 0x9f, 0x24, 0xd7, 0xc6, 0xec, 0xd0, 0x9b, 0x25,
    0x82, 0xe3, 0xcc, 0xc2, 0xc4, 0x45, 0xc5, 0x8c, 0x97, 0x7a, 0x06, 0x6b,
    0x2a, 0x11, 0x9f, 0xa9, 0x0a, 0x6e, 0x48, 0x3b, 0x6f, 0xdb, 0xd4, 0x11,
    0x19, 0x42, 0xf7, 0x8f, 0x07, 0xbf, 0xf5, 0x53, 0x5f, 0x9c, 0x3e, 0xf4,
    0x17, 0x2c, 0xe6, 0x69, 0xac, 0x4e, 0x32, 0x4c, 0x62, 0x77, 0xea, 0xb7,
    0xe8, 0xe5, 0xbb, 0x34, 0xbc, 0x19, 0x8b, 0xae, 0x9c, 0x51, 0xe7, 0xb7,
    0x7e, 0xb5, 0x53, 0xb1, 0x33, 0x22, 0xe5, 0x6d, 0xcf, 0x70, 0x3c, 0x1a,
    0xfa, 0xe2, 0x9b, 0x67, 0xb6, 0x83, 0xf4, 0x8d, 0xa5, 0xaf, 0x62, 0x4c,
    0x4d, 0xe0, 0x58, 0xac, 0x64, 0x34, 0x12, 0x03, 0xf8, 0xb6, 0x8d, 0x94,
    0x63, 0x24, 0xa4, 0x71,
};

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_ */
I did try this code on a couple of other sites that seemed to work okay. These sites also had the https:// but did not seem to care about the certificate matching, as I did try using these sites with an incorrect trustanchors.h file, and they worked fine.

Any help to point me in the right direction would be very much appreciated!
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: [AsyncWebServer_STM32][NUCLEO-F767ZI] Attempting to read XML file

Post by fpiSTM »

Unfortunately I have no more clue to help you as I never do this. :?
Maybe someone else can help. Maybe @khoih-prog who made a lot of work around this.
khoih-prog
Posts: 102
Joined: Thu Feb 27, 2020 7:54 am
Location: Toronto

Re: [AsyncWebServer_STM32][NUCLEO-F767ZI] Attempting to read XML file

Post by khoih-prog »

Thanks @fpiSTM for helping and informing.
Hi @exdes ,
I'm currently busy working on Raspberry Pico, and can't help right now, but will have a look at the issue shortly.
In the meantime, could you help, if possible, by using other boards, with SSL easier to use, such as ESP32/ESP8266, to see if you can access OK.
If OK, this can be a bug in the related library and I'll spend time to fix.
exdes
Posts: 11
Joined: Fri May 07, 2021 6:16 pm

Re: [AsyncWebServer_STM32][NUCLEO-F767ZI] Attempting to read XML file

Post by exdes »

Thank-you @fpiSTM and @khoih-prog for your help. Unfortunately I do not have another board with networking capability available for testing. I did spend some more time on this but still no luck. I did cut out unused code from the original listing and spent more time educating myself on this topic. Please see the updated code below, though no functional changes have been made.

Code: Select all

#include "defines.h"

// You must have SSL Certificates here
#include "trustanchors.h"

const uint16_t  server_port = 443;

// Initialize the SSL client library
// Arguments: EthernetClient, our trust anchors
EthernetClient    client;
EthernetSSLClient sslClient(client, TAs, (size_t)TAs_NUM);

// Variables to measure the speed
unsigned long beginMicros, endMicros;
unsigned long byteCount = 0;
unsigned long loopCount = 0;

bool printWebData = true;  // set to false for better speed measurement



void setup()
{
	// Open serial communications and wait for port to open:
	Serial.begin(115200);
	while (!Serial);
	
	Serial.print("\nStart EthernetHTTPS_STM32 on " + String(BOARD_NAME));
	Serial.println(" with " + String(SHIELD_TYPE));
	Serial.println(ETHERNET_WEBSERVER_SSL_STM32_VERSION);
	
	
	// start the ethernet connection and the server:
	// Use DHCP dynamic IP and random mac
	uint16_t index = millis() % NUMBER_OF_MAC;
	
	// Use Static IP
	//Ethernet.begin(mac[index], ip);
	Ethernet.begin(mac[index]);
	Serial.println("");
	Serial.print(F("Using mac index = "));
	Serial.println(index);
	
	Serial.print(F("Connected! IP address: "));
	Serial.println(Ethernet.localIP());
	
	// give the Ethernet shield a second to initialize:
	delay(2000);
	
	// connect!
	connectSSL();
}



void connectSSL() 
{
//	char* server = "www.arduino.cc";
//	char* query  = "GET /asciilogo.txt HTTP/1.1";

	char* server = "dd.weather.gc.ca";
	char* query = "GET /citypage_weather/xml/ON/s0000573_e.xml HTTP/1.1";

//char* server = "media.flaticon.com";
//char* query  = "GET /dist/min/img/logo/flaticon_negative.svg HTTP/1.1";
	
	Serial.print("Connecting to ");
	Serial.print(server);
	Serial.println("...");
	
	// if you get a connection, report back via serial:
	auto start = millis();
	
	if (sslClient.connect(server, server_port)) 
	{
		auto time = millis() - start;
		
		Serial.print("Took: ");
		Serial.println(time);
		
		// Make a HTTP request:
		sslClient.println(query);     
		sslClient.println("User-Agent: SSLClientOverEthernet");
		sslClient.print("Host: ");
		sslClient.println(server);
		sslClient.println("Connection: close");
		sslClient.println();
		sslClient.flush();
	} 
	else 
	{
		// if you didn't get a connection to the server:
		Serial.println("connection failed");
	}

	beginMicros = micros();
}


void Show_Response()
{
	// if there are incoming bytes available
	// from the server, read them and print them:
	int len = sslClient.available();
	
	if (len > 0)
	{
		byte buffer[80];
		
		if (len > 80)	{ len = 80; }
		
		sslClient.read(buffer, len);
		
		if (printWebData)
		{
			Serial.write(buffer, len); // show in the serial monitor (slows some boards)
		}
		
		byteCount = byteCount + len;
	}

	// if the server's disconnected, stop the sslClient:
	if (!sslClient.connected())
	{
		endMicros = micros();
		
		Serial.println();
		Serial.println("Disconnecting.\n");
		sslClient.stop();
		
		Serial.print("Received ");
		Serial.print(byteCount);
		Serial.print(" bytes in ");
		float seconds = (float)(endMicros - beginMicros) / 1000000.0;
		Serial.print(seconds, 4);
		float rate = (float)byteCount / seconds / 1000.0;
		Serial.print(" s, rate = ");
		Serial.print(rate);
		Serial.print(" kbytes/second");
		Serial.println();
		
		while(1);
	}
}



void loop()
{
	Show_Response();
}
The output is still the same:

Code: Select all

Start EthernetHTTPS_STM32 on NUCLEO_F767ZI with LAN8742A Ethernet & STM32Ethernet Library
EthernetWebServer_SSL_STM32 v1.3.0

Using mac index = 17
Connected! IP address: 192.168.2.111
Connecting to dd.weather.gc.ca...
(EthernetSSLClient)(SSL_WARN)(m_run_until): Terminating because the ssl engine closed
(EthernetSSLClient)(SSL_ERROR)(m_start_ssl): Failed to initlalize the SSL layer
(EthernetSSLClient)(SSL_ERROR)(m_print_br_error): Issuer/Subject DN mismatch in the chain.
connection failed
(EthernetSSLClient)(SSL_ERROR)(available): Cannot operate on a closed SSL connection.
(EthernetSSLClient)(SSL_ERROR)(m_print_br_error): Issuer/Subject DN mismatch in the chain.

Disconnecting.

Received 0 bytes in 0.0100 s, rate = 0.00 kbytes/second
I will continue to work away at this, and I still have other pressing things that need to be done, so there is no rush. I suspect I am probably missing something basic.
Post Reply

Return to “General discussion”