#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef OPENSSL_NO_ENGINE
#include
#endif
int make_server_private_key()
{
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
ERR_load_crypto_strings();
SSL_CTX *ctx = SSL_CTX_new (SSLv23_server_method ());
SSL_CTX_set_options (ctx,
SSL_OP_SINGLE_DH_USE |
SSL_OP_SINGLE_ECDH_USE |
SSL_OP_NO_SSLv2);
EVP_PKEY *evk = EVP_PKEY_new();
EC_KEY *ec_server = EC_KEY_new_by_curve_name (NID_sm2p256v1);
if (! ec_server)
printf("ecdh error!EC_KEY_new_by_curve_name\n");
EC_KEY_generate_key(ec_server);
BIO *bio_out = BIO_new_file("server_private.key", "w");
PEM_write_bio_ECPrivateKey(bio_out, ec_server, NULL, NULL, 0, NULL, NULL);
BIO_free(bio_out);
EC_KEY_free(ec_server);
EVP_PKEY_free(evk);
return 0;
}
int make_cert(char* name_C, char* name_S, char* name_L, char* name_O, char * name_OU, char* name_CN,
char* PrivateKeyFileName, char* CertFileName )
{
X509 *x;
EVP_PKEY *pk;
X509_NAME *name = NULL;
BIO * key = NULL;
key = BIO_new(BIO_s_file());
BIO_read_filename(key,PrivateKeyFileName);
EC_KEY *ecdh = PEM_read_bio_ECPrivateKey(key, NULL, NULL, NULL);
EVP_PKEY *evk = EVP_PKEY_new();
EVP_PKEY_set1_EC_KEY(evk, ecdh);
X509 *x509 = NULL;
if (evk == NULL)
{
abort();
return(0);
}
else
pk = evk;
if ((x = X509_new()) == NULL)
return(0);
X509_set_version(x, 2);
int serial = 12345;
ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
X509_gmtime_adj(X509_get_notBefore(x), 0);
int days = 36500;
X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days);
X509_set_pubkey(x, pk);
name = X509_get_subject_name(x);
X509_NAME_add_entry_by_txt(name, "C",
MBSTRING_ASC, name_C, -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "S",
MBSTRING_ASC, name_S, -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "L",
MBSTRING_ASC, name_L, -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O",
MBSTRING_ASC, name_O, -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "OU",
MBSTRING_ASC, name_OU, -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN",
MBSTRING_ASC, name_CN, -1, -1, 0);
X509_NAME *issuer_name=NULL;
if (!issuer_name)
X509_set_issuer_name(x, name);
else
X509_set_issuer_name(x, issuer_name);
int n=X509_sign(x, evk, EVP_sm3());
x509 = x;
evk = pk;
BIO *bio_x = BIO_new_file(CertFileName, "w");
PEM_write_bio_X509(bio_x, x509);
printf("n=%d\n",n);
BIO_free(bio_x);
EVP_PKEY_free(evk);
EC_KEY_free(ecdh);
X509_free(x509);
return(1);
}
以下代码有可能不符合国标:
int signature(char *msg)
{
int ret = 0;
unsigned int slen=256;
unsigned char sig[256];
BIO * key = NULL;
key = BIO_new(BIO_s_file());
BIO_read_filename(key,"server_private.key");
EC_KEY *ecdh = PEM_read_bio_ECPrivateKey(key, NULL, NULL, NULL);
printf("sig len:%d\n", ECDSA_size(ecdh));
if (!SM2_sign(0,msg, strlen(msg), sig,&slen,ecdh))
{
return 0;
}
FILE *fp = fopen("server_16.sig", "wb");
for(int i=0; i < slen; i++)
{
fwrite(((unsigned char*)(sig+i)), 1, 1, fp);
}
fclose(fp);
printf("slen:%d\n", slen);
for(int i=0; i < slen; i++)
{
printf("%02x ", *((unsigned char*)(sig+i)));
}
printf("\n");
/* 成功 */
ret = 1;
/* 清理 */
return ret;
}
int verify_sig(void *sig, char *msg, size_t slen)
{
int nRet;
ECDSA_SIG *s;
const unsigned char *p = sig;
unsigned char *der = NULL;
int derlen = -1;
int ret = -1;
FILE *fp = fopen("server_cert.pem", "r");
X509 *cert = PEM_read_X509(fp, NULL, NULL, NULL);
//FILE *fp = fopen("server_cert.der", "r");
//X509 *cert = d2i_X509_fp(fp, NULL);
EVP_PKEY *evk = X509_get_pubkey(cert);
EC_KEY *ec_key=EVP_PKEY_get0_EC_KEY(evk);
printf("\nslen:%ld\n", slen);
for(int i=0; i < slen; i++)
{
printf("%02x ", *((unsigned char*)(sig+i)));
}
printf("\n");
nRet = SM2_verify(0,msg, strlen(msg), sig, slen,ec_key);
return nRet == 1 ? 1 : 0;
}