TLS 1.3 server auth only

This commit is contained in:
Zhi Guan
2022-07-20 16:42:32 +08:00
parent 48e0178837
commit 89f57327aa
25 changed files with 5208 additions and 1102 deletions

View File

@@ -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)

10
demos/tlcp_client.sh Executable file
View File

@@ -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

22
demos/tlcp_server.sh Executable file
View File

@@ -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

15
demos/tls12.sh Executable file
View File

@@ -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

10
demos/tls12_client.sh Executable file
View File

@@ -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

16
demos/tls12_server.sh Executable file
View File

@@ -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

View File

@@ -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

View File

@@ -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,

2573
src/bak_tls13.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -58,6 +58,7 @@
#include <gmssl/hex.h>
#include <gmssl/gf128.h>
#include <gmssl/endian.h>
#include <gmssl/error.h>
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);
}
*/

124
src/gf128_gcc.c Normal file
View File

@@ -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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/hex.h>
#include <gmssl/gf128.h>
#include <gmssl/endian.h>
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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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,

View File

@@ -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
&not_before, &not_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;
}

View File

@@ -51,6 +51,8 @@
#include <stdlib.h>
#include <gmssl/gcm.h>
#include <gmssl/hex.h>
#include <gmssl/rand.h>
#include <gmssl/block_cipher.h>
#include <gmssl/error.h>
@@ -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;
}

View File

@@ -52,44 +52,95 @@
#include <assert.h>
#include <gmssl/hex.h>
#include <gmssl/gf128.h>
#include <gmssl/error.h>
/*
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;
}

119
tests/tls13test.c Normal file
View File

@@ -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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/oid.h>
#include <gmssl/x509.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
#include <gmssl/tls.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
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;
}

View File

@@ -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")) {

View File

@@ -47,147 +47,156 @@
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <gmssl/tls.h>
#include <gmssl/error.h>
// 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 <str>\n");
printf(" -port <num>\n");
printf(" -cacerts <file>\n");
printf(" -cert <file>\n");
printf(" -key <file>\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;
}

View File

@@ -47,127 +47,176 @@
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <gmssl/mem.h>
#include <gmssl/sm2.h>
#include <gmssl/tls.h>
#include <gmssl/error.h>
static void print_usage(const char *prog)
{
printf("Usage: %s [options]\n", prog);
printf(" -port <num>\n");
printf(" -cert <file>\n");
printf(" -signkey <file>\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;
}