源码下载地址:https://github.com/guanzhi/GmSSL/releases
编译文档地址:http://gmssl.org/docs/install.html
一、环境准备
1.安装ActivePerl和Visual Studio
ActivePerl下载地址:https://www.activestate.com/products/perl/
Visual Studio下载地址:https://visualstudio.microsoft.com/zh-hans/
我这边ActivePerl使用的5.28,Visual Studio使用的2019
二、编译步骤
【注意】需要使用Visual Studio中的命令行工具执行,x64和ia32需要使用不同版本的命令行工具执行。不要使用cmd执行,不要使用vscode控制台执行。
1.32位版本
perl Configure VC-WIN32
nmake
2.64位版本
perl Configure VC-WIN64A
nmake
如果执行过nmake命令,可以执行nmake clean清除编译过程文件
执行perl Configure -h 可以查看支持编译的平台和架构信息
三、中间遇到的问题
1.解决缺少Win32::Console问题
打开C:\Perl64\site\lib\ActivePerl\Cofnig.pm文件,注释掉以下代码,我这版本在393行
# Prevent calling Win32::Console::DESTROY on a STDOUT handle
# my $console;
sub _warn {
# my($msg) = @_;
# unless (-t STDOUT) {
# print "\n$msg\n";
# return;
# }
# require Win32::Console;
# unless ($console) {
# $console = Win32::Console->new(Win32::Console::STD_OUTPUT_HANDLE());
# }
# my($col,undef) = $console->Size;
# print "\n";
# my $attr = $console->Attr;
# $console->Attr($Win32::Console::FG_RED | $Win32::Console::BG_WHITE);
# for (split(/\n/, "$msg")) {
# $_ .= " " while length() < $col-1;
# print "$_\n";
# }
# $console->Attr($attr);
# print "\n";
}
2.fatal error LNK1112:模块计算机类型“x86”与目标计算机类型“x64”冲突
NMAKE:fatal error U1007:"link":返回代码“0x1”
此错误是perl Configure xxx生成的版本和nmake执行的版本不同造成的
比如perl Configure VC-WIN32生成配置,nmake是在64位的控制台里执行或者
perl Configure VC-WIN64A生成配置,nmake在32位控制台执行。
3.error LNK2001:无法解析外部符号 EVP_get_ciphernames
error LNK2001:无法解析外部符号 EVP_get_digestnames
NMAKE:fatal error U1007:"link":返回代码“0x1”
此错误是,因为GmSLL当前代码版本【crypto\evp\names2.c】在windows平台有问题
修源码改成为一下版本,此源码来源于GmSSL-gmbrowser-v0.1,下载地址:https://github.com/guanzhi/GmSSL/releases
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <internal/objects.h>
#include <openssl/x509.h>
#include "internal/evp_int.h"
const EVP_CIPHER *EVP_get_default_cipher(void)
{
return NULL;
}
/*
* use MD5 as default:
* X509_REQ_to_X509 x509_r2x.c
* X509_issuer_and_serial_hash x509_cmp.c
* X509_NAME_hash_old x509_cmp.c
* PEM_ASN1_write_bio pem_lib.c
*/
const EVP_MD *EVP_get_default_digest(void)
{
#if !defined(OPENSSL_NO_MD5)
return EVP_md5();
#elif !defined(OPENSSL_NO_SHA)
return EVP_sha1();
#elif !defined(OPENSSL_NO_SM3)
return EVP_sm3();
#elif !defined(OPENSSL_NO_RIPEMD)
return EVP_rmd160();
#else
return NULL;
#endif
}
static void cipher_name_len(const EVP_CIPHER *cipher, const char *from,
const char *to, void *x)
{
*((int *)x) += strlen(EVP_CIPHER_name(cipher));
}
static void cipher_name(const EVP_CIPHER *cipher, const char *from,
const char *to, void *x)
{
strcat((char *)x, EVP_CIPHER_name(cipher));
}
char *EVP_get_ciphernames(int aliases)
{
char *ret = NULL;
int len = 0;
EVP_CIPHER_do_all_sorted(cipher_name_len, &len);
ret = OPENSSL_zalloc(len);
if (!ret) {
return NULL;
}
EVP_CIPHER_do_all_sorted(cipher_name, ret);
return ret;
}
char *EVP_get_digestnames(int aliases)
{
return "sm3:sha1:sha256";
}