├── .gitignore ├── sm4-demo ├── config.h.in ├── CMakeLists.txt └── src │ └── main.c ├── clone_openssl.bash ├── download_openssl.bash ├── .travis.yml ├── ssl-demo ├── README.md.txt ├── CMakeLists.txt └── src │ ├── client │ └── client.c │ └── server │ └── server.c ├── command-line-demo └── README.md.txt └── ssl-gm-demo └── README.md.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.[oa] 2 | *.so 3 | *.swp 4 | *.bak 5 | *.log 6 | *.cmake 7 | CMakeCache.txt 8 | CMakeFiles 9 | *.tar.* 10 | openssl 11 | -------------------------------------------------------------------------------- /sm4-demo/config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** Define to 1 if you have the header file */ 4 | #cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@ 5 | -------------------------------------------------------------------------------- /clone_openssl.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | clone_from_url="https://github.com/openssl/openssl.git" 4 | openssl_git_tag="OpenSSL_1_1_1c" 5 | build_dir=openssl 6 | if [ ! -d "$build_dir" ] ; then 7 | echo "Cloning tag $openssl_git_tag from $clone_from_url" 8 | git clone --depth=1 -b $openssl_git_tag $clone_from_url 9 | fi -------------------------------------------------------------------------------- /download_openssl.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | tarball_version="1.1.1c" 4 | tarball_filename="openssl-$tarball_version.tar.gz" 5 | download_from_url="https://openssl.org/source/$tarball_filename" 6 | wget --continue $download_from_url 7 | 8 | build_dir=openssl 9 | if [ ! -d "$build_dir" ] ; then 10 | tar xf $tarball_filename 11 | mv "openssl-$tarball_version" "$build_dir" 12 | fi -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | language: c 4 | compiler: 5 | - gcc 6 | 7 | env: 8 | 9 | addons: 10 | apt: 11 | packages: 12 | - cmake 13 | - libssl-dev 14 | 15 | install: 16 | - mkdir -p build 17 | - pushd build 18 | - cmake ../sm4-demo 19 | - make 20 | - popd # build 21 | 22 | script: 23 | # TODO: Check the demo program's output. 24 | - ./build/demo 25 | 26 | after_failure: 27 | # TODO: Report failure infomation 28 | -------------------------------------------------------------------------------- /ssl-demo/README.md.txt: -------------------------------------------------------------------------------- 1 | 参考:https://blog.csdn.net/oj847935591/article/details/79362542 2 | 作者:Brown_IT小白 3 | 来源:CSDN 4 | 5 | # 制作serverKey.pem和serverCert.cer 6 | ``` 7 | openssl req -newkey rsa:2048 -nodes -keyout serverKey.pem \ 8 | -x509 -days 365 -out serverCert.cer \ 9 | -subj "/C=CN/ST=GD/L=GZ/O=abc/OU=defg/CN=hijk/emailAddress=132456.com" 10 | ``` 11 | 12 | # CentOS环境编译前需要安装开发工具 13 | ``` 14 | sudo yum groupinstall "Development Tools" 15 | sudo yum install cmake3 openssl-devel 16 | ``` 17 | 18 | # 编译步骤 19 | ``` 20 | cmake3 . 21 | make 22 | ``` 23 | -------------------------------------------------------------------------------- /sm4-demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | project(DEMO LANGUAGES C) 3 | include(${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) 4 | check_include_file("stdint.h" HAVE_STDINT_H) 5 | configure_file( 6 | "${PROJECT_SOURCE_DIR}/config.h.in" 7 | "${PROJECT_BINARY_DIR}/config.h" 8 | ) 9 | include_directories(${PROJECT_BINARY_DIR}) 10 | add_definitions(-DHAVE_CONFIG_H) 11 | aux_source_directory(./src DEMO_SOURCES) 12 | add_executable(demo ${DEMO_SOURCES}) 13 | set_property(TARGET demo PROPERTY C_STANDARD 11) 14 | 15 | find_package(OpenSSL REQUIRED) 16 | target_include_directories(demo PRIVATE ${OPENSSL_INCLUDE_DIR}) 17 | target_link_libraries(demo PRIVATE 18 | ${OPENSSL_CRYPTO_LIBRARY} 19 | ) 20 | -------------------------------------------------------------------------------- /ssl-demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | project(demo1 LANGUAGES C) 3 | 4 | aux_source_directory(./src/client client_SOURCES) 5 | aux_source_directory(./src/server server_SOURCES) 6 | add_executable(client ${client_SOURCES}) 7 | add_executable(server ${server_SOURCES}) 8 | set_property(TARGET client PROPERTY C_STANDARD 11) 9 | set_property(TARGET server PROPERTY C_STANDARD 11) 10 | 11 | find_package(OpenSSL REQUIRED) 12 | target_include_directories(client PRIVATE ${OPENSSL_INCLUDE_DIR}) 13 | target_include_directories(server PRIVATE ${OPENSSL_INCLUDE_DIR}) 14 | target_link_libraries(client PRIVATE 15 | ${OPENSSL_LIBRARIES} 16 | ) 17 | target_link_libraries(server PRIVATE 18 | ${OPENSSL_LIBRARIES} 19 | ) 20 | -------------------------------------------------------------------------------- /command-line-demo/README.md.txt: -------------------------------------------------------------------------------- 1 | # 制作serverKey.pem和serverCert.cer 2 | ``` 3 | openssl req -newkey rsa:2048 -nodes -keyout serverKey.pem \ 4 | -x509 -days 365 -out serverCert.cer \ 5 | -subj "/C=CN/ST=GD/L=GZ/O=abc/OU=defg/CN=server/emailAddress=server@132456.com" 6 | ``` 7 | 8 | # 验证 9 | ``` 10 | 在第一个终端窗口运行 11 | openssl s_server -accept 4430 -key serverKey.pem -cert serverCert.cer 12 | 13 | 在第二个终端窗口制作clientKey.pem和clientCert.cer,然后运行openssl s_client 14 | openssl req -newkey rsa:2048 -nodes -keyout clientKey.pem \ 15 | -x509 -days 365 -out clientCert.cer \ 16 | -subj "/C=CN/ST=GD/L=GZ/O=abc/OU=defg/CN=client/emailAddress=client@132456.com" 17 | openssl s_client -connect 127.0.0.1:4430 -key clientKey.pem -cert clientCert.cer 18 | ``` 19 | -------------------------------------------------------------------------------- /ssl-gm-demo/README.md.txt: -------------------------------------------------------------------------------- 1 | 2 | # 下载GmSSL 3 | 网址:https://github.com/guanzhi/GmSSL 4 | 如果通过源码包方式下载需要手动解压缩 5 | 如果通过git方式下载可以按标签找出特定版本 6 | 7 | # GmSSL编译步骤 8 | ``` 9 | cd GmSSL-master 10 | ./config 11 | make 12 | sudo make install 13 | ``` 14 | 15 | # 安装之后的环境配置 16 | 默认会安装到/usr/local/bin和/usr/local/lib64目录, 17 | 需要注意运行gmssl工具前,还需要手动配置环境变量LD_LIBRARY_PATH=/usr/local/lib64 18 | ``` 19 | export LD_LIBRARY_PATH=/usr/local/lib64 20 | GmSSL> version 21 | GmSSL 2.0 - OpenSSL 1.1.0d 26 Jan 2017 22 | GmSSL> quit 23 | ``` 24 | 25 | # 制作SM2椭圆曲线密钥文件和X509格式的证书 26 | 27 | ``` 28 | # 设置环境变量 29 | export LD_LIBRARY_PATH=/usr/local/lib64 30 | 31 | # 椭圆曲线签名密钥skey 32 | gmssl sm2 -genkey -out ca.skey.pem 33 | 34 | # 创建CA根证书 35 | gmssl req -new -nodes -x509 -days 3650 \ 36 | -key ca.skey.pem -out ca.cert.pem \ 37 | -subj "/C=CN/ST=GD/L=GZ/O=abc/OU=defg/CN=CA/emailAddress=CA@132456.com" 38 | 39 | # 创建用户密钥和用户证书 40 | 41 | # 通讯测试 42 | gmssl s_server -accept 4433 -key serverKey.pem -cert serverCert.cer 43 | gmssl s_client -connect 127.0.0.1:4433 -key clientKey.pem -cert clientCert.cer 44 | ``` 45 | 46 | # 参考文档: 47 | * https://github.com/guanzhi/GmSSL/tree/master#quick-start 48 | -------------------------------------------------------------------------------- /ssl-demo/src/client/client.c: -------------------------------------------------------------------------------- 1 | /** 文件名: client.c */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define CHK_ERR(err, s) if((err) == -1) { perror(s); return -1; } 16 | #define CHK_RV(rv, s) if((rv) != 1) { printf("%s error\n", s); return -1; } 17 | #define CHK_NULL(x, s) if((x) == NULL) { printf("%s error\n", s); return -1; } 18 | #define CHK_SSL(err, s) if((err) == -1) { ERR_print_errors_fp(stderr); return -1;} 19 | 20 | int main() 21 | { 22 | int rv; 23 | int err; 24 | int client_fd; 25 | struct sockaddr_in socketAddrClient; 26 | const SSL_METHOD *meth = NULL; 27 | SSL_CTX *ctx = NULL; 28 | SSL *ssl = NULL; 29 | char buf[4096]; 30 | 31 | rv = SSL_library_init(); 32 | CHK_RV(rv, "SSL_library_init"); 33 | 34 | meth = TLS_client_method(); 35 | ctx = SSL_CTX_new(meth); 36 | CHK_NULL(ctx, "SSL_CTX_new"); 37 | 38 | client_fd = socket(AF_INET, SOCK_STREAM, 0); 39 | CHK_ERR(client_fd, "socket"); 40 | memset(&socketAddrClient, 0, sizeof(socketAddrClient)); 41 | socketAddrClient.sin_family = AF_INET; 42 | socketAddrClient.sin_port = htons(8443); 43 | socketAddrClient.sin_addr.s_addr = inet_addr("127.0.0.1"); 44 | 45 | err = connect(client_fd, (struct sockaddr *)&socketAddrClient, sizeof(socketAddrClient)); 46 | CHK_ERR(err, "connect"); 47 | ssl = SSL_new(ctx); 48 | CHK_NULL(ssl, "SSL_new"); 49 | rv = SSL_set_fd(ssl, client_fd); 50 | CHK_RV(rv, "SSL_set_fd"); 51 | rv = SSL_connect(ssl); 52 | CHK_RV(rv, "SSL_connect"); 53 | 54 | rv = SSL_write(ssl, "Hello, I am the client", strlen("Hello, I am the client")); 55 | CHK_SSL(rv, "SSL_write"); 56 | rv = SSL_read(ssl, buf, sizeof(buf) - 1); 57 | CHK_SSL(rv, "SSL_read"); 58 | buf[rv] = '\0'; 59 | printf("Got %d chars :%s\n", rv, buf); 60 | 61 | SSL_shutdown(ssl); 62 | close(client_fd); 63 | SSL_free(ssl); 64 | SSL_CTX_free(ctx); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /ssl-demo/src/server/server.c: -------------------------------------------------------------------------------- 1 | /** 文件名: server.c */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define CERTSERVER "serverCert.cer" 16 | #define KEYSERVER "serverKey.pem" 17 | 18 | #define CHK_ERR(err, s) if((err) == -1) { perror(s); return -1; } 19 | #define CHK_RV(rv, s) if((rv) != 1) { printf("%s error\n", s); return -1; } 20 | #define CHK_NULL(x, s) if((x) == NULL) { printf("%s error\n", s); return -1; } 21 | #define CHK_SSL(err, s) if((err) == -1) { ERR_print_errors_fp(stderr); return -1;} 22 | 23 | int main() 24 | { 25 | int rv, err; 26 | SSL_CTX *ctx = NULL; 27 | const SSL_METHOD *meth = NULL; 28 | int listen_sd; 29 | int accept_sd; 30 | struct sockaddr_in socketAddrServer; 31 | struct sockaddr_in socketAddrClient; 32 | int socketAddrClientLen; 33 | SSL *ssl = NULL; 34 | char buf[4096]; 35 | 36 | rv = SSL_library_init(); 37 | CHK_RV(rv, "SSL_library_init"); 38 | 39 | meth = TLS_server_method(); 40 | ctx = SSL_CTX_new(meth); 41 | CHK_NULL(ctx, "SSL_CTX_new"); 42 | 43 | rv = SSL_CTX_use_certificate_file(ctx, CERTSERVER, SSL_FILETYPE_PEM); 44 | CHK_RV(rv, "SSL_CTX_use_certicificate_file"); 45 | 46 | rv = SSL_CTX_use_PrivateKey_file(ctx, KEYSERVER, SSL_FILETYPE_PEM); 47 | CHK_RV(rv, "SSL_CTX_use_PrivateKey_file"); 48 | 49 | rv = SSL_CTX_check_private_key(ctx); 50 | CHK_RV(rv, "SSL_CTX_check_private_key"); 51 | 52 | listen_sd = socket(AF_INET, SOCK_STREAM, 0); 53 | CHK_ERR(listen_sd, "socket"); 54 | memset(&socketAddrServer, 0, sizeof(socketAddrServer)); 55 | socketAddrServer.sin_family = AF_INET; 56 | socketAddrServer.sin_port = htons(8443); 57 | socketAddrServer.sin_addr.s_addr = INADDR_ANY; 58 | 59 | err = bind(listen_sd, (struct sockaddr *)&socketAddrServer, sizeof(socketAddrServer)); 60 | CHK_ERR(err, "bind"); 61 | err = listen(listen_sd, 5); 62 | CHK_ERR(err, "listen"); 63 | 64 | socketAddrClientLen = sizeof(socketAddrClient); 65 | accept_sd = accept(listen_sd, (struct sockaddr *)&socketAddrClient, &socketAddrClientLen); 66 | CHK_ERR(accept_sd, "accept"); 67 | close(listen_sd); 68 | printf("Connect to %s, port 0x%04X(=%d)\n", inet_ntoa(socketAddrClient.sin_addr), (int)ntohs(socketAddrClient.sin_port), (int)ntohs(socketAddrClient.sin_port)); 69 | 70 | ssl = SSL_new(ctx); 71 | CHK_NULL(ssl, "SSL_new"); 72 | rv = SSL_set_fd(ssl, accept_sd); 73 | CHK_RV(rv, "SSL_set_fd"); 74 | rv = SSL_accept(ssl); 75 | CHK_RV(rv, "SSL_accpet"); 76 | 77 | rv = SSL_read(ssl, buf, sizeof(buf) - 1); 78 | CHK_SSL(rv, "SSL_read"); 79 | buf[rv] = '\0'; 80 | printf("Got %d chars :%s\n", rv, buf); 81 | rv = SSL_write(ssl, "I accept your request", strlen("I accept your request")); 82 | CHK_SSL(rv, "SSL_write"); 83 | 84 | close(accept_sd); 85 | SSL_free(ssl); 86 | SSL_CTX_free(ctx); 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /sm4-demo/src/main.c: -------------------------------------------------------------------------------- 1 | /** 文件名: main.c */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "openssl/err.h" 7 | #include "openssl/evp.h" 8 | 9 | #if !defined(OPENSSL_VERSION_NUMBER) 10 | #define OPENSSL_VERSION_NUMBER 0 11 | #endif 12 | 13 | /* Before OpenSSL 1.1.1-pre1, we did not have EVP_sm4_ecb() */ 14 | #if defined(OPENSSL_NO_SM4) || \ 15 | OPENSSL_VERSION_NUMBER < 0x10101001L 16 | static const EVP_CIPHER *(*EVP_sm4_ecb)()=EVP_aes_128_ecb; 17 | #endif 18 | 19 | typedef struct { 20 | const unsigned char *in_data; 21 | size_t in_data_len; 22 | int in_data_is_already_padded; 23 | const unsigned char *in_ivec; 24 | const unsigned char *in_key; 25 | size_t in_key_len; 26 | } test_case_t; 27 | 28 | 29 | void test_encrypt_with_cipher(const test_case_t *in, const EVP_CIPHER *cipher) 30 | { 31 | unsigned char *out_buf = NULL; 32 | int out_len; 33 | int out_padding_len; 34 | EVP_CIPHER_CTX *ctx; 35 | 36 | ctx = EVP_CIPHER_CTX_new(); 37 | EVP_EncryptInit_ex(ctx, cipher, NULL, in->in_key, in->in_ivec); 38 | 39 | if (in->in_data_is_already_padded) 40 | { 41 | /* Check whether the input data is already padded. 42 | And its length must be an integral multiple of the cipher's block size. */ 43 | const size_t bs = EVP_CIPHER_block_size(cipher); 44 | if (in->in_data_len % bs != 0) 45 | { 46 | printf("ERROR-1: data length=%d which is not added yet; block size=%d\n", (int) in->in_data_len, (int) bs); 47 | /* Warning: Remember to do some clean-ups */ 48 | EVP_CIPHER_CTX_free(ctx); 49 | return; 50 | } 51 | /* Disable the implicit PKCS#7 padding defined in EVP_CIPHER */ 52 | EVP_CIPHER_CTX_set_padding(ctx, 0); 53 | } 54 | 55 | out_buf = (unsigned char *) malloc(((in->in_data_len>>4)+1) << 4); 56 | out_len = 0; 57 | EVP_EncryptUpdate(ctx, out_buf, &out_len, in->in_data, in->in_data_len); 58 | if (1) 59 | { 60 | printf("Debug: out_len=%d\n", out_len); 61 | } 62 | 63 | out_padding_len = 0; 64 | EVP_EncryptFinal_ex(ctx, out_buf+out_len, &out_padding_len); 65 | if (1) 66 | { 67 | printf("Debug: out_padding_len=%d\n", out_padding_len); 68 | } 69 | 70 | EVP_CIPHER_CTX_free(ctx); 71 | if (1) 72 | { 73 | int i; 74 | int len; 75 | len = out_len + out_padding_len; 76 | for (i=0; i= 0x10101001L); 93 | int have_aes = 1; 94 | const unsigned char data[]= 95 | { 96 | 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 97 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 98 | }; 99 | unsigned char ivec[EVP_MAX_IV_LENGTH]; ///< IV 向量 100 | const unsigned char key1[16] = ///< key_data, 密钥内容, 至少16字节 101 | { 102 | 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 103 | 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 104 | }; 105 | test_case_t tc; 106 | 107 | tc.in_data = data; 108 | tc.in_data_len = sizeof(data); 109 | tc.in_data_is_already_padded = (tc.in_data_len % 16)==0; // Hard coded 16 as the cipher's block size 110 | tc.in_key = key1; 111 | tc.in_key_len = sizeof(key1); 112 | memset(ivec, 0x00, EVP_MAX_IV_LENGTH); 113 | tc.in_ivec = ivec; 114 | 115 | #if defined(OPENSSL_NO_SM4) 116 | have_sm4 = 0; 117 | #endif 118 | if (have_sm4) 119 | { 120 | printf("[1]\n"); 121 | printf("Debug: EVP_sm4_ecb() test\n"); 122 | test_encrypt_with_cipher(&tc, EVP_sm4_ecb()); 123 | } 124 | #if defined(OPENSSL_NO_AES) 125 | have_aes = 0; 126 | #endif 127 | if (have_aes) 128 | { 129 | printf("[2]\n"); 130 | printf("Debug: EVP_aes_128_ecb() test\n"); 131 | test_encrypt_with_cipher(&tc, EVP_aes_128_ecb()); 132 | } 133 | } 134 | 135 | --------------------------------------------------------------------------------