diff --git a/CMakeLists.txt b/CMakeLists.txt index c98887fd..5b0cc19d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,7 +64,7 @@ add_library( src/tlcp.c src/tls.c src/tls12.c -# src/tls13.c + src/tls13.c src/tls_ext.c src/tls_trace.c src/version.c @@ -138,8 +138,8 @@ add_executable( tools/tlcp_server.c tools/tls12_client.c tools/tls12_server.c -# tools/tls13_client.c -# tools/tls13_server.c + tools/tls13_client.c + tools/tls13_server.c tools/sdfutil.c tools/skfutil.c ) @@ -258,6 +258,8 @@ target_link_libraries (zuctest LINK_PUBLIC gmssl) #add_executable(tlstest tests/tlstest.c) #target_link_libraries (tlstest LINK_PUBLIC gmssl) +add_executable(tls13test tests/tls13test.c) +target_link_libraries (tls13test LINK_PUBLIC gmssl) enable_testing() @@ -290,7 +292,7 @@ add_test(NAME sm2 COMMAND sm2test) add_test(NAME sm3 COMMAND sm3test) add_test(NAME sm4 COMMAND sm4test) add_test(NAME sm9 COMMAND sm9test) -#add_test(NAME tls COMMAND tlstest) +add_test(NAME tls13 COMMAND tls13test) add_test(NAME x509 COMMAND x509test) add_test(NAME x509_oid COMMAND x509_oidtest) add_test(NAME x509_alg COMMAND x509_algtest) diff --git a/demos/tlcp_client.sh b/demos/tlcp_client.sh new file mode 100755 index 00000000..31088861 --- /dev/null +++ b/demos/tlcp_client.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +# 当服务器发送CertificateRequest而Client又没有用证书、密钥时,会SegFault + + +#../build/bin/tls12_client -host 127.0.0.1 -cacert cacert.pem -cert cert.pem -key key.pem -pass 123456 +../build/bin/tlcp_client -host 127.0.0.1 -cacert cacert.pem # -cert cert.pem -key key.pem -pass 123456 + + diff --git a/demos/tlcp_server.sh b/demos/tlcp_server.sh new file mode 100755 index 00000000..171a792d --- /dev/null +++ b/demos/tlcp_server.sh @@ -0,0 +1,22 @@ +#!/bin/bash + + +gmssl sm2keygen -pass 1234 -out cakey.pem +gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN CA -days 365 -key cakey.pem -pass 1234 -out cacert.pem -key_usage keyCertSign -key_usage cRLSign +gmssl certparse -in cacert.pem + +gmssl sm2keygen -pass 1234 -out signkey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key signkey.pem -pass 1234 -out signreq.pem +gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem +gmssl certparse -in signcert.pem + +gmssl sm2keygen -pass 1234 -out enckey.pem +gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -days 365 -key enckey.pem -pass 1234 -out encreq.pem +gmssl reqsign -in encreq.pem -days 365 -key_usage keyEncipherment -cacert cacert.pem -key cakey.pem -pass 1234 -out enccert.pem +gmssl certparse -in enccert.pem + +cat signcert.pem > cert.pem +cat enccert.pem >> cert.pem + +sudo gmssl tlcp_server -cert cert.pem -key signkey.pem -pass 1234 -ex_key enckey.pem -ex_pass 1234 # -cacert cacert.pem + diff --git a/demos/tls12.sh b/demos/tls12.sh new file mode 100755 index 00000000..4cf1e78a --- /dev/null +++ b/demos/tls12.sh @@ -0,0 +1,15 @@ +#!/bin/bash -x + + +# server-authentication only +../build/bin/tls12_server -cert cert.pem -key key.pem -pass 123456 1>/dev/null 2>/dev/null & +sleep 3 +../build/bin/tls12_client -host 127.0.0.1 -cacert cacert.pem + + +# mutual authentication, i.e. client certificate requested +../build/bin/tls12_server -cert cert.pem -key key.pem -pass 123456 -cacert cacert.pem 1>/dev/null 2>/dev/null & +sleep 3 +../build/bin/tls12_client -host 127.0.0.1 -cacert cacert.pem -cert cert.pem -key key.pem -pass 123456 + + diff --git a/demos/tls12_client.sh b/demos/tls12_client.sh new file mode 100755 index 00000000..ab013397 --- /dev/null +++ b/demos/tls12_client.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +# 当服务器发送CertificateRequest而Client又没有用证书、密钥时,会SegFault + + +#../build/bin/tls12_client -host 127.0.0.1 -cacert cacert.pem -cert cert.pem -key key.pem -pass 123456 +../build/bin/tls12_client -host 127.0.0.1 -cacert cacert.pem # -cert cert.pem -key key.pem -pass 123456 + + diff --git a/demos/tls12_server.sh b/demos/tls12_server.sh new file mode 100755 index 00000000..78fc2cb2 --- /dev/null +++ b/demos/tls12_server.sh @@ -0,0 +1,16 @@ +#!/bin/bash + + +# 现在的错误是服务器想要让客户端发送证书,但是客户端没有发证书 +# 如果要求客户端发送证书,那么服务器必须准备相应的CA证书 +# 客户端的证书和CA证书有什么区别吗?可能没有区别,但是还应该生成一个 +# 客户端的名字是什么呢? +# +# 服务器的证书需要设定服务器名字,也就是127.0.0.1或者localhost +# 这个名字和SNI是有关系的 + +# 客户端的名字可以任意定了,而且客户端的CA可以有所不同吧 + + +../build/bin/tls12_server -cert cert.pem -key key.pem -pass 123456 #-cacert cacert.pem + diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index 8596e2a9..dbe817d8 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -285,7 +285,7 @@ typedef enum { TLS_extension_supported_ekt_ciphers = 39, TLS_extension_pre_shared_key = 41, TLS_extension_early_data = 42, - TLS_extension_supported_protocols = 43, + TLS_extension_supported_versions = 43, TLS_extension_cookie = 44, TLS_extension_psk_key_exchange_modes = 46, TLS_extension_certificate_authorities = 47, @@ -544,20 +544,52 @@ int tls_record_get_handshake_server_hello(const uint8_t *record, int tls_server_hello_print(FILE *fp, const uint8_t *server_hello, size_t len, int format, int indent); // Extensions -int tls_ext_signature_algors_to_bytes(const int *algors, size_t algors_count, +int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, + uint8_t **out, size_t *outlen); +int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen); +int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen); + +int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, + uint8_t **out, size_t *outlen); +int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen); +int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen); + +int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen); +int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen); +int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen); +int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen); +int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen); + +int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, + uint8_t **out, size_t *outlen); +int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, uint8_t **out, size_t *outlen); -int tls_exts_add_ec_point_formats(uint8_t *exts, size_t *extslen, size_t maxlen, const int *formats, size_t formats_cnt); -int tls_exts_add_supported_groups(uint8_t *exts, size_t *extslen, size_t maxlen, const int *curves, size_t curves_cnt); -int tls_exts_add_signature_algors(uint8_t *exts, size_t *extslen, size_t maxlen, const int *algs, size_t algs_cnt); +int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen); + +int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); +int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); +int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen); +int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, + const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, + uint8_t **out, size_t *outlen); +int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point); + + +int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, + uint8_t **out, size_t *outlen); int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); -int tls_process_client_ec_point_formats(const uint8_t *data, size_t datalen, uint8_t *exts, size_t *extslen, size_t maxlen); -int tls_process_client_signature_algorithms(const uint8_t *data, size_t datalen, uint8_t *exts, size_t *extslen, size_t maxlen); -int tls_process_client_supported_groups(const uint8_t *data, size_t datalen, uint8_t *exts, size_t *extslen, size_t maxlen); int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen); +int tls_process_server_exts(const uint8_t *exts, size_t extslen, + int *ec_point_format, int *supported_group, int *signature_algor); -int tls_process_server_exts(const uint8_t *exts, size_t extslen, int *ec_point_format, int *supported_group, int *signature_algor); // Certificate int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, @@ -750,7 +782,13 @@ typedef struct { int sock; + uint8_t enced_record[TLS_MAX_RECORD_SIZE]; + size_t enced_record_len; + + uint8_t record[TLS_MAX_RECORD_SIZE]; + + // 其实这个就不太对了,还是应该有一个完整的密文记录 uint8_t data[TLS_MAX_PLAINTEXT_SIZE]; size_t datalen; @@ -781,6 +819,9 @@ typedef struct { uint8_t client_write_iv[12]; // tls13 uint8_t server_write_iv[12]; // tls13 + BLOCK_CIPHER_KEY client_write_key; + BLOCK_CIPHER_KEY server_write_key; + } TLS_CONNECT; @@ -809,8 +850,41 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t pa int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen); +int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *server_cacerts_fp, + FILE *client_certs_fp, const SM2_KEY *client_sign_key); +int tls13_accept(TLS_CONNECT *conn, int port, + FILE *server_certs_fp, const SM2_KEY *server_sign_key, + FILE *client_cacerts_fp); +int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen); +int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen); + + +int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen); +int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, + int *ec_point_format, int *supported_group, int *signature_algor); + + +int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen); + +int tls13_extension_print(FILE *fp, int fmt, int ind, + int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen); +int tls13_extensions_print(FILE *fp, int fmt, int ind, + int handshake_type, const uint8_t *exts, size_t extslen); + +int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen); +int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen); + + +int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], int record_type, + const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content + uint8_t *out, size_t *outlen); // TLSCiphertext.encrypted_record +int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + int *record_type, uint8_t *out, size_t *outlen); + #define TLS_DEBUG @@ -820,11 +894,13 @@ int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen); # define tls_record_trace(fp,rec,reclen,fmt,ind) tls_record_print(fp,rec,reclen,fmt,ind) # define tlcp_record_trace(fp,rec,reclen,fmt,ind) tlcp_record_print(fp,rec,reclen,fmt,ind) # define tls12_record_trace(fp,rec,reclen,fmt,ind) tls12_record_print(fp,rec,reclen,fmt,ind) +# define tls13_record_trace(fp,rec,reclen,fmt,ind) tls13_record_print(fp,fmt,ind,rec,reclen) #else # define tls_trace(s) # define tls_record_trace(fp,rec,reclen,fmt,ind) # define tlcp_record_trace(fp,rec,reclen,fmt,ind) # define tls12_record_trace(fp,rec,reclen,fmt,ind) +# define tls13_record_trace(fp,rec,reclen,fmt,ind) #endif diff --git a/include/gmssl/x509.h b/include/gmssl/x509.h index 43e41d69..1a857a86 100644 --- a/include/gmssl/x509.h +++ b/include/gmssl/x509.h @@ -371,6 +371,14 @@ int x509_certs_get_cert_by_issuer_and_serial_number( const uint8_t *serial, size_t serial_len, const uint8_t **cert, size_t *cert_len); + +typedef enum { + X509_verify_err_cert_revoked = -2, + X509_verify_err_cert_not_yet_valid = -3, + X509_verify_err_cert_has_expired = -4, + X509_verify_err_cert_chain_too_long = -5, +} X509_VERIFY_ERR; + int x509_certs_verify(const uint8_t *certs, size_t certslen, const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result); int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, diff --git a/src/bak_tls13.c b/src/bak_tls13.c new file mode 100644 index 00000000..52eeaa42 --- /dev/null +++ b/src/bak_tls13.c @@ -0,0 +1,2573 @@ +/* + * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const int tls13_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; + +int tls13_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) +{ + // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 + // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) + format |= tls13_ciphers[0] << 8; + return tls13_record_trace(fp, record, recordlen, format, indent); +} + + +/* +struct { + opaque content[TLSPlaintext.length]; + ContentType type; + uint8 zeros[length_of_padding]; +} TLSInnerPlaintext; + +struct { + ContentType opaque_type = application_data; // 23 + ProtocolVersion legacy_record_version = 0x0303; // TLS v1.2 + uint16 length; + opaque encrypted_record[TLSCiphertext.length]; +} TLSCiphertext; +*/ +int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], int record_type, + const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content + uint8_t *out, size_t *outlen) // TLSCiphertext.encrypted_record +{ + uint8_t nonce[12]; + uint8_t aad[5]; + uint8_t *gmac; + uint8_t *mbuf = malloc(inlen + 256); // FIXME: update gcm_encrypt API + size_t mlen, clen; + + // nonce = (zeros|seq_num) xor (iv) + nonce[0] = nonce[1] = nonce[2] = 0; + memcpy(nonce + 3, seq_num, 8); + gmssl_memxor(nonce, nonce, iv, 12); + + // TLSInnerPlaintext + memcpy(mbuf, in, inlen); + mbuf[inlen] = record_type; + memset(mbuf + inlen + 1, 0, padding_len); + mlen = inlen + 1 + padding_len; + clen = mlen + GHASH_SIZE; + + // aad = TLSCiphertext header + aad[0] = TLS_record_application_data; + aad[1] = 0x03; //TLS_protocol_tls12_major; + aad[2] = 0x03; //TLS_protocol_tls12_minor; + aad[3] = clen >> 8; + aad[4] = clen; + + gmac = out + mlen; + if (gcm_encrypt(key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *in, size_t inlen, + int *record_type, uint8_t *out, size_t *outlen) +{ + uint8_t nonce[12]; + uint8_t aad[5]; + size_t mlen; + const uint8_t *gmac; + size_t i; + + // nonce = (zeros|seq_num) xor (iv) + nonce[0] = nonce[1] = nonce[2] = 0; + memcpy(nonce + 3, seq_num, 8); + gmssl_memxor(nonce, nonce, iv, 12); + + // aad = TLSCiphertext header + aad[0] = TLS_record_application_data; + aad[1] = 0x03; //TLS_protocol_tls12_major; + aad[2] = 0x03; //TLS_protocol_tls12_minor; + aad[3] = inlen >> 8; + aad[4] = inlen; + + if (inlen < GHASH_SIZE) { + error_print(); + return -1; + } + mlen = inlen - GHASH_SIZE; + gmac = in + mlen; + + if (gcm_decrypt(key, iv, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) { + error_print(); + return -1; + } + + // remove padding, get record_type + *record_type = 0; + while (mlen--) { + if (out[mlen] != 0) { + *record_type = out[mlen]; + break; + } + } + if (!tls_record_type_name(*record_type)) { + error_print(); + return -1; + } + return 1; +} + +int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len, + uint8_t *enced_record, size_t *enced_recordlen) +{ + if (tls13_gcm_encrypt(key, iv, + seq_num, record[0], record + 5, recordlen - 5, padding_len, + enced_record + 5, enced_recordlen) != 1) { + error_print(); + return -1; + } + + enced_record[0] = TLS_record_application_data; + enced_record[1] = 0x03; //TLS_protocol_tls12_major; + enced_record[2] = 0x03; //TLS_protocol_tls12_minor; + enced_record[3] = (*enced_recordlen) >> 8; + enced_record[4] = (*enced_recordlen); + + (*enced_recordlen) += 5; + return 1; +} + +int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *enced_record, size_t enced_recordlen, + uint8_t *record, size_t *recordlen) +{ + int record_type; + + if (tls13_gcm_decrypt(key, iv, + seq_num, enced_record + 5, enced_recordlen - 5, + &record_type, record + 5, recordlen) != 1) { + error_print(); + return -1; + } + record[0] = record_type; + record[1] = 0x03; //TLS_protocol_tls12_major; + record[2] = 0x03; //TLS_protocol_tls12_minor; + record[3] = (*recordlen) >> 8; + record[4] = (*recordlen); + + (*recordlen) += 5; + return 1; +} + +int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t padding_len) +{ + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + uint8_t *record = conn->record; + size_t recordlen; + + tls_trace("<<<< [ApplicationData]\n"); + + if (conn->is_client) { + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if (tls13_gcm_encrypt(key, iv, + seq_num, TLS_record_application_data, data, datalen, padding_len, + record + 5, &recordlen) != 1) { + error_print(); + return -1; + } + + record[0] = TLS_record_application_data; + record[1] = TLS_protocol_tls12 >> 8; + record[2] = TLS_protocol_tls12 & 0xff; + record[3] = recordlen >> 8; + record[4] = recordlen; + recordlen += 5; + + tls_record_send(record, recordlen, conn->sock); + tls_seq_num_incr(seq_num); + + return 1; +} + +int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen) +{ + int record_type; + uint8_t *record = conn->record; + size_t recordlen; + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + + + tls_trace(">>>> [ApplicationData]\n"); + + if (conn->is_client) { + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (record[0] != TLS_record_application_data) { + error_print(); + return -1; + } + + if (tls13_gcm_decrypt(key, iv, + seq_num, record + 5, recordlen - 5, + &record_type, data, datalen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(seq_num); + + if (record_type != TLS_record_application_data) { + error_print(); + return -1; + } + return 1; +} + + +/* +HKDF-Expand-Label(Secret, Label, Context, Length) = + HKDF-Expand(Secret, HkdfLabel, Length); + + HkdfLabel = struct { + uint16 length = Length; + opaque label<7..255> = "tls13 " + Label; + opaque context<0..255> = Context; } + +Derive-Secret(Secret, Label, Messages) = + HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length) + +*/ + +int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]) +{ + size_t dgstlen; + if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1 + || dgstlen != 32) { + error_print(); + return -1; + } + return 1; +} + +int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32], + const char *label, const uint8_t *context, size_t context_len, + size_t outlen, uint8_t *out) +{ + uint8_t label_len; + uint8_t hkdf_label[2 + 256 + 256]; + uint8_t *p = hkdf_label; + size_t hkdf_label_len = 0; + + label_len = strlen("tls13") + strlen(label); + tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len); + tls_uint8_to_bytes(label_len, &p, &hkdf_label_len); + tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len); + tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len); + tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len); + + hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out); + return 1; +} + +int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]) +{ + DIGEST_CTX ctx = *dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + + if (digest_finish(&ctx, dgst, &dgstlen) != 1 + || tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) { + error_print(); + return -1; + } + return 1; +} + + +/* +data to be signed in certificate_verify: + - A string that consists of octet 32 (0x20) repeated 64 times + - The context string + - A single 0 byte which serves as the separator + - The content to be signed +*/ +int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server) +{ + uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; + uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; + + SM2_SIGN_CTX sm2_ctx; + DIGEST_CTX temp_dgst_ctx; + uint8_t prefix[64]; + uint8_t *context_str = is_server ? server_context_str : client_context_str; + size_t context_str_len = sizeof(client_context_str); + uint8_t dgst[64]; + size_t dgstlen; + + memset(prefix, 0x20, 64); + temp_dgst_ctx = *dgst_ctx; + digest_finish(&temp_dgst_ctx, dgst, &dgstlen); + + sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_sign_update(&sm2_ctx, prefix, 64); + sm2_sign_update(&sm2_ctx, context_str, context_str_len); + sm2_sign_update(&sm2_ctx, dgst, dgstlen); + sm2_sign_finish(&sm2_ctx, sig, siglen); + + return 1; +} + +int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server) +{ + uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; + uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; + + int ret; + SM2_SIGN_CTX sm2_ctx; + DIGEST_CTX temp_dgst_ctx; + uint8_t prefix[64]; + uint8_t dgst[64]; + size_t dgstlen; + + memset(prefix, 0x20, 64); + temp_dgst_ctx = *dgst_ctx; + digest_finish(&temp_dgst_ctx, dgst, &dgstlen); + + sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + sm2_verify_update(&sm2_ctx, prefix, 64); + sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str)); + sm2_verify_update(&sm2_ctx, dgst, dgstlen); + ret = sm2_verify_finish(&sm2_ctx, sig, siglen); + + return ret; +} + +/* + verify_data in Finished + + finished_key = + HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) + Structure of this message: + struct { + opaque verify_data[Hash.length]; + } Finished; + The verify_data value is computed as follows: + verify_data = + HMAC(finished_key, + Transcript-Hash(Handshake Context, + Certificate*, CertificateVerify*)) +*/ + +int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret, + const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len) +{ + DIGEST_CTX temp_dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + uint8_t finished_key[64]; + size_t finished_key_len; + + temp_dgst_ctx = *dgst_ctx; + digest_finish(&temp_dgst_ctx, dgst, &dgstlen); + finished_key_len = dgstlen; + + tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret, + "finished", NULL, 0, finished_key_len, finished_key); + + hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len); + + return 1; +} + +/* +Handshakes + +*/ + +int tls_ext_supported_versions_to_bytes(const int *versions, size_t versions_count, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_supported_versions; + uint8_t versions_len = sizeof(uint16_t) * versions_count; + size_t i; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(1 + versions_len, out, outlen); + tls_uint8_to_bytes(versions_len, out, outlen); + for (i = 0; i < versions_count; i++) { + tls_uint16_to_bytes(versions[i], out, outlen); + } + return 1; +} + +int tls_ext_signature_algorithms_to_bytes(const int *algors, size_t algors_count, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_signature_algorithms; + uint16_t algors_len = sizeof(uint16_t) * algors_count; + size_t i; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(2 + algors_len, out, outlen); + tls_uint16_to_bytes(algors_len, out, outlen); + for (i = 0; i < algors_count; i++) { + tls_uint16_to_bytes(algors[i], out, outlen); + } + return 1; +} + +int tls_ext_supported_groups_to_bytes(const int *groups, size_t groups_count, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_supported_groups; + uint16_t groups_len = sizeof(uint16_t) * groups_count; + size_t i; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(2 + groups_len, out, outlen); + tls_uint16_to_bytes(groups_len, out, outlen); + for (i = 0; i < groups_count; i++) { + tls_uint16_to_bytes(groups[i], out, outlen); + } + return 1; +} + +int tls_ext_key_share_client_hello_to_bytes( + const SM2_POINT *sm2_point, const SM2_POINT *p256_point, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + uint16_t client_shares_len = 0; + uint8_t sm2_key_exchange[65]; + uint8_t p256_key_exchange[65]; + + if (sm2_point) { + sm2_point_to_uncompressed_octets(sm2_point, sm2_key_exchange); + client_shares_len += 69; + } + if (p256_point) { + sm2_point_to_uncompressed_octets(p256_point, p256_key_exchange); + client_shares_len += 69; + } + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(2 + client_shares_len, out, outlen); + tls_uint16_to_bytes(client_shares_len, out, outlen); + if (sm2_point) { + tls_uint16_to_bytes(TLS_curve_sm2p256v1, out, outlen); + tls_uint16array_to_bytes(sm2_key_exchange, 65, out, outlen); + } + if (p256_point) { + tls_uint16_to_bytes(TLS_curve_secp256r1, out, outlen); + tls_uint16array_to_bytes(p256_key_exchange, 65, out, outlen); + } + return 1; +} + +int tls_ext_key_share_server_hello_to_bytes(const SM2_POINT *sm2_point, const SM2_POINT *p256_point, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + uint16_t group; + uint8_t key_exchange[65]; + + if (sm2_point) { + group = TLS_curve_sm2p256v1; + sm2_point_to_uncompressed_octets(sm2_point, key_exchange); + } else if (p256_point) { + group = TLS_curve_secp256r1; + sm2_point_to_uncompressed_octets(p256_point, key_exchange); + } + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(69, out, outlen); + tls_uint16_to_bytes(group, out, outlen); + tls_uint16array_to_bytes(key_exchange, 65, out, outlen); + return 1; +} + +/* +ClientHello Extensions: + supported_versions + supported_groups + signature_algorithms +*/ +int tls13_client_hello_extensions_set(uint8_t *exts, size_t *extslen, const SM2_POINT *sm2_point) +{ + uint8_t *p = exts; + int versions[] = { TLS_protocol_tls13 }; + int supported_groups[] = { TLS_curve_sm2p256v1 }; + int sign_algors[] = { TLS_sig_sm2sig_sm3 }; + + *extslen = 0; + tls_ext_supported_versions_to_bytes(versions, 1, &p, extslen); + tls_ext_supported_groups_to_bytes(supported_groups, 1, &p, extslen); + tls_ext_signature_algorithms_to_bytes(sign_algors, 1, &p, extslen); + tls_ext_key_share_client_hello_to_bytes(sm2_point, NULL, &p, extslen); + return 1; +} + +int tls_ext_supported_groups_match(const uint8_t *ext_data, size_t ext_datalen, int group) +{ + const uint8_t *p; + size_t len; + + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || ext_datalen > 0) { + error_print(); + return -1; + } + while (len) { + uint16_t supported_group; + if (tls_uint16_from_bytes(&supported_group, &p, &len) != 1) { + error_print(); + return -1; + } + if (supported_group == group) { + return 1; + } + } + error_print(); + return -1; +} + +int tls_ext_signature_algorithms_match(const uint8_t *ext_data, size_t ext_datalen, int algor) +{ + const uint8_t *p; + size_t len; + + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || ext_datalen > 0) { + error_print(); + return -1; + } + while (len) { + uint16_t supported_algor; + if (tls_uint16_from_bytes(&supported_algor, &p, &len) != 1) { + error_print(); + return -1; + } + if (supported_algor == algor) { + return 1; + } + } + error_print(); + return -1; +} + +int tls_ext_supported_versions_match(const uint8_t *ext_data, size_t ext_datalen, int version) +{ + const uint8_t *p; + size_t len; + + if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || ext_datalen > 0) { + error_print(); + return -1; + } + while (len) { + uint16_t supported_version; + if (tls_uint16_from_bytes(&supported_version, &p, &len) != 1) { + error_print(); + return -1; + } + if (supported_version == version) { + return 1; + } + } + error_print(); + return -1; +} + +int tls_ext_key_share_client_hello_get(const uint8_t *ext_data, size_t ext_datalen, + int prefered_curve, int *curve, SM2_POINT *point) +{ + const uint8_t *client_shares; + size_t client_shares_len; + + *curve = 0; + + if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &ext_data, &ext_datalen) != 1 + || ext_datalen > 0) { + error_print(); + return -1; + } + while (client_shares_len) { + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1 + || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) { + error_print(); + return -1; + } + switch (group) { + case TLS_curve_sm2p256v1: + case TLS_curve_secp256r1: + if (key_exchange_len != 65) { + error_print(); + return -1; + } + if (sm2_point_from_octets(point, key_exchange, key_exchange_len) != 1) { + error_print(); + return -1; + } + *curve = group; + if (prefered_curve == group) { + return 1; + } + break; + } + } + + error_print(); + return -1; +} + +int tls13_client_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_POINT *client_ecdhe_public) +{ + /* + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + + switch (ext_type) { + case TLS_extension_supported_groups: + if (sm2_point && tls_ext_supported_groups_match(ext_data, ext_datalen, TLS_curve_sm2p256v1)) { + } else if (p256_point && tls_ext_supported_groups_match(ext_data, ext_datalen, TLS_curve_secp256r1)) { + error_print(); + return -1; + } + break; + case TLS_extension_signature_algorithms: + if (sm2_point && tls_ext_signature_algorithms_match(ext_data, ext_datalen, TLS_sig_ecdsa_secp256r1_sha256)) { + } else if (p256_point && tls_ext_signature_algorithms_match(ext_data, ext_datalen, TLS_sig_sm2sig_sm3)) { + } else { + error_print(); + return -1; + } + break; + case TLS_extension_supported_versions: + if (tls_ext_supported_versions_match(ext_data, ext_datalen, TLS_version_tls13) != 1) { + error_print(); + return -1; + } + break; + case TLS_extension_key_share: + break; + + default: + error_print(); + return -1; + } + } + + */ + return 1; +} + +int tls13_server_hello_extensions_set(uint8_t *exts, size_t *extslen, + const SM2_POINT *sm2_point, const SM2_POINT *p256_point) +{ + uint8_t *p = exts; + int version = TLS_protocol_tls13; + + *extslen = 0; + tls_ext_supported_versions_to_bytes(&version, 1, &p, extslen); + tls_ext_key_share_server_hello_to_bytes(sm2_point, p256_point, &p, extslen); + return 1; +} + +int tls_client_key_shares_from_bytes(SM2_POINT *sm2_point, const uint8_t **in, size_t *inlen) +{ + const uint8_t *key_shares; + size_t key_shares_len; + + tls_uint16array_from_bytes(&key_shares, &key_shares_len, in, inlen); + + while (key_shares_len) { + uint16_t group; + const uint8_t *key_exch; + size_t key_exch_len; + + tls_uint16_from_bytes(&group, &key_shares, &key_shares_len); + tls_uint16array_from_bytes(&key_exch, &key_exch_len, &key_shares, &key_shares_len); + + if (key_exch_len != 65) { + error_print(); + return -1; + } + + switch (group) { + case TLS_curve_sm2p256v1: + sm2_point_from_octets(sm2_point, key_exch, key_exch_len); + break; + default: + error_print(); + return -1; + } + } + + return 1; +} + +int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_POINT *sm2_point) +{ + uint16_t version; + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + const uint8_t *p; + size_t len; + + tls_uint16_from_bytes(&ext_type, &exts, &extslen); + tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen); + + switch (ext_type) { + case TLS_extension_supported_versions: + if (tls_uint16_from_bytes(&version, &ext_data, &ext_datalen) != 1 + || ext_datalen > 0) { + error_print(); + return -1; + } + if (version != TLS_protocol_tls13) { + error_print(); + return -1; + } + break; + case TLS_extension_key_share: + if (tls_client_key_shares_from_bytes(sm2_point, &ext_data, &ext_datalen) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + } + return 1; +} + + +/* +struct { + Extension extensions<0..2^16-1>; +} EncryptedExtensions; +*/ +static int tls13_encrypted_exts[] = { + TLS_extension_server_name, + TLS_extension_max_fragment_length, + TLS_extension_supported_groups, + TLS_extension_use_srtp, + TLS_extension_heartbeat, + TLS_extension_application_layer_protocol_negotiation, + TLS_extension_client_certificate_type, + TLS_extension_server_certificate_type, + TLS_extension_early_data, +}; + +int tls13_record_set_handshake_encrypted_extensions(uint8_t *record, size_t *recordlen, + const uint8_t *exts_data, size_t exts_datalen) +{ + int type = TLS_handshake_encrypted_extensions; + uint8_t *p = record + 5 + 4; + size_t len = 0; + + tls_uint16array_to_bytes(exts_data, exts_datalen, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + return 1; +} + +int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record) +{ + int type; + const uint8_t *p; + size_t len; + const uint8_t *exts_data; + size_t exts_datalen; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_uint16array_from_bytes(&exts_data, &exts_datalen, &p, &len) != 1) { + error_print(); + return -1; + } + // 当前实现不需要在EncryptedExtensions提供扩展 + if (exts_datalen) { + error_print(); + return -1; + } + return 1; +} + + +/* + ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法 + ServerHello.Extensions.supported_groups 决定了服务器的公钥类型, + 因此也决定了服务器的签名算法 + ServerHello.cipher_suite决定了哈希函数 +*/ + +/* +struct { + SignatureScheme algorithm; + opaque signature<0..2^16-1>; +} CertificateVerify; +*/ +int tls13_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, + int sign_algor, const uint8_t *sig, size_t siglen) +{ + int type = TLS_handshake_certificate_verify; + uint8_t *p = record + 5 + 4; + size_t len = 0; + + tls_uint16_to_bytes((uint16_t)sign_algor, &p, &len); + tls_uint16array_to_bytes(sig, siglen, &p, &len); + + if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_record_get_handshake_certificate_verify(const uint8_t *record, + int *sign_algor, const uint8_t **sig, size_t *siglen) +{ + int type; + const uint8_t *p; + size_t len ; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1 + || type != TLS_handshake_certificate_verify) { + error_print(); + return -1; + } + + *sign_algor = 0; + tls_uint16_from_bytes((uint16_t *)sign_algor, &p, &len); + tls_uint16array_from_bytes(sig, siglen, &p, &len); + + + return 1; +} + +/* +struct { + opaque certificate_request_context<0..2^8-1>; + Extension extensions<2..2^16-1>; +} CertificateRequest; +*/ +static int tls13_certificate_request_exts[] = { + TLS_extension_status_request, + TLS_extension_signature_algorithms, + TLS_extension_signed_certificate_timestamp, + TLS_extension_certificate_authorities, + TLS_extension_oid_filters, + TLS_extension_signature_algorithms_cert, +}; + +int tls13_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, + const uint8_t *req_context, size_t req_context_len, + const uint8_t *exts, size_t extslen) +{ + int type = TLS_handshake_certificate_request; + uint8_t *p = record + 5 + 4; + size_t len = 0; + int sign_algors[] = { TLS_sig_sm2sig_sm3, TLS_sig_ecdsa_secp256r1_sha256 }; + size_t sign_algors_count = sizeof(sign_algors)/sizeof(sign_algors[0]); + + tls_ext_signature_algorithms_to_bytes(sign_algors, 2, NULL, &extslen); + tls_uint8array_to_bytes(req_context, req_context_len, &p, &len); + tls_uint16_to_bytes(extslen, &p, &len); + tls_ext_signature_algorithms_to_bytes(sign_algors, sign_algors_count, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + + return 1; +} + +int tls13_record_get_handshake_certificate_request(const uint8_t *record, + const uint8_t **req_context, size_t *req_context_len, + const uint8_t **exts, size_t *extslen) +{ + + return 1; +} + + +/* +struct { + opaque cert_data<1..2^24-1>; + Extension extensions<0..2^16-1>; +} CertificateEntry; + +struct { + opaque certificate_request_context<0..2^8-1>; + CertificateEntry certificate_list<0..2^24-1>; +} TLS13Certificate; +*/ + +static const int tls13_handshake_certificate_exts[] = { + TLS_extension_status_request, + TLS_extension_signed_certificate_timestamp, +}; + +// TODO: 当前未设置CertificateEntry.extensions +int tls13_record_set_handshake_certificate_from_pem(uint8_t *record, size_t *recordlen, FILE *fp) +{ + int type = TLS_handshake_certificate; + uint8_t *data = record + 5 + 4; + uint8_t *certs = data + 3; + size_t datalen, certslen = 0; + + for (;;) { + int ret; + uint8_t cert[1024]; + size_t certlen; + + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), fp) < 0) { + error_print(); + return -1; + } else if (!ret) { + break; + } + + tls_uint24array_to_bytes(cert, certlen, &certs, &certslen); + x509_cert_print(stderr, 0, 0, "Certificate", cert, certlen); + } + datalen = certslen; + tls_uint24_to_bytes((uint24_t)certslen, &data, &datalen); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + return 1; +} + +int tls13_record_get_handshake_certificate(const uint8_t *record, uint8_t *data, size_t *datalen) +{ + int type; + const uint8_t *cp; + + if (tls_record_get_handshake(record, &type, &cp, datalen) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate) { + error_print(); + return -1; + } + + // 这里我还是要接收一下Extensions + memcpy(data, cp, *datalen); + return 1; +} + + + + + +/* +finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) + +struct { + opaque verify_data[Hash.length]; +} Finished; + +verify_data = HMAC(finished_key, Hash(Handshake Context, Certificate*, CertificateVerify*)) +Hash = SM3, SHA256 or SHA384 +*/ + + +int tls13_record_set_handshake_finished(uint8_t *record, size_t *recordlen, + const uint8_t *verify_data, size_t verify_data_len) +{ + int type = TLS_handshake_finished; + if (!record || !recordlen || !verify_data) { + error_print(); + return -1; + } + tls_record_set_handshake(record, recordlen, type, verify_data, verify_data_len); + return 1; +} + +int tls13_record_get_handshake_finished(const uint8_t *record, + const uint8_t **verify_data, size_t *verify_data_len) +{ + int type; + + if (tls_record_get_handshake(record, &type, verify_data, verify_data_len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_finished) { + error_print(); + return -1; + } + if (*verify_data_len != SM3_DIGEST_SIZE + && *verify_data_len != SHA384_DIGEST_SIZE) { + error_print(); + return -1; + } + return 1; +} + + +int tls13_padding_len_rand(size_t *padding_len) +{ + uint8_t val; + rand_bytes(&val, 1); + *padding_len = val % 128; + return 1; +} + + + +int tls13_cipher_suite_get(int cipher_suite, const DIGEST **digest, const BLOCK_CIPHER **cipher) +{ + switch (cipher_suite) { + case TLS_cipher_sm4_gcm_sm3: + *digest = DIGEST_sm3(); + *cipher = BLOCK_CIPHER_sm4(); + break; + case TLS_cipher_aes_128_gcm_sha256: + *digest = DIGEST_sha256(); + *cipher = BLOCK_CIPHER_aes128(); + break; + default: + error_print(); + return -1; + } + return 1; +} + + + +/* + Client Server + +Key ^ ClientHello +Exch | + key_share* + | + signature_algorithms* + | + psk_key_exchange_modes* + v + pre_shared_key* --------> + ServerHello ^ Key + + key_share* | Exch + + pre_shared_key* v + + + | ecdhe => handshake_secret | + | handshake_secret => master_secret | + | handshake_secret, client_hello, server_hello | + | => client_handshake_traffic_secret | + | => server_handshake_traffic_secret | + + + {EncryptedExtensions} ^ Server + {CertificateRequest*} v Params + {Certificate} ^ + {CertificateVerify} | Auth + {Finished} v + + + master_secret, ClientHello .. server Finished + => server_application_traffic_secret_0 + + <-------- [Application Data*] + + ^ {Certificate*} +Auth | {CertificateVerify*} + v {Finished} --------> + + + + master_secret, ClientHello .. server Finished + => client_application_traffic_secret_0 + + [Application Data] <-------> [Application Data] + + +TLS 1.3的区别: + + * 首先在最开始的握手阶段就协商好了密钥,因此握手之后传输的就是加密消息了 + * 因此在第二阶段,双方不再发送ServerKeyExchange和ClientKeyExchange + * 服务器先发送CertificateRequest,再发送Certificate + * 没有ChangeCipherSpec了 + * 在握手阶段就需要加密,并且Certificate也在其中,因此需要格外的大的密文数据缓冲 + + 0 + | + v +[1] PSK -> HKDF-Extract = Early Secret + | +[2] +-----> Derive-Secret(., "ext binder" | "res binder", "") + | = binder_key + | +[3] +-----> Derive-Secret(., "c e traffic", ClientHello) + | = client_early_traffic_secret + | +[4] +-----> Derive-Secret(., "e exp master", ClientHello) + | = early_exporter_master_secret + v +[5] Derive-Secret(., "derived", "") + | + v +[6] (EC)DHE -> HKDF-Extract = Handshake Secret + | +[7] +-----> Derive-Secret(., "c hs traffic", + | ClientHello...ServerHello) + | = client_handshake_traffic_secret + | +[8] +-----> Derive-Secret(., "s hs traffic", + | ClientHello...ServerHello) + | = server_handshake_traffic_secret + v +[9] Derive-Secret(., "derived", "") + | + v +[10] 0 -> HKDF-Extract = Master Secret + | +[11] +-----> Derive-Secret(., "c ap traffic", + | ClientHello...server Finished) + | = client_application_traffic_secret_0 + | +[12] +-----> Derive-Secret(., "s ap traffic", + | ClientHello...server Finished) + | = server_application_traffic_secret_0 + | +[13] +-----> Derive-Secret(., "exp master", + | ClientHello...server Finished) + | = exporter_master_secret + | +[14] +-----> Derive-Secret(., "res master", + ClientHello...client Finished) + = resumption_master_secret + +*/ + +int tls13_do_connect(TLS_CONNECT *conn) +{ + int ret = -1; + uint8_t *record = conn->record; + uint8_t finished_record[TLS_FINISHED_RECORD_BUF_SIZE]; + size_t recordlen, finished_record_len; + + uint8_t client_random[32]; + uint8_t server_random[32]; + int protocol; + int cipher_suite; + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + + uint8_t client_exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t client_exts_len = 0; + const uint8_t *server_exts; + size_t server_exts_len; + + // 扩展的协商结果,-1 表示服务器不支持该扩展(未给出响应) + int ec_point_format = -1; + int supported_group = -1; + int signature_algor = -1; + + + SM2_KEY server_sign_key; + SM2_SIGN_CTX verify_ctx; + SM2_SIGN_CTX sign_ctx; + const uint8_t *sig; + size_t siglen; + uint8_t pre_master_secret[48]; + SM3_CTX sm3_ctx; + SM3_CTX tmp_sm3_ctx; + uint8_t sm3_hash[32]; + const uint8_t *verify_data; + size_t verify_data_len; + uint8_t local_verify_data[12]; + + int handshake_type; + const uint8_t *server_enc_cert; // 这几个值也是不需要的 + size_t server_enc_cert_len; + uint8_t server_enc_cert_lenbuf[3]; + const uint8_t *cp; + uint8_t *p; + size_t len; + + int depth = 5; + int alert = 0; + int verify_result; + + + // 初始化记录缓冲 + tls_record_set_protocol(record, TLS_protocol_tls1); // ClientHello的记录层协议版本是TLSv1.0 + tls_record_set_protocol(finished_record, conn->protocol); + + // 准备Finished Context(和ClientVerify) + sm3_init(&sm3_ctx); + if (conn->client_certs_len) + sm2_sign_init(&sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); + + + // send ClientHello + tls_random_generate(client_random); + int ec_point_formats[] = { TLS_point_uncompressed }; + size_t ec_point_formats_cnt = 1; + int supported_groups[] = { TLS_curve_sm2p256v1 }; + size_t supported_groups_cnt = 1; + int signature_algors[] = { TLS_sig_sm2sig_sm3 }; + size_t signature_algors_cnt = 1; + + client_exts_len = 0; + tls_exts_add_ec_point_formats(client_exts, &client_exts_len, sizeof(client_exts), ec_point_formats, ec_point_formats_cnt); + tls_exts_add_supported_groups(client_exts, &client_exts_len, sizeof(client_exts), supported_groups, supported_groups_cnt); + tls_exts_add_signature_algors(client_exts, &client_exts_len, sizeof(client_exts), signature_algors, signature_algors_cnt); + + if (tls_record_set_handshake_client_hello(record, &recordlen, + conn->protocol, client_random, NULL, 0, + tls12_ciphers, tls12_ciphers_count, + client_exts, client_exts_len) != 1) { + error_print(); + goto end; + } + tls_trace("send ClientHello\n"); + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerHello + tls_trace("recv ServerHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + if (tls_record_get_handshake_server_hello(record, + &protocol, &random, &session_id, &session_id_len, &cipher_suite, + &server_exts, &server_exts_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (protocol != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; + } + // tls12_ciphers 应该改为conn的内部变量 + if (tls_cipher_suite_in_list(cipher_suite, tls12_ciphers, tls12_ciphers_count) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + goto end; + } + if (!server_exts) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (tls_process_server_exts(server_exts, server_exts_len, &ec_point_format, &supported_group, &signature_algor) != 1 + || ec_point_format < 0 + || supported_group < 0 + || signature_algor < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + memcpy(server_random, random, 32); + memcpy(conn->session_id, session_id, session_id_len); + conn->cipher_suite = cipher_suite; + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerCertificate + tls_trace("recv ServerCertificate\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + + if (tls_record_get_handshake_certificate(record, + conn->server_certs, &conn->server_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // verify ServerCertificate + if (x509_certs_verify(conn->server_certs, conn->server_certs_len, + conn->ca_certs, conn->ca_certs_len, depth, &verify_result) != 1) { + error_print(); + tls_send_alert(conn, alert); + goto end; + } + + // recv ServerKeyExchange + tls_trace("recv ServerKeyExchange\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + + int curve; + SM2_POINT server_ecdhe_public; + if (tls_record_get_handshake_server_key_exchange_ecdhe(record, &curve, &server_ecdhe_public, &sig, &siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (curve != TLS_curve_sm2p256v1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // verify ServerKeyExchange + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cp, &len) != 1 + || x509_cert_get_subject_public_key(cp, len, &server_sign_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + goto end; + } + if (tls_verify_server_ecdh_params(&server_sign_key, // 这应该是签名公钥 + client_random, server_random, curve, &server_ecdhe_public, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + + // recv CertificateRequest or ServerHelloDone + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol + || tls_record_get_handshake(record, &handshake_type, &cp, &len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (handshake_type == TLS_handshake_certificate_request) { + const uint8_t *cert_types; + size_t cert_types_len; + const uint8_t *ca_names; + size_t ca_names_len; + + // recv CertificateRequest + tls_trace("recv CertificateRequest\n"); + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_certificate_request(record, + &cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if(!conn->client_certs_len) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (tls_cert_types_accepted(cert_types, cert_types_len, conn->client_certs, conn->client_certs_len) != 1 + || tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unsupported_certificate); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // recv ServerHelloDone + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + } else { + // 这个得处理一下 + conn->client_certs_len = 0; + gmssl_secure_clear(&conn->sign_key, sizeof(SM2_KEY)); + } + tls_trace("recv ServerHelloDone\n"); + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_handshake_server_hello_done(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // send ClientCertificate + if (conn->client_certs_len) { + tls_trace("send ClientCertificate\n"); + if (tls_record_set_handshake_certificate(record, &recordlen, conn->client_certs, conn->client_certs_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + } + + // generate MASTER_SECRET + tls_trace("generate secrets\n"); + SM2_KEY client_ecdh; + sm2_key_generate(&client_ecdh); + sm2_ecdh(&client_ecdh, &server_ecdhe_public, &server_ecdhe_public); + memcpy(pre_master_secret, &server_ecdhe_public, 32); // 这个做法很不优雅 + // ECDHE和ECC的PMS结构是不一样的吗? + + if (tls_prf(pre_master_secret, 32, "master secret", + client_random, 32, server_random, 32, + 48, conn->master_secret) != 1 + || tls_prf(conn->master_secret, 48, "key expansion", + server_random, 32, client_random, 32, + 96, conn->key_block) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + sm3_hmac_init(&conn->client_write_mac_ctx, conn->key_block, 32); + sm3_hmac_init(&conn->server_write_mac_ctx, conn->key_block + 32, 32); + sm4_set_encrypt_key(&conn->client_write_enc_key, conn->key_block + 64); + sm4_set_decrypt_key(&conn->server_write_enc_key, conn->key_block + 80); + tls_secrets_print(stderr, + pre_master_secret, 48, + client_random, server_random, + conn->master_secret, + conn->key_block, 96, + 0, 4); + + // send ClientKeyExchange + tls_trace("send ClientKeyExchange\n"); + if (tls_record_set_handshake_client_key_exchange_ecdhe(record, &recordlen, &client_ecdh.public_key) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + if (conn->client_certs_len) + sm2_sign_update(&sign_ctx, record + 5, recordlen - 5); + + // send CertificateVerify + if (conn->client_certs_len) { + tls_trace("send CertificateVerify\n"); + uint8_t sigbuf[SM2_MAX_SIGNATURE_SIZE]; + if (sm2_sign_finish(&sign_ctx, sigbuf, &siglen) != 1 + || tls_record_set_handshake_certificate_verify(record, &recordlen, sigbuf, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + sm3_update(&sm3_ctx, record + 5, recordlen - 5); + } + + // send [ChangeCipherSpec] + tls_trace("send [ChangeCipherSpec]\n"); + if (tls_record_set_change_cipher_spec(record, &recordlen) !=1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // send Client Finished + tls_trace("send Finished\n"); + memcpy(&tmp_sm3_ctx, &sm3_ctx, sizeof(sm3_ctx)); + sm3_finish(&tmp_sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "client finished", + sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1 + || tls_record_set_handshake_finished(finished_record, &finished_record_len, + local_verify_data, sizeof(local_verify_data)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); + sm3_update(&sm3_ctx, finished_record + 5, finished_record_len - 5); + + // encrypt Client Finished + tls_trace("encrypt Finished\n"); + if (tls_record_encrypt(&conn->client_write_mac_ctx, &conn->client_write_enc_key, + conn->client_seq_num, finished_record, finished_record_len, record, &recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + goto end; + } + + // [ChangeCipherSpec] + tls_trace("recv [ChangeCipherSpec]\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + tls12_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_get_change_cipher_spec(record) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + + // Finished + tls_trace("recv Finished\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1 + || tls_record_protocol(record) != conn->protocol) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (recordlen > sizeof(finished_record)) { + error_print(); // 解密可能导致 finished_record 溢出 + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tls12_record_trace(stderr, record, recordlen, (1<<24), 0); // 强制打印密文原数据 + tls_trace("decrypt Finished\n"); + if (tls_record_decrypt(&conn->server_write_mac_ctx, &conn->server_write_enc_key, + conn->server_seq_num, record, recordlen, finished_record, &finished_record_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + goto end; + } + tls12_record_trace(stderr, finished_record, finished_record_len, 0, 0); + tls_seq_num_incr(conn->server_seq_num); + if (tls_record_get_handshake_finished(finished_record, &verify_data, &verify_data_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + if (verify_data_len != sizeof(local_verify_data)) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + goto end; + } + sm3_finish(&sm3_ctx, sm3_hash); + if (tls_prf(conn->master_secret, 48, "server finished", + sm3_hash, 32, NULL, 0, sizeof(local_verify_data), local_verify_data) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + goto end; + } + if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decrypt_error); + goto end; + } + tls_trace("Connection established!\n"); + + + conn->protocol = conn->protocol; + conn->cipher_suite = cipher_suite; + + ret = 1; + +end: + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret)); + return 1; +} + +int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *server_cacerts_fp, + FILE *client_certs_fp, const SM2_KEY *client_sign_key) +{ + uint8_t *record = conn->record; + size_t recordlen; + + // 在TLS1.3握手过程中,加密的消息有哪些?最大值是多少? + uint8_t enced_record[256]; + size_t enced_recordlen; + + + int type; + const uint8_t *data; + size_t datalen; + + uint8_t client_random[32]; + uint8_t server_random[32]; + uint8_t exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t extslen; + const uint8_t *server_exts; + size_t server_exts_len; + + + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; + size_t siglen = sizeof(sig); + uint8_t verify_data[32]; + size_t verify_data_len; + + int server_sign_algor; + const uint8_t *server_sig; + size_t server_siglen; + const uint8_t *server_verify_data; + size_t server_verify_data_len; + + SM2_KEY client_ecdhe; + SM2_POINT server_ecdhe_public; + SM2_KEY server_sign_key; + const DIGEST *digest = NULL; + DIGEST_CTX dgst_ctx; // secret generation过程中需要ClientHello等数据输入的 + DIGEST_CTX null_dgst_ctx; // secret generation过程中不需要握手数据的 + const BLOCK_CIPHER *cipher = NULL; + size_t padding_len; + + uint8_t zeros[32] = {0}; + uint8_t psk[32] = {0}; + uint8_t early_secret[32]; + uint8_t handshake_secret[32]; + uint8_t master_secret[32]; + uint8_t client_handshake_traffic_secret[32]; + uint8_t server_handshake_traffic_secret[32]; + uint8_t client_application_traffic_secret[32]; + uint8_t server_application_traffic_secret[32]; + uint8_t client_write_key[16]; + uint8_t server_write_key[16]; + + struct sockaddr_in server; + server.sin_addr.s_addr = inet_addr(hostname); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + + + if ((conn->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + error_print(); + return -1; + } + + + if (connect(conn->sock, (struct sockaddr *)&server , sizeof(server)) < 0) { + error_print(); + return -1; + } + + conn->is_client = 1; + tls_record_set_protocol(enced_record, TLS_protocol_tls12); + + + // 1. send ClientHello + // 和之前的主要区别是要提供ECDHE + // + + tls_trace("send ClientHello\n"); + tls_record_set_protocol(record, TLS_protocol_tls12); + rand_bytes(client_random, 32); + sm2_key_generate(&client_ecdhe); // 生成ECDHE + tls13_client_hello_extensions_set(exts, &extslen, &(client_ecdhe.public_key)); + tls_record_set_handshake_client_hello(record, &recordlen, + TLS_protocol_tls12, client_random, NULL, 0, + tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]), + exts, extslen); + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + + // 2. recv ServerHello + tls_trace(">>>> ServerHello\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, enced_record, enced_recordlen, 0, 0); + tls_seq_num_incr(conn->server_seq_num); + + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + if (tls_record_get_handshake_server_hello(enced_record, + &conn->protocol, &random, &session_id, &session_id_len, + &conn->cipher_suite, &server_exts, &server_exts_len) != 1) { + error_print(); + return -1; + } + memcpy(server_random, random, 32); + memcpy(conn->session_id, session_id, session_id_len); + conn->session_id_len = session_id_len; + + if (conn->protocol != TLS_protocol_tls12) { + error_print(); + return -1; + } + if (tls_cipher_suite_in_list(conn->cipher_suite, + tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0])) != 1) { + error_print(); + return -1; + } + tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); + // 这个有一个独特的函数从扩展中读取ECDHE + if (tls13_server_hello_extensions_get(server_exts, server_exts_len, &server_ecdhe_public) != 1) { + error_print(); + return -1; + } + + + /* + generate handshake keys + uint8_t client_write_key[32] + uint8_t server_write_key[32] + uint8_t client_write_iv[12] + uint8_t server_write_iv[12] + */ + digest_init(&dgst_ctx, digest); + null_dgst_ctx = dgst_ctx;// null_dgst_ctx已经初始化了,这个是干什么的? + digest_update(&dgst_ctx, record + 5, recordlen - 5); // update ClientHello + digest_update(&dgst_ctx, enced_record + 5, enced_recordlen - 5); // update ServerHello + + sm2_ecdh(&client_ecdhe, &server_ecdhe_public, &server_ecdhe_public); + + /* [1] */ tls13_hkdf_extract(digest, zeros, psk, early_secret); + /* [5] */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); + /* [6] */ tls13_hkdf_extract(digest, (uint8_t *)&server_ecdhe_public, handshake_secret, handshake_secret); + /* [7] */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); + /* [8] */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); + /* [9] */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); + /* [10] */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); + + //[sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length) + //[sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length) + //[sender] in {server, client} + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + + // 后面的消息都是加密的了 + + // 3. recv {EncryptedExtensions} + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + if (tls13_record_get_handshake_encrypted_extensions(record) != 1) { + error_print(); + return -1; + } + + // 5. recv {CertififcateRequest*} or {Certificate} + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls_seq_num_incr(conn->server_seq_num); + + if (tls_record_get_handshake(record, &type, &data, &datalen) != 1) { + error_print(); + return -1; + } + if (type == TLS_handshake_certificate_request) { + tls_trace("<<<< CertificateRequest\n"); + + const uint8_t *request_context; + size_t request_context_len; + const uint8_t *cert_request_exts; + size_t cert_request_extslen; + + // 暂时不处理certificate_request数据 + if (tls13_record_get_handshake_certificate_request(record, + &request_context, &request_context_len, + &cert_request_exts, &cert_request_extslen) != 1) { + error_print(); + return -1; + } + + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + } else { + // 清空客户端签名密钥 + client_sign_key = NULL; // 指示不需要发送client Certificate + } + + + // 6. recv Server {Certificate} + + tls_trace(">>>> Server Certificate\n"); + tls13_record_trace(stderr, record, recordlen, 0, 0); + if (tls13_record_get_handshake_certificate(record, conn->server_certs, &conn->server_certs_len) != 1) { + error_print(); + return -1; + } + const uint8_t *cert; + size_t certlen; + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &server_sign_key) != 1) { + error_print(); + return -1; + } + + // 7. recv Server {CertificateVerify} + + tls_trace(">>>> {CertificateVerify}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls_seq_num_incr(conn->server_seq_num); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + if (tls13_record_get_handshake_certificate_verify(record, + &server_sign_algor, &server_sig, &server_siglen) != 1) { + error_print(); + return -1; + } + if (server_sign_algor != TLS_sig_sm2sig_sm3) { + error_print(); + return -1; + } + if (tls13_verify(&server_sign_key, &dgst_ctx, server_sig, server_siglen, 1) != 1) { + error_print(); + return -1; + } + + // use Transcript-Hash(Handshake Context, Certificate*, CertificateVerify*) + tls13_compute_verify_data(server_handshake_traffic_secret, + &dgst_ctx, verify_data, &verify_data_len); + + // 8. recv Server {Finished} + tls_trace(">>>> server {Finished}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls_seq_num_incr(conn->server_seq_num); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + if (tls13_record_get_handshake_finished(record, + &server_verify_data, &server_verify_data_len) != 1) { + error_print(); + return -1; + } + if (server_verify_data_len != verify_data_len + || memcmp(server_verify_data, verify_data, verify_data_len) != 0) { + error_print(); + return -1; + } + + // generate server_application_traffic_secret + // update server_write_key, server_write_iv + /* {12} */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + + + if (client_sign_key) { + int client_sign_algor; + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; + size_t siglen; + + // 9. send client {Certificate*} + tls_trace("<<<< client {Certificate}\n"); + if (tls13_record_set_handshake_certificate_from_pem(record, &recordlen, + client_certs_fp) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + + // 10. send client {CertificateVerify*} + tls_trace("<<<< client {CertificateVerify}\n"); + client_sign_algor = TLS_sig_sm2sig_sm3; + tls13_sign(client_sign_key, &dgst_ctx, sig, &siglen, 0); + if (tls13_record_set_handshake_certificate_verify(record, &recordlen, + client_sign_algor, sig, siglen) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + } + + // 11. send client {Finished} + + tls_trace("<<<< client {Finished}\n"); + if (tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, + verify_data, &verify_data_len) != 1) { + error_print(); + return -1; + } + if (tls_record_set_handshake_finished(record, &recordlen, verify_data, 32) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + + // generate client_application_traffic_secret + // update client_write_key, client_write_iv + + /* 11 */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); + tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + + tls_trace("++++ Connection established\n"); + return 1; +} + +int tls13_accept(TLS_CONNECT *conn, int port, + FILE *server_certs_fp, const SM2_KEY *server_sign_key, + FILE *client_cacerts_fp) +{ + uint8_t *record = conn->record; + size_t recordlen; + uint8_t enced_record[25600]; + size_t enced_recordlen = sizeof(enced_record); + + uint8_t client_random[32]; + uint8_t server_random[32]; + const uint8_t *client_ciphers; + size_t client_ciphers_len; + uint8_t exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t extslen; + + SM2_KEY server_ecdhe; + SM2_POINT client_ecdhe_public; + SM2_KEY client_sign_key; + const BLOCK_CIPHER *cipher; + const DIGEST *digest; + DIGEST_CTX dgst_ctx; + DIGEST_CTX null_dgst_ctx; + size_t padding_len; + + + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; + size_t siglen = sizeof(sig); + + uint8_t verify_data[32]; + size_t verify_data_len; + + const uint8_t *client_verify_data; + size_t client_verify_data_len; + + + size_t i; + + uint8_t client_write_key[16]; + uint8_t server_write_key[16]; + + uint8_t zeros[32] = {0}; + uint8_t psk[32] = {0}; + uint8_t early_secret[32]; + uint8_t binder_key[32]; + uint8_t handshake_secret[32]; + uint8_t client_handshake_traffic_secret[32]; + uint8_t server_handshake_traffic_secret[32]; + uint8_t client_application_traffic_secret[32]; + uint8_t server_application_traffic_secret[32]; + uint8_t master_secret[32]; + + + int sock; + struct sockaddr_in server_addr; + struct sockaddr_in client_addr; + socklen_t client_addrlen; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + error_print(); + return -1; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(port); + + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + error_print(); + return -1; + } + + error_puts("start listen ..."); + listen(sock, 5); + + memset(conn, 0, sizeof(*conn)); + + + + client_addrlen = sizeof(client_addr); + if ((conn->sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { + error_print(); + return -1; + } + + error_puts("connected\n"); + + + // 1. Recv ClientHello + + tls_trace(">>>> ClientHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); + tls_seq_num_incr(conn->client_seq_num); + + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *client_exts; + size_t client_exts_len; + + if (tls_record_get_handshake_client_hello(record, + &conn->protocol, &random, &session_id, &session_id_len, + &client_ciphers, &client_ciphers_len, &client_exts, &client_exts_len) != 1) { + error_print(); + return -1; + } + memcpy(client_random, random, 32); + memcpy(conn->session_id, session_id, session_id_len); + conn->session_id_len = session_id_len; + + if (conn->protocol != TLS_protocol_tls12 + || session_id_len != 32) { + error_print(); + return -1; + } + /* + for (i = 0; i < sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]); i++) { + if (tls_cipher_suite_in_list(tls13_ciphers[i], client_ciphers, client_ciphers_count) == 1) { + conn->cipher_suite = tls13_ciphers[i]; + break; + } + } + if (conn->cipher_suite == 0) { + error_puts("no common cipher_suite"); + return -1; + } + */ + + if (tls13_client_hello_extensions_get(exts, extslen, &client_ecdhe_public) != 1) { + error_print(); + return -1; + } + + tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); + digest_init(&dgst_ctx, digest); + null_dgst_ctx = dgst_ctx; + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + + // 2. Send ServerHello + + tls_trace("<<<< ServerHello\n"); + + rand_bytes(server_random, 32); + sm2_key_generate(&server_ecdhe); + tls13_server_hello_extensions_set(exts, &extslen, &(server_ecdhe.public_key), NULL); + + if (tls_record_set_handshake_server_hello(enced_record, &enced_recordlen, + conn->protocol, server_random, session_id, 32, + conn->cipher_suite, exts, extslen) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, enced_record, enced_recordlen, 0, 0); + + digest_update(&dgst_ctx, record + 5, recordlen - 5); + if (tls_record_send(record, recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + + + sm2_ecdh(&server_ecdhe, &client_ecdhe_public, &client_ecdhe_public); + + /* 1 */ tls13_hkdf_extract(digest, zeros, psk, early_secret); + /* 5 */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); + /* 6 */ tls13_hkdf_extract(digest, (uint8_t *)&client_ecdhe_public, handshake_secret, handshake_secret); + /* 7 */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); + /* 8 */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); + /* 9 */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); + /* 10 */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); + + // generate client_write_key, client_write_iv + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + + // generate server_write_key, server_write_iv + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + + + + // 3. Send {EncryptedExtensions} + + + tls_trace("<<<< {EncryptedExtensions}\n"); + tls13_record_set_handshake_encrypted_extensions(record, &recordlen, NULL, 0); // 不发送EncryptedExtensions扩展 + tls13_record_trace(stderr, record, recordlen, 0, 0); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + + + + + + // 4. Send {CertificateRequest*} + + if (client_cacerts_fp) { + + tls_trace("<<<< {CertificateRequest*}\n"); + uint8_t request_context[32]; + // TODO: 设置certificate_request中的extensions! + if (tls13_record_set_handshake_certificate_request(record, &recordlen, + request_context, 32, NULL, 0) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + } + + // 6. send server {Certificate} + + tls_trace("<<<< server {Certificate}\n"); + if (tls13_record_set_handshake_certificate_from_pem(record, &recordlen, server_certs_fp) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + + + if (tls_record_get_handshake_certificate(record, conn->server_certs, &conn->server_certs_len) != 1) { + error_print(); + return -1; + } + + + + // 7. Send {CertificateVerify} + + tls_trace("<<<< server {CertificateVerify}\n"); + tls13_sign(server_sign_key, &dgst_ctx, sig, &siglen, 1); + if (tls13_record_set_handshake_certificate_verify(record, &recordlen, + TLS_sig_sm2sig_sm3, sig, siglen) != 1) { + error_print(); + return -1; + } + + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + + + // 8. Send server {Finished} + + tls_trace("<<<< server {Finished}\n"); + + // compute server verify_data before digest_update() + tls13_compute_verify_data(server_handshake_traffic_secret, + &dgst_ctx, verify_data, &verify_data_len); + + if (tls13_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { + error_print(); + return -1; + } + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, record, recordlen, padding_len, + enced_record, &enced_recordlen) != 1) { + error_print(); + return -1; + } + + if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + + + // generate server_application_traffic_secret + // update server_write_key, server_write_iv + /* 12 */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); + block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + + + // 10. Recv client {Certificate*} + + if (client_cacerts_fp) { + + tls_trace(">>> client {Certificate*}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + if (tls13_record_get_handshake_certificate(record, + conn->client_certs, &conn->client_certs_len) != 1) { + error_print(); + return -1; + } + const uint8_t *cert; + size_t certlen; + if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &client_sign_key) != 1) { + error_print(); + return -1; + } + } + + // 11. Recv client {CertificateVerify*} + + if (client_cacerts_fp) { + + int client_sign_algor; + const uint8_t *client_sig; + size_t client_siglen; + + tls_trace(">>>> client {CertificateVerify*}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, enced_record, enced_recordlen, record, &recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + if (tls13_record_get_handshake_certificate_verify(record, &client_sign_algor, &client_sig, &client_siglen) != 1) { + error_print(); + return -1; + } + if (tls13_verify(&client_sign_key, &dgst_ctx, client_sig, client_siglen, 0) != 1) { + error_print(); + return -1; + } + } + + // 12. Recv client {Finished} + + tls_trace(">>>> client {Finished}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, enced_record, enced_recordlen, + record, &recordlen) != 1) { + error_print(); + return -1; + } + + tls_seq_num_incr(conn->client_seq_num); + if (tls13_record_get_handshake_finished(record, &client_verify_data, &client_verify_data_len) != 1) { + error_print(); + return -1; + } + if (tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len) != 1) { + error_print(); + return -1; + } + if (client_verify_data_len != verify_data_len + || memcmp(client_verify_data, verify_data, verify_data_len) != 0) { + error_print(); + return -1; + } + + tls_trace("Connection Established!\n\n"); + return 1; +} diff --git a/src/gcm.c b/src/gcm.c index 6c746cf8..144e6986 100644 --- a/src/gcm.c +++ b/src/gcm.c @@ -122,14 +122,17 @@ int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, uint8_t *out, size_t taglen, uint8_t *tag) { if (key->cipher == BLOCK_CIPHER_sm4()) { - sm4_gcm_encrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag); - return 1; + if (sm4_gcm_encrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { + error_print(); + return -1; + } } else if (key->cipher == BLOCK_CIPHER_aes128()) { - aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag); - return 1; + if (aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { + error_print(); + return -1; + } } - error_print(); - return -1; + return 1; } int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, @@ -137,10 +140,15 @@ int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *tag, size_t taglen, uint8_t *out) { if (key->cipher == BLOCK_CIPHER_sm4()) { - sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out); + if (sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { + error_print(); + return -1; + } } else if (key->cipher == BLOCK_CIPHER_aes128()) { - aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out); + if (aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { + error_print(); + return -1; + } } - error_print(); - return -1; + return 1; } diff --git a/src/gf128.c b/src/gf128.c index db4da42b..8e178247 100644 --- a/src/gf128.c +++ b/src/gf128.c @@ -58,6 +58,7 @@ #include #include #include +#include gf128_t gf128_zero(void) @@ -84,7 +85,6 @@ int gf128_equ_hex(gf128_t a, const char *s) return memcmp(bin1, bin2, sizeof(bin1)) == 0; } -// FIXME: 这个函数不支持struct void gf128_print_bits(gf128_t a) { int i; @@ -104,27 +104,47 @@ int gf128_print(FILE *fp, int fmt, int ind, const char *label, gf128_t a) uint8_t be[16]; int i; - printf("%s", label); + printf("%s: ", label); gf128_to_bytes(a, be); for (i = 0; i < 16; i++) { - printf("%02X", be[i]); + printf("%02x", be[i]); } printf("\n"); return 1; } +static uint64_t reverse_bits(uint64_t a) +{ + uint64_t r = 0; + int i; + + for (i = 0; i < 63; i++) { + r |= a & 1; + r <<= 1; + a >>= 1; + } + r |= a & 1; + return r; +} + gf128_t gf128_from_bytes(const uint8_t p[16]) { gf128_t r; - r.hi = GETU64(p); - r.lo = GETU64(p + 8); + + r.lo = GETU64(p); + r.hi = GETU64(p + 8); + + r.lo = reverse_bits(r.lo); + r.hi = reverse_bits(r.hi); return r; } void gf128_to_bytes(gf128_t a, uint8_t p[16]) { - PUTU64(p, a.hi); - PUTU64(p + 8, a.lo); + a.lo = reverse_bits(a.lo); + a.hi = reverse_bits(a.hi); + PUTU64(p, a.lo); + PUTU64(p + 8, a.hi); } gf128_t gf128_add(gf128_t a, gf128_t b) @@ -193,68 +213,3 @@ gf128_t gf128_mul2(gf128_t a) return r; } - -/* -gf128_t gf128_mul(gf128_t a, gf128_t b) -{ - const gf128_t mask = (gf128_t)1 << 127; - - gf128_t r = 0; - int i; - - for (i = 0; i < 128; i++) { - // r = r * 2 - if (r & mask) - r = (r << 1) ^ 0x87; - else r <<= 1; - - // if b[127-i] == 1, r = r + a - if (b & mask) - r ^= a; - b <<= 1; - } - return r; -} - -gf128_t gf128_add(gf128_t a, gf128_t b) -{ - return a ^ b; -} - -gf128_t gf128_mul2(gf128_t a) -{ - if (a & ((gf128_t)1 << 127)) - return (a << 1) ^ 0x87; - else return (a << 1); -} - -gf128_t gf128_reverse(gf128_t a) -{ - gf128_t r = 0; - int i; - - for (i = 0; i < 128; i++) { - r = (r << 1) | (a & 1); - a >>= 1; - } - return r; -} - -gf128_t gf128_from_bytes(const uint8_t p[16]) -{ - uint64_t hi = GETU64(p); - uint64_t lo = GETU64(p + 8); - gf128_t r = (gf128_t)hi << 64 | lo; - r = gf128_reverse(r); - return r; -} - -void gf128_to_bytes(gf128_t a, uint8_t p[16]) -{ - a = gf128_reverse(a); - uint64_t hi = a >> 64; - uint64_t lo = a; - PUTU64(p, hi); - PUTU64(p + 8, lo); -} -*/ diff --git a/src/gf128_gcc.c b/src/gf128_gcc.c new file mode 100644 index 00000000..a1cd1fed --- /dev/null +++ b/src/gf128_gcc.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1 + * A + B mod f(x) = a xor b + * A * 2 mod f(x) + */ + + +#include +#include +#include +#include +#include +#include + + +gf128_t gf128_mul(gf128_t a, gf128_t b) +{ + const gf128_t mask = (gf128_t)1 << 127; + + gf128_t r = 0; + int i; + + for (i = 0; i < 128; i++) { + // r = r * 2 + if (r & mask) + r = (r << 1) ^ 0x87; + else r <<= 1; + + // if b[127-i] == 1, r = r + a + if (b & mask) + r ^= a; + b <<= 1; + } + return r; +} + +gf128_t gf128_add(gf128_t a, gf128_t b) +{ + return a ^ b; +} + +gf128_t gf128_mul2(gf128_t a) +{ + if (a & ((gf128_t)1 << 127)) + return (a << 1) ^ 0x87; + else return (a << 1); +} + +gf128_t gf128_reverse(gf128_t a) +{ + gf128_t r = 0; + int i; + + for (i = 0; i < 128; i++) { + r = (r << 1) | (a & 1); + a >>= 1; + } + return r; +} + +gf128_t gf128_from_bytes(const uint8_t p[16]) +{ + uint64_t hi = GETU64(p); + uint64_t lo = GETU64(p + 8); + gf128_t r = (gf128_t)hi << 64 | lo; + r = gf128_reverse(r); + return r; +} + +void gf128_to_bytes(gf128_t a, uint8_t p[16]) +{ + a = gf128_reverse(a); + uint64_t hi = a >> 64; + uint64_t lo = a; + PUTU64(p, hi); + PUTU64(p + 8, lo); +} diff --git a/src/sm2_lib.c b/src/sm2_lib.c index 193450fd..d35c29c2 100644 --- a/src/sm2_lib.c +++ b/src/sm2_lib.c @@ -69,6 +69,8 @@ int sm2_do_sign_ex(const SM2_KEY *key, int fixed_outlen, const uint8_t dgst[32], SM2_BN r; SM2_BN s; + format_bytes(stderr, 0, 0, "sm2_do_sign_ex dgst", dgst, 32); + retry: sm2_bn_from_bytes(d, key->private_key); @@ -143,6 +145,8 @@ int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATUR SM2_BN x; SM2_BN t; + format_bytes(stderr, 0, 0, "sm2_do_verify dgst", dgst, 32); + // parse signature values sm2_bn_from_bytes(r, sig->r); //print_bn("r", r); sm2_bn_from_bytes(s, sig->s); //print_bn("s", s); diff --git a/src/tls.c b/src/tls.c index be7ab744..9f002fa3 100644 --- a/src/tls.c +++ b/src/tls.c @@ -118,6 +118,13 @@ void tls_array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size *outlen += datalen; } +/* +这几个函数要区分data = NULL, datalen = 0 和 data = NULL, datalen != 0的情况 +前者意味着数据为空,因此输出的就是一个长度 +后者意味着数据不为空,只是我们不想输出数据,只输出头部的长度,并且更新整个的输出长度。 这种情况应该避免! + +*/ + void tls_uint8array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) { tls_uint8_to_bytes((uint8_t)datalen, out, outlen); @@ -637,7 +644,6 @@ int tls_record_set_handshake(uint8_t *record, size_t *recordlen, error_print(); return -1; } - if (!tls_protocol_name(tls_record_protocol(record))) { error_print(); return -1; @@ -2310,11 +2316,9 @@ int tls_do_handshake(TLS_CONNECT *conn) case TLS_protocol_tls12: if (conn->is_client) return tls12_do_connect(conn); else return tls12_do_accept(conn); - /* case TLS_protocol_tls13: if (conn->is_client) return tls13_do_connect(conn); else return tls13_do_accept(conn); - */ } error_print(); return -1; diff --git a/src/tls12.c b/src/tls12.c index a598155b..2f768180 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -203,6 +203,27 @@ int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM return 1; } +/* + Client Server + + ClientHello --------> + ServerHello + Certificate + ServerKeyExchange + CertificateRequest* + <-------- ServerHelloDone + Certificate* + ClientKeyExchange + CertificateVerify* + [ChangeCipherSpec] + Finished --------> + [ChangeCipherSpec] + <-------- Finished + Application Data <-------> Application Data + + +*/ + int tls12_do_connect(TLS_CONNECT *conn) { int ret = -1; @@ -275,9 +296,14 @@ int tls12_do_connect(TLS_CONNECT *conn) size_t signature_algors_cnt = 1; client_exts_len = 0; + /* tls_exts_add_ec_point_formats(client_exts, &client_exts_len, sizeof(client_exts), ec_point_formats, ec_point_formats_cnt); tls_exts_add_supported_groups(client_exts, &client_exts_len, sizeof(client_exts), supported_groups, supported_groups_cnt); tls_exts_add_signature_algors(client_exts, &client_exts_len, sizeof(client_exts), signature_algors, signature_algors_cnt); + */ + + + if (tls_record_set_handshake_client_hello(record, &recordlen, conn->protocol, client_random, NULL, 0, @@ -332,7 +358,7 @@ int tls12_do_connect(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_unexpected_message); goto end; } - if (tls_process_server_exts(server_exts, server_exts_len, &ec_point_format, &supported_group, &signature_algor) != 1 + if (tls_process_server_hello_exts(server_exts, server_exts_len, &ec_point_format, &supported_group, &signature_algor) != 1 || ec_point_format < 0 || supported_group < 0 || signature_algor < 0) { @@ -780,7 +806,7 @@ int tls12_do_accept(TLS_CONNECT *conn) server_exts_len = 0; curve = TLS_curve_sm2p256v1; - tls_process_client_exts(client_exts, client_exts_len, server_exts, &server_exts_len, sizeof(server_exts)); + tls_process_client_hello_exts(client_exts, client_exts_len, server_exts, &server_exts_len, sizeof(server_exts)); diff --git a/src/tls13.c b/src/tls13.c index 17f53c2a..883b823c 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,6 +70,23 @@ #include #include +static const int tls13_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; +static size_t tls13_ciphers_count = sizeof(tls13_ciphers)/sizeof(int); + +/* +int tls13_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) +{ + // 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的 + // 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8) + format |= tls13_ciphers[0] << 8; + return tls_record_print(fp, record, recordlen, format, indent); +} +*/ + +static int tls13_client_hello_exts[] = { + TLS_extension_supported_versions, + TLS_extension_padding, +}; /* @@ -94,12 +111,17 @@ int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], uint8_t nonce[12]; uint8_t aad[5]; uint8_t *gmac; - uint8_t *mbuf = malloc(inlen + 256); // FIXME: update gcm_encrypt API + uint8_t *mbuf = NULL; // FIXME: update gcm_encrypt API size_t mlen, clen; + if (!(mbuf = malloc(inlen + 256))) { + error_print(); + return -1; + } + // nonce = (zeros|seq_num) xor (iv) - nonce[0] = nonce[1] = nonce[2] = 0; - memcpy(nonce + 3, seq_num, 8); + nonce[0] = nonce[1] = nonce[2] = nonce[3] = 0; + memcpy(nonce + 4, seq_num, 8); gmssl_memxor(nonce, nonce, iv, 12); // TLSInnerPlaintext @@ -111,16 +133,19 @@ int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], // aad = TLSCiphertext header aad[0] = TLS_record_application_data; - aad[1] = TLS_version_tls12_major; - aad[2] = TLS_version_tls12_minor; + aad[1] = 0x03; //TLS_protocol_tls12_major; + aad[2] = 0x03; //TLS_protocol_tls12_minor; aad[3] = clen >> 8; aad[4] = clen; gmac = out + mlen; if (gcm_encrypt(key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac) != 1) { error_print(); + free(mbuf); return -1; } + *outlen = clen; + free(mbuf); return 1; } @@ -135,14 +160,14 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], size_t i; // nonce = (zeros|seq_num) xor (iv) - nonce[0] = nonce[1] = nonce[2] = 0; - memcpy(nonce + 3, seq_num, 8); + nonce[0] = nonce[1] = nonce[2] = nonce[3] = 0; + memcpy(nonce + 4, seq_num, 8); gmssl_memxor(nonce, nonce, iv, 12); // aad = TLSCiphertext header aad[0] = TLS_record_application_data; - aad[1] = TLS_version_tls12_major; - aad[2] = TLS_version_tls12_minor; + aad[1] = 0x03; //TLS_protocol_tls12_major; + aad[2] = 0x03; //TLS_protocol_tls12_minor; aad[3] = inlen >> 8; aad[4] = inlen; @@ -153,11 +178,10 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], mlen = inlen - GHASH_SIZE; gmac = in + mlen; - if (gcm_decrypt(key, iv, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) { + if (gcm_decrypt(key, nonce, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) { error_print(); return -1; } - // remove padding, get record_type *record_type = 0; while (mlen--) { @@ -166,6 +190,7 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], break; } } + *outlen = mlen; if (!tls_record_type_name(*record_type)) { error_print(); return -1; @@ -173,10 +198,13 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], return 1; } +// 这个函数是不对的,在我们的一些情况下,加密的时候并不会组成完整的数据 int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len, uint8_t *enced_record, size_t *enced_recordlen) { + // 被加密的是握手消息或者是应用层数据 + if (tls13_gcm_encrypt(key, iv, seq_num, record[0], record + 5, recordlen - 5, padding_len, enced_record + 5, enced_recordlen) != 1) { @@ -184,9 +212,9 @@ int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], return -1; } - enced_record[0] = TLS_record_application_data; - enced_record[1] = TLS_version_tls12_major; - enced_record[2] = TLS_version_tls12_minor; + enced_record[0] = TLS_record_application_data; // 显然这个不太对啊 + enced_record[1] = 0x03; //TLS_protocol_tls12_major; + enced_record[2] = 0x03; //TLS_protocol_tls12_minor; enced_record[3] = (*enced_recordlen) >> 8; enced_record[4] = (*enced_recordlen); @@ -207,8 +235,8 @@ int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], return -1; } record[0] = record_type; - record[1] = TLS_version_tls12_major; - record[2] = TLS_version_tls12_minor; + record[1] = 0x03; //TLS_protocol_tls12_major; + record[2] = 0x03; //TLS_protocol_tls12_minor; record[3] = (*recordlen) >> 8; record[4] = (*recordlen); @@ -244,8 +272,8 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t pa } record[0] = TLS_record_application_data; - record[1] = TLS_version_tls12 >> 8; - record[2] = TLS_version_tls12 & 0xff; + record[1] = TLS_protocol_tls12 >> 8; + record[2] = TLS_protocol_tls12 & 0xff; record[3] = recordlen >> 8; record[4] = recordlen; recordlen += 5; @@ -278,7 +306,7 @@ int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen) seq_num = conn->server_seq_num; } - if (tls12_record_recv(record, &recordlen, conn->sock) != 1) { + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { error_print(); return -1; } @@ -362,62 +390,103 @@ int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGES return 1; } +static const uint8_t TLS13_client_context_str_and_zero[] = "TLS 1.3, client CertificateVerify"; +static const uint8_t TLS13_server_context_str_and_zero[] = "TLS 1.3, server CertificateVerify"; +static size_t TLS13_client_context_str_and_zero_size = sizeof(TLS13_client_context_str_and_zero); +static size_t TLS13_server_context_str_and_zero_size = sizeof(TLS13_server_context_str_and_zero); -/* -data to be signed in certificate_verify: - - A string that consists of octet 32 (0x20) repeated 64 times - - The context string - - A single 0 byte which serves as the separator - - The content to be signed -*/ -int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server) +int tls13_sign_certificate_verify(int tls_mode, + const SM2_KEY *key, const char *signer_id, size_t signer_id_len, + const DIGEST_CTX *tbs_dgst_ctx, + uint8_t *sig, size_t *siglen) { - uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; - uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; - - SM2_SIGN_CTX sm2_ctx; - DIGEST_CTX temp_dgst_ctx; + SM2_SIGN_CTX sign_ctx; uint8_t prefix[64]; - uint8_t *context_str = is_server ? server_context_str : client_context_str; - size_t context_str_len = sizeof(client_context_str); + const uint8_t *context_str_and_zero; + size_t context_str_and_zero_len; + DIGEST_CTX dgst_ctx; uint8_t dgst[64]; size_t dgstlen; memset(prefix, 0x20, 64); - temp_dgst_ctx = *dgst_ctx; - digest_finish(&temp_dgst_ctx, dgst, &dgstlen); - sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - sm2_sign_update(&sm2_ctx, prefix, 64); - sm2_sign_update(&sm2_ctx, context_str, context_str_len); - sm2_sign_update(&sm2_ctx, dgst, dgstlen); - sm2_sign_finish(&sm2_ctx, sig, siglen); + switch (tls_mode) { + case TLS_client_mode: + context_str_and_zero = TLS13_client_context_str_and_zero; + context_str_and_zero_len = TLS13_client_context_str_and_zero_size; + break; + case TLS_server_mode: + context_str_and_zero = TLS13_server_context_str_and_zero; + context_str_and_zero_len = TLS13_server_context_str_and_zero_size; + break; + default: + error_print(); + return -1; + } + dgst_ctx = *tbs_dgst_ctx; + digest_finish(&dgst_ctx, dgst, &dgstlen); + + format_bytes(stderr, 0, 0, "tls13_sign_certificate_verify dgst", dgst, dgstlen); + + sm2_sign_init(&sign_ctx, key, signer_id, signer_id_len); + sm2_sign_update(&sign_ctx, prefix, 64); + sm2_sign_update(&sign_ctx, context_str_and_zero, context_str_and_zero_len); + sm2_sign_update(&sign_ctx, dgst, dgstlen); + sm2_sign_finish(&sign_ctx, sig, siglen); + + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); return 1; } -int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server) +int tls13_verify_certificate_verify(int tls_mode, + const SM2_KEY *public_key, const char *signer_id, size_t signer_id_len, + const DIGEST_CTX *tbs_dgst_ctx, const uint8_t *sig, size_t siglen) { - uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; - uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; - int ret; - SM2_SIGN_CTX sm2_ctx; - DIGEST_CTX temp_dgst_ctx; + SM2_SIGN_CTX verify_ctx; uint8_t prefix[64]; + const uint8_t *context_str_and_zero; + size_t context_str_and_zero_len; + DIGEST_CTX dgst_ctx; uint8_t dgst[64]; size_t dgstlen; memset(prefix, 0x20, 64); - temp_dgst_ctx = *dgst_ctx; - digest_finish(&temp_dgst_ctx, dgst, &dgstlen); - sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); - sm2_verify_update(&sm2_ctx, prefix, 64); - sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str)); - sm2_verify_update(&sm2_ctx, dgst, dgstlen); - ret = sm2_verify_finish(&sm2_ctx, sig, siglen); + switch (tls_mode) { + case TLS_client_mode: + context_str_and_zero = TLS13_client_context_str_and_zero; + context_str_and_zero_len = TLS13_client_context_str_and_zero_size; + break; + case TLS_server_mode: + context_str_and_zero = TLS13_server_context_str_and_zero; + context_str_and_zero_len = TLS13_server_context_str_and_zero_size; + break; + default: + error_print(); + return -1; + } + dgst_ctx = *tbs_dgst_ctx; + digest_finish(&dgst_ctx, dgst, &dgstlen); + + format_bytes(stderr, 0, 0, "tls13_verify_certificate_verify dgst", dgst, dgstlen); + + sm2_verify_init(&verify_ctx, public_key, signer_id, signer_id_len); + sm2_verify_update(&verify_ctx, prefix, 64); + sm2_verify_update(&verify_ctx, context_str_and_zero, context_str_and_zero_len); + sm2_verify_update(&verify_ctx, dgst, dgstlen); + + format_bytes(stderr, 0, 0, "477", sig, siglen); + + if ((ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { + error_print(); + return -1; + } + if (ret != 1) { + error_print(); + } return ret; } @@ -463,250 +532,52 @@ Handshakes */ -int tls_ext_supported_versions_to_bytes(const int *versions, size_t versions_count, - uint8_t **out, size_t *outlen) +int tls13_client_hello_exts_set(uint8_t *exts, size_t *extslen, size_t maxlen, + const SM2_POINT *client_ecdhe_public) { - uint16_t ext_type = TLS_extension_supported_versions; - uint8_t versions_len = sizeof(uint16_t) * versions_count; - size_t i; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(1 + versions_len, out, outlen); - tls_uint8_to_bytes(versions_len, out, outlen); - for (i = 0; i < versions_count; i++) { - tls_uint16_to_bytes(versions[i], out, outlen); - } - return 1; -} - -int tls_ext_signature_algorithms_to_bytes(const int *algors, size_t algors_count, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_signature_algorithms; - uint16_t algors_len = sizeof(uint16_t) * algors_count; - size_t i; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(2 + algors_len, out, outlen); - tls_uint16_to_bytes(algors_len, out, outlen); - for (i = 0; i < algors_count; i++) { - tls_uint16_to_bytes(algors[i], out, outlen); - } - return 1; -} - -int tls_ext_supported_groups_to_bytes(const int *groups, size_t groups_count, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_supported_groups; - uint16_t groups_len = sizeof(uint16_t) * groups_count; - size_t i; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(2 + groups_len, out, outlen); - tls_uint16_to_bytes(groups_len, out, outlen); - for (i = 0; i < groups_count; i++) { - tls_uint16_to_bytes(groups[i], out, outlen); - } - return 1; -} - -int tls_ext_key_share_client_hello_to_bytes( - const SM2_POINT *sm2_point, const SM2_POINT *p256_point, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_key_share; - uint16_t client_shares_len = 0; - uint8_t sm2_key_exchange[65]; - uint8_t p256_key_exchange[65]; - - if (sm2_point) { - sm2_point_to_uncompressed_octets(sm2_point, sm2_key_exchange); - client_shares_len += 69; - } - if (p256_point) { - sm2_point_to_uncompressed_octets(p256_point, p256_key_exchange); - client_shares_len += 69; - } - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(2 + client_shares_len, out, outlen); - tls_uint16_to_bytes(client_shares_len, out, outlen); - if (sm2_point) { - tls_uint16_to_bytes(TLS_curve_sm2p256v1, out, outlen); - tls_uint16array_to_bytes(sm2_key_exchange, 65, out, outlen); - } - if (p256_point) { - tls_uint16_to_bytes(TLS_curve_secp256r1, out, outlen); - tls_uint16array_to_bytes(p256_key_exchange, 65, out, outlen); - } - return 1; -} - -int tls_ext_key_share_server_hello_to_bytes(const SM2_POINT *sm2_point, const SM2_POINT *p256_point, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_key_share; - uint16_t group; - uint8_t key_exchange[65]; - - if (sm2_point) { - group = TLS_curve_sm2p256v1; - sm2_point_to_uncompressed_octets(sm2_point, key_exchange); - } else if (p256_point) { - group = TLS_curve_secp256r1; - sm2_point_to_uncompressed_octets(p256_point, key_exchange); - } - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes(69, out, outlen); - tls_uint16_to_bytes(group, out, outlen); - tls_uint16array_to_bytes(key_exchange, 65, out, outlen); - return 1; -} - -/* -ClientHello Extensions: - supported_versions - supported_groups - signature_algorithms -*/ -int tls13_client_hello_extensions_set(uint8_t *exts, size_t *extslen, const SM2_POINT *sm2_point) -{ - uint8_t *p = exts; - int versions[] = { TLS_version_tls13 }; + int protocols[] = { TLS_protocol_tls13 }; int supported_groups[] = { TLS_curve_sm2p256v1 }; - int sign_algors[] = { TLS_sig_sm2sig_sm3 }; + int sig_algs[] = { TLS_sig_sm2sig_sm3 }; + size_t protocols_cnt = sizeof(protocols)/sizeof(int); + size_t supported_groups_cnt = sizeof(supported_groups)/sizeof(int); + size_t sig_algs_cnt = sizeof(sig_algs)/sizeof(int); + + + if (!exts || !extslen || !client_ecdhe_public) { + error_print(); + return -1; + } *extslen = 0; - tls_ext_supported_versions_to_bytes(versions, 1, &p, extslen); - tls_ext_supported_groups_to_bytes(supported_groups, 1, &p, extslen); - tls_ext_signature_algorithms_to_bytes(sign_algors, 1, &p, extslen); - tls_ext_key_share_client_hello_to_bytes(sm2_point, NULL, &p, extslen); + if (tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, NULL, extslen) != 1 + || tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, NULL, extslen) != 1 + || tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, NULL, extslen) != 1 + || tls13_client_key_share_ext_to_bytes(client_ecdhe_public, NULL, extslen) != 1) { + error_print(); + return -1; + } + if (*extslen > maxlen) { + error_print(); + return -1; + } + *extslen = 0; + tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, &exts, extslen); + tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, &exts, extslen); + tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, &exts, extslen); + tls13_client_key_share_ext_to_bytes(client_ecdhe_public, &exts, extslen); return 1; } -int tls_ext_supported_groups_match(const uint8_t *ext_data, size_t ext_datalen, int group) +int tls13_process_client_hello_exts(const uint8_t *exts, size_t extslen, + const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, + uint8_t *server_exts, size_t *server_exts_len, size_t server_exts_maxlen) { - const uint8_t *p; size_t len; - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || ext_datalen > 0) { - error_print(); - return -1; - } - while (len) { - uint16_t supported_group; - if (tls_uint16_from_bytes(&supported_group, &p, &len) != 1) { - error_print(); - return -1; - } - if (supported_group == group) { - return 1; - } - } - error_print(); - return -1; -} -int tls_ext_signature_algorithms_match(const uint8_t *ext_data, size_t ext_datalen, int algor) -{ - const uint8_t *p; - size_t len; + len = *server_exts_len; + server_exts += *server_exts_len; - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || ext_datalen > 0) { - error_print(); - return -1; - } - while (len) { - uint16_t supported_algor; - if (tls_uint16_from_bytes(&supported_algor, &p, &len) != 1) { - error_print(); - return -1; - } - if (supported_algor == algor) { - return 1; - } - } - error_print(); - return -1; -} - -int tls_ext_supported_versions_match(const uint8_t *ext_data, size_t ext_datalen, int version) -{ - const uint8_t *p; - size_t len; - - if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || ext_datalen > 0) { - error_print(); - return -1; - } - while (len) { - uint16_t supported_version; - if (tls_uint16_from_bytes(&supported_version, &p, &len) != 1) { - error_print(); - return -1; - } - if (supported_version == version) { - return 1; - } - } - error_print(); - return -1; -} - -int tls_ext_key_share_client_hello_get(const uint8_t *ext_data, size_t ext_datalen, - int prefered_curve, int *curve, SM2_POINT *point) -{ - const uint8_t *client_shares; - size_t client_shares_len; - - *curve = 0; - - if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &ext_data, &ext_datalen) != 1 - || ext_datalen > 0) { - error_print(); - return -1; - } - while (client_shares_len) { - uint16_t group; - const uint8_t *key_exchange; - size_t key_exchange_len; - - if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1 - || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) { - error_print(); - return -1; - } - switch (group) { - case TLS_curve_sm2p256v1: - case TLS_curve_secp256r1: - if (key_exchange_len != 65) { - error_print(); - return -1; - } - if (sm2_point_from_octets(point, key_exchange, key_exchange_len) != 1) { - error_print(); - return -1; - } - *curve = group; - if (prefered_curve == group) { - return 1; - } - break; - } - } - - error_print(); - return -1; -} - -int tls13_client_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_POINT *client_ecdhe_public) -{ - /* while (extslen) { uint16_t ext_type; const uint8_t *ext_data; @@ -720,27 +591,35 @@ int tls13_client_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_P switch (ext_type) { case TLS_extension_supported_groups: - if (sm2_point && tls_ext_supported_groups_match(ext_data, ext_datalen, TLS_curve_sm2p256v1)) { - } else if (p256_point && tls_ext_supported_groups_match(ext_data, ext_datalen, TLS_curve_secp256r1)) { + if (tls_process_client_supported_groups(ext_data, ext_datalen, NULL, &len) != 1 + || len > server_exts_maxlen) { error_print(); return -1; } + tls_process_client_supported_groups(ext_data, ext_datalen, &server_exts, server_exts_len); break; case TLS_extension_signature_algorithms: - if (sm2_point && tls_ext_signature_algorithms_match(ext_data, ext_datalen, TLS_sig_ecdsa_secp256r1_sha256)) { - } else if (p256_point && tls_ext_signature_algorithms_match(ext_data, ext_datalen, TLS_sig_sm2sig_sm3)) { - } else { + if (tls_process_client_signature_algorithms(ext_data, ext_datalen, NULL, &len) != 1 + || len > server_exts_maxlen) { error_print(); return -1; } + tls_process_client_signature_algorithms(ext_data, ext_datalen, &server_exts, server_exts_len); break; case TLS_extension_supported_versions: - if (tls_ext_supported_versions_match(ext_data, ext_datalen, TLS_version_tls13) != 1) { + if (tls13_process_client_supported_versions(ext_data, ext_datalen, NULL, &len) != 1 + || len > server_exts_maxlen) { error_print(); return -1; } + tls13_process_client_supported_versions(ext_data, ext_datalen, &server_exts, server_exts_len); break; case TLS_extension_key_share: + if (tls13_process_client_key_share(ext_data, ext_datalen, server_ecdhe_key, client_ecdhe_public, &server_exts, server_exts_len) != 1 + || len > server_exts_maxlen) { + error_print(); + return -1; + } break; default: @@ -749,19 +628,6 @@ int tls13_client_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_P } } - */ - return 1; -} - -int tls13_server_hello_extensions_set(uint8_t *exts, size_t *extslen, - const SM2_POINT *sm2_point, const SM2_POINT *p256_point) -{ - uint8_t *p = exts; - int version = TLS_version_tls13; - - *extslen = 0; - tls_ext_supported_versions_to_bytes(&version, 1, &p, extslen); - tls_ext_key_share_server_hello_to_bytes(sm2_point, p256_point, &p, extslen); return 1; } @@ -798,6 +664,7 @@ int tls_client_key_shares_from_bytes(SM2_POINT *sm2_point, const uint8_t **in, s return 1; } +// 这个函数不是太正确,应该也是一个process int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_POINT *sm2_point) { uint16_t version; @@ -818,20 +685,21 @@ int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_P error_print(); return -1; } - if (version != TLS_version_tls13) { + if (version != TLS_protocol_tls13) { error_print(); return -1; } break; case TLS_extension_key_share: - if (tls_client_key_shares_from_bytes(sm2_point, &ext_data, &ext_datalen) != 1) { + if (tls13_process_server_key_share(ext_data, ext_datalen, sm2_point) != 1) { error_print(); return -1; } break; - default: - error_print(); - return -1; + //default: + // FIXME: 还有几个扩展没有处理! + //error_print(); + //return -1; } } return 1; @@ -855,15 +723,48 @@ static int tls13_encrypted_exts[] = { TLS_extension_early_data, }; -int tls13_record_set_handshake_encrypted_extensions(uint8_t *record, size_t *recordlen, - const uint8_t *exts_data, size_t exts_datalen) +int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen) +{ + const uint8_t *exts; + size_t extslen; + + format_print(fp, fmt, ind, "extensions\n"); + ind += 4; + + if (tls_uint16array_from_bytes(&exts, &extslen, &data, &datalen) != 1) { + error_print(); + return -1; + } + if (exts) { + tls13_extensions_print(fp, fmt, ind, TLS_handshake_encrypted_extensions, exts, extslen); + } + if (tls_length_is_zero(datalen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_record_set_handshake_encrypted_extensions(uint8_t *record, size_t *recordlen) { int type = TLS_handshake_encrypted_extensions; uint8_t *p = record + 5 + 4; size_t len = 0; + uint8_t exts[128]; + size_t extslen = 0; + uint8_t *pexts = exts; + const int supported_groups[] = { TLS_curve_sm2p256v1 }; - tls_uint16array_to_bytes(exts_data, exts_datalen, &p, &len); + tls_supported_groups_ext_to_bytes(supported_groups, sizeof(supported_groups)/sizeof(int), &pexts, &extslen); + + format_bytes(stderr, 0, 0, "extensions", exts, extslen); + + tls_uint16array_to_bytes(exts, extslen, &p, &len); tls_record_set_handshake(record, recordlen, type, NULL, len); + + + format_bytes(stderr, 0, 0, "encrypted_ext", record, *recordlen); + return 1; } @@ -885,8 +786,9 @@ int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record) } // 当前实现不需要在EncryptedExtensions提供扩展 if (exts_datalen) { - error_print(); - return -1; + // FIXME: 实际上supported_groups是放在这里的,应该加以处理 + //error_print(); + //return -1; } return 1; } @@ -904,6 +806,8 @@ struct { SignatureScheme algorithm; opaque signature<0..2^16-1>; } CertificateVerify; + +注意:TLS 1.2中只有RAW signature, 也就是没有经过uint16array封装的,这其实不太符合TLS的设计逻辑 */ int tls13_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, int sign_algor, const uint8_t *sig, size_t siglen) @@ -939,105 +843,295 @@ int tls13_record_get_handshake_certificate_verify(const uint8_t *record, tls_uint16_from_bytes((uint16_t *)sign_algor, &p, &len); tls_uint16array_from_bytes(sig, siglen, &p, &len); - return 1; } + /* struct { opaque certificate_request_context<0..2^8-1>; Extension extensions<2..2^16-1>; } CertificateRequest; + +certificate_request_context 用于 Post-handshake Authentication,否则应该长度为0 + */ static int tls13_certificate_request_exts[] = { + TLS_extension_signature_algorithms, // 必须包含 TLS_extension_status_request, - TLS_extension_signature_algorithms, TLS_extension_signed_certificate_timestamp, TLS_extension_certificate_authorities, TLS_extension_oid_filters, TLS_extension_signature_algorithms_cert, }; -int tls13_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, - const uint8_t *req_context, size_t req_context_len, - const uint8_t *exts, size_t extslen) -{ - int type = TLS_handshake_certificate_request; - uint8_t *p = record + 5 + 4; - size_t len = 0; - int sign_algors[] = { TLS_sig_sm2sig_sm3, TLS_sig_ecdsa_secp256r1_sha256 }; - size_t sign_algors_count = sizeof(sign_algors)/sizeof(sign_algors[0]); - tls_ext_signature_algorithms_to_bytes(sign_algors, 2, NULL, &extslen); - tls_uint8array_to_bytes(req_context, req_context_len, &p, &len); - tls_uint16_to_bytes(extslen, &p, &len); - tls_ext_signature_algorithms_to_bytes(sign_algors, sign_algors_count, &p, &len); - tls_record_set_handshake(record, recordlen, type, NULL, len); - - return 1; -} - -int tls13_record_get_handshake_certificate_request(const uint8_t *record, - const uint8_t **req_context, size_t *req_context_len, - const uint8_t **exts, size_t *extslen) -{ - - return 1; -} /* -struct { - opaque cert_data<1..2^24-1>; - Extension extensions<0..2^16-1>; -} CertificateEntry; - struct { opaque certificate_request_context<0..2^8-1>; - CertificateEntry certificate_list<0..2^24-1>; -} TLS13Certificate; + Extension extensions<2..2^16-1>; +} CertificateRequest; + +extensiosns: + Extension signature_algorithms MUST be specified */ +int tls13_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, + const uint8_t *request_context, size_t request_context_len, + const uint8_t *exts, size_t extslen) +{ + int type = TLS_handshake_certificate_request; + uint8_t *data; + size_t datalen = 0; + + if (!record || !recordlen) { + error_print(); + return -1; + } + data = tls_handshake_data(tls_record_data(record)); + tls_uint8array_to_bytes(request_context, request_context_len, &data, &datalen); + tls_uint16array_to_bytes(exts, extslen, &data, &datalen); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + return 1; +} + +int tls13_record_set_handshake_certificate_request_default(uint8_t *record, size_t *recordlen) +{ + int sig_algs[] = { TLS_sig_sm2sig_sm3 }; + uint8_t exts[256]; + uint8_t *p = exts; + size_t extslen = 0; + + tls_signature_algorithms_ext_to_bytes(sig_algs, sizeof(sig_algs)/sizeof(int), &p, &extslen); + tls13_record_set_handshake_certificate_request(record, recordlen, NULL, 0, exts, extslen); + return 1; +} + +int tls13_record_get_handshake_certificate_request(const uint8_t *record, + const uint8_t **requst_context, size_t *request_context_len, + const uint8_t **exts, size_t *exts_len) +{ + int type; + const uint8_t *p; + size_t len; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate_request) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(requst_context, request_context_len, &p, &len) != 1 + || tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1 + || tls_length_is_zero(*exts_len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} static const int tls13_handshake_certificate_exts[] = { TLS_extension_status_request, TLS_extension_signed_certificate_timestamp, }; +/* +enum { X509(0), RawPublicKey(2), (255) } CertificateType; -// TODO: 当前未设置CertificateEntry.extensions -int tls13_record_set_handshake_certificate_from_pem(uint8_t *record, size_t *recordlen, FILE *fp) +struct { + select (certificate_type) { + case RawPublicKey: opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; -- TLS 1.3可以只传公钥不传证书 + case X509: opaque cert_data<1..2^24-1>; + }; + Extension extensions<0..2^16-1>; +} CertificateEntry; + +struct { + opaque certificate_request_context<0..2^8-1>; -- 用于客户端证书,服务器证书该域长度为0 + CertificateEntry certificate_list<0..2^24-1>; +} Certificate; + +TLS 1.3 Certificate: + + * TLS 1.3 支持发送公钥,可以去掉嵌入式环境的证书传输开销 + * TLS 1.3 的证书链中增加了 certificate_request_context + 用于客户端发送证书时标识context,服务器端的证书中该域的长度为0 + * 证书链中每个证书都有一个独立的扩展域,TLS 1.2 中的证书相关扩展移至此处 + +Extensions in client Certificate MUST from ClientHello +Extensions in server Certificate MUST from CertificateRequest +Entensions apply to entire chain SHOULD be in the first CertificateEntry + +目前CertificateEntry中的扩展主要用于服务器证书的验证 +客户端在ClientHello中可以包含status_request 和 signed_certificate_timestamp +让服务器提供 OCSP 的状态证明和时间戳信息 +服务器则在证书消息的每个证书否面附带这两个扩展,提供相关信息 + +在 RFC 8446 (TLS 1.3) 中还没有涉及客户端证书的具体扩展 +但是客户端在提供客户端证书时,应该响应服务器CertificateRequest消息中的扩展 + +目前GmSSLv3还不支持这两个证书扩展的生成,但是提供解析和显示 + +Valid extensions for server certificates: + TLS_extension_status_request (5) + TLS_extension_signed_certificate_timestamp (18) +*/ + +int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen) { - int type = TLS_handshake_certificate; - uint8_t *data = record + 5 + 4; - uint8_t *certs = data + 3; - size_t datalen, certslen = 0; + const uint8_t *p; + size_t len; - for (;;) { - int ret; - uint8_t cert[1024]; - size_t certlen; + if (tls_uint8array_from_bytes(&p, &len, &cert, &certlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "certificate_request_context", p, len); - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), fp) < 0) { + format_print(fp, fmt, ind, "certificate_list\n"); + ind += 4; + if (tls_uint24array_from_bytes(&p, &len, &cert, &certlen) != 1) { + error_print(); + return -1; + } + while (len) { + const uint8_t *cert_data; + size_t cert_data_len; + const uint8_t *exts; + size_t extslen; + + if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &p, &len) != 1 + || tls_uint16array_from_bytes(&exts, &extslen, &p, &len) != 1) { error_print(); return -1; - } else if (!ret) { - break; } - - tls_uint24array_to_bytes(cert, certlen, &certs, &certslen); - x509_cert_print(stderr, 0, 0, "Certificate", cert, certlen); + if (!cert_data) { + error_print(); + return -1; + } + x509_cert_print(fp, fmt, ind, "cert_data", cert_data, cert_data_len); + tls13_extensions_print(fp, fmt, ind, TLS_handshake_certificate, exts, extslen); } - datalen = certslen; - tls_uint24_to_bytes((uint24_t)certslen, &data, &datalen); - tls_record_set_handshake(record, recordlen, type, NULL, datalen); return 1; } -int tls13_record_get_handshake_certificate(const uint8_t *record, uint8_t *data, size_t *datalen) +int tls13_certificate_list_to_bytes(const uint8_t *certs, size_t certslen, + uint8_t **out, size_t *outlen) +{ + uint8_t *p = NULL; + size_t cert_list_len = 0; + + if (out && *out) { + p = (*out) + tls_uint24_size(); + } + while (certslen) { + const uint8_t *cert; + size_t certlen; + const uint8_t *entry_exts = NULL; + size_t entry_exts_len = 0; + + if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + tls_uint24array_to_bytes(cert, certlen, &p, &cert_list_len); + tls_uint16array_to_bytes(entry_exts, entry_exts_len, &p, &cert_list_len); + + } + tls_uint24array_to_bytes(NULL, cert_list_len, out, outlen); + return 1; +} + +int tls13_process_certificate_list(const uint8_t *cert_list, size_t cert_list_len, + uint8_t *certs, size_t *certs_len) +{ + *certs_len = 0; + + while (cert_list_len) { + const uint8_t *cert_data; + size_t cert_data_len; + const uint8_t *exts; + size_t exts_len; + const uint8_t *cert; + size_t cert_len; + + if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &cert_list, &cert_list_len) != 1 + || tls_uint16array_from_bytes(&exts, &exts_len, &cert_list, &cert_list_len) != 1) { + error_print(); + return -1; + } + if (x509_cert_from_der(&cert, &cert_len, &cert_data, &cert_data_len) != 1 + || asn1_length_is_zero(cert_data_len) != 1 + || x509_cert_to_der(cert, cert_len, &certs, certs_len) != 1) { + error_print(); + return -1; + } + + while (exts_len) { + int ext_type; + const uint8_t *ext_data; + size_t ext_data_len; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_data_len, &exts, &exts_len) != 1) { + error_print(); + return -1; + } + switch (ext_type) { + case TLS_extension_status_request: + case TLS_extension_signed_certificate_timestamp: + error_print(); + return -1; + default: + error_print(); + return -1; + } + } + } + return 1; +} + +int tls13_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, + const uint8_t *request_context, size_t request_context_len, + const uint8_t *certs, size_t certslen) +{ + int type = TLS_handshake_certificate; + uint8_t *data; + size_t datalen; + + if (!record || !recordlen || !certs || !certslen) { + error_print(); + return -1; + } + + datalen = 0; + tls_uint8array_to_bytes(request_context, request_context_len, NULL, &datalen); + tls13_certificate_list_to_bytes(certs, certslen, NULL, &datalen); + if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) { + error_print(); + return -1; + } + + data = tls_handshake_data(tls_record_data(record)); + datalen = 0; + tls_uint8array_to_bytes(request_context, request_context_len, &data, &datalen); + tls13_certificate_list_to_bytes(certs, certslen, &data, &datalen); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + + return 1; +} + +int tls13_record_get_handshake_certificate(const uint8_t *record, + const uint8_t **cert_request_context, size_t *cert_request_context_len, + const uint8_t **cert_list, size_t *cert_list_len) { int type; - const uint8_t *cp; + const uint8_t *p; + size_t len; - if (tls_record_get_handshake(record, &type, &cp, datalen) != 1) { + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { error_print(); return -1; } @@ -1045,16 +1139,21 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, uint8_t *data, error_print(); return -1; } - - // 这里我还是要接收一下Extensions - memcpy(data, cp, *datalen); + if (tls_uint8array_from_bytes(cert_request_context, cert_request_context_len, &p, &len) != 1 + || tls_uint24array_from_bytes(cert_list, cert_list_len, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (*cert_list == NULL) { + error_print(); + return -1; + } return 1; } - - /* finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) @@ -1109,7 +1208,6 @@ int tls13_padding_len_rand(size_t *padding_len) return 1; } -static const int tls13_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; int tls13_cipher_suite_get(int cipher_suite, const DIGEST **digest, const BLOCK_CIPHER **cipher) @@ -1174,6 +1272,13 @@ Auth | {CertificateVerify*} [Application Data] <-------> [Application Data] +TLS 1.3的区别: + + * 首先在最开始的握手阶段就协商好了密钥,因此握手之后传输的就是加密消息了 + * 因此在第二阶段,双方不再发送ServerKeyExchange和ClientKeyExchange + * 服务器先发送CertificateRequest,再发送Certificate + * 没有ChangeCipherSpec了 + * 在握手阶段就需要加密,并且Certificate也在其中,因此需要格外的大的密文数据缓冲 0 | @@ -1225,13 +1330,12 @@ Auth | {CertificateVerify*} */ -int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *server_cacerts_fp, - FILE *client_certs_fp, const SM2_KEY *client_sign_key) +int tls13_do_connect(TLS_CONNECT *conn) { uint8_t *record = conn->record; + uint8_t *enced_record = conn->enced_record; size_t recordlen; - uint8_t enced_record[256]; size_t enced_recordlen; @@ -1239,11 +1343,25 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve const uint8_t *data; size_t datalen; + int protocol; uint8_t client_random[32]; uint8_t server_random[32]; - uint8_t session_id[32]; - uint8_t exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t extslen; + int cipher_suite; + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + + int protocols[] = { TLS_protocol_tls13 }; + int supported_groups[] = { TLS_curve_sm2p256v1 }; + int sign_algors[] = { TLS_sig_sm2sig_sm3 }; + + uint8_t client_exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t client_exts_len; + const uint8_t *server_exts; + size_t server_exts_len; + + + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; size_t siglen = sizeof(sig); uint8_t verify_data[32]; @@ -1258,9 +1376,10 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve SM2_KEY client_ecdhe; SM2_POINT server_ecdhe_public; SM2_KEY server_sign_key; - const DIGEST *digest = NULL; - DIGEST_CTX dgst_ctx; - DIGEST_CTX null_dgst_ctx; + + const DIGEST *digest = DIGEST_sm3(); + DIGEST_CTX dgst_ctx; // secret generation过程中需要ClientHello等数据输入的 + DIGEST_CTX null_dgst_ctx; // secret generation过程中不需要握手数据的 const BLOCK_CIPHER *cipher = NULL; size_t padding_len; @@ -1276,79 +1395,74 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve uint8_t client_write_key[16]; uint8_t server_write_key[16]; - struct sockaddr_in server; - server.sin_addr.s_addr = inet_addr(hostname); - server.sin_family = AF_INET; - server.sin_port = htons(port); + uint8_t *p; - - if ((conn->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - error_print(); - return -1; - } - - - if (connect(conn->sock, (struct sockaddr *)&server , sizeof(server)) < 0) { - error_print(); - return -1; - } - conn->is_client = 1; - tls_record_set_version(enced_record, TLS_version_tls12); - - + tls_record_set_protocol(enced_record, TLS_protocol_tls12); + digest_init(&dgst_ctx, digest); + null_dgst_ctx = dgst_ctx;// null_dgst_ctx已经初始化了,这个是干什么的? // 1. send ClientHello - - tls_trace("<<<< ClientHello\n"); - tls_record_set_version(record, TLS_version_tls12); - rand_bytes(client_random, 32); - rand_bytes(session_id, 32); + tls_trace("send ClientHello\n"); + tls_record_set_protocol(record, TLS_protocol_tls12); + rand_bytes(client_random, 32); // TLS 1.3 Random 不再包含 UNIX Time sm2_key_generate(&client_ecdhe); - tls13_client_hello_extensions_set(exts, &extslen, &(client_ecdhe.public_key)); + tls13_client_hello_exts_set(client_exts, &client_exts_len, sizeof(client_exts), &(client_ecdhe.public_key)); + tls_record_set_handshake_client_hello(record, &recordlen, - TLS_version_tls12, client_random, session_id, 32, + TLS_protocol_tls12, client_random, NULL, 0, tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]), - exts, extslen); - tls_record_print(stderr, record, recordlen, 0, 0); + client_exts, client_exts_len); + tls13_record_trace(stderr, record, recordlen, 0, 0); if (tls_record_send(record, recordlen, conn->sock) != 1) { error_print(); return -1; } tls_seq_num_incr(conn->client_seq_num); + digest_update(&dgst_ctx, record + 5, recordlen - 5); // 2. recv ServerHello - - tls_trace(">>>> ServerHello\n"); - if (tls12_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + tls_trace("recv ServerHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { error_print(); return -1; } - tls_record_print(stderr, enced_record, enced_recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls_seq_num_incr(conn->server_seq_num); - if (tls_record_get_handshake_server_hello(enced_record, - &conn->version, server_random, conn->session_id, &conn->session_id_len, - &conn->cipher_suite, exts, &extslen) != 1) { + + if (tls_record_get_handshake_server_hello(record, + &protocol, &random, &session_id, &session_id_len, + &cipher_suite, &server_exts, &server_exts_len) != 1) { error_print(); return -1; } - if (conn->version != TLS_version_tls12) { + + + memcpy(server_random, random, 32); + memcpy(conn->session_id, session_id, session_id_len); + conn->session_id_len = session_id_len; + + if (protocol != TLS_protocol_tls12) { error_print(); return -1; } - if (tls_cipher_suite_in_list(conn->cipher_suite, + if (tls_cipher_suite_in_list(cipher_suite, tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0])) != 1) { error_print(); return -1; } + conn->cipher_suite = cipher_suite; tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); - if (tls13_server_hello_extensions_get(exts, extslen, &server_ecdhe_public) != 1) { + // 这个有一个独特的函数从扩展中读取ECDHE + if (tls13_server_hello_extensions_get(server_exts, server_exts_len, &server_ecdhe_public) != 1) { error_print(); return -1; } + conn->protocol = TLS_protocol_tls13; // 这个位置对吗? + /* generate handshake keys @@ -1357,21 +1471,22 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve uint8_t client_write_iv[12] uint8_t server_write_iv[12] */ - digest_init(&dgst_ctx, digest); - null_dgst_ctx = dgst_ctx; - digest_update(&dgst_ctx, record + 5, recordlen - 5); // update ClientHello - digest_update(&dgst_ctx, enced_record + 5, enced_recordlen - 5); // update ServerHello + digest_update(&dgst_ctx, record + 5, recordlen - 5); // update ServerHello sm2_ecdh(&client_ecdhe, &server_ecdhe_public, &server_ecdhe_public); - /* 1 */ tls13_hkdf_extract(digest, zeros, psk, early_secret); - /* 5 */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); - /* 6 */ tls13_hkdf_extract(digest, (uint8_t *)&server_ecdhe_public, handshake_secret, handshake_secret); - /* 7 */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); - /* 8 */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); - /* 9 */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); - /* 10 */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); + /* [1] */ tls13_hkdf_extract(digest, zeros, psk, early_secret); + /* [5] */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); + /* [6] */ tls13_hkdf_extract(digest, (uint8_t *)&server_ecdhe_public, handshake_secret, handshake_secret); + /* [7] */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); + /* [8] */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); + /* [9] */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); + /* [10] */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); + + //[sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length) + //[sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length) + //[sender] in {server, client} tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); @@ -1379,18 +1494,31 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + + format_bytes(stderr, 0, 0, "client_write_key", client_write_key, 16); + format_bytes(stderr, 0, 0, "server_write_key", server_write_key, 16); + format_bytes(stderr, 0, 0, "client_write_iv", conn->client_write_iv, 12); + format_bytes(stderr, 0, 0, "server_write_iv", conn->server_write_iv, 12); + + + + // 后面的消息都是加密的了 + // 3. recv {EncryptedExtensions} - if (tls12_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + printf("recv {EncryptedExtensions}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { error_print(); return -1; } + format_bytes(stderr, 0, 0, "{EncryptedExtensions}", enced_record, enced_recordlen); + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, conn->server_seq_num, enced_record, enced_recordlen, record, &recordlen) != 1) { error_print(); return -1; } - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); digest_update(&dgst_ctx, record + 5, recordlen - 5); tls_seq_num_incr(conn->server_seq_num); @@ -1400,7 +1528,7 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve } // 5. recv {CertififcateRequest*} or {Certificate} - if (tls12_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { error_print(); return -1; } @@ -1410,7 +1538,7 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve error_print(); return -1; } - tls_record_print(stderr, record, recordlen, 0, 0); + digest_update(&dgst_ctx, record + 5, recordlen - 5); tls_seq_num_incr(conn->server_seq_num); if (tls_record_get_handshake(record, &type, &data, &datalen) != 1) { @@ -1447,21 +1575,37 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve digest_update(&dgst_ctx, record + 5, recordlen - 5); } else { + conn->client_certs_len = 0; // 清空客户端签名密钥 - client_sign_key = NULL; // 指示不需要发送client Certificate + //client_sign_key = NULL; // 指示不需要发送client Certificate } // 6. recv Server {Certificate} + tls_trace("recv Server {Certificate}\n"); + tls13_record_trace(stderr, record, recordlen, 0, 0); - tls_trace(">>>> Server Certificate\n"); - tls_record_print(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_certificate(record, conn->server_certs, &conn->server_certs_len) != 1) { + const uint8_t *request_context; // 这个在什么情况下用到? + size_t request_context_len; + const uint8_t *cert_list; + size_t cert_list_len; + + if (tls13_record_get_handshake_certificate(record, + &request_context, &request_context_len, + &cert_list, &cert_list_len) != 1) { error_print(); return -1; } - if (tls_certificate_get_public_keys(conn->server_certs, conn->server_certs_len, - &server_sign_key, NULL) != 1) { + + if (tls13_process_certificate_list(cert_list, cert_list_len, conn->server_certs, &conn->server_certs_len) != 1) { + error_print(); + return -1; + } + + const uint8_t *cert; + size_t certlen; + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &server_sign_key) != 1) { error_print(); return -1; } @@ -1469,7 +1613,7 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve // 7. recv Server {CertificateVerify} tls_trace(">>>> {CertificateVerify}\n"); - if (tls12_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { error_print(); return -1; } @@ -1479,9 +1623,7 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve error_print(); return -1; } - tls_record_print(stderr, record, recordlen, 0, 0); - tls_seq_num_incr(conn->server_seq_num); - digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls13_record_trace(stderr, record, recordlen, 0, 0); if (tls13_record_get_handshake_certificate_verify(record, &server_sign_algor, &server_sig, &server_siglen) != 1) { @@ -1492,18 +1634,23 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve error_print(); return -1; } - if (tls13_verify(&server_sign_key, &dgst_ctx, server_sig, server_siglen, 1) != 1) { + if (tls13_verify_certificate_verify(TLS_server_mode, &server_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, &dgst_ctx, server_sig, server_siglen) != 1) { error_print(); return -1; } + tls_seq_num_incr(conn->server_seq_num); + digest_update(&dgst_ctx, record + 5, recordlen - 5); + + // use Transcript-Hash(Handshake Context, Certificate*, CertificateVerify*) tls13_compute_verify_data(server_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len); + // 8. recv Server {Finished} - tls_trace(">>>> server {Finished}\n"); - if (tls12_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + tls_trace("recv Server {Finished}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { error_print(); return -1; } @@ -1513,7 +1660,7 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve error_print(); return -1; } - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls_seq_num_incr(conn->server_seq_num); digest_update(&dgst_ctx, record + 5, recordlen - 5); @@ -1530,26 +1677,30 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve // generate server_application_traffic_secret // update server_write_key, server_write_iv - /* 12 */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); + /* {12} */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - if (client_sign_key) { + if (conn->client_certs_len) { int client_sign_algor; uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; size_t siglen; - // 9. send client {Certificate*} - tls_trace("<<<< client {Certificate}\n"); - if (tls13_record_set_handshake_certificate_from_pem(record, &recordlen, - client_certs_fp) != 1) { + error_print(); + + // send client {Certificate*} + tls_trace("send Client {Certificate}\n"); + + + if (tls_record_set_handshake_certificate(record, &recordlen, conn->client_certs, conn->client_certs_len) != 1) { error_print(); - return -1; + tls_send_alert(conn, TLS_alert_internal_error); + goto end; } digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, @@ -1564,17 +1715,19 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve return -1; } + // 10. send client {CertificateVerify*} tls_trace("<<<< client {CertificateVerify}\n"); - client_sign_algor = TLS_sig_sm2sig_sm3; - tls13_sign(client_sign_key, &dgst_ctx, sig, &siglen, 0); + client_sign_algor = TLS_sig_sm2sig_sm3; // 应该放在conn里面 + tls13_sign_certificate_verify(TLS_client_mode, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, &dgst_ctx, sig, &siglen); + if (tls13_record_set_handshake_certificate_verify(record, &recordlen, client_sign_algor, sig, siglen) != 1) { error_print(); return -1; } digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, @@ -1590,63 +1743,67 @@ int tls13_connect(TLS_CONNECT *conn, const char *hostname, int port, FILE *serve } } - // 11. send client {Finished} - - tls_trace("<<<< client {Finished}\n"); + // send Client {Finished} + tls_trace("send Client {Finished}\n"); if (tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, - verify_data, &verify_data_len) != 1) { + verify_data, &verify_data_len) != 1 + || tls_record_set_handshake_finished(record, &recordlen, + verify_data, verify_data_len) != 1) { error_print(); - return -1; - } - if (tls_record_set_handshake_finished(record, &recordlen, verify_data) != 1) { - error_print(); - return -1; + tls_send_alert(conn, TLS_alert_internal_error); + goto end; } + tls13_record_trace(stderr, record, recordlen, 0, 0); digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, conn->client_seq_num, record, recordlen, padding_len, enced_record, &enced_recordlen) != 1) { error_print(); - return -1; + tls_send_alert(conn, TLS_alert_internal_error); + goto end; } tls_seq_num_incr(conn->client_seq_num); if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { error_print(); - return -1; + goto end; } - // generate client_application_traffic_secret - // update client_write_key, client_write_iv - + // Generate client_application_traffic_secret, update client_write_key, client_write_iv /* 11 */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); tls_trace("++++ Connection established\n"); + +end: return 1; } -int tls13_accept(TLS_CONNECT *conn, int port, - FILE *server_certs_fp, const SM2_KEY *server_sign_key, - FILE *client_cacerts_fp) +int tls13_do_accept(TLS_CONNECT *conn) { uint8_t *record = conn->record; size_t recordlen; uint8_t enced_record[25600]; size_t enced_recordlen = sizeof(enced_record); + int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; + + + int protocol; + const uint8_t *random; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *client_exts; + size_t client_exts_len; + uint8_t client_random[32]; uint8_t server_random[32]; - uint8_t session_id[32]; - size_t session_id_len; - int client_ciphers[12] = {0}; - size_t client_ciphers_count = sizeof(client_ciphers)/sizeof(client_ciphers[0]); - uint8_t exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t extslen; + const uint8_t *client_ciphers; + size_t client_ciphers_len; + uint8_t server_exts[TLS_MAX_EXTENSIONS_SIZE]; + size_t server_exts_len; SM2_KEY server_ecdhe; SM2_POINT client_ecdhe_public; @@ -1666,8 +1823,6 @@ int tls13_accept(TLS_CONNECT *conn, int port, const uint8_t *client_verify_data; size_t client_verify_data_len; - - size_t i; uint8_t client_write_key[16]; @@ -1685,97 +1840,75 @@ int tls13_accept(TLS_CONNECT *conn, int port, uint8_t master_secret[32]; - int sock; - struct sockaddr_in server_addr; - struct sockaddr_in client_addr; - socklen_t client_addrlen; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - error_print(); - return -1; - } - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_port = htons(port); - - if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - error_print(); - return -1; - } - - error_puts("start listen ..."); - listen(sock, 5); - - memset(conn, 0, sizeof(*conn)); - - - - client_addrlen = sizeof(client_addr); - if ((conn->sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { - error_print(); - return -1; - } - - error_puts("connected\n"); + int client_verify = 0; + if (conn->ca_certs_len) + client_verify = 1; // 1. Recv ClientHello - - tls_trace(">>>> ClientHello\n"); - if (tls12_record_recv(record, &recordlen, conn->sock) != 1) { + tls_trace("recv ClientHello\n"); + if (tls_record_recv(record, &recordlen, conn->sock) != 1) { error_print(); return -1; } - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls_seq_num_incr(conn->client_seq_num); if (tls_record_get_handshake_client_hello(record, - &conn->version, client_random, session_id, &session_id_len, - client_ciphers, &client_ciphers_count, exts, &extslen) != 1) { + &protocol, &random, + &session_id, &session_id_len, // 不支持SessionID,不做任何处理 + &client_ciphers, &client_ciphers_len, + &client_exts, &client_exts_len) != 1) { error_print(); return -1; } - if (conn->version != TLS_version_tls12 - || session_id_len != 32) { + if (protocol != TLS_protocol_tls12) { error_print(); - return -1; + tls_send_alert(conn, TLS_alert_protocol_version); + goto end; } - for (i = 0; i < sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]); i++) { - if (tls_cipher_suite_in_list(tls13_ciphers[i], client_ciphers, client_ciphers_count) == 1) { - conn->cipher_suite = tls13_ciphers[i]; - break; - } + memcpy(client_random, random, 32); + if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, + server_ciphers, sizeof(server_ciphers)/sizeof(int), + &conn->cipher_suite) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + goto end; } - if (conn->cipher_suite == 0) { - error_puts("no common cipher_suite"); - return -1; - } - if (tls13_client_hello_extensions_get(exts, extslen, &client_ecdhe_public) != 1) { + + if (!client_exts) { error_print(); return -1; } - tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); + + tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); // 这个函数是否应该放到tls_里面? + digest_init(&dgst_ctx, digest); - null_dgst_ctx = dgst_ctx; + null_dgst_ctx = dgst_ctx; // 在密钥导出函数中可能输入的消息为空,因此需要一个空的dgst_ctx,这里不对了,应该在tls13_derive_secret里面直接支持NULL! + digest_update(&dgst_ctx, record + 5, recordlen - 5); - // 2. Send ServerHello - - tls_trace("<<<< ServerHello\n"); - + tls_trace("send ServerHello\n"); rand_bytes(server_random, 32); sm2_key_generate(&server_ecdhe); - tls13_server_hello_extensions_set(exts, &extslen, &(server_ecdhe.public_key), NULL); - if (tls_record_set_handshake_server_hello(enced_record, &enced_recordlen, - conn->version, server_random, session_id, 32, - conn->cipher_suite, exts, extslen) != 1) { + if (tls13_process_client_hello_exts(client_exts, client_exts_len, + &server_ecdhe, &client_ecdhe_public, + server_exts, &server_exts_len, sizeof(server_exts)) != 1) { error_print(); return -1; } - tls_record_print(stderr, enced_record, enced_recordlen, 0, 0); + + tls_record_set_protocol(record, TLS_protocol_tls12); + if (tls_record_set_handshake_server_hello(record, &recordlen, + TLS_protocol_tls12, server_random, NULL, 0, + conn->cipher_suite, server_exts, server_exts_len) != 1) { + error_print(); + return -1; + } + tls13_record_trace(stderr, record, recordlen, 0, 0); digest_update(&dgst_ctx, record + 5, recordlen - 5); if (tls_record_send(record, recordlen, conn->sock) != 1) { @@ -1805,23 +1938,35 @@ int tls13_accept(TLS_CONNECT *conn, int port, block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + format_bytes(stderr, 0, 0, "client_write_key", client_write_key, 16); + format_bytes(stderr, 0, 0, "server_write_key", server_write_key, 16); + format_bytes(stderr, 0, 0, "client_write_iv", conn->client_write_iv, 12); + format_bytes(stderr, 0, 0, "server_write_iv", conn->server_write_iv, 12); // 3. Send {EncryptedExtensions} + tls_trace("send {EncryptedExtensions}\n"); - - tls_trace("<<<< {EncryptedExtensions}\n"); - tls13_record_set_handshake_encrypted_extensions(record, &recordlen, NULL, 0); // 不发送EncryptedExtensions扩展 - tls_record_print(stderr, record, recordlen, 0, 0); + tls_record_set_protocol(record, TLS_protocol_tls12); + tls13_record_set_handshake_encrypted_extensions(record, &recordlen); + tls13_record_trace(stderr, record, recordlen, 0, 0); digest_update(&dgst_ctx, record + 5, recordlen - 5); tls13_padding_len_rand(&padding_len); + + format_bytes(stderr, 0, 0, "EncedExts", record, recordlen); + + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, conn->server_seq_num, record, recordlen, padding_len, enced_record, &enced_recordlen) != 1) { error_print(); return -1; } + // FIXME: tls13_record_encrypt需要支持握手消息 + // tls_record_data(enced_record)[0] = TLS_handshake_encrypted_extensions; + + printf("enced_recordlen = %zu\n", enced_recordlen); if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { error_print(); @@ -1830,14 +1975,10 @@ int tls13_accept(TLS_CONNECT *conn, int port, tls_seq_num_incr(conn->server_seq_num); - - - // 4. Send {CertificateRequest*} + if (client_verify) { - if (client_cacerts_fp) { - - tls_trace("<<<< {CertificateRequest*}\n"); + tls_trace("send {CertificateRequest*}\n"); uint8_t request_context[32]; // TODO: 设置certificate_request中的extensions! if (tls13_record_set_handshake_certificate_request(record, &recordlen, @@ -1846,7 +1987,7 @@ int tls13_accept(TLS_CONNECT *conn, int port, return -1; } digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, @@ -1862,69 +2003,73 @@ int tls13_accept(TLS_CONNECT *conn, int port, tls_seq_num_incr(conn->server_seq_num); } - // 6. send server {Certificate} + // 6. send Server {Certificate} - tls_trace("<<<< server {Certificate}\n"); - if (tls13_record_set_handshake_certificate_from_pem(record, &recordlen, server_certs_fp) != 1) { + tls_trace("send Server {Certificate}\n"); + // 我们需要首先将原始的证书准备好,然后再输入到这个结构里面 + + if (tls13_record_set_handshake_certificate(record, &recordlen, NULL, 0, conn->server_certs, conn->server_certs_len) != 1) { error_print(); - return -1; + goto end; } digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, conn->server_seq_num, record, recordlen, padding_len, enced_record, &enced_recordlen) != 1) { error_print(); - return -1; + goto end; } if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { error_print(); - return -1; + goto end; } + tls_seq_num_incr(conn->server_seq_num); - + /* + // 这个函数不对啊,怎么出现在此处了? if (tls_record_get_handshake_certificate(record, conn->server_certs, &conn->server_certs_len) != 1) { error_print(); - return -1; + goto end; } + */ + // 7. Send Server {CertificateVerify} - // 7. Send {CertificateVerify} - - tls_trace("<<<< server {CertificateVerify}\n"); - tls13_sign(server_sign_key, &dgst_ctx, sig, &siglen, 1); + tls_trace("send Server {CertificateVerify}\n"); + tls13_sign_certificate_verify(TLS_server_mode, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, &dgst_ctx, sig, &siglen); if (tls13_record_set_handshake_certificate_verify(record, &recordlen, TLS_sig_sm2sig_sm3, sig, siglen) != 1) { error_print(); - return -1; + goto end; } digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, conn->server_seq_num, record, recordlen, padding_len, enced_record, &enced_recordlen) != 1) { error_print(); - return -1; + goto end; } if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { error_print(); - return -1; + goto end; } tls_seq_num_incr(conn->server_seq_num); - // 8. Send server {Finished} + // 8. Send Server {Finished} - tls_trace("<<<< server {Finished}\n"); + tls_trace("send Server {Finished}\n"); // compute server verify_data before digest_update() tls13_compute_verify_data(server_handshake_traffic_secret, @@ -1932,22 +2077,22 @@ int tls13_accept(TLS_CONNECT *conn, int port, if (tls13_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { error_print(); - return -1; + goto end; } digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, conn->server_seq_num, record, recordlen, padding_len, enced_record, &enced_recordlen) != 1) { error_print(); - return -1; + goto end; } if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { error_print(); - return -1; + goto end; } tls_seq_num_incr(conn->server_seq_num); @@ -1960,12 +2105,12 @@ int tls13_accept(TLS_CONNECT *conn, int port, tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - // 10. Recv client {Certificate*} + // 10. Recv Client {Certificate*} - if (client_cacerts_fp) { + if (client_verify) { - tls_trace(">>> client {Certificate*}\n"); - if (tls12_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + tls_trace("recv Client {Certificate*}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { error_print(); return -1; } @@ -1977,16 +2122,23 @@ int tls13_accept(TLS_CONNECT *conn, int port, } tls_seq_num_incr(conn->client_seq_num); digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); + + const uint8_t *request_context; + size_t request_context_len; + const uint8_t *cert_list; + size_t cert_list_len; if (tls13_record_get_handshake_certificate(record, - conn->client_certs, &conn->client_certs_len) != 1) { + &request_context, &request_context_len, + &cert_list, &cert_list_len) != 1) { error_print(); return -1; } - // FIXME: verify client's certificate with ca certs - if (tls_certificate_get_public_keys(conn->client_certs, conn->client_certs_len, - &client_sign_key, NULL) != 1) { + const uint8_t *cert; + size_t certlen; + if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &client_sign_key) != 1) { error_print(); return -1; } @@ -1994,13 +2146,13 @@ int tls13_accept(TLS_CONNECT *conn, int port, // 11. Recv client {CertificateVerify*} - if (client_cacerts_fp) { + if (client_verify) { int client_sign_algor; const uint8_t *client_sig; size_t client_siglen; - tls_trace(">>>> client {CertificateVerify*}\n"); + tls_trace("recv Client {CertificateVerify*}\n"); if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { error_print(); return -1; @@ -2012,22 +2164,22 @@ int tls13_accept(TLS_CONNECT *conn, int port, } tls_seq_num_incr(conn->client_seq_num); digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_record_print(stderr, record, recordlen, 0, 0); + tls13_record_trace(stderr, record, recordlen, 0, 0); if (tls13_record_get_handshake_certificate_verify(record, &client_sign_algor, &client_sig, &client_siglen) != 1) { error_print(); return -1; } - if (tls13_verify(&client_sign_key, &dgst_ctx, client_sig, client_siglen, 0) != 1) { + if (tls13_verify_certificate_verify(TLS_client_mode, &client_sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, &dgst_ctx, client_sig, client_siglen) != 1) { error_print(); return -1; } } - // 12. Recv client {Finished} + // 12. Recv Client {Finished} - tls_trace(">>>> client {Finished}\n"); - if (tls12_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + tls_trace("recv Client {Finished}\n"); + if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { error_print(); return -1; } @@ -2055,5 +2207,7 @@ int tls13_accept(TLS_CONNECT *conn, int port, } tls_trace("Connection Established!\n\n"); + +end: return 1; } diff --git a/src/tls_ext.c b/src/tls_ext.c index 45a1fc49..8f6ddfde 100644 --- a/src/tls_ext.c +++ b/src/tls_ext.c @@ -67,138 +67,55 @@ #include -#define TLS_EXTENSION_HEADER_SIZE 4 +/* +ec_point_formats -#if 0 - -int tls_exts_add(uint8_t *exts, size_t *extslen, size_t maxlen, - int type, const uint8_t *data, size_t datalen) + struct { + ECPointFormat ec_point_format_list<1..2^8-1> + } ECPointFormatList; +*/ +int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, + uint8_t **out, size_t *outlen) { - if (!exts || !extslen) { - error_print(); - return -1; - } - if (datalen > TLS_MAX_PLAINTEXT_SIZE - || *extslen + TLS_EXTENSION_HEADER_SIZE + datalen > maxlen) { - error_print(); - return -1; - } - exts += *extslen; - tls_uint16_to_bytes(type, &exts, extslen); - tls_uint16array_to_bytes(data, datalen, &exts, extslen); - return 1; -} -#endif - -int tls_exts_add_ec_point_formats(uint8_t *exts, size_t *extslen, size_t maxlen, - const int *formats, size_t formats_cnt) -{ - int type = TLS_extension_ec_point_formats; - size_t datalen = tls_uint8_size() + tls_uint8_size() * formats_cnt; + uint16_t ext_type = TLS_extension_ec_point_formats; + size_t ext_datalen; + size_t ec_point_format_list_len; size_t i; - if (!exts || !extslen || !formats || !formats_cnt) { + if (!formats || !formats_cnt || !outlen) { error_print(); return -1; } - if (formats_cnt > 256) { + ec_point_format_list_len = tls_uint8_size() * formats_cnt; + if (ec_point_format_list_len < 1 || ec_point_format_list_len > 255) { error_print(); return -1; } - if (*extslen + TLS_EXTENSION_HEADER_SIZE + datalen > maxlen) { - error_print(); - return -1; - } - exts += *extslen; - tls_uint16_to_bytes(type, &exts, extslen); - tls_uint16_to_bytes(datalen, &exts, extslen); - tls_uint8_to_bytes(tls_uint8_size() * formats_cnt, &exts, extslen); + ext_datalen = tls_uint8_size() + ec_point_format_list_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint8_to_bytes((uint8_t)ec_point_format_list_len, out, outlen); for (i = 0; i < formats_cnt; i++) { if (!tls_ec_point_format_name(formats[i])) { error_print(); return -1; } - tls_uint8_to_bytes(formats[i], &exts, extslen); + tls_uint8_to_bytes((uint8_t)formats[i], out, outlen); } return 1; } -#define TLS_MAX_SUPPORTED_GROUPS_COUNT 64 - -int tls_exts_add_supported_groups(uint8_t *exts, size_t *extslen, size_t maxlen, - const int *curves, size_t curves_cnt) -{ - int type = TLS_extension_supported_groups; - size_t datalen = tls_uint16_size() + tls_uint16_size() * curves_cnt; - size_t i; - - if (!exts || !extslen || !curves || !curves_cnt) { - error_print(); - return -1; - } - if (curves_cnt > TLS_MAX_SUPPORTED_GROUPS_COUNT) { - error_print(); - return -1; - } - if (*extslen + TLS_EXTENSION_HEADER_SIZE + datalen > maxlen) { - error_print(); - return -1; - } - exts += *extslen; - tls_uint16_to_bytes(type, &exts, extslen); - tls_uint16_to_bytes(datalen, &exts, extslen); - tls_uint16_to_bytes(tls_uint16_size() * curves_cnt, &exts, extslen); - for (i = 0; i < curves_cnt; i++) { - tls_uint16_to_bytes(curves[i], &exts, extslen); - } - return 1; -} - -#define TLS_MAX_SIGNATURE_ALGORS_COUNT 64 - -int tls_exts_add_signature_algors(uint8_t *exts, size_t *extslen, size_t maxlen, - const int *algs, size_t algs_cnt) -{ - int type = TLS_extension_signature_algorithms; - size_t datalen = tls_uint16_size() + tls_uint16_size() * algs_cnt; - size_t i; - - if (!exts || !extslen || !algs || !algs_cnt) { - error_print(); - return -1; - } - if (algs_cnt > TLS_MAX_SIGNATURE_ALGORS_COUNT) { - error_print(); - return -1; - } - if (*extslen + TLS_EXTENSION_HEADER_SIZE + datalen > maxlen) { - error_print(); - return -1; - } - exts += *extslen; - tls_uint16_to_bytes(type, &exts, extslen); - tls_uint16_to_bytes(datalen, &exts, extslen); - tls_uint16_to_bytes(tls_uint16_size() * algs_cnt, &exts, extslen); - for (i = 0; i < algs_cnt; i++) { - tls_uint16_to_bytes(algs[i], &exts, extslen); - } - return 1; -} - -int tls_process_client_ec_point_formats(const uint8_t *data, size_t datalen, - uint8_t *exts, size_t *extslen, size_t maxlen) +int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) { int shared_formats[] = { TLS_point_uncompressed }; size_t shared_formats_cnt = 0; const uint8_t *p; size_t len; - if (!data || !datalen || !exts || !extslen) { - error_print(); - return -1; - } - if (tls_uint8array_from_bytes(&p, &len, &data, &datalen) != 1 - || tls_length_is_zero(datalen) != 1) { + if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { error_print(); return -1; } @@ -216,21 +133,25 @@ int tls_process_client_ec_point_formats(const uint8_t *data, size_t datalen, shared_formats_cnt = 1; } } - if (tls_exts_add_ec_point_formats(exts, extslen, maxlen, shared_formats, shared_formats_cnt) != 1) { + if (!shared_formats_cnt) { + error_print(); + return -1; + } + if (tls_ec_point_formats_ext_to_bytes(shared_formats, shared_formats_cnt, out, outlen) != 1) { error_print(); return -1; } return 1; } -int tls_process_server_ec_point_formats(const uint8_t *data, size_t datalen) +int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen) { const uint8_t *p; size_t len; uint8_t format; - if (tls_uint8array_from_bytes(&p, &len, &data, &datalen) != 1 - || tls_length_is_zero(datalen) != 1) { + if (tls_uint8array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { error_print(); return -1; } @@ -246,20 +167,193 @@ int tls_process_server_ec_point_formats(const uint8_t *data, size_t datalen) return 1; } -int tls_process_client_signature_algors(const uint8_t *data, size_t datalen, - uint8_t *exts, size_t *extslen, size_t maxlen) +#define TLS_MAX_SUPPORTED_GROUPS_COUNT 64 + + +/* +supported_groups + + struct { + NamedGroup named_group_list<2..2^16-1>; + } NamedGroupList; +*/ +int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_supported_groups; + size_t ext_datalen; + size_t named_group_list_len; + size_t i; + + if (!groups || !groups_cnt) { + error_print(); + return -1; + } + if (!outlen) { + error_print(); + return -1; + } + + if (groups_cnt > ((1<<16) - 1)/2) { + error_print(); + return -1; + } + named_group_list_len = tls_uint16_size() * groups_cnt; + ext_datalen = tls_uint16_size() + named_group_list_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes((uint16_t)named_group_list_len, out, outlen); + for (i = 0; i < groups_cnt; i++) { + if (!tls_named_curve_name(groups[i])) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)groups[i], out, outlen); + } + return 1; +} + +int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) +{ + int shared_groups[] = { TLS_curve_sm2p256v1 }; + size_t shared_groups_cnt = 0; + const uint8_t *p; + size_t len; + + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + while (len) { + uint16_t group; + if (tls_uint16_from_bytes(&group, &p, &len) != 1) { + error_print(); + return -1; + } + if (!tls_named_curve_name(group)) { + error_print(); + return -1; + } + if (group == shared_groups[0]) { + shared_groups_cnt = 1; + } + } + if (!shared_groups_cnt) { + error_print(); + return -1; + } + if (tls_supported_groups_ext_to_bytes(shared_groups, shared_groups_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *p; + size_t len; + uint16_t group; + + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (tls_uint16_from_bytes(&group, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (group != TLS_curve_sm2p256v1) { + error_print(); + return -1; + } + return 1; +} + + + +#define TLS_MAX_SIGNATURE_ALGORS_COUNT 64 + +/* +signature_algorithms +signature_algorithms_cert + + struct { + SignatureScheme supported_signature_algorithms<2..2^16-2>; + } SignatureSchemeList; +*/ +int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen) +{ + size_t ext_datalen; + size_t supported_signature_algorithms_len; + size_t i; + + if (!algs || !algs_cnt || !outlen) { + error_print(); + return -1; + } + if (algs_cnt > ((1<<16) - 2)/2) { + error_print(); + return -1; + } + supported_signature_algorithms_len = tls_uint16_size() * algs_cnt; + ext_datalen = tls_uint16_size() + supported_signature_algorithms_len; + + tls_uint16_to_bytes((uint16_t)ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes((uint16_t)supported_signature_algorithms_len, out, outlen); + for (i = 0; i < algs_cnt; i++) { + if (!tls_signature_scheme_name(algs[i])) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)algs[i], out, outlen); + } + return 1; +} + +int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen) +{ + int ext_type = TLS_extension_signature_algorithms; + if (tls_signature_algorithms_ext_to_bytes_ex(ext_type, algs, algs_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, + uint8_t **out, size_t *outlen) +{ + int ext_type = TLS_extension_signature_algorithms_cert; + if (tls_signature_algorithms_ext_to_bytes_ex(ext_type, algs, algs_cnt, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) { int shared_algs[1] = { TLS_sig_sm2sig_sm3 }; size_t shared_algs_cnt = 0; const uint8_t *p; size_t len; - if (!data || !datalen || !exts || !extslen) { + if (!ext_data || !ext_datalen || !outlen) { error_print(); return -1; } - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || tls_length_is_zero(datalen) != 1) { + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { error_print(); return -1; } @@ -277,21 +371,25 @@ int tls_process_client_signature_algors(const uint8_t *data, size_t datalen, shared_algs_cnt = 1; } } - if (tls_exts_add_signature_algors(exts, extslen, maxlen, shared_algs, shared_algs_cnt) != 1) { + if (!shared_algs_cnt) { + error_print(); + return -1; + } + if (tls_signature_algorithms_ext_to_bytes(shared_algs, shared_algs_cnt, out, outlen) != 1) { error_print(); return -1; } return 1; } -int tls_process_server_signature_algors(const uint8_t *data, size_t datalen) +int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen) { const uint8_t *p; size_t len; uint16_t alg; - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || tls_length_is_zero(datalen) != 1) { + if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { error_print(); return -1; } @@ -307,65 +405,428 @@ int tls_process_server_signature_algors(const uint8_t *data, size_t datalen) return 1; } -int tls_process_client_supported_groups(const uint8_t *data, size_t datalen, uint8_t *exts, size_t *extslen, size_t maxlen) +/* +supported_versions + + struct { + select (Handshake.msg_type) { + case client_hello: + ProtocolVersion versions<2..254>; + case server_hello: -- and HelloRetryRequest + ProtocolVersion selected_version; + }; + } SupportedVersions; +*/ + +int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, + int handshake_type, const uint8_t *data, size_t datalen) { - int shared_curves[1] = { TLS_curve_sm2p256v1 }; - size_t shared_curves_cnt = 0; + const uint8_t *versions; + size_t versions_len; + uint16_t version; + + switch (handshake_type) { + case TLS_handshake_client_hello: + format_print(fp, fmt, ind, "versions\n"); + ind += 4; + + if (tls_uint8array_from_bytes(&versions, &versions_len, &data, &datalen) != 1) { + error_print(); + return -1; + } + if (versions_len < 2 || versions_len > 254) { + error_print(); + return -1; + } + while (versions_len) { + if (tls_uint16_from_bytes(&version, &versions, &versions_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (0x%04x)\n", tls_protocol_name(version), version); + } + break; + + case TLS_handshake_server_hello: + case TLS_handshake_hello_retry_request: + if (tls_uint16_from_bytes(&version, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "selected_version: %s (0x%04x)\n", tls_protocol_name(version), version); + break; + + default: + error_print(); + return -1; + } + + if (datalen) { + error_print(); + return -1; + } + return 1; +} + +int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, + uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_supported_versions; + size_t ext_datalen; + size_t i; + + if (!protos || !protos_cnt || !outlen) { + error_print(); + return -1; + } + switch (handshake_type) { + case TLS_handshake_client_hello: + { + size_t versions_len; + if (protos_cnt > 254/2) { + error_print(); + return -1; + } + versions_len = tls_uint16_size() * protos_cnt; + ext_datalen = tls_uint8_size() + versions_len; + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint8_to_bytes((uint8_t)versions_len, out, outlen); + for (i = 0; i < protos_cnt; i++) { + if (!tls_protocol_name(protos[i])) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)protos[i], out, outlen); + } + break; + } + case TLS_handshake_server_hello: + case TLS_handshake_hello_retry_request: + { + uint16_t selected_version; + if (protos_cnt > 1) { + error_print(); + return -1; + } + selected_version = protos[0]; + ext_datalen = tls_uint16_size(); + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes(selected_version, out, outlen); + break; + } + default: + error_print(); + return -1; + } + return 1; +} + +int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) +{ + const uint8_t *versions; + size_t versions_len; + int selected_version = -1; + size_t len; + + if (tls_uint8array_from_bytes(&versions, &versions_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (versions_len < 2 || versions_len > 254) { + error_print(); + return -1; + } + while (versions_len) { + uint16_t proto; + if (tls_uint16_from_bytes(&proto, &versions, &versions_len) != 1) { + error_print(); + return -1; + } + if (!tls_protocol_name(proto)) { + error_print(); + return -1; + } + if (proto == TLS_protocol_tls13) { + selected_version = proto; + } + } + if (selected_version < 0) { + error_print(); + return -1; + } + if (tls13_supported_versions_ext_to_bytes(TLS_handshake_server_hello, &selected_version, 1, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen) +{ + uint16_t selected_version; + + if (tls_uint16_from_bytes(&selected_version, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (selected_version != TLS_protocol_tls13) { + error_print(); + return -1; + } + return 1; +} + +/* +key_share + +实际上这个 key_share 也存在相同的问题 + + + struct { + NamedGroup group; + opaque key_exchange<1..2^16-1>; + } KeyShareEntry; + + struct { + KeyShareEntry client_shares<0..2^16-1>; + } KeyShareClientHello; + + struct { + KeyShareEntry server_share; + } KeyShareServerHello; +*/ + +int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen) +{ + const uint8_t *client_shares; + size_t client_shares_len; + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + switch (handshake_type) { + case TLS_handshake_client_hello: + format_print(fp, fmt, ind, "client_shares\n"); + ind += 4; + if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "KeyShareEntry\n"); + ind += 4; + while (client_shares_len) { + if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1) goto err; + format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); + if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) goto err; + format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); + } + break; + case TLS_handshake_server_hello: + format_print(fp, fmt, ind, "server_share\n"); + ind += 4; + if (tls_uint16_from_bytes(&group, &data, &datalen) != 1) goto err; + format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); + if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &data, &datalen) != 1) goto err; + format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); + break; + default: + error_print(); + return -1; + } + if (tls_length_is_zero(datalen) != 1) goto err; + return 1; +err: + error_print(); + return -1; +} + +int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) +{ + uint16_t group = TLS_curve_sm2p256v1; + uint8_t key_exchange[65]; + + if (!point || !outlen) { + error_print(); + return -1; + } + sm2_point_to_uncompressed_octets(point, key_exchange); + tls_uint16_to_bytes(group, out, outlen); + tls_uint16array_to_bytes(key_exchange, 65, out, outlen); + return 1; +} + +int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + size_t ext_datalen = 0; + + if (!point || !outlen) { + error_print(); + return -1; + } + tls13_key_share_entry_to_bytes(point, NULL, &ext_datalen); + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(ext_datalen, out, outlen); + tls13_key_share_entry_to_bytes(point, out, outlen); + return 1; +} + +int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point) +{ + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + if (!point) { + error_print(); + return -1; + } + if (tls_uint16_from_bytes(&group, &ext_data, &ext_datalen) != 1 + || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (group != TLS_curve_sm2p256v1) { + error_print(); + return -1; + } + if (key_exchange_len != 65) { + error_print(); + return -1; + } + if (sm2_point_from_octets(point, key_exchange, key_exchange_len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + size_t ext_datalen; + size_t client_shares_len = 0; + + if (!point || !outlen) { + error_print(); + return -1; + } + tls13_key_share_entry_to_bytes(point, NULL, &client_shares_len); + ext_datalen = tls_uint16_size() + client_shares_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(ext_datalen, out, outlen); + tls_uint16_to_bytes(client_shares_len, out, outlen); + tls13_key_share_entry_to_bytes(point, out, outlen); + return 1; +} + +int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, + const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public, + uint8_t **out, size_t *outlen) +{ + const uint8_t *client_shares; + size_t client_shares_len; + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + if (!server_ecdhe_key || !client_ecdhe_public || !outlen) { + error_print(); + return -1; + } + if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + while (client_shares_len) { + if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1 + || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) { + error_print(); + return -1; + } + if (!tls_named_curve_name(group)) { + error_print(); + return -1; + } + if (!key_exchange) { + error_print(); + return -1; + } + if (group == TLS_curve_sm2p256v1) { + if (key_exchange_len != 65) { + error_print(); + return -1; + } + if (sm2_point_from_octets(client_ecdhe_public, key_exchange, key_exchange_len) != 1) { + error_print(); + return -1; + } + if (tls13_server_key_share_ext_to_bytes(&server_ecdhe_key->public_key, out, outlen) != 1) { + error_print(); + return -1; + } + return 1; + } + } + error_print(); + return -1; +} + +/* +certificate_authorities + + opaque DistinguishedName<1..2^16-1>; + + struct { + DistinguishedName authorities<3..2^16-1>; + } CertificateAuthoritiesExtension; +*/ + +int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, + uint8_t **out, size_t *outlen) +{ + int ext_type = TLS_extension_certificate_authorities; + size_t ext_datalen; + size_t authorities_len; + const uint8_t *name; + size_t namelen; const uint8_t *p; size_t len; - if (!data || !datalen || !exts || !extslen) { - error_print(); - return -1; - } - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || tls_length_is_zero(datalen) != 1) { - error_print(); - return -1; - } + p = ca_names; + len = ca_names_len; + authorities_len = 0; while (len) { - uint16_t curve; - if (tls_uint16_from_bytes(&curve, &p, &len) != 1) { + if (x509_name_from_der(&name, &namelen, &p, &len) != 1) { error_print(); return -1; } - if (!tls_named_curve_name(curve)) { - error_print(); - return -1; - } - if (curve == shared_curves[0]) { - shared_curves_cnt = 1; - } + tls_uint16array_to_bytes(name, namelen, NULL, &authorities_len); } - if (tls_exts_add_supported_groups(exts, extslen, maxlen, shared_curves, shared_curves_cnt) != 1) { + if (authorities_len < 3 || authorities_len > (1 << 16) - 1) { error_print(); return -1; } + ext_datalen = tls_uint16_size() + authorities_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(ext_datalen, out, outlen); + tls_uint16_to_bytes(authorities_len, out, outlen); + while (ca_names_len) { + x509_name_from_der(&name, &namelen, &ca_names, &ca_names_len); + tls_uint16array_to_bytes(name, namelen, out, outlen); + } return 1; } -int tls_process_server_supported_groups(const uint8_t *data, size_t datalen) -{ - const uint8_t *p; - size_t len; - uint16_t curve; - - if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 - || tls_length_is_zero(datalen) != 1) { - error_print(); - return -1; - } - if (tls_uint16_from_bytes(&curve, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (curve != TLS_curve_sm2p256v1) { - error_print(); - return -1; - } - return 1; -} int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) { @@ -383,7 +844,7 @@ int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const u return 1; } -int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen) +int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen) { int type; const uint8_t *data; @@ -397,19 +858,19 @@ int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, s switch (type) { case TLS_extension_ec_point_formats: - if (tls_process_client_ec_point_formats(data, datalen, out, outlen, maxlen) != 1) { + if (tls_process_client_ec_point_formats(data, datalen, &out, outlen) != 1) { error_print(); return -1; } break; case TLS_extension_signature_algorithms: - if (tls_process_client_signature_algors(data, datalen, out, outlen, maxlen) != 1) { + if (tls_process_client_signature_algorithms(data, datalen, &out, outlen) != 1) { error_print(); return -1; } break; case TLS_extension_supported_groups: - if (tls_process_client_supported_groups(data, datalen, out, outlen, maxlen) != 1) { + if (tls_process_client_supported_groups(data, datalen, &out, outlen) != 1) { error_print(); return -1; } @@ -422,7 +883,7 @@ int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, s return 1; } -int tls_process_server_exts(const uint8_t *exts, size_t extslen, +int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, int *ec_point_format, int *supported_group, int *signature_algor) { int type; @@ -468,3 +929,78 @@ int tls_process_server_exts(const uint8_t *exts, size_t extslen, } return 1; } + + + +static int tls13_server_hello_exts[] = { + TLS_extension_key_share, + TLS_extension_pre_shared_key, + TLS_extension_supported_versions, +}; + +/* +struct { + Extension extensions<0..2^16-1>; +} EncryptedExtensions; +*/ +static int tls13_encrypted_extensions_exts[] = { + TLS_extension_server_name, + TLS_extension_max_fragment_length, + TLS_extension_supported_groups, // 必须放在EE中,不能放在SH中 + TLS_extension_use_srtp, + TLS_extension_heartbeat, + TLS_extension_application_layer_protocol_negotiation, + TLS_extension_client_certificate_type, + TLS_extension_server_certificate_type, + TLS_extension_early_data, +}; + +static int tls13_certificate_exts[] = { + TLS_extension_status_request, + TLS_extension_signed_certificate_timestamp, +}; + +static int tls13_certificate_request_exts[] = { + TLS_extension_status_request, + TLS_extension_signature_algorithms, + TLS_extension_signed_certificate_timestamp, + TLS_extension_certificate_authorities, + TLS_extension_oid_filters, + TLS_extension_signature_algorithms_cert, +}; + +static int tls13_hello_retry_request_exts[] = { + TLS_extension_key_share, + TLS_extension_cookie, + TLS_extension_supported_versions, +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tls_trace.c b/src/tls_trace.c index 07495122..03a26dc5 100644 --- a/src/tls_trace.c +++ b/src/tls_trace.c @@ -86,19 +86,27 @@ const char *tls_protocol_name(int protocol) const char *tls_cipher_suite_name(int cipher) { switch (cipher) { - case TLS_cipher_ecdhe_sm4_cbc_sm3: return "ECDHE_SM4_CBC_SM3"; - case TLS_cipher_ecdhe_sm4_gcm_sm3: return "ECDHE_SM4_GCM_SM3"; - case TLS_cipher_ecc_sm4_cbc_sm3: return "ECC_SM4_CBC_SM3"; - case TLS_cipher_ecc_sm4_gcm_sm3: return "ECC_SM4_GCM_SM3"; - case TLS_cipher_ibsdh_sm4_cbc_sm3: return "IBSDH_SM4_CBC_SM3"; - case TLS_cipher_ibsdh_sm4_gcm_sm3: return "IBSDH_SM4_GCM_SM3"; - case TLS_cipher_ibc_sm4_cbc_sm3: return "IBC_SM4_CBC_SM3"; - case TLS_cipher_ibc_sm4_gcm_sm3: return "IBC_SM4_GCM_SM3"; - case TLS_cipher_rsa_sm4_cbc_sm3: return "RSA_SM4_CBC_SM3"; - case TLS_cipher_rsa_sm4_gcm_sm3: return "RSA_SM4_GCM_SM3"; - case TLS_cipher_rsa_sm4_cbc_sha256: return "RSA_SM4_CBC_SHA256"; - case TLS_cipher_rsa_sm4_gcm_sha256: return "RSA_SM4_GCM_SHA256"; - case TLS_cipher_empty_renegotiation_info_scsv: return "EMPTY_RENEGOTIATION_INFO_SCSV"; + case TLS_cipher_null_with_null_null: return "TLS_NULL_WITH_NULL_NULL"; + case TLS_cipher_sm4_gcm_sm3: return "TLS_SM4_GCM_SM3"; + case TLS_cipher_sm4_ccm_sm3: return "TLS_SM4_CCM_SM3"; + case TLS_cipher_ecdhe_sm4_cbc_sm3: return "TLS_ECDHE_SM4_CBC_SM3"; + case TLS_cipher_ecdhe_sm4_gcm_sm3: return "TLS_ECDHE_SM4_GCM_SM3"; + case TLS_cipher_ecc_sm4_cbc_sm3: return "TLS_ECC_SM4_CBC_SM3"; + case TLS_cipher_ecc_sm4_gcm_sm3: return "TLS_ECC_SM4_GCM_SM3"; + case TLS_cipher_ibsdh_sm4_cbc_sm3: return "TLS_IBSDH_SM4_CBC_SM3"; + case TLS_cipher_ibsdh_sm4_gcm_sm3: return "TLS_IBSDH_SM4_GCM_SM3"; + case TLS_cipher_ibc_sm4_cbc_sm3: return "TLS_IBC_SM4_CBC_SM3"; + case TLS_cipher_ibc_sm4_gcm_sm3: return "TLS_IBC_SM4_GCM_SM3"; + case TLS_cipher_rsa_sm4_cbc_sm3: return "TLS_RSA_SM4_CBC_SM3"; + case TLS_cipher_rsa_sm4_gcm_sm3: return "TLS_RSA_SM4_GCM_SM3"; + case TLS_cipher_rsa_sm4_cbc_sha256: return "TLS_RSA_SM4_CBC_SHA256"; + case TLS_cipher_rsa_sm4_gcm_sha256: return "TLS_RSA_SM4_GCM_SHA256"; + case TLS_cipher_aes_128_gcm_sha256: return "TLS_AES_128_GCM_SHA256"; + case TLS_cipher_aes_256_gcm_sha384: return "TLS_AES_256_GCM_SHA384"; + case TLS_cipher_chacha20_poly1305_sha256: return "TLS_CHACHA20_POLY1305_SHA256"; + case TLS_cipher_aes_128_ccm_sha256: return "TLS_AES_128_CCM_SHA256"; + case TLS_cipher_aes_128_ccm_8_sha256: return "TLS_AES_128_CCM_8_SHA256"; + case TLS_cipher_empty_renegotiation_info_scsv: return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; } return NULL; } @@ -156,7 +164,7 @@ const char *tls_extension_name(int ext) case TLS_extension_supported_ekt_ciphers: return "supported_ekt_ciphers"; case TLS_extension_pre_shared_key: return "pre_shared_key"; case TLS_extension_early_data: return "early_data"; - case TLS_extension_supported_protocols: return "supported_protocols"; + case TLS_extension_supported_versions: return "supported_versions"; case TLS_extension_cookie: return "cookie"; case TLS_extension_psk_key_exchange_modes: return "psk_key_exchange_modes"; case TLS_extension_certificate_authorities: return "certificate_authorities"; @@ -201,13 +209,25 @@ const char *tls_handshake_type_name(int type) case TLS_handshake_hello_request: return "HelloRequest"; case TLS_handshake_client_hello: return "ClientHello"; case TLS_handshake_server_hello: return "ServerHello"; + case TLS_handshake_hello_verify_request: return "HelloVerifyRequest"; + case TLS_handshake_new_session_ticket: return "NewSessionTicket"; + case TLS_handshake_end_of_early_data: return "EndOfEarlyData"; + case TLS_handshake_hello_retry_request: return "HelloRetryRequest"; + case TLS_handshake_encrypted_extensions: return "EncryptedExtensions"; case TLS_handshake_certificate: return "Certificate"; case TLS_handshake_server_key_exchange: return "ServerKeyExchange"; case TLS_handshake_certificate_request: return "CertificateRequest"; case TLS_handshake_server_hello_done: return "ServerHelloDone"; - case TLS_handshake_certificate_verify: return "CertificateRequest"; + case TLS_handshake_certificate_verify: return "CertificateVerify"; case TLS_handshake_client_key_exchange: return "ClientKeyExchange"; case TLS_handshake_finished: return "Finished"; + case TLS_handshake_certificate_url: return "CertificateUrl"; + case TLS_handshake_certificate_status: return "CertificateStatus"; + case TLS_handshake_supplemental_data: return "SupplementalData"; + case TLS_handshake_key_update: return "KeyUpdate"; + case TLS_handshake_compressed_certificate: return "CompressedCertificate"; + case TLS_handshake_ekt_key: return "EktKey"; + case TLS_handshake_message_hash: return "MessageHash"; } return NULL; } @@ -366,6 +386,7 @@ int tls_pre_master_secret_print(FILE *fp, const uint8_t pre_master_secret[48], i return 1; } +// supported_versions 的格式还受到 handshake_type 影响 int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen, int format, int indent) { const uint8_t *p; @@ -375,6 +396,20 @@ int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen, indent += 4; switch (type) { + case TLS_extension_supported_versions: + if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 + || tls_length_is_zero(datalen) != 1 + || len % 2) { + error_print(); + return -1; + } + while (len) { + uint16_t proto; + tls_uint16_from_bytes(&proto, &p, &len); + format_print(fp, format, indent, "%s (0x%04x)\n", + tls_protocol_name(proto), proto); + } + break; case TLS_extension_supported_groups: if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1 || datalen @@ -443,6 +478,56 @@ int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen, return 1; } +int tls13_extension_print(FILE *fp, int fmt, int ind, + int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen) +{ + switch (ext_type) { + case TLS_extension_supported_groups: + case TLS_extension_ec_point_formats: + case TLS_extension_signature_algorithms: + return tls_extension_print(fp, ext_type, ext_data, ext_datalen, fmt, ind); + } + + format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); + ind += 4; + + switch (ext_type) { + case TLS_extension_supported_versions: + tls13_supported_versions_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); + break; + case TLS_extension_key_share: + tls13_key_share_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); + break; + default: + error_print(); + return -1; + } + return 1; +} + +int tls13_extensions_print(FILE *fp, int fmt, int ind, + int handshake_type, const uint8_t *exts, size_t extslen) +{ + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + format_print(fp, fmt, ind, "Extensions\n"); + ind += 4; + while (extslen > 0) { + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + if (tls13_extension_print(fp, fmt, ind, handshake_type, ext_type, ext_data, ext_datalen) != 1) { + error_print(); + return -1; + } + } + return 1; +} + int tls_extensions_print(FILE *fp, const uint8_t *exts, size_t extslen, int format, int indent) { uint16_t ext_type; @@ -516,7 +601,8 @@ int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int fo } if (datalen > 0) { if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto end; - tls_extensions_print(fp, exts, exts_len, format, indent); + //tls_extensions_print(fp, exts, exts_len, format, indent); + tls13_extensions_print(fp, format, indent, TLS_handshake_client_hello, exts, exts_len); } if (datalen > 0) { error_print(); @@ -556,7 +642,8 @@ int tls_server_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int fo if (datalen > 0) { if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto bad; //format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print - tls_extensions_print(fp, exts, exts_len, format, indent); + //tls_extensions_print(fp, exts, exts_len, format, indent); + tls13_extensions_print(fp, format, indent, TLS_handshake_server_hello, exts, exts_len); } return 1; bad: @@ -572,8 +659,7 @@ int tls_certificate_print(FILE *fp, const uint8_t *data, size_t datalen, int for const uint8_t *der; size_t derlen; - if (tls_uint24array_from_bytes(&certs, &certslen, &data, &datalen) != 1 - || datalen > 0) { + if (tls_uint24array_from_bytes(&certs, &certslen, &data, &datalen) != 1) { error_print(); return -1; } @@ -585,6 +671,11 @@ int tls_certificate_print(FILE *fp, const uint8_t *data, size_t datalen, int for (void)x509_cert_print(fp, format, indent, "Certificate", der, derlen); (void)x509_cert_to_pem(der, derlen, fp); } + + if (datalen) { + error_print(); + return -1; + } return 1; } @@ -794,17 +885,41 @@ int tls_finished_print(FILE *fp, const uint8_t *data, size_t datalen, int format return 1; } +int tls13_handshake_print(FILE *fp, int fmt, int ind, const uint8_t *handshake, size_t handshake_len) +{ + const uint8_t *p = handshake; + size_t len = handshake_len; + uint8_t type; + const uint8_t *data; + size_t datalen; + + if (tls_uint8_from_bytes(&type, &handshake, &handshake_len) != 1 + || tls_uint24array_from_bytes(&data, &datalen, &handshake, &handshake_len) != 1 + || tls_length_is_zero(handshake_len) != 1) { + error_print(); + return -1; + } + + switch (type) { + case TLS_handshake_certificate: + return tls13_certificate_print(fp, fmt, ind, data, datalen); + } + + return tls_handshake_print(fp, p, len, fmt, ind); +} + +// 这个是有问题的,因为TLS 1.3的证书和TLS 1.2是不一样的 int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, int format, int indent) { const uint8_t *cp = handshake; - int type; + uint8_t type; const uint8_t *data; size_t datalen = 0; format_print(fp, format, indent, "Handshake\n"); indent += 4; - if (tls_uint8_from_bytes((uint8_t *)&type, &cp, &handshakelen) != 1) { + if (tls_uint8_from_bytes(&type, &cp, &handshakelen) != 1) { error_print(); return -1; } @@ -829,6 +944,10 @@ int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, case TLS_handshake_server_hello: if (tls_server_hello_print(fp, data, datalen, format, indent) != 1) { error_print(); return -1; } break; + case TLS_handshake_encrypted_extensions: + tls13_encrypted_extensions_print(fp, format, indent, data, datalen); + break; + case TLS_handshake_certificate: if (tls_certificate_print(fp, data, datalen, format, indent) != 1) { error_print(); return -1; } break; @@ -888,9 +1007,86 @@ int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, in return 1; } +int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen) +{ + const uint8_t *data; + size_t datalen; + int protocol; + + format |= TLS_cipher_sm4_gcm_sm3 << 8; + + if (!fp || !record || recordlen < 5) { + error_print(); + return -1; + } + protocol = tls_record_protocol(record); + format_print(fp, format, indent, "Record\n"); indent += 4; + format_print(fp, format, indent, "ContentType: %s (%d)\n", tls_record_type_name(record[0]), record[0]); + format_print(fp, format, indent, "Version: %s (%d.%d)\n", tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + format_print(fp, format, indent, "Length: %d\n", tls_record_data_length(record)); + + data = tls_record_data(record); + datalen = tls_record_data_length(record); + + if (recordlen < tls_record_length(record)) { + error_print(); + return -1; + } + + // 最高字节设置后强制打印记录原始数据 + if (format >> 24) { + format_bytes(fp, format, indent, "Data", data, datalen); + fprintf(fp, "\n"); + return 1; + } + + switch (record[0]) { + case TLS_record_handshake: + tls13_handshake_print(fp, format, indent, data, datalen); + break; + case TLS_record_alert: + if (tls_alert_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_change_cipher_spec: + if (tls_change_cipher_spec_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_application_data: + if (tls_application_data_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + + recordlen -= tls_record_length(record); + if (recordlen) { + format_print(fp, 0, 0, "DataLeftInRecord: %zu\n", recordlen); + } + + fprintf(fp, "\n"); + return 1; + +} + + +// 仅从record数据是不能判断这个record是TLS 1.2还是TLS 1.3 +// 不同协议上,同名的握手消息,其格式也是不一样的。这真是太恶心了!!!! + // 当消息为ClientKeyExchange,ServerKeyExchange,需要密码套件中的密钥交换算法信息 // 当消息为加密的Finished,记录类型为Handshake,但是记录负载数据中没有Handshake头 // 注意:这里的recordlen 是冗余的,要容忍recordlen的错误 +// +// supported_versions 的格式由handshake_type 是否为ClientHello, ServerHello 决定 +// record中是包含这个信息的,但是在exts中没有这个信息 int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent) { const uint8_t *data; @@ -959,6 +1155,34 @@ int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int for fprintf(fp, "\n"); return 1; + + + + + + + + + + + + + + + + + + + + + + + + + + + + } int tls_secrets_print(FILE *fp, diff --git a/src/x509_cer.c b/src/x509_cer.c index 8afd09b5..3bcb9b89 100644 --- a/src/x509_cer.c +++ b/src/x509_cer.c @@ -1507,6 +1507,43 @@ int x509_certs_get_cert_by_issuer_and_serial_number( return 0; } +int x509_cert_check(const uint8_t *cert, size_t certlen) +{ + time_t not_before; + time_t not_after; + time_t now; + + x509_cert_get_details(cert, certlen, + NULL, // version + NULL, NULL, // serial + NULL, // signature_algor + NULL, NULL, // issuer + ¬_before, ¬_after, // validity + NULL, NULL, // subject + NULL, // subject_public_key + NULL, NULL, // issuer_unique_id + NULL, NULL, // subject_unique_id + NULL, NULL, // extensions + NULL, // signature_algor + NULL, NULL); // signature + + // not_before < now < not_after + time(&now); + if (not_before >= not_after) { + error_print(); + return -1; + } + if (now < not_before) { + error_print(); + return X509_verify_err_cert_not_yet_valid; + } + if (not_after < now) { + error_print(); + return X509_verify_err_cert_has_expired; + } + + return 1; +} int x509_certs_verify(const uint8_t *certs, size_t certslen, const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result) @@ -1517,7 +1554,6 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, size_t cacertlen; const uint8_t *name; size_t namelen; - *verify_result = -1; if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { @@ -1525,6 +1561,11 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, return -1; } while (certslen) { + + if ((*verify_result = x509_cert_check(cert, certlen)) < 0) { + error_print(); + return -1; + } if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) { error_print(); return -1; @@ -1582,6 +1623,10 @@ int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen, // 要检查这两个证书的类型是否分别为签名和加密证书 // FIXME: 检查depth while (certslen) { + if ((*verify_result = x509_cert_check(cert, certlen)) < 0) { + error_print(); + return -1; + } if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) { error_print(); return -1; @@ -1702,6 +1747,3 @@ end: if (buf) free(buf); return ret; } - - - diff --git a/tests/gcmtest.c b/tests/gcmtest.c index 6fa755ec..763dbe43 100644 --- a/tests/gcmtest.c +++ b/tests/gcmtest.c @@ -51,6 +51,8 @@ #include #include #include +#include +#include #include @@ -130,8 +132,6 @@ int test_ghash(void) size_t Hlen, Alen, Clen, Tlen; int i; - printf("%s\n", __FUNCTION__); - for (i = 0; i < sizeof(ghash_tests)/sizeof(ghash_tests[0]); i++) { hex_to_bytes(ghash_tests[i].H, strlen(ghash_tests[i].H), H, &Hlen); hex_to_bytes(ghash_tests[i].A, strlen(ghash_tests[i].A), A, &Alen); @@ -139,22 +139,93 @@ int test_ghash(void) hex_to_bytes(ghash_tests[i].T, strlen(ghash_tests[i].T), T, &Tlen); ghash(H, A, Alen, C, Clen, out); - printf(" test %d %s\n", i + 1, memcmp(out ,T, Tlen) == 0 ? "ok" : "error"); - /* - format_print(stdout, 0, 2, "H = %s\n", ghash_tests[i].H); - format_print(stdout, 0, 2, "A = %s\n", ghash_tests[i].A); - format_print(stdout, 0, 2, "C = %s\n", ghash_tests[i].C); - format_bytes(stdout, 0, 2, "GHASH(H,A,C) = ", out, 16); - format_print(stdout, 0, 2, " = %s\n\n", ghash_tests[i].T); - */ + if (memcmp(out, T, Tlen) != 0) { + format_print(stderr, 0, 0, "test %d failed\n", i + 1); + format_print(stderr, 0, 2, "H = %s\n", ghash_tests[i].H); + format_print(stderr, 0, 2, "A = %s\n", ghash_tests[i].A); + format_print(stderr, 0, 2, "C = %s\n", ghash_tests[i].C); + format_bytes(stderr, 0, 2, "GHASH(H,A,C) = ", out, 16); + format_print(stderr, 0, 2, " = %s\n\n", ghash_tests[i].T); + } } - return 0; + + printf("%s() ok\n", __FUNCTION__); + return 1; } +int test_gcm(void) +{ + BLOCK_CIPHER_KEY block_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t aad[64]; + uint8_t in[100]; + uint8_t out[sizeof(in)]; + uint8_t buf[sizeof(in)]; + uint8_t tag[16]; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + rand_bytes(aad, sizeof(aad)); + rand_bytes(in, sizeof(in)); + + memset(out, 0, sizeof(out)); + memset(buf, 0, sizeof(buf)); + memset(tag, 0, sizeof(tag)); + + if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_aes128(), key) != 1) { + error_print(); + return -1; + } + if (gcm_encrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != 1) { + error_print(); + return -1; + } + if (gcm_decrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), out, sizeof(out), tag, sizeof(tag), buf) != 1) { + error_print(); + return -1; + } + if (memcmp(buf, in, sizeof(in)) != 0) { + error_print(); + return -1; + } + + memset(out, 0, sizeof(out)); + memset(buf, 0, sizeof(buf)); + memset(tag, 0, sizeof(tag)); + + if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { + error_print(); + return -1; + } + if (gcm_encrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != 1) { + error_print(); + return -1; + } + if (gcm_decrypt(&block_key, iv, sizeof(iv), aad, sizeof(aad), out, sizeof(out), tag, sizeof(tag), buf) != 1) { + error_print(); + return -1; + } + if (memcmp(buf, in, sizeof(in)) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + + + int main(int argc, char **argv) { - int err = 0; - err += test_ghash(); - return err; + if (test_ghash() != 1) goto err; + if (test_gcm() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; } diff --git a/tests/gf128test.c b/tests/gf128test.c index cf76eb98..ae45d400 100644 --- a/tests/gf128test.c +++ b/tests/gf128test.c @@ -52,44 +52,95 @@ #include #include #include +#include -/* -a = de300f9301a499a965f8bf677e99e80d -b = 14b267838ec9ef1bb7b5ce8c19e34bc6 -a + b = ca8268108f6d76b2d24d71eb677aa3cb -a - b = ca8268108f6d76b2d24d71eb677aa3cb -a * b = 28e63413cd53b01a3b469375781942c6 -a * 2 = bc601f2603493352cbf17ecefd33d09d -*/ + +int test_gf128_from_hex(void) +{ + char *tests[] = { + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "10000000000000000000000000000000", + "de300f9301a499a965f8bf677e99e80d", + "14b267838ec9ef1bb7b5ce8c19e34bc6", + }; + gf128_t a; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + a = gf128_from_hex(tests[i]); + if (gf128_equ_hex(a, tests[i]) != 1) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_gf128_mul2(void) +{ + char *tests[] = { + "00000000000000000000000000000001", + "de300f9301a499a965f8bf677e99e80d", + }; + char *results[] = { + "e1000000000000000000000000000000", + "8e1807c980d24cd4b2fc5fb3bf4cf406", + }; + gf128_t a; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + a = gf128_from_hex(tests[i]); + a = gf128_mul2(a); + if (gf128_equ_hex(a, results[i]) != 1) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_gf128_mul(void) +{ + char *hex_a = "de300f9301a499a965f8bf677e99e80d"; + char *hex_b = "14b267838ec9ef1bb7b5ce8c19e34bc6"; + char *hex_add_a_b = "ca8268108f6d76b2d24d71eb677aa3cb"; + char *hex_mul_a_b = "7d87dda57a20b0c51d9743071ab14010"; + gf128_t a, b, r; + + a = gf128_from_hex(hex_a); + b = gf128_from_hex(hex_b); + + r = gf128_add(a, b); + if (gf128_equ_hex(r, hex_add_a_b) != 1) { + error_print(); + return -1; + } + + r = gf128_mul(a, b); + if (gf128_equ_hex(r, hex_mul_a_b) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} int main(void) { - gf128_t zero = gf128_from_hex("00000000000000000000000000000000"); - gf128_t one = gf128_from_hex("00000000000000000000000000000001"); - gf128_t ones = gf128_from_hex("11111111111111111111111111111111"); - gf128_t a = gf128_from_hex("de300f9301a499a965f8bf677e99e80d"); - gf128_t b = gf128_from_hex("14b267838ec9ef1bb7b5ce8c19e34bc6"); - gf128_t r; - - /* - r = gf128_add(a, b); - gf128_print("a + b = ", r); - - r = gf128_mul(a, b); - gf128_print("a * b = ", r); - - r = gf128_mul2(a); - gf128_print("a * 2 = ", r); - */ - - gf128_t H = gf128_from_hex("66e94bd4ef8a2c3b884cfa59ca342b2e"); - gf128_t C = gf128_from_hex("0388dace60b6a392f328c2b971b2fe78"); - gf128_t T = gf128_mul(C, H); - - - gf128_print(stderr, 0, 0, "C", C); - gf128_print(stderr, 0, 0, "H", H); - gf128_print(stderr, 0, 0, "C * H", T); - + if (test_gf128_from_hex() != 1) goto err; + if (test_gf128_mul2() != 1) goto err; + if (test_gf128_mul() != 1) goto err; + printf("%s all tests passed\n", __FILE__); return 0; +err: + error_print(); + return -1; + } diff --git a/tests/tls13test.c b/tests/tls13test.c new file mode 100644 index 00000000..bb63a378 --- /dev/null +++ b/tests/tls13test.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_tls13_gcm(void) +{ + + BLOCK_CIPHER_KEY block_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t seq_num[8] = {0,0,0,0,0,0,0,1}; + int record_type = TLS_record_handshake; + uint8_t in[40]; + size_t padding_len = 8; + uint8_t out[256]; + size_t outlen; + uint8_t buf[256]; + size_t buflen; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + rand_bytes(in, sizeof(in)); + + memset(out, 1, sizeof(out)); + outlen = 0; + memset(buf, 1, sizeof(buf)); + buflen = 0; + + if (block_cipher_set_encrypt_key(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { + error_print(); + return -1; + } + + if (tls13_gcm_encrypt(&block_key, iv, seq_num, record_type, in, sizeof(in), padding_len, out, &outlen) != 1) { + error_print(); + return -1; + } + if (tls13_gcm_decrypt(&block_key, iv, seq_num, out, outlen, &record_type, buf, &buflen) != 1) { + error_print(); + return -1; + } + + if (buflen != sizeof(in)) { + error_print(); + return -1; + } + if (memcmp(in, buf, buflen) != 0) { + error_print(); + return -1; + } + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_tls13_gcm() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return -1; +} diff --git a/tools/gmssl.c b/tools/gmssl.c index 02de94cf..d000acf8 100644 --- a/tools/gmssl.c +++ b/tools/gmssl.c @@ -226,12 +226,10 @@ int main(int argc, char **argv) return tls12_client_main(argc, argv); } else if (!strcmp(*argv, "tls12_server")) { return tls12_server_main(argc, argv); -/* } else if (!strcmp(*argv, "tls13_client")) { return tls13_client_main(argc, argv); } else if (!strcmp(*argv, "tls13_server")) { return tls13_server_main(argc, argv); -*/ } else if (!strcmp(*argv, "sdfutil")) { return sdfutil_main(argc, argv); } else if (!strcmp(*argv, "skfutil")) { diff --git a/tools/tls13_client.c b/tools/tls13_client.c index 9b45d865..f2a3d715 100644 --- a/tools/tls13_client.c +++ b/tools/tls13_client.c @@ -47,147 +47,156 @@ */ #include +#include #include #include + #include +#include +#include +#include +#include #include #include +// TLSv1.2客户单和TLCP客户端可能没有什么区别 + +static int client_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; + static const char *http_get = "GET / HTTP/1.1\r\n" "Hostname: aaa\r\n" "\r\n\r\n"; -void print_usage(const char *prog) -{ - printf("Usage: %s [options]\n", prog); - printf(" -host \n"); - printf(" -port \n"); - printf(" -cacerts \n"); - printf(" -cert \n"); - printf(" -key \n"); -} +static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]"; -int tls13_client_main(int argc , char *argv[]) +int tls13_client_main(int argc, char *argv[]) { int ret = -1; char *prog = argv[0]; char *host = NULL; int port = 443; + char *cacertfile = NULL; + char *certfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + struct sockaddr_in server; + int sock; + TLS_CTX ctx; TLS_CONNECT conn; char buf[100] = {0}; size_t len = sizeof(buf); - - char *cacertsfile = NULL; - char *certfile = NULL; - char *keyfile = NULL; - - FILE *cacertsfp = NULL; - FILE *certfp = NULL; - FILE *keyfp = NULL; - SM2_KEY sign_key; - - - if (argc < 2) { - print_usage(prog); - return 0; - } + char send_buf[1024] = {0}; + size_t send_len; argc--; argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } while (argc >= 1) { if (!strcmp(*argv, "-help")) { - print_usage(prog); + printf("usage: %s %s\n", prog, options); return 0; - } else if (!strcmp(*argv, "-host")) { if (--argc < 1) goto bad; host = *(++argv); - } else if (!strcmp(*argv, "-port")) { if (--argc < 1) goto bad; port = atoi(*(++argv)); - - } else if (!strcmp(*argv, "-cacerts")) { + } else if (!strcmp(*argv, "-cacert")) { if (--argc < 1) goto bad; - cacertsfile = *(++argv); - + cacertfile = *(++argv); } else if (!strcmp(*argv, "-cert")) { if (--argc < 1) goto bad; certfile = *(++argv); - } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; keyfile = *(++argv); - + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); } else { - print_usage(prog); + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); return 0; } argc--; argv++; } - if (!host /*|| !certfile || !keyfile */) { - print_usage(prog); + if (!host) { + fprintf(stderr, "%s: '-in' option required\n", prog); return -1; } - if (cacertsfile) { - if (!(cacertsfp = fopen(cacertsfile, "r"))) { - error_print(); - return -1; - } - } - if (certfile) { - if (!(certfp = fopen(certfile, "r"))) { - error_print(); - return -1; - } - } - if (keyfile) { - if (!(keyfp = fopen(keyfile, "r"))) { - error_print(); - return -1; - } - if (sm2_private_key_info_decrypt_from_pem(&sign_key, "password", keyfp) != 1) { - error_print(); - return -1; - } - } - + memset(&ctx, 0, sizeof(ctx)); memset(&conn, 0, sizeof(conn)); - if (tls13_connect(&conn, host, port, cacertsfp, certfp, &sign_key) != 1) { - error_print(); - return -1; + server.sin_addr.s_addr = inet_addr(host); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + fprintf(stderr, "%s: open socket error : %s\n", prog, strerror(errno)); + goto end; + } + if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) { + fprintf(stderr, "%s: connect error : %s\n", prog, strerror(errno)); + goto end; } - // 这个client 发收了一个消息就结束了 - if (tls_send(&conn, (uint8_t *)"12345\n", 6) != 1) { - error_print(); - return -1; + if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_client_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, client_ciphers, sizeof(client_ciphers)/sizeof(client_ciphers[0])) != 1 + || tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1 + || tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { + fprintf(stderr, "%s: context init error\n", prog); + goto end; + } + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, sock) != 1 + || tls_do_handshake(&conn) != 1) { + fprintf(stderr, "%s: error\n", prog); + goto end; } for (;;) { - memset(buf, 0, sizeof(buf)); - len = sizeof(buf); - if (tls_recv(&conn, (uint8_t *)buf, &len) != 1) { - error_print(); - return -1; + size_t sentlen; + + memset(send_buf, 0, sizeof(send_buf)); + if (!fgets(send_buf, sizeof(send_buf), stdin)) { + if (feof(stdin)) { + tls_shutdown(&conn); + goto end; + } else { + continue; + } } - if (len > 0) { + if (tls_send(&conn, (uint8_t *)send_buf, strlen(send_buf), &sentlen) != 1) { + fprintf(stderr, "%s: send error\n", prog); + goto end; + } + + { + memset(buf, 0, sizeof(buf)); + len = sizeof(buf); + if (tls_recv(&conn, (uint8_t *)buf, sizeof(len), &len) != 1) { + goto end; + } + buf[len] = 0; printf("%s\n", buf); - break; } } - return 1; -bad: - fprintf(stderr, "%s: command error\n", prog); +end: + close(sock); + tls_ctx_cleanup(&ctx); + tls_cleanup(&conn); return 0; } - - diff --git a/tools/tls13_server.c b/tools/tls13_server.c index 5f05382d..b557b593 100644 --- a/tools/tls13_server.c +++ b/tools/tls13_server.c @@ -47,127 +47,176 @@ */ #include +#include #include #include #include +#include +#include +#include +#include +#include #include #include #include -static void print_usage(const char *prog) -{ - printf("Usage: %s [options]\n", prog); - printf(" -port \n"); - printf(" -cert \n"); - printf(" -signkey \n"); -} +static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]"; -int tls13_server_main(int argc , char *argv[]) +int tls13_server_main(int argc , char **argv) { - int ret = -1; + int ret = 1; char *prog = argv[0]; int port = 443; char *certfile = NULL; - char *signkeyfile = NULL; - FILE *certfp = NULL; - FILE *signkeyfp = NULL; - SM2_KEY signkey; + char *keyfile = NULL; + char *pass = NULL; + char *cacertfile = NULL; + int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3, }; uint8_t verify_buf[4096]; - + TLS_CTX ctx; TLS_CONNECT conn; char buf[1600] = {0}; size_t len = sizeof(buf); - if (argc < 2) { - print_usage(prog); - return 0; - } + int sock; + struct sockaddr_in server_addr; + struct sockaddr_in client_addr; + socklen_t client_addrlen; + int conn_sock; + argc--; argv++; - while (argc >= 1) { - if (!strcmp(*argv, "-help")) { - print_usage(prog); - return 0; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + return 0; } else if (!strcmp(*argv, "-port")) { if (--argc < 1) goto bad; port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cert")) { if (--argc < 1) goto bad; certfile = *(++argv); - - } else if (!strcmp(*argv, "-signkey")) { + } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; - signkeyfile = *(++argv); - + keyfile = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-cacert")) { + if (--argc < 1) goto bad; + cacertfile = *(++argv); } else { - print_usage(prog); - return 0; + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; +bad: + fprintf(stderr, "%s: option '%s' argument required\n", prog, *argv); + return 1; } argc--; argv++; } - - if (!certfile || !signkeyfile) { - print_usage(prog); - return -1; - } - - if (!(certfp = fopen(certfile, "r"))) { - error_print(); - return -1; - } - - - if (!(signkeyfp = fopen(signkeyfile, "r"))) { - error_print(); - return -1; - } - if (sm2_private_key_info_decrypt_from_pem(&signkey, "password", signkeyfp) != 1) { - error_print(); - return -1; + if (!certfile) { + fprintf(stderr, "%s: '-cert' option required\n", prog); + return 1; + } + if (!keyfile) { + fprintf(stderr, "%s: '-key' option required\n", prog); + return 1; + } + if (!pass) { + fprintf(stderr, "%s: '-pass' option required\n", prog); + return 1; } + memset(&ctx, 0, sizeof(ctx)); memset(&conn, 0, sizeof(conn)); - if (tls13_accept(&conn, port, certfp, &signkey, certfp) != 1) { + + if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_server_mode) != 1 + || tls_ctx_set_cipher_suites(&ctx, server_ciphers, sizeof(server_ciphers)/sizeof(int)) != 1 + || tls_ctx_set_certificate_and_key(&ctx, certfile, keyfile, pass) != 1) { error_print(); return -1; } - - // 我要做一个反射的服务器,接收到用户的输入之后,再反射回去 - for (;;) { - - // 接收一个消息 - // 按道理说第二次执行的时候是不可能成功的了,因此客户端没有数据发过来 - do { - len = sizeof(buf); - if (tls_recv(&conn, (uint8_t *)buf, &len) != 1) { - error_print(); - return -1; - } - } while (!len); - - - // 把这个消息再发回去 - if (tls_send(&conn, (uint8_t *)buf, len) != 1) { + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { error_print(); return -1; } + } - fprintf(stderr, "-----------------\n\n\n\n\n\n"); + // Socket + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + error_print(); + return 1; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(port); + if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + error_print(); + perror("tlcp_accept: bind: "); + goto end; + } + puts("start listen ...\n"); + listen(sock, 1); + + +restart: + + client_addrlen = sizeof(client_addr); + if ((conn_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addrlen)) < 0) { + error_print(); + goto end; + } + puts("socket connected\n"); + + if (tls_init(&conn, &ctx) != 1 + || tls_set_socket(&conn, conn_sock) != 1) { + error_print(); + return -1; + } + + if (tls_do_handshake(&conn) != 1) { + error_print(); // 为什么这个会触发呢? + return -1; + } + + for (;;) { + + int rv; + size_t sentlen; + + do { + len = sizeof(buf); + if ((rv = tls_recv(&conn, (uint8_t *)buf, sizeof(buf), &len)) != 1) { + if (rv < 0) fprintf(stderr, "%s: recv failure\n", prog); + else fprintf(stderr, "%s: Disconnected by remote\n", prog); + + //close(conn.sock); + tls_cleanup(&conn); + goto restart; + } + } while (!len); + + if (tls_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) { + fprintf(stderr, "%s: send failure, close connection\n", prog); + close(conn.sock); + goto end; + } } - - return 1; -bad: - fprintf(stderr, "%s: command error\n", prog); - - return 0; +end: + return ret; }