| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- #include "board.h"
- #include <string.h>
- /* wolfssl includes. */
- #include <wolfssl/ssl.h>
- #include <wolfssl/internal.h>
- #include "api.h"
- #include "sockets.h"
- #define HTTPS_GET_API "GET / HTTP/1.1\r\n" /* HOST, host-port, URI */\
- "Host: www.baidu.com\r\n" /* server name */ \
- "\r\n"
- typedef struct {
- uint32_t ContentLength;
- }https_header_t;
- const char s__host_name[] = "www.baidu.com";
- static const unsigned char __ssl_root_certificate[] =
- "-----BEGIN CERTIFICATE-----"
- "MIIJ7DCCCNSgAwIBAgIMTkADpl62gfh/S9jrMA0GCSqGSIb3DQEBCwUAMFAxCzAJ"
- "BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSYwJAYDVQQDEx1H"
- "bG9iYWxTaWduIFJTQSBPViBTU0wgQ0EgMjAxODAeFw0yNDA3MDgwMTQxMDJaFw0y"
- "NTA4MDkwMTQxMDFaMIGAMQswCQYDVQQGEwJDTjEQMA4GA1UECBMHYmVpamluZzEQ"
- "MA4GA1UEBxMHYmVpamluZzE5MDcGA1UEChMwQmVpamluZyBCYWlkdSBOZXRjb20g"
- "U2NpZW5jZSBUZWNobm9sb2d5IENvLiwgTHRkMRIwEAYDVQQDEwliYWlkdS5jb20w"
- "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1wFMskJ2dseOqoHptNwot"
- "FOhdBERsZ4VQnRNKXEEXMQEfgbNtScQ+C/Z+IpRAt1EObhYlifn74kt2nTsCQLng"
- "jfQkRVBuO/6PNGKdlCYGBeGqAL7xR+LOyHnpH9mwCBJc+WVt2zYM9I1clpXCJa+I"
- "tsq6qpb1AGoQxRDZ2n4K8Gd61wgNCPHDHc/Lk9NPJoUBMvYWvEe5lKhHsJtWtHe4"
- "QC3y58Vi+r5R0PWn2hyTBr9fCo58p/stDiRqp9Irtmi95YhwkNkmgwpMB8RhcGoN"
- "h+Uw5TkPZVj4AVaoPT1ED/GMKZev0+ypmp0+nmjVg2x7yUfLUfp3X7oBdI4TS2hv"
- "AgMBAAGjggaTMIIGjzAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADCBjgYI"
- "KwYBBQUHAQEEgYEwfzBEBggrBgEFBQcwAoY4aHR0cDovL3NlY3VyZS5nbG9iYWxz"
- "aWduLmNvbS9jYWNlcnQvZ3Nyc2FvdnNzbGNhMjAxOC5jcnQwNwYIKwYBBQUHMAGG"
- "K2h0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2dzcnNhb3Zzc2xjYTIwMTgwVgYD"
- "VR0gBE8wTTBBBgkrBgEEAaAyARQwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cu"
- "Z2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCAYGZ4EMAQICMD8GA1UdHwQ4MDYw"
- "NKAyoDCGLmh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vZ3Nyc2FvdnNzbGNhMjAx"
- "OC5jcmwwggNhBgNVHREEggNYMIIDVIIJYmFpZHUuY29tggxiYWlmdWJhby5jb22C"
- "DHd3dy5iYWlkdS5jboIQd3d3LmJhaWR1LmNvbS5jboIPbWN0LnkubnVvbWkuY29t"
- "ggthcG9sbG8uYXV0b4IGZHd6LmNuggsqLmJhaWR1LmNvbYIOKi5iYWlmdWJhby5j"
- "b22CESouYmFpZHVzdGF0aWMuY29tgg4qLmJkc3RhdGljLmNvbYILKi5iZGltZy5j"
- "b22CDCouaGFvMTIzLmNvbYILKi5udW9taS5jb22CDSouY2h1YW5rZS5jb22CDSou"
- "dHJ1c3Rnby5jb22CDyouYmNlLmJhaWR1LmNvbYIQKi5leXVuLmJhaWR1LmNvbYIP"
- "Ki5tYXAuYmFpZHUuY29tgg8qLm1iZC5iYWlkdS5jb22CESouZmFueWkuYmFpZHUu"
- "Y29tgg4qLmJhaWR1YmNlLmNvbYIMKi5taXBjZG4uY29tghAqLm5ld3MuYmFpZHUu"
- "Y29tgg4qLmJhaWR1cGNzLmNvbYIMKi5haXBhZ2UuY29tggsqLmFpcGFnZS5jboIN"
- "Ki5iY2Vob3N0LmNvbYIQKi5zYWZlLmJhaWR1LmNvbYIOKi5pbS5iYWlkdS5jb22C"
- "EiouYmFpZHVjb250ZW50LmNvbYILKi5kbG5lbC5jb22CCyouZGxuZWwub3JnghIq"
- "LmR1ZXJvcy5iYWlkdS5jb22CDiouc3UuYmFpZHUuY29tgggqLjkxLmNvbYISKi5o"
- "YW8xMjMuYmFpZHUuY29tgg0qLmFwb2xsby5hdXRvghIqLnh1ZXNodS5iYWlkdS5j"
- "b22CESouYmouYmFpZHViY2UuY29tghEqLmd6LmJhaWR1YmNlLmNvbYIOKi5zbWFy"
- "dGFwcHMuY26CDSouYmR0anJjdi5jb22CDCouaGFvMjIyLmNvbYIMKi5oYW9rYW4u"
- "Y29tgg8qLnBhZS5iYWlkdS5jb22CESoudmQuYmRzdGF0aWMuY29tghEqLmNsb3Vk"
- "LmJhaWR1LmNvbYISY2xpY2suaG0uYmFpZHUuY29tghBsb2cuaG0uYmFpZHUuY29t"
- "ghBjbS5wb3MuYmFpZHUuY29tghB3bi5wb3MuYmFpZHUuY29tghR1cGRhdGUucGFu"
- "LmJhaWR1LmNvbTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0j"
- "BBgwFoAU+O9/8s14Z6jeb48kjYjxhwMCs+swHQYDVR0OBBYEFK3KAFTK2OWUto+D"
- "2ieAKE5ZJDsYMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgCvGBoo1oyj4KmK"
- "TJxnqwn4u7wiuq68sTijoZ3T+bYDDQAAAZCQAGzzAAAEAwBHMEUCIFwF5Jc+zyIF"
- "Gnpxchz9fY1qzlqg/oVrs2nnuxcpBuuIAiEAu3scD6u51VOP/9aMSqR2yKHZLbHw"
- "Fos9U7AzSdLIZa8AdgAS8U40vVNyTIQGGcOPP3oT+Oe1YoeInG0wBYTr5YYmOgAA"
- "AZCQAG3iAAAEAwBHMEUCIBBYQ6NP7VUDgfktWRg5QxT23QAbTqYovtV2D9O8Qc0T"
- "AiEA2P7+44EvQ5adwL1y56oyxv/m+Gujeia7wpo7+Xbhv6MAdwAN4fIwK9MNwUBi"
- "EgnqVS78R3R8sdfpMO8OQh60fk6qNAAAAZCQAGy+AAAEAwBIMEYCIQDU7Hxtx4c9"
- "p9Jd+cr+DCMtyRYSc0b8cktCcbMmtDE9ygIhAIpJd4yb7jtxnaEC8oLWDushbK1v"
- "0BIuZu6YrQvsf1nQMA0GCSqGSIb3DQEBCwUAA4IBAQCh9DfewC012/+fHZpmSpCn"
- "y+h3/+ClAZ8cJVO+LCmYz9r6bkyhcFquJ5qUpyoW8AYtU0oUFlqH6zLIyujW+7lq"
- "wFxB6NsXKKdwBKmMbmnZr2Fca5f+TtwD/GDJgG/egr7fI1u8194j9KEl8cK8Fujm"
- "+UsoWklEzd1It9xkLazJR/6SwbhSR4k610pvj8rQrS4wAewuYFDaDOfqsHtDIsx1"
- "tZfIfoB/O1wGWZQJU2M9wC8uYq0jQ2Q0MQJXuyJz04MFiGrPAS1Uk8mWd8M+3p65"
- "Xy4iAf8uWzs1M+fcwBE8BNBghkQgE+FSUsldm+5ZBCazU0joJswzldWisXMLTagI"
- "-----END CERTIFICATE-----"
- ;
- static const size_t __ssl_root_certificate_len = sizeof(__ssl_root_certificate);
- /*
- *行长度不包含行尾的\r\n
- */
- static int https_content_get_line_len(const char *https_content, int content_len)
- {
- int ret = -1;
- int step = 0;
- int cnt;
- if (!https_content || (content_len <= 0))
- goto exit;
- for (cnt = 0; cnt < content_len; cnt++) {
- if (https_content[cnt] == '\r') {
- step = 1;
- } else if (https_content[cnt] == '\n') {
- if (step == 1) {
- ret = cnt - 1;
- break;
- }
- } else {
- step = 0;
- }
- }
- exit:
- return ret;
- }
- static int https_content_get_line_pos(const char *https_content, int content_len, uint32_t line)
- {
- int pos = -1;
- int cur_pos;
- int step = 0;
- int line_cnt = 0;
- if (!https_content || (content_len <= 0))
- goto exit;
- for (cur_pos = 0; cur_pos < content_len; cur_pos++) {
- if (step == 2) {
- line_cnt++;
- step = 0;
- if (line_cnt == line) {
- pos = cur_pos;
- break;
- }
- }
- if (https_content[cur_pos] == '\r') {
- step = 1;
- } else if (https_content[cur_pos] == '\n') {
- if (step == 1) {
- step = 2;
- }
- } else {
- step = 0;
- }
- }
- exit:
- return pos;
- }
- static int https_get_content_length(const char *https_content, int content_len)
- {
- int ret = -1;
- int line_len = 0;
- int pos = 0;
- int pos_cnt = 0;
- const char header_start[] = "HTTP";
- const char ContentLength[] = "Content-Length";
- if (!https_content || content_len < 4) {
- ret = -1;
- goto exit;
- }
- if (memcmp((const void *)https_content, (const void *)header_start, 4) != 0) {
- ret = -1;
- goto exit;
- }
- while (1) {
- pos = https_content_get_line_pos(&https_content[pos_cnt], content_len - pos_cnt, 1);
- if (pos > -1) {
- pos_cnt += pos;
- line_len = https_content_get_line_len(&https_content[pos_cnt], content_len - pos_cnt);
- if (line_len <= 0) {
- break;
- } else if (line_len >= strlen(ContentLength)) {
- if (memcmp((const char *)&https_content[pos_cnt], (const char *)ContentLength, strlen(ContentLength)) == 0) {
- sscanf((const char *)&https_content[pos_cnt + strlen(ContentLength) + 2], "%d\r\n", &ret);
- break;
- }
- }
- } else {
- break;
- }
- }
- exit:
- return ret;
- }
- static int https_get_content_pos(const char *https_content, int content_len)
- {
- int ret = -1;
- int line_len = 0;
- int pos = 0;
- int pos_cnt = 0;
- int flag = 0;
- const char header_start[] = "HTTP";
- if (!https_content || content_len < 4) {
- ret = -1;
- goto exit;
- }
- if (memcmp((const void *)https_content, (const void *)header_start, 4) != 0) {
- ret = -1;
- goto exit;
- }
- while (1) {
- pos = https_content_get_line_pos(&https_content[pos_cnt], content_len - pos_cnt, 1);
- if (pos > -1) {
- pos_cnt += pos;
- line_len = https_content_get_line_len(&https_content[pos_cnt], content_len - pos_cnt);
- if (flag) {
- ret = pos_cnt;
- break;
- } else {
- if (line_len < 0) {
- break;
- } else if (line_len == 0) {
- flag = 1;
- }
- }
- } else {
- break;
- }
- }
- exit:
- return ret;
- }
- void https_client_test(void)
- {
- WOLFSSL_CTX* ctx = NULL;
- ip_addr_t server_ip ;
- err_t err = ERR_OK;
- int sockfd;
- struct sockaddr_in servaddr;
- WOLFSSL* ssl = NULL;
- char http_head[] = HTTPS_GET_API;
- int recv_len = 0;
- int total_recv_len = 0;
- char *rbuf = NULL;
- uint32_t pg_size = 1024 * 16;
- int ContentLength = -1;
- int content_start_pos = -1;
- //创建 wolfssl 需要的空间等配置
- if ( WOLFSSL_SUCCESS != wolfSSL_Init()) {
- printf("-------------- wolfssl init fail! --------------\n");
- goto exit;
- }
- //初始化 结构体 WOLFSSL_CTX
- if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
- printf("-------------- wolfSSL_CTX_new fail! --------------\n");
- goto exit;
- }
- //加载 CA 证书到 WOLFSSL_CTX
- if ( wolfSSL_CTX_load_verify_buffer(ctx, (unsigned char *)__ssl_root_certificate, \
- __ssl_root_certificate_len, WOLFSSL_FILETYPE_PEM) != SSL_SUCCESS) {
- printf("-------------- wolfSSL_CTX_load_verify_buffer fail! --------------\n");
- goto exit;
- }
- //进行域名解析
- err = netconn_gethostbyname(s__host_name, &server_ip);
- if (err != ERR_OK) {
- printf("-------------- netconn_gethostbyname fail! --------------\n");
- goto exit;
- }
- if (server_ip.addr == 0) {
- printf("-------------- DNS fail! --------------\n");
- goto exit;
- }
- // 进行 socket 连接
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- goto exit;
- memset(&servaddr, sizeof(servaddr), 0);
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(443);
- inet_pton(AF_INET, inet_ntoa(server_ip), &servaddr.sin_addr);
- /* Connect to socket file descriptor */
- if (0 > connect(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr))) {
- printf("-------------- https connect socket fail! --------------\n");
- goto exit;
- }
- //进行 SSL 的初始化
- wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); // 尝试解决 -188, -155
- if ((ssl = wolfSSL_new(ctx)) == NULL) {
- printf("-------------- wolfSSL_new fail! --------------\n");
- goto exit;
- }
- //进行 SSL 和 socket 绑定
- if( WOLFSSL_SUCCESS != wolfSSL_set_fd(ssl, sockfd)) {
- printf("-------------- wolfSSL_set_fd fail! --------------\n");
- goto exit;
- }
- //访问
- if (wolfSSL_write(ssl, http_head, strlen(http_head)) != strlen(http_head)) {
- printf("-------------- wolfSSL_write fail! --------------\n");
- goto exit;
- }
- //接收
- for(;;) {
- if (total_recv_len == 0)
- rbuf = (char *)pvPortRealloc(rbuf, pg_size);
- else
- rbuf = (char *)pvPortRealloc(rbuf, total_recv_len + pg_size);
- if (!rbuf) {
- printf("realloc fail!\n");
- goto exit;
- }
- if ((ContentLength > 0) && (content_start_pos > 0)) {
- if (((ContentLength + content_start_pos) - total_recv_len) >= pg_size) {
- recv_len = wolfSSL_read(ssl, rbuf + total_recv_len, pg_size);
- } else {
- recv_len = wolfSSL_read(ssl, rbuf + total_recv_len, ((ContentLength + content_start_pos) - total_recv_len));
- }
- } else {
- recv_len = wolfSSL_read(ssl, rbuf + total_recv_len, pg_size);
- }
- if(recv_len <= 0) {
- break;
- }
- total_recv_len += recv_len;
- if ((ContentLength > 0) && (content_start_pos > 0)) {
- if ((ContentLength + content_start_pos) <= total_recv_len)
- break;
- }
- if (ContentLength == -1) {
- ContentLength = https_get_content_length((const char *)rbuf, total_recv_len);
- if (ContentLength > 0)
- printf("ContentLength = %d\n", ContentLength);
- }
- if ((ContentLength > 0) && (content_start_pos == -1)) {
- content_start_pos = https_get_content_pos((const char *)rbuf, total_recv_len);
- if (content_start_pos > 0)
- printf("content_start_pos = %d\n", content_start_pos);
- }
- }
- printf("\n ========== \n\n");
- printf("https recv data : recv_len = 0x%x\n",total_recv_len);
- printf("addr:0x%x\n", (uint32_t)rbuf);
- printf("\n ========== \n\n");
- exit:
- //释放空间
- if (ssl)
- wolfSSL_free(ssl); /* Free WOLFSSL object */
- if (ctx)
- wolfSSL_CTX_free(ctx); /* Free WOLFSSL_CTX object */
- wolfSSL_Cleanup(); /* Free wolfSSL */
- //关闭 socket
- if (sockfd != -1)
- closesocket(sockfd);
- if (rbuf)
- vPortFree((void *)rbuf);
- return;
- }
|