SSL

SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。
  SSL (Secure Socket Layer)   
为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃 听。

目前一般通用之规格为40 bit之安全标准,美国则已推出128 bit之更高安全标准,但限制出境。只要3.0版本以上之I.E.或Netscape浏览器即可支持SSL。  
 当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。   

SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层:
SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。   SSL协议提供的服务主要有:   
1)认证用户和服务器,确保数据发送到正确的客户机和服务器;    2)加密数据以防止数据中途被窃取;   
3)维护数据的完整性,确保数据在传输过程中不被改变。   
SSL协议的工作流程:   
服务器认证阶段:
1)客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接;
2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息;
3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器;
4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器。   
用户认证阶段:在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户,客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证。   
从SSL 协议所提供的服务及其工作流程可以看出,SSL协议运行的基础是商家对消费者信息保密的承诺,这就有利于商家而不利于消费者。在电子商务初级阶段,由于运作电子商务的企业大多是信誉较高的大公司,因此这问题还没有充分暴露出来。但随着电子商务的发展,各中小型公司也参与进来,这样在电子支付过程中的单一认证问题就越来越突出。虽然在SSL3.0中通过数字签名和数字证书可实现浏览器和Web服务器双方的身份验证,但是SSL协议仍存在一些问题,比如,只能提供交易中客户与服务器间的双方认证,在涉及多方的电子交易中,SSL协议并不能协调各方间的安全传输和信任关系。在这种情况下,Visa和 MasterCard两大信用卡公组织制定了SET协议,为网上信用卡支付提供了全球性的标准。   
https介绍   
HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议   它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作,并返回网络上传送回的结果。HTTPS实际上应用了Netscape的完全套接字层(SSL)作为HTTP应用层的子层。(HTTPS使用端口443,而不是象HTTP那样使用端口80来和TCP/IP进行通信。)SSL使用40 位关键字作为RC4流加密算法,这对于商业信息的加密是合适的。HTTPS和SSL支持使用X.509数字认证,如果需要的话用户可以确认发送者是谁。。   
https是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,https的安全基础是SSL,因此加密的详细内容请看SSL。   
它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。这个系统的最初研发由网景公司进行,提供了身份验证与加密通讯方法,现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。   

限制   

它的安全保护依赖浏览器的正确实现以及服务器软件、实际加密算法的支持.   一种常见的误解是“银行用户在线使用https:就能充分彻底保障他们的银行卡号不被偷窃。”实际上,与服务器的加密连接中能保护银行卡号的部分,只有用户到服务器之间的连接及服务器自身。并不能绝对确保服务器自己是安全的,这点甚至已被攻击者利用,常见例子是模仿银行域名的钓鱼攻击。少数罕见攻击在网站传输客户数据时发生,攻击者尝试窃 听数据于传输中。   

商业网站被人们期望迅速尽早引入新的特殊处理程序到金融网关,仅保留传输码(transaction number)。不过他们常常存储银行卡号在同一个数据库里。那些数据库和服务器少数情况有可能被未授权用户攻击和损害。

加密和认证
首先我们需要区分加密和认证这两个基本概念。
加密是将数据资料加密,使得非法用户即使取得加密过的资料,也无法获取正确的资料内容,所以 数据加密可以保护数据,防止监听攻击。其重点在于数据的安全性。身份认证是用来判断某个身份的真实性,确认身份后,系统才可以依不同的身份给予不同的权 限。其重点在于用户的真实性。两者的侧重点是不同的。


公钥和私钥
公 钥和私钥就是俗称的不对称加密方式,是从以前的对称加密(使用用户名与密码)方式的提高。

在现代密码体制中加密和解密是采用不同的密钥(公开密钥),也就是非对称密钥密码系统,每个通信方均需要两个密钥,即公钥和私钥,这两把密钥可以互为加解 密。公钥是公开的,不需要保密,而私钥是由个人自己持有,并且必须妥善保管和注意保密。

  公钥私钥的原则:

一个公钥对应一个私钥。
密钥对中,让大家都知道的是公钥,不告诉大家,只有自己知道的,是私钥。
如果用其中一个密钥加密数据,则只有对应的那个密钥才可以解密。
如果用其中一个密钥可以进行解密数据,则该数据必然是对应的那个密钥进行的加密。
用电子邮件的方式说明一下原理。
使用公钥与私钥的目的就是实现安全的电子邮件,必须实现如下目的:
1. 我发送给你的内容必须加密,在邮件的传输过程中不能被别人看到。
2. 必须保证是我发送的邮件,不是别人冒充我的。
要达到这样的目标必须发送邮件的两人都有公钥和私钥。
公钥,就是给大家用的,你可以通过电子邮件发布,可以通过网站让别人下载,公钥其实是用来加密/验章用的。私钥,就是自己的,必须非常小心保存,最好加上 密码,私钥是用来解密/签章,首先就Key的所有权来说,私钥只有个人拥有。公钥与私钥的作用是:用公钥加密的内容只能用私钥解密,用私钥加密的内容只能 用公钥解密。
比如说,我要给你发送一个加密的邮件。首先,我必须拥有你的公钥,你也必须拥有我的公钥。
首先,我用你的公钥给这个邮件加密,这样就保证这个邮件不被别人看到,而且保证这个邮件在传送过程中没有被修改。你收到邮件后,用你的私钥就可以解密,就 能看到内容。
其次我用我的私钥给这个邮件加密,发送到你手里后,你可以用我的公钥解密。因为私钥只有我手里有,这样就保证了这个邮件是我发送的。



非对称密钥密码的主要应用就是公钥加密和公钥认证,而公钥加密的过程和公钥认证的过程是不一样的,下面我就详细讲解一下两者的区别。



基于公开密钥的加密过程

比如有两个用户Alice和Bob,Alice想把一段明文通过双钥加密的技术发送给Bob,Bob有一对公钥和私钥,那么加密解密的过程如下:

Bob将他的公开密钥传送给Alice。
Alice用Bob的公开密钥加密她的消息,然后传送给Bob。
Bob用他的私人密钥解密Alice的消息。
 Alice使用Bob的公钥进行加密,Bob用自己的私钥进行解密。



基于公开密钥的认证过程

  身份认证和加密就不同了,主要用户鉴别用户的真伪。这里我们只要能够鉴别一个用户的私钥是正确的,就可以鉴别这个用户的真伪。

  还是Alice和Bob这两个用户,Alice想让Bob知道自己是真实的Alice,而不是假冒的,因此Alice只要使用公钥密码学对文件 签名发送给Bob,Bob使用Alice的公钥对文件进行解密,如果可以解密成功,则证明Alice的私钥是正确的,因而就完成了对Alice的身份鉴 别。整个身份认证的过程如下:

Alice用她的私人密钥对文件加密,从而对文件签名。
Alice将签名的文件传送给Bob。
Bob用Alice的公钥解密文件,从而验证签名。
 Alice使用自己的私钥加密,Bob用Alice的公钥进行解密。



根证书

根证书是CA认证中心给自己颁发的证书,是信任链的起始点。安装根证书意味着对这个CA认证中心的信任。



总结



根据非对称密码学的原理,每个证书持有人都有一对公钥和私钥,这两把密钥可以互为加解密。公钥是公开的,不需要保密,而私钥是由证书持人自己持有,并且必 须妥善保管和注意保密。

数字证书则是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机 构的公章)后形成的一个数字文件。CA完成签发证书后,会将证书发布在CA的证书库(目录服务器)中,任何人都可以查询和下载,因此数字证书和公钥一样是 公开的。  

可以这样说,数字证书就是经过CA认证过的公钥,而私钥一般情况都是由证书持有者在自己本地生成的,由证书持有者自己负责保管。具体使用时,签名操作是发 送方用私钥进行签名,接受方用发送方证书来验证签名;加密操作则是用接受方的证书进行加密,接受方用自己的私钥进行解密。
/* Copyright© 2024 TP-Link Systems Inc. * file brief SSL APIs for mbedtls details author Wang Shiqin version 1.0.0 date 16Sep19 warning history \arg */ #if defined(INCLUDE_SSL) && defined(INCLUDE_SSL_MBEDTLS) //#define SSL_DEBUG_TIME #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/time.h> #include “ssl_backend.h” #include “ssl_mbedtls.h” #include <mbedtls/debug.h> #ifdef INCLUDE_IMDA static int g_ciphersuite[7] = { 0x2F, /* TLS_RSA_WITH_AES_128_CBC_SHA / 0x35, / TLS_RSA_WITH_AES_256_CBC_SHA / 0xC02F, / TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 / 0xC014, / TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA / 0xC013, / TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA / 0, 0 }; #elif defined(INCLUDE_CIPHER_LIST) static int g_ciphersuite[5] = { 0xC030, / TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 / 0xC02B, / TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 / 0xC0AD, / TLS_ECDHE_ECDSA_WITH_AES_256_CCM / 0xC0AC, / TLS_ECDHE_ECDSA_WITH_AES_128_CCM / 0 }; #else static int g_ciphersuite[7] = { 0x2F, / TLS_RSA_WITH_AES_128_CBC_SHA / 0x35, / TLS_RSA_WITH_AES_256_CBC_SHA / 0x0A, / TLS_RSA_WITH_3DES_EDE_CBC_SHA / 0xC02F, / TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 / 0xC014, / TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA / 0xC013, / TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */ 0 }; #endif static int g_accept_timeout = 5000; /* 5s / static int g_read_timeout = 5000; / 5s / static int g_write_timeout = 5000; / 5s */ void set_debug_level(int level) { ssl_log(SSL_ERROR, “mbedtls_debug_set_threshold %d”, level); mbedtls_debug_set_threshold(level); } void tls_init_lib(void) { ssl_loglevel_init(); } void tls_free_lib(void) { } void tls_clear_error(void) { } int tls_ctx_server_new(struct tls_root_ctx *ctx) { ssl_log(SSL_DEBUG, “enter %s”, FUNCTION); if (NULL == ctx) return -1; ctx->ca_chain = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt)); if (NULL == ctx->ca_chain) goto error; ctx->crt_chain = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt)); if (NULL == ctx->crt_chain) goto error; ctx->priv_key = (mbedtls_pk_context*)malloc(sizeof(mbedtls_pk_context)); if (NULL == ctx->priv_key) goto error; mbedtls_x509_crt_init(ctx->ca_chain); mbedtls_x509_crt_init(ctx->crt_chain); mbedtls_pk_init(ctx->priv_key); ctx->endpoint = MBEDTLS_SSL_IS_SERVER; ctx->initialised = 1; return 0; error: ssl_log(SSL_ERROR, “tls_ctx_server_new failed”); if (ctx->ca_chain) free(ctx->ca_chain); if (ctx->crt_chain) free(ctx->crt_chain); if (ctx->priv_key) free(ctx->priv_key); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return -1; } int tls_ctx_client_new(struct tls_root_ctx *ctx) { ssl_log(SSL_DEBUG, “enter %s”, FUNCTION); if (NULL == ctx) return -1; ctx->ca_chain = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt)); if (NULL == ctx->ca_chain) goto error; ctx->crt_chain = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt)); if (NULL == ctx->crt_chain) goto error; ctx->priv_key = (mbedtls_pk_context*)malloc(sizeof(mbedtls_pk_context)); if (NULL == ctx->priv_key) goto error; mbedtls_x509_crt_init(ctx->ca_chain); mbedtls_x509_crt_init(ctx->crt_chain); mbedtls_pk_init(ctx->priv_key); ctx->verify_time = 0; ctx->verify_cn = NULL; ctx->endpoint = MBEDTLS_SSL_IS_CLIENT; ctx->initialised = 1; return 0; error: ssl_log(SSL_ERROR, “tls_ctx_client_new failed”); if (ctx->ca_chain) free(ctx->ca_chain); if (ctx->crt_chain) free(ctx->crt_chain); if (ctx->priv_key) free(ctx->priv_key); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return -1; } void tls_ctx_free(struct tls_root_ctx *ctx) { if (ctx) { mbedtls_pk_free(ctx->priv_key); if (ctx->priv_key) { free(ctx->priv_key); } mbedtls_x509_crt_free(ctx->ca_chain); if (ctx->ca_chain) { free(ctx->ca_chain); } mbedtls_x509_crt_free(ctx->crt_chain); if (ctx->crt_chain) { free(ctx->crt_chain); } ctx->verify_time = 0; ctx->verify_cn = NULL; ctx->initialised = 0; free(ctx); ctx = NULL; } } int tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) { return 0; } static int verify_callback( void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags ) { char buf[1024]; ((void) data); ssl_log(SSL_ERROR, "Verify requested for (Depth %d):", depth); mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt); ssl_log(SSL_ERROR, "%s", buf); if ((*flags) == 0) { ssl_log(SSL_ERROR, "This certificate has no flags"); } else { mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", *flags); ssl_log(SSL_ERROR, "%s\n", buf); } return 0; } int tls_ctx_verify_cloud(struct tls_root_ctx *ctx, char *cert_file, int verify_time, char *cn) { ssl_log(SSL_DEBUG, “enter %s”, FUNCTION); if (NULL == ctx || NULL == cert_file) return -1; if (NULL == ctx->crt_chain || mbedtls_x509_crt_parse_file(ctx->crt_chain, cert_file) != 0) { ssl_log(SSL_ERROR, "load cer file error"); return -1; } ctx->verify_time = verify_time; ctx->verify_cn = cn; ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int tls_ctx_verify_ca_buf(struct tls_root_ctx *ctx, const void *cert_buf, size_t len) { int ret = 0; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == cert_buf || NULL == ctx || NULL == ctx->crt_chain) return -1; ssl_log(SSL_DEBUG, "buf len: %d %d", len, strlen(cert_buf)); if ((ret = mbedtls_x509_crt_parse(ctx->crt_chain, cert_buf, len)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509_crt_parse fail. ret=%d", ret); return -1; } ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int tls_ctx_verify_init(struct tls_root_ctx *ctx, int depth, char *ca_path, void *ud) { ssl_log(SSL_DEBUG, “enter %s”, FUNCTION); if (NULL == ctx || NULL == ca_path) return -1; if (NULL == ctx->ca_chain || mbedtls_x509_crt_parse_file(ctx->ca_chain, ca_path) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509_crt_parse_file fail."); return -1; } ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int tls_ctx_check_key(struct tls_root_ctx *ctx, char *cert_file, char *key_file, void *passwd) { int status; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ctx || NULL == cert_file || NULL == key_file || NULL == ctx->crt_chain) return -1; if ((status = mbedtls_x509_crt_parse_file(ctx->crt_chain, cert_file)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509_crt_parse_file fail. ret=%d", status); return -1; } if (NULL == ctx->priv_key) return -1; status = mbedtls_pk_parse_keyfile(ctx->priv_key, key_file, NULL); if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status) { status = mbedtls_pk_parse_keyfile(ctx->priv_key, key_file, (const char*)passwd); } if (0 != status) { ssl_log(SSL_ERROR, "Cannot load private key file %s", key_file); return -1; } if (mbedtls_pk_check_pair(&ctx->crt_chain->pk, ctx->priv_key) != 0) { ssl_log(SSL_ERROR, "Private key does not match the certificate"); return -1; } ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } static void tp_debug(void *ctx, int level, const char *file, int line, const char *str) { const char *p, *basename; /* Extract basename from file */ for (p = basename = file; *p != '\0'; p++) if (*p == '/' || *p == '\\') basename = p + 1; fprintf((FILE *)ctx, "%s:%04d: |%d| %s", basename, line, level, str); fflush((FILE *)ctx); } static void ssl_init_debug_level(void) { int level = 1; FILE *f = NULL; char line[5] = {0}; f = fopen("/var/mbedtls/dbg", "r"); if (f == NULL || fgets(line, sizeof(line), f) == NULL || sscanf(line, "%d", &level) != 1) { level = 0; } if (f != NULL) fclose(f); set_debug_level(level); } static void ssl_init_timeout(void) { int accept_timeout = 5000; int read_timeout = 5000; int write_timeout = 5000; FILE *f = NULL; char line[32] = {0}; f = fopen("/var/mbedtls/timeout", "r"); if (f == NULL || fgets(line, sizeof(line), f) == NULL || sscanf(line, "%d %d %d", &accept_timeout, &read_timeout, &write_timeout) != 3) { if (f != NULL) fclose(f); return; } if (f != NULL) fclose(f); g_accept_timeout = accept_timeout; g_read_timeout = read_timeout; g_write_timeout = write_timeout; ssl_log(SSL_ERROR, "g_accept_timeout: %d, g_read_timeout: %d, g_write_timeout: %d\n", g_accept_timeout, g_read_timeout, g_write_timeout); } static void ssl_init_hs_dbg_level(void) { int level = 1; FILE *f = NULL; char line[5] = {0}; f = fopen("/var/mbedtls/hs", "r"); if (f == NULL || fgets(line, sizeof(line), f) == NULL || sscanf(line, "%d", &level) != 1) { level = 0; } if (f != NULL) fclose(f); set_debug_level(level); } static void ssl_init_stream(struct tp_stream *stream) { stream->buf[0] = ‘\0’; stream->cur = stream->buf; stream->end = stream->buf; } static inline void buf_free_entry(struct buf_entry *entry) { if (NULL != entry) { //printf(“-free %p\n”, entry); free(entry->data); free(entry); } } static void buf_free_entries(struct write_buf *buf) { while (buf->first_block) { struct buf_entry *cur_block = buf->first_block; buf->first_block = cur_block->next_block; buf_free_entry(cur_block); } buf->last_block = NULL; buf->cur_block = NULL; buf->data_len = 0; } static struct buf_entry* buf_create_entry(void) { struct buf_entry *entry = (struct buf_entry *)malloc(sizeof(struct buf_entry)); if (NULL == entry) return NULL; entry->data = (char *)malloc(TP_BUF_ENTRY_LEN); if (NULL == entry->data) { free(entry); return NULL; } entry->used_len = 0; entry->free_len = TP_BUF_ENTRY_LEN; entry->next_block = NULL; //printf("+create %p\n", entry); return entry; } static int buf_write_data_1block(struct write_buf *buf, char *in, size_t len) { struct buf_entry *cur_block = buf->cur_block; if (len > TP_BUF_ENTRY_LEN) { return -1; } if (NULL == cur_block) { cur_block = buf_create_entry(); if (NULL == cur_block) return -1; cur_block->next_block = NULL; if (NULL == buf->first_block) { buf->first_block = cur_block; } if (NULL != buf->last_block) { buf->last_block->next_block = cur_block; } buf->last_block = buf->cur_block = cur_block; } else { if (cur_block->free_len < len) { cur_block= cur_block->next_block; if (NULL == cur_block) { cur_block = buf_create_entry(); if (NULL == cur_block) return -1; cur_block->next_block = NULL; buf->last_block->next_block = cur_block; buf->last_block = buf->cur_block = cur_block; } else { if (cur_block->free_len != TP_BUF_ENTRY_LEN || cur_block->used_len > 0) { ssl_log(SSL_ERROR, "free_len: %d, used_len: %d\n", cur_block->free_len, cur_block->used_len); return -1; } buf->cur_block = cur_block; } } } //printf("cur_block: %p\n", cur_block); if (cur_block->free_len < len) { ssl_log(SSL_ERROR, "free_len: %d, len: %d\n", cur_block->free_len, len); return -1; } if (cur_block->used_len + len > TP_BUF_ENTRY_LEN) { ssl_log(SSL_ERROR, "used_len: %d, len: %d\n", cur_block->used_len, len); return -1; } memcpy(cur_block->data + cur_block->used_len, in, len); cur_block->used_len += len; cur_block->free_len -= len; buf->data_len += len; return len; } static int buf_write_data(struct write_buf *buf, char *in, size_t len) { int ret; size_t write_len = 0; size_t left_len = len; while (left_len > 0) { ret = (left_len < TP_BUF_ENTRY_LEN) ? left_len : TP_BUF_ENTRY_LEN; ret = buf_write_data_1block(buf, in + write_len, ret); if (ret <= 0) return -1; write_len += ret; left_len -= ret; } return write_len; } static int buf_read_data(struct write_buf *buf, char *out, size_t len) { size_t read_len = 0; struct buf_entry *cur_block = buf->first_block; while (cur_block) { if (cur_block->used_len == 0) return read_len; if (len - read_len < cur_block->used_len) return read_len; memcpy(out + read_len, cur_block->data, cur_block->used_len); read_len += cur_block->used_len; cur_block = cur_block->next_block; } return read_len; } static size_t buf_get_data_len(struct write_buf *buf) { return buf->data_len; } static void buf_reinit(struct write_buf *buf) { if (NULL == buf) return; struct buf_entry *cur_block = buf->first_block; while (cur_block) { cur_block->free_len = TP_BUF_ENTRY_LEN; cur_block->used_len = 0; cur_block = cur_block->next_block; } buf->cur_block = buf->first_block; buf->data_len = 0; } #if 0 static void buf_info(struct write_buf *buf) { struct buf_entry *cur_block; printf("%d (%p %p %p)\n", buf->data_len, buf->first_block, buf->cur_block, buf->last_block); cur_block = buf->first_block; while (cur_block) { printf("%p: %d %d\n", cur_block, cur_block->free_len, cur_block->used_len); cur_block = cur_block->next_block; } } #endif static long long get_time_ms() { struct timeval tv; if (0 != gettimeofday(&tv, NULL)) { return 0; } return ((long long)tv.tv_sec * 1000 + (long long)tv.tv_usec / 1000); } #ifdef INCLUDE_HTTP_SSL_MIN_TLS1_2 int ssl_init(struct tp_ssl *ssl, const struct tls_root_ctx *ssl_ctx, int is_server, int is_cwmp) #else int ssl_init(struct tp_ssl *ssl, const struct tls_root_ctx ssl_ctx, int is_server) #endif / INCLUDE_HTTP_SSL_MIN_TLS1_2 */ { int ret = -1; const char *pers = “tp_ssl”; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl_ctx) return -1; memset(ssl, 0, sizeof(struct tp_ssl)); ssl_init_debug_level(); ssl_init_timeout(); mbedtls_ctr_drbg_init(&ssl->ctr_drbg); mbedtls_entropy_init(&ssl->entropy); if ((ret = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg, mbedtls_entropy_func, &ssl->entropy, (const unsigned char *) pers, strlen(pers))) != 0) { ssl_log(SSL_ERROR, "mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } /* Initialise SSL config */ mbedtls_ssl_config_init(&ssl->ssl_config); if ((ret = mbedtls_ssl_config_defaults(&ssl->ssl_config, ssl_ctx->endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_config_defaults returned %d\n", ret ); goto exit; } mbedtls_ssl_conf_rng(&ssl->ssl_config, mbedtls_ctr_drbg_random, &ssl->ctr_drbg); mbedtls_ssl_conf_dbg(&ssl->ssl_config, tp_debug, stdout); mbedtls_ssl_cache_init(&ssl->cache); mbedtls_ssl_conf_session_cache(&ssl->ssl_config, &ssl->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set); mbedtls_ssl_conf_ciphersuites(&ssl->ssl_config, g_ciphersuite); mbedtls_ssl_conf_ca_chain(&ssl->ssl_config, ssl_ctx->ca_chain, NULL); if ((ret = mbedtls_ssl_conf_own_cert(&ssl->ssl_config, ssl_ctx->crt_chain, ssl_ctx->priv_key)) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_conf_own_cert returned %d\n", ret ); goto exit; } if (!is_server) { mbedtls_ssl_conf_verify(&ssl->ssl_config, verify_callback, NULL); mbedtls_ssl_conf_authmode(&ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL); } #ifdef INCLUDE_IMDA mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); #else #ifdef INCLUDE_HTTP_SSL_MIN_TLS1_2 if (1 != is_cwmp) { mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); } else #endif /* INCLUDE_HTTP_SSL_MIN_TLS1_2 / { mbedtls_ssl_conf_min_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); } #endif / INCLUDE_IMDA */ mbedtls_ssl_conf_max_version(&ssl->ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); /* Initialise SSL context */ ssl->ctx = (mbedtls_ssl_context*)malloc(sizeof(mbedtls_ssl_context)); if (NULL == ssl->ctx) goto exit; mbedtls_ssl_init(ssl->ctx); if (mbedtls_ssl_setup(ssl->ctx, &ssl->ssl_config) != 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_setup failed"); return -1; } if (is_server) { ssl->endpoint = MBEDTLS_SSL_IS_SERVER; } else { if (ssl_ctx->verify_cn) { mbedtls_ssl_set_hostname(ssl->ctx, ssl_ctx->verify_cn); ssl->verify_cn = 1; } if (ssl_ctx->verify_time) { ssl->verify_time = 1; } ssl->endpoint = MBEDTLS_SSL_IS_CLIENT; } ssl_init_stream(&ssl->stream); ret = 0; exit: ssl_log(SSL_DEBUG, "leave %s ret=%d", __FUNCTION__, ret); return ret; } void ssl_free(struct tp_ssl *ssl) { if (ssl) { if (ssl->ctx) { mbedtls_ssl_free(ssl->ctx); free(ssl->ctx); } mbedtls_ssl_config_free(&ssl->ssl_config); mbedtls_ctr_drbg_free(&ssl->ctr_drbg); mbedtls_entropy_free(&ssl->entropy); mbedtls_ssl_cache_free(&ssl->cache); if (ssl->endpoint == MBEDTLS_SSL_IS_SERVER) { mbedtls_net_free(&ssl->client_fd); } if (ssl->endpoint == MBEDTLS_SSL_IS_CLIENT) { mbedtls_net_free(&ssl->server_fd); } buf_free_entries(&ssl->out); ssl->verify_cn = 0; ssl->verify_time = 0; free(ssl); ssl = NULL; } } void ssl_shutdown(struct tp_ssl *ssl) { int ret; if (NULL == ssl || NULL == ssl->ctx) return; do { ssl_log(SSL_DEBUG, "=========================================================== ->\n"); ret = mbedtls_ssl_close_notify(ssl->ctx); ssl_log(SSL_DEBUG, "=========================================================== <-\n"); } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE); } int ssl_reset(struct tp_ssl *ssl, const struct tls_root_ctx *ssl_ctx) { if (NULL == ssl || NULL == ssl->ctx) return -1; //mbedtls_ssl_session_reset(ssl->ctx); if (ssl->endpoint == MBEDTLS_SSL_IS_SERVER) { ssl_log(SSL_DEBUG, "close %d", ssl->client_fd.fd); mbedtls_net_free(&ssl->client_fd); } if (ssl->endpoint == MBEDTLS_SSL_IS_CLIENT) { ssl_log(SSL_DEBUG, "close %d", ssl->server_fd.fd); mbedtls_net_free(&ssl->server_fd); } ssl_init_stream(&ssl->stream); //buf_reinit(&ssl->out); buf_free_entries(&ssl->out); /* free the out buffer, not just reinit */ return 0; } #if defined (INCLUDE_DYNDNS_HTTPS) || defined(INCLUDE_NOIPDNS_HTTPS) int ssl_connect(struct tp_ssl *ssl, int sockfd, int timeout, int needTrustedCA) #else int ssl_connect(struct tp_ssl ssl, int sockfd, int timeout) #endif / INCLUDE_DYNDNS_HTTPS || INCLUDE_NOIPDNS_HTTPS */ { int ret; unsigned int flags; long long time_remain = (long long)timeout; long long time_begin = 0; long long time_spend = 0; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl->ctx) { return -1; } mbedtls_net_init(&ssl->server_fd); ssl_log(SSL_DEBUG, "mbedtls_ssl_set_bio"); ssl->server_fd.fd = sockfd; //mbedtls_ssl_set_bio(ssl->ctx, &ssl->server_fd, mbedtls_net_send, mbedtls_net_recv, NULL); mbedtls_ssl_conf_read_timeout(&ssl->ssl_config, timeout); mbedtls_ssl_set_bio(ssl->ctx, &ssl->server_fd, mbedtls_net_send, NULL, mbedtls_net_recv_timeout); ssl_log(SSL_DEBUG, "mbedtls_ssl_handshake"); ssl_init_hs_dbg_level(); while((ret = mbedtls_ssl_handshake(ssl->ctx)) != 0) { if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ssl_log(SSL_ERROR, "mbedtls_ssl_handshake returned -0x%x", -ret); return -1; } time_begin = get_time_ms(); time_remain -= time_spend; ssl_log(SSL_ERROR, "==> time_remain: %llu ms time_spend: %llu ms", time_remain, time_spend); if (time_remain < 0) { ssl_log(SSL_ERROR, "==> mbedtls_ssl_handshake timeout %d ms", timeout); return -1; } fd_set fds; FD_ZERO(&fds); FD_SET(sockfd, &fds); struct timeval tv; tv.tv_sec = (long)(time_remain / 1000); tv.tv_usec = (long)(time_remain % 1000) * 1000; switch (ret) { case MBEDTLS_ERR_SSL_WANT_READ: select(sockfd +1, &fds, NULL, NULL, &tv); break; case MBEDTLS_ERR_SSL_WANT_WRITE: select(sockfd +1, NULL, &fds, NULL, &tv); break; default: ssl_log(SSL_ERROR, "mbedtls_ssl_handshake returned -0x%x", -ret); return -1; } time_spend = get_time_ms() - time_begin; } ssl_init_debug_level(); ssl_log(SSL_DEBUG, "mbedtls_ssl_get_verify_result"); if ((flags = mbedtls_ssl_get_verify_result(ssl->ctx)) != 0) { char vrfy_buf[512]; ssl_log(SSL_ERROR, "mbedtls_ssl_get_verify_result failed"); mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags); ssl_log(SSL_ERROR, "%s", vrfy_buf); ssl_log(SSL_ERROR, "verify flags: 0x%x", flags); if ((ssl->verify_time && (MBEDTLS_X509_BADCERT_EXPIRED & flags)) || (ssl->verify_cn && (MBEDTLS_X509_BADCERT_CN_MISMATCH & flags)) || (MBEDTLS_X509_BADCERT_REVOKED & flags) || (MBEDTLS_X509_BADCERT_BAD_MD & flags)) { return -1; } #if defined (INCLUDE_DYNDNS_HTTPS) || defined(INCLUDE_NOIPDNS_HTTPS) if (needTrustedCA && (MBEDTLS_X509_BADCERT_NOT_TRUSTED & flags)) { return -1; } #endif /* INCLUDE_DYNDNS_HTTPS || INCLUDE_NOIPDNS_HTTPS */ } ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int ssl_accept(struct tp_ssl *ssl, int sockfd) { int ret; long long time_remain = (long long)g_accept_timeout; long long time_begin = 0; long long time_spend = 0; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl->ctx) { return -1; } mbedtls_net_init(&ssl->client_fd); mbedtls_ssl_session_reset(ssl->ctx); ssl->client_fd.fd = sockfd; mbedtls_ssl_conf_read_timeout(&ssl->ssl_config, time_remain); mbedtls_ssl_set_bio(ssl->ctx, &ssl->client_fd, mbedtls_net_send, NULL, mbedtls_net_recv_timeout); #ifdef SSL_DEBUG_TIME struct timeval time_s; struct timeval time_e; int time = 0; gettimeofday(&time_s, NULL); #endif ssl_init_hs_dbg_level(); while((ret = mbedtls_ssl_handshake(ssl->ctx)) != 0) { if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ssl_log(SSL_ERROR, “mbedtls_ssl_handshake returned -0x%x”, -ret); return -1; } time_begin = get_time_ms(); time_remain -= time_spend; ssl_log(SSL_ERROR, "==> time_remain: %llu ms time_spend: %llu ms", time_remain, time_spend); if (time_remain < 0) { ssl_log(SSL_ERROR, "==> mbedtls_ssl_handshake timeout %d ms", g_accept_timeout); return -1; } fd_set fds; FD_ZERO(&fds); FD_SET(sockfd, &fds); struct timeval tv; tv.tv_sec = (long)(time_remain / 1000); tv.tv_usec = (long)(time_remain % 1000) * 1000; switch (ret) { case MBEDTLS_ERR_SSL_WANT_READ: select(sockfd +1, &fds, NULL, NULL, &tv); break; case MBEDTLS_ERR_SSL_WANT_WRITE: select(sockfd +1, NULL, &fds, NULL, &tv); break; default: ssl_log(SSL_ERROR, "mbedtls_ssl_handshake returned -0x%x", -ret); return -1; } time_spend = get_time_ms() - time_begin; } ssl_init_debug_level(); #ifdef SSL_DEBUG_TIME gettimeofday(&time_e, NULL); time = ((time_e.tv_sec - time_s.tv_sec) * 1000000 + time_e.tv_usec - time_s.tv_usec); printf(“<<<<< ssl handshake: %d us %d >>>>>\n”, time, sockfd); #endif ssl_log(SSL_DEBUG, "[ Protocol is %s ]\n[ Ciphersuite is %s ]", mbedtls_ssl_get_version(ssl->ctx), mbedtls_ssl_get_ciphersuite(ssl->ctx)); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int ssl_read(struct tp_ssl *ssl, void *buf, int len) { int ret; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl->ctx || NULL == buf) { return -1; } long long time_out = (long long)g_read_timeout; long long time_begin = get_time_ms(); do { ret = mbedtls_ssl_read(ssl->ctx, buf, len); if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { if (get_time_ms() - time_begin > time_out) { ssl_log(SSL_ERROR, "mbedtls_ssl_read timeout: %llu ms", time_out); return -1; } else { usleep(20 * 1000); continue; } } if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { ssl_log(SSL_ERROR, "MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY"); break; } if(ret == MBEDTLS_ERR_NET_CONN_RESET) { ssl_log(SSL_ERROR, "MBEDTLS_ERR_NET_CONN_RESET"); break; } if(ret <= 0) { ssl_log(SSL_ERROR, "mbedtls_ssl_read returned %d", ret); break; } if (ret > 0) { ssl_log(SSL_DEBUG, "read buf: len=%d [\n%s\n] ", len, (char*)buf); break; } }while (1); ssl_log(SSL_DEBUG, "leave %s ret=%d", __FUNCTION__, ret); //printf("++++++ ssl_read %d %d ++++++\n", len, ret); return ret; } int ssl_write(struct tp_ssl *ssl, void *buf, int len) { int ret = 0; int written = 0; int frags = 0; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == ssl || NULL == ssl->ctx || NULL == buf) { return -1; } for (written = 0, frags = 0; written < len; written += ret, frags++) { long long time_out = (long long)g_write_timeout; long long time_begin = get_time_ms(); while ((ret = mbedtls_ssl_write(ssl->ctx, buf + written, len - written)) <= 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ssl_log(SSL_ERROR, "mbedtls_ssl_write returned %d", ret); return ret; } if (get_time_ms() - time_begin > time_out) { ssl_log(SSL_ERROR, "mbedtls_ssl_write timeout: %llu ms", time_out); return -1; } else { usleep(20 * 1000); continue; } } } ssl_log(SSL_DEBUG, "leave %s ret=%d", __FUNCTION__, ret); //printf("frags=%d\n", frags); return written; } int bio_printf(struct tp_ssl *ssl, const char *format, …) { va_list args; int ret; char buf[1024] = {0}; va_start(args, format); ret = vsnprintf(buf, 1024, format, args); va_end(args); //printf("++++++ bio_printf %d ++++++\n", ret); //printf("++ %s", buf); return bio_write(ssl, buf, ret); } int bio_write(struct tp_ssl *ssl, void *buf, int len) { //printf(“++++++ bio_write %d ++++++\n”, len); if (NULL == ssl || NULL == buf) return -1; return buf_write_data(&ssl->out, buf, len); } int bio_flush(struct tp_ssl *ssl) { int ret; int len; char *buf; if (NULL == ssl) return -1; len = buf_get_data_len(&ssl->out); if (0 == len) return 0; buf = (char *)malloc(len); if (NULL == buf) return -1; ret = buf_read_data(&ssl->out, buf, len); if (ret != len) { free(buf); return -1; } //buf_info(&ssl->out); ret = ssl_write(ssl, buf, len); if (ret != len) { ssl_log(SSL_ERROR, "ssl_write len=%d ret=%d\n", len, ret); } free(buf); buf_reinit(&ssl->out); //buf_info(&ssl->out); ssl_log(SSL_DEBUG, "++++++ bio_flush %d ++++++\n", len); return ret; } int bio_read(struct tp_ssl *ssl, void *buf, int len) { int ret = 0; if (NULL == ssl || NULL == buf) return -1; struct tp_stream *stream = &ssl->stream; if ((stream->end - stream->cur) == 0) return 0; if (len <= (stream->end - stream->cur)) { memcpy(buf, stream->cur, len); ret = len; } else { memcpy(buf, stream->cur, (stream->end - stream->cur)); ret = (stream->end - stream->cur); } stream->cur += ret; //printf("++++++ bio_read %d ++++++\n", len); return ret; } int bio_gets(struct tp_ssl *ssl, void *buf, int len) { int ret = 0; char *index = (char *)buf; if (NULL == ssl || NULL == buf) return -1; struct tp_stream *stream = &ssl->stream; //printf("++++++ bio_gets %d ++++++\n", len); while(--len) { if (stream->cur < stream->end) { if ((*index = *stream->cur++) == '\n') { if (index > (char *)buf && *(index - 1) == '\r') { index++; break; } } index++; } else { len++; stream->cur = stream->buf; ret = ssl_read(ssl, stream->buf, TP_STREAM_LEN); if (ret == 0) { ssl_log(SSL_ERROR, "ssl_read returned %d", ret); return 0; } if (ret < 0) { ssl_log(SSL_ERROR, "ssl_read returned %d", ret); return -1; } stream->buf[ret] = '\0'; stream->end = stream->cur + ret; continue; } } if (index > (char *)buf) { *index = '\0'; //printf("-- %s", (char *)buf); ssl_log(SSL_DEBUG, "bio_gets: %s", (char *)buf); return (index - (char *)buf); } ssl_log(SSL_DEBUG, "bio_gets: \n%s", (char *)buf); return ret; } int gen_rand_bytes(unsigned char *buf, size_t len) { int ret; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_entropy_init( &entropy ); if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)"RANDOM_GEN", 10)) != 0) { ssl_log(SSL_ERROR, "failed in mbedtls_ctr_drbg_seed: %d", ret); goto exit; } mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF); if ((ret = mbedtls_ctr_drbg_random(&ctr_drbg, buf, len)) != 0) { ssl_log(SSL_ERROR, "failed in mbedtls_ctr_drbg_random: %d", ret); goto exit; } ret = 0; exit: mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); return ret; } unsigned long long gen_rand_num(int predicable) { int i; unsigned char buf[8]; unsigned long long rand = 0; if (gen_rand_bytes(buf, 8) != 0) { return 0; } for (i = 0; i < 8; i++) { rand = (rand << 8) | buf[i]; } ssl_log(SSL_DEBUG, "gen rand: %llx\n", rand); return rand; } #if 0 #define DEV_RANDOM_THRESHOLD 32 static int dev_random_entropy_poll( void *data, unsigned char *output, size_t len, size_t *olen ) { FILE *file; size_t ret, left = len; unsigned char *p = output; ((void) data); ssl_log(SSL_DEBUG, "enter %s\n", __FUNCTION__); *olen = 0; file = fopen( "/dev/random", "rb" ); if (file == NULL) return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); while (left > 0) { /* /dev/random can return much less than requested. If so, try again */ ret = fread(p, 1, left, file); if (ret == 0 && ferror( file)) { fclose (file); return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); } p += ret; left -= ret; sleep(1); printf("ret=%d left=%d\n", ret, left); } fclose(file); *olen = len; ssl_log(SSL_DEBUG, "leave %s\n", __FUNCTION__); return 0; } #endif int gen_pkey(pkey_t **pkey, unsigned int bits) { int ret = -1; mbedtls_pk_context *key; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; const char *pers = "gen_key"; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == pkey) return -1; key = (mbedtls_pk_context*)malloc(sizeof(mbedtls_pk_context)); if (NULL == key) return -1; mbedtls_pk_init(key); mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); #if 0 if ((ret = mbedtls_entropy_add_source(&entropy, dev_random_entropy_poll, NULL, DEV_RANDOM_THRESHOLD, MBEDTLS_ENTROPY_SOURCE_STRONG)) != 0) { ssl_log(SSL_ERROR, “mbedtls_entropy_add_source returned -0x%04x”, -ret); goto exit; } ssl_log(SSL_DEBUG, “mbedtls_entropy_add_source done”); #endif if ((ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers))) != 0) { ssl_log(SSL_ERROR, "mbedtls_ctr_drbg_seed returned -0x%04x", -ret ); goto exit; } ssl_log(SSL_DEBUG, "mbedtls_ctr_drbg_seed done"); if ((ret = mbedtls_pk_setup(key, mbedtls_pk_info_from_type((mbedtls_pk_type_t)MBEDTLS_PK_RSA))) != 0) { ssl_log(SSL_ERROR, "mbedtls_pk_setup returned -0x%04x", -ret ); goto exit; } ssl_log(SSL_DEBUG, "mbedtls_pk_setup done"); ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(*key), mbedtls_ctr_drbg_random, &ctr_drbg, bits, 65537); if(ret != 0) { ssl_log(SSL_ERROR, "mbedtls_rsa_gen_key returned -0x%04x", -ret ); goto exit; } ssl_log(SSL_DEBUG, "mbedtls_rsa_gen_key done"); ret = 0; *pkey = key; exit: if (ret != 0) mbedtls_pk_free(key); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return ret; } static int print_pkey(pkey_t *key) { int ret = -1; mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); mbedtls_mpi_init(&N); mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&D); mbedtls_mpi_init(&E); mbedtls_mpi_init(&DP); mbedtls_mpi_init(&DQ); mbedtls_mpi_init(&QP); if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*key); if ((ret = mbedtls_rsa_export(rsa, &N, &P, &Q, &D, &E)) != 0 || (ret = mbedtls_rsa_export_crt(rsa, &DP, &DQ, &QP)) != 0) { ssl_log(SSL_ERROR, "could not export RSA parameters"); goto exit; } mbedtls_mpi_write_file("N: ", &N, 16, NULL); mbedtls_mpi_write_file("E: ", &E, 16, NULL); mbedtls_mpi_write_file("D: ", &D, 16, NULL); mbedtls_mpi_write_file("P: ", &P, 16, NULL); mbedtls_mpi_write_file("Q: ", &Q, 16, NULL); mbedtls_mpi_write_file("DP: ", &DP, 16, NULL); mbedtls_mpi_write_file("DQ: ", &DQ, 16, NULL); mbedtls_mpi_write_file("QP: ", &QP, 16, NULL); } else { ssl_log(SSL_ERROR, "error pk type."); goto exit; } ret = 0; exit: mbedtls_mpi_free(&N); mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&D); mbedtls_mpi_free(&E); mbedtls_mpi_free(&DP); mbedtls_mpi_free(&DQ); mbedtls_mpi_free(&QP); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return ret; } int write_private_key(pkey_t *key, const char *output_file) { int ret; FILE *f = NULL; unsigned char *output_buf = NULL; size_t len = 0; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == key || NULL == output_file) return -1; print_pkey(key); output_buf = (unsigned char *)malloc(16000); if (NULL == output_buf) return -1; memset(output_buf, 0, 16000); if((ret = mbedtls_pk_write_key_pem(key, output_buf, 16000)) != 0) { ssl_log(SSL_ERROR, "mbedtls_pk_write_key_pem returned -0x%04x", -ret ); goto exit; } len = strlen((char *)output_buf); if((f = fopen(output_file, "wb")) == NULL) { ssl_log(SSL_ERROR, "open %s fail.", output_file); goto exit; } if(fwrite(output_buf, 1, len, f) != len) { ssl_log(SSL_ERROR, "fwrite fail."); goto exit; } ret = 0; exit: if (f) fclose(f); if (output_buf) free(output_buf); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return ret; } void free_pkey(pkey_t *key) { if (key) { mbedtls_pk_free(key); free(key); key = NULL; } } static int gen_cert(unsigned char *buf, size_t size, int self_sign, int is_ca, x509_cert_t *issuer_cert, pkey_t *issuer_key, pkey_t *subject_key, char *subject_name, char *issuer_name, const char *not_before, const char *not_after, int pathlen, const char *san) { int ret = 0; mbedtls_x509write_cert crt; mbedtls_mpi serial; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; char ca_subject_name[256]; pkey_t *set_subject_key, *set_issuer_key; char *set_subject_name, *set_issuer_name; int max_pathlen = pathlen; const char *pers = "tp-link app"; unsigned long long serial_num; char serial_str[20] = {0}; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == buf || NULL == issuer_key) return -1; set_subject_key = subject_key; set_issuer_key = issuer_key; set_subject_name = subject_name; set_issuer_name = issuer_name; mbedtls_x509write_crt_init(&crt); mbedtls_mpi_init(&serial); mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers))) != 0) { ssl_log(SSL_ERROR, "mbedtls_ctr_drbg_seed fail."); goto exit; } serial_num = gen_rand_num(0); snprintf(serial_str, 20, "%llx", serial_num); if ((ret = mbedtls_mpi_read_string(&serial, 16, serial_str)) != 0) { ssl_log(SSL_ERROR, "mbedtls_mpi_read_string fail."); goto exit; } if(!self_sign) { if (NULL == issuer_cert) { ssl_log(SSL_ERROR, "issuer_cert should not be NULL."); goto exit; } ret = mbedtls_x509_dn_gets(ca_subject_name, sizeof(ca_subject_name), &issuer_cert->subject); if( ret < 0 ) { ssl_log(SSL_ERROR, "mbedtls_x509_dn_gets fail."); goto exit; } set_issuer_name = ca_subject_name; if (NULL == subject_key) { ssl_log(SSL_ERROR, "subject_key and issuer_key should not be NULL."); goto exit; } } if (issuer_cert) { if (mbedtls_pk_check_pair(&issuer_cert->pk, issuer_key) != 0) { ssl_log(SSL_ERROR, "issuer_key does not match issuer certificate."); goto exit; } } if (self_sign) { set_subject_name = set_issuer_name; set_subject_key = set_issuer_key; } mbedtls_x509write_crt_set_subject_key(&crt, set_subject_key); mbedtls_x509write_crt_set_issuer_key(&crt, set_issuer_key); if ((ret = mbedtls_x509write_crt_set_subject_name(&crt, set_subject_name)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_subject_name " "returned -0x%04x", -ret); goto exit; } if ((ret = mbedtls_x509write_crt_set_issuer_name(&crt, set_issuer_name)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_issuer_name " "returned -0x%04x", -ret); goto exit; } mbedtls_x509write_crt_set_version(&crt, 2); mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256); if ((ret = mbedtls_x509write_crt_set_serial(&crt, &serial)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_serial " "returned -0x%04x", -ret); goto exit; } if ((ret = mbedtls_x509write_crt_set_validity(&crt, not_before, not_after)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_validity " "returned -0x%04x", -ret); goto exit; } if (is_ca) { max_pathlen = 0; } if ((ret = mbedtls_x509write_crt_set_basic_constraints(&crt, is_ca, max_pathlen)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_basic_constraints " "returned -0x%04x", -ret); goto exit; } if ((ret = mbedtls_x509write_crt_set_subject_key_identifier(&crt)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_subject_key_identifier " "returned -0x%04x", -ret); goto exit; } if ((ret = mbedtls_x509write_crt_set_authority_key_identifier(&crt)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_authority_key_identifier " "returned -0x%04x", -ret); goto exit; } if (!is_ca && san) { // set san ssl_log(SSL_DEBUG, "san: %s", san); ret = mbedtls_x509write_crt_set_subject_alt_name(&crt, (const unsigned char *)san, strlen(san)); //char *san_tmp = "DNS:tplinkmodem.net,DNS:192.168.1.1,IP:192.168.1.1"; //ret = mbedtls_x509write_crt_set_subject_alt_name(&crt, (const unsigned char *)san_tmp, strlen(san_tmp)); if (ret != 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_set_subject_alt_name " "returned -0x%04x", -ret); goto exit; } } if ((ret = mbedtls_x509write_crt_pem(&crt, buf, size, mbedtls_ctr_drbg_random, &ctr_drbg)) < 0) { ssl_log(SSL_ERROR, "mbedtls_x509write_crt_pem " "returned -0x%04x", -ret); goto exit; } ret = 0; exit: mbedtls_x509write_crt_free(&crt); mbedtls_mpi_free(&serial); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return ret; } int gen_ca_cert_file(const char *cert_file, pkey_t *pkey, const char *org, const char *orgUnit) { int ret = -1; FILE *f = NULL; unsigned char *output_buf = NULL; char issuer_name[256] = {0}; size_t len = 0; const char *not_before = “20010101000000”; const char *not_after = “20371231235959”; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == cert_file || NULL == pkey || NULL == org || NULL == orgUnit) return -1; output_buf = (unsigned char *)malloc(4096); if (NULL == output_buf) return -1; snprintf(issuer_name, 256, "CN=%s,O=%s,OU=%s", "TP-Link SOHO Router CA", org, orgUnit); memset(output_buf, 0, 4096); if (gen_cert(output_buf, 4096, 1, 1, NULL, pkey, NULL, NULL, issuer_name, not_before, not_after, 0, NULL) != 0) { ssl_log(SSL_ERROR, "gen_cert fail."); ret = -1; goto exit; } len = strlen((char *)output_buf); f = fopen(cert_file, "w"); if (f == NULL) { ssl_log(SSL_ERROR, "open %s fail.", cert_file); ret = -1; goto exit; } if (fwrite(output_buf, 1, len, f) != len) { ssl_log(SSL_ERROR, "fwrite fail."); ret = -1; goto exit; } ret = 0; exit: if (f) fclose(f); if (output_buf) free(output_buf); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return ret; } int gen_ca_cert_buf(void *cert_buf, size_t len, pkey_t *pkey, const char *org, const char *orgUnit) { char issuer_name[256] = {0}; const char *not_before = “20010101000000”; const char *not_after = “20371231235959”; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); snprintf(issuer_name, 256, "CN=%s,O=%s,OU=%s", "TP-Link SOHO Router CA", org, orgUnit); if (gen_cert(cert_buf, len, 1, 1, NULL, pkey, NULL, NULL, issuer_name, not_before, not_after, 0, NULL) != 0) { ssl_log(SSL_ERROR, "gen_cert fail."); return -1; } ssl_log(SSL_DEBUG, "cert buf: \n%s\n", (char *)cert_buf); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int gen_server_cert_file(const char *cert_file, pkey_t *pkey, x509_cert_t *issuer_cert, pkey_t *issuer_key, const char *cn, char *san) { FILE *f; unsigned char output_buf[4096]; char subject_name[256] = {0}; size_t len = 0; char not_before[20] = {0}; char not_after[20] = {0}; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); snprintf(subject_name, 256, "CN=%s", cn); snprintf(not_before, 20, "%04d%02d%02d%02d%02d%02d", issuer_cert->valid_from.year, issuer_cert->valid_from.mon, issuer_cert->valid_from.day, issuer_cert->valid_from.hour, issuer_cert->valid_from.min, issuer_cert->valid_from.sec ); snprintf(not_after, 20, "%04d%02d%02d%02d%02d%02d", issuer_cert->valid_to.year, issuer_cert->valid_to.mon, issuer_cert->valid_to.day, issuer_cert->valid_to.hour, issuer_cert->valid_to.min, issuer_cert->valid_to.sec ); memset(output_buf, 0, 4096); if (gen_cert(output_buf, 4096, 0, 0, issuer_cert, issuer_key, pkey, subject_name, NULL, not_before, not_after, 1, san) != 0) { ssl_log(SSL_ERROR, "gen_cert fail."); return -1; } len = strlen((char *)output_buf); if ((f = fopen(cert_file, "w")) == NULL) { ssl_log(SSL_ERROR, "open %s fail.", cert_file); return -1; } if (fwrite(output_buf, 1, len, f) != len) { ssl_log(SSL_ERROR, "fwrite fail."); fclose(f); return -1; } fclose(f); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } void free_cert(x509_cert_t *cert) { if (cert) { mbedtls_x509_crt_free(cert); free(cert); cert = NULL; } } int load_cert_from_file(const char *cert_file, x509_cert_t **cert) { int ret = 0; x509_cert_t *tmp = NULL; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == cert_file || NULL == cert) return -1; if (access(cert_file, 0) != 0) { ssl_log(SSL_ERROR, "File %s is not exist.", cert_file); return -1; } tmp = (x509_cert_t *)malloc(sizeof(x509_cert_t)); if (NULL == tmp) return -1; mbedtls_x509_crt_init(tmp); if ((ret = mbedtls_x509_crt_parse_file(tmp, cert_file)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509_crt_parse_file fail. ret=%d", ret); free(tmp); return -1; } *cert = tmp; ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int load_pkey_from_file(const char *key_file, pkey_t **pkey) { int ret = 0; pkey_t *tmp = NULL; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == key_file || NULL == pkey) return -1; if (access(key_file, 0) != 0) { ssl_log(SSL_ERROR, "File %s is not exist.", key_file); return -1; } tmp = (pkey_t *)malloc(sizeof(pkey_t)); if (NULL == tmp) return -1; mbedtls_pk_init(tmp); if ((ret = mbedtls_pk_parse_keyfile(tmp, key_file, NULL)) != 0) { ssl_log(SSL_ERROR, "mbedtls_pk_parse_keyfile fail. ret=%d", ret); free(tmp); return -1; } *pkey = tmp; ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int load_cert_from_buf(const void *cert_buf, size_t len, x509_cert_t **cert) { int ret = 0; x509_cert_t *tmp = NULL; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == cert_buf || NULL == cert) return -1; tmp = (x509_cert_t *)malloc(sizeof(x509_cert_t)); if (NULL == tmp) return -1; ssl_log(SSL_DEBUG, "cert buf: \n%s\n", (char *)cert_buf); mbedtls_x509_crt_init(tmp); ssl_log(SSL_DEBUG, "buf len: %d %d", len, strlen(cert_buf)); if ((ret = mbedtls_x509_crt_parse(tmp, cert_buf, len)) != 0) { ssl_log(SSL_ERROR, "mbedtls_x509_crt_parse fail. ret=%d", ret); free(tmp); return -1; } *cert = tmp; ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int load_pkey_from_buf(const void *key_buf, size_t len, pkey_t **pkey) { int ret = 0; pkey_t *tmp = NULL; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == key_buf || NULL == pkey) return -1; tmp = (pkey_t *)malloc(sizeof(pkey_t)); if (NULL == tmp) return -1; ssl_log(SSL_DEBUG, "key buf: \n%s\n", (char *)key_buf); mbedtls_pk_init(tmp); ssl_log(SSL_DEBUG, "buf len: %d %d", len, strlen(key_buf)); if (mbedtls_pk_parse_key(tmp, key_buf, len, NULL, 0) != 0) { ssl_log(SSL_ERROR, "mbedtls_pk_parse_key fail. ret=%d", ret); free(tmp); return -1; } *pkey = tmp; ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } int write_cert_to_buf(x509_cert_t *cert, void *cert_buf, size_t len) { return -1; } int write_pkey_to_buf(pkey_t *pkey, void *key_buf, size_t len) { int ret = 0; ssl_log(SSL_DEBUG, "enter %s", __FUNCTION__); if (NULL == pkey || NULL == key_buf) return -1; if ((ret = mbedtls_pk_write_key_pem(pkey, key_buf, len)) != 0) { ssl_log(SSL_ERROR, "mbedtls_pk_write_key_pem failed. ret=%d", ret); return -1; } ssl_log(SSL_DEBUG, "key buf: \n%s\n", (char *)key_buf); ssl_log(SSL_DEBUG, "leave %s", __FUNCTION__); return 0; } #endif /* INCLUDE_SSL && INCLUDE_SSL_MBEDTLS */整理代码缩进,空格等格式问题
10-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值