#include "StdAfx.h" #include "VerifyCertificate.h" time_t NowTime() { time_t t_Now = time(0); struct tm* tm_Now = localtime(&t_Now); tm_Now->tm_hour =0; tm_Now->tm_min = 0; tm_Now->tm_sec = 0; return mktime(tm_Now); } X509* LoadCert(const char * cert, const int certlen, const char *p12pass, const int format) { //CLogFile* log = new CLogFile("log.txt"); //log->LOGERROR("test, %s", cert); if (NULL == cert) { //log->LOGERROR("Input cert path is null"); printf("Input cert path is null"); return NULL; } X509 * x509=NULL; BIO * in=NULL; if(certlen==0) { if((in=BIO_new_file(cert, "r"))==NULL) { //log->LOGERROR("BIO_new_file err, file path is %s", cert); return NULL; } } else { if((in=BIO_new_mem_buf((void*)cert,certlen))== NULL) { //log->LOGERROR("BIO_new_mem_buf err, file path is %s", cert); return NULL; } } if(format==FORMAT_DER) { x509=d2i_X509_bio(in,NULL); } else if(format==FORMAT_PEM) { x509=PEM_read_bio_X509(in,NULL,NULL,NULL); } else if(format==FORMAT_P12) { PKCS12 *p12 = d2i_PKCS12_bio(in, NULL); PKCS12_parse(p12, p12pass, NULL, &x509, NULL); PKCS12_free(p12); } else { BIO_free(in); return NULL; } BIO_free(in); if(x509) { return x509; } else { //log->LOGERROR("PEM_read_bio_X509 return null,file path is %s", cert); return NULL; } } X509_CRL* LoadCrl(const char *crlFile) { if (NULL == crlFile) { printf("Input crl path is null"); return NULL; } X509_CRL *crl = NULL; BIO *in = NULL; if((in=BIO_new_file(crlFile, "r"))==NULL) { return NULL; } crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); BIO_free(in); return crl; } //DWORD CheckCertLife(const char *pubCert, const int pubCertLen, const int certFormat) //{ // //CLogFile* log = new CLogFile("log.txt"); // //log->LOGERROR("test, %s", pubCert); // DWORD utcTime = 0; // struct tm *ptm = NULL; // // if (NULL == pubCert) // { // return INPUT_NULL_ERR; // } // // X509 *x509=LoadCert(pubCert,pubCertLen,NULL,certFormat); // if (NULL == x509) // { // return LOAD_CERT_ERR; // } // // //以加密锁内时钟为基准时间 // int nRet = GetUTCTimeFromUkey(&utcTime); // if (nRet != DONGLE_SUCCESS) // { // return GET_UKEY_CLOCK_ERR; // } // // //小时+8转换为标准时间 // if (sizeof(int) == 4) // { // ptm = _gmtime32((const __time32_t *)&utcTime); // } // else if(sizeof(int)==8) // { // ptm = _gmtime64((const __time64_t *)&utcTime); // } // else // { // ptm = gmtime((const time_t *)&utcTime); // } // ptm->tm_hour += 8; // // time_t ct = mktime(ptm); // // //CTime time = CTime::GetCurrentTime(); // //time_t ct = time.GetTime(); // // asn1_string_st *before=X509_get_notBefore(x509), *after=X509_get_notAfter(x509); // ASN1_UTCTIME *be=ASN1_STRING_dup(before), *af=ASN1_STRING_dup(after); // // int ret = ASN1_UTCTIME_cmp_time_t(be,ct); // if (ASN1_UTCTIME_cmp_time_t(be,ct) >= 0) // { // return CERT_NOT_START_VALIDITY_ERR; // } // // if (ASN1_UTCTIME_cmp_time_t(af,ct) <= 0) // { // return CERT_OVERTIME_ERR; // } // // M_ASN1_UTCTIME_free(be); // M_ASN1_UTCTIME_free(af); // X509_free(x509); // // return SUCCESS; //} DWORD CheckCertLife(const char *pubCert, const int pubCertLen, const int certFormat) { //CLogFile* log = new CLogFile("log.txt"); //log->LOGERROR("test, %s", pubCert); DWORD utcTime = 0; struct tm *ptm = NULL; if (NULL == pubCert) { return INPUT_NULL_ERR; } X509 *x509=LoadCert(pubCert,pubCertLen,NULL,certFormat); if (NULL == x509) { return LOAD_CERT_ERR; } time_t ct = NowTime(); asn1_string_st *before=X509_get_notBefore(x509), *after=X509_get_notAfter(x509); ASN1_UTCTIME *be=ASN1_STRING_dup(before), *af=ASN1_STRING_dup(after); int ret = ASN1_UTCTIME_cmp_time_t(be,ct); if (ASN1_UTCTIME_cmp_time_t(be,ct) >= 0) { return CERT_NOT_START_VALIDITY_ERR; } if (ASN1_UTCTIME_cmp_time_t(af,ct) <= 0) { return CERT_OVERTIME_ERR; } M_ASN1_UTCTIME_free(be); M_ASN1_UTCTIME_free(af); X509_free(x509); return SUCCESS; } DWORD VerifCrl(const char *strCrlFile, const char *pchCaCertFile) { if (NULL == strCrlFile || NULL == pchCaCertFile) { printf("Input parameter is null,crl path=%s, ca cert path=%s\n", strCrlFile, pchCaCertFile); return INPUT_NULL_ERR; } X509_CRL *crl = LoadCrl(strCrlFile); if (NULL == crl) { printf("load %s err\n",strCrlFile); return LOAD_CRL_ERR; } X509 *cert = LoadCert(pchCaCertFile, 0, NULL, FORMAT_PEM); if (NULL == cert) { printf("load %s err\n", pchCaCertFile); return LOAD_CERT_ERR; } EVP_PKEY *pubkey = X509_get_pubkey(cert); if (!pubkey) { printf("get CRL issuer public key from %s err\n", pchCaCertFile); return GET_PUBKEY_FROM_CERT_ERR; } //RSA* rasKey = RSA_new(); //ReadPublicKeyFile(pchCaCertFile,rasKey); //ReadPrivateKeyFile(pchCaCertFile,NULL, &rasKey); //EVP_PKEY *pubkey = EVP_PKEY_new(); //EVP_PKEY_assign_RSA(pubkey,rasKey); //if (0 == X509_CRL_verify(crl,cert->cert_info->key->pkey)) int ret = X509_CRL_verify(crl,pubkey); if (ret < 0) { printf("Verify CRL failure,crl path=%s, ca cert path=%s\n", strCrlFile, pchCaCertFile); return CRL_VERIFY_ERR; } //下面会导致循环的直接崩溃 //EVP_PKEY_free(pubkey); X509_CRL_free(crl); X509_free(cert); return SUCCESS; } DWORD CheckCertWithCrl(const char *pubCert, const int pubCertLen, const int certFormat, const char *crlData, const int crlLen) { if (NULL == pubCert || NULL == crlData) { printf("CheckCertWithCrl Input parameter is null,cert path=%s, crl path=%s\n", pubCert, crlData); return INPUT_NULL_ERR; } X509 *x509=LoadCert(pubCert,pubCertLen,NULL,certFormat); if (NULL == x509) { printf("load %s err\n", pubCert); return LOAD_CERT_ERR; } BIO * in=NULL; if(crlLen==0) { if((in=BIO_new_file(crlData, "r"))==NULL) return LOAD_CRL_ERR; } else { if((in=BIO_new_mem_buf((void*)crlData,crlLen))== NULL) return LOAD_CRL_ERR; } X509_CRL *crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); STACK_OF(X509_REVOKED) *revoked=crl->crl->revoked; X509_REVOKED *rc; ASN1_INTEGER *serial=X509_get_serialNumber(x509); int num=sk_X509_REVOKED_num(revoked); DWORD dwRet = SUCCESS; for(int i=0;iserialNumber)==0) dwRet = CERT_REVOKED_ERR; X509_REVOKED_free(rc); } ASN1_INTEGER_free(serial); X509_CRL_free(crl); X509_free(x509); EVP_cleanup(); return dwRet; } DWORD VerifyCertSign(const char* pchRootCert, const char* pchSignCACert, const char *pchCert) { if (NULL == pchRootCert) { printf("rootcert path is null, %s\n", pchRootCert); return INPUT_NULL_ERR; } if (NULL == pchCert) { printf("cert path is null, %s\n", pchCert); return INPUT_NULL_ERR; } OpenSSL_add_all_algorithms(); int rv; X509_STORE_CTX *ctx = NULL; //证书存储区句柄 X509 *usrCert1 = NULL; //X509证书结构体,保存用户证书 X509 *usrCert3 = NULL; //X509证书结构体,保存用户证书 //X509 *caCert = NULL; //X509证书结构体,保存CA证书 X509 *rootCert = NULL; //X509证书结构体,保存根证书 STACK_OF(X509) *caCertStack = NULL; X509_STORE *rootCertStore = NULL; //证书存储区 int j = 0; unsigned char *pTmp = NULL; BIO *pbio; pbio = BIO_new_file(pchRootCert,"r"); rootCert = PEM_read_bio_X509(pbio, NULL,NULL,NULL); if (rootCert == NULL) { printf("Load %s err.\n", pchRootCert); return LOAD_CERT_ERR; } //BIO_free(pbio); //读取签名证书 if (NULL != pchSignCACert) { pbio = BIO_new_file(pchSignCACert,"r"); usrCert1 = PEM_read_bio_X509(pbio, NULL,NULL,NULL); if (usrCert1 == NULL) { printf("Load %s err.\n", pchSignCACert); return LOAD_CERT_ERR; } //BIO_free(pbio); } //读取待验证的用户证书,三级证书。 if (NULL != pchCert) { pbio = BIO_new_file(pchCert,"r"); usrCert3 = PEM_read_bio_X509(pbio, NULL,NULL,NULL); if (usrCert3 == NULL) { printf("Load %s err.\n", pchCert); return LOAD_CERT_ERR; } //BIO_free(pbio); } //新建X509证书存储区 rootCertStore = X509_STORE_new(); //添加根证书到证书存储区 //********************************************************************** //★★★★★多级证书关键处在这里,将所有的根证书加到这里。 X509_STORE_add_cert(rootCertStore,rootCert); if (NULL != usrCert1) { X509_STORE_add_cert(rootCertStore,usrCert1); } //********************************************************************** //设置检查CRL标志位,如果设置此标志位,则检查CRL,否则不检查CRL。 //X509_STORE_set_flags(rootCertStore,X509_V_FLAG_CRL_CHECK); //新建证书存储区句柄 ctx = X509_STORE_CTX_new(); //初始化根证书存储区、用户证书 //如果待验证跟证书为空,则表示验证根证书自验证 if (NULL != usrCert3) { rv = X509_STORE_CTX_init(ctx,rootCertStore,usrCert3,caCertStack); } else { rv = X509_STORE_CTX_init(ctx,rootCertStore,rootCert,caCertStack); } if(rv != 1) { printf("X509_STORE_CTX_init err\n"); BIO_free(pbio); X509_free(usrCert1); if (NULL != usrCert3) { X509_free(usrCert3); } X509_free(rootCert); X509_STORE_CTX_cleanup(ctx); X509_STORE_CTX_free(ctx); X509_STORE_free(rootCertStore); return CERT_SIGN_VERIFY_ERR; } //验证用户证书 DWORD dwRet = SUCCESS; rv = X509_verify_cert(ctx); if(rv != 1) { printf("verify error= %d,info:%s\n", ctx->error,X509_verify_cert_error_string(ctx->error)); switch (ctx->error) { case X509_V_ERR_CERT_SIGNATURE_FAILURE: dwRet = CERT_SIGNATURE_FAILURE_ERR; break; case X509_V_ERR_CERT_NOT_YET_VALID: dwRet = CERT_NOT_YET_VALID_ERR; break; case X509_V_ERR_CERT_HAS_EXPIRED: dwRet = CERT_HAS_EXPIRED_ERR; break; default: dwRet = CERT_SIGN_VERIFY_ERR; break; } } //else //{ // printf("verify cer OK\n"); //} BIO_free(pbio); X509_free(usrCert1); //下面会导致循环的第二次崩溃 if (NULL != usrCert3) { X509_free(usrCert3); } X509_free(rootCert); X509_STORE_CTX_cleanup(ctx); X509_STORE_CTX_free(ctx); X509_STORE_free(rootCertStore); return dwRet; } DWORD VerifyCert(const char *strRootCert, const char *strCaCert, const char *strCert, const char *strCrl, const int iCertFormat) { if ((NULL == strRootCert) || (NULL == strCert)) { printf("Input file path is null\n"); return INPUT_NULL_ERR; } DWORD dwRet = SUCCESS; //证书HID验证 char strCertHID[17] = {0}; if (!GetHIDFromCert(strCert, FORMAT_PEM, strCertHID)) { printf("Get UserID form %s err!", strCert); return dwRet; } USBKEY_INFO info; unsigned count = 0; dwRet = FindUsbKey(&info, &count); if (DONGLE_SUCCESS != dwRet) { printf("FindUsbKey fail, errcode=0x%08X!", dwRet); return dwRet; } char strUkeyHID[32] = {0}; for (int i = 0; i < 8; i++) { sprintf(strUkeyHID+2*i, "%02X ", info.m_HID[i]); } if (0 != memcmp(strCertHID, strUkeyHID, 16)) { printf("HID is not equal"); return CERT_HID_VERIFY_ERR; } //校验证书有效期 //因有的厂商Ukey不带时钟,且后期会对终端进行时间同步,openssl验证有效期接口会更加终端系统时间来校验证书时间,故不单独再对有效期进行校验 if(0) { dwRet = CheckCertLife(strRootCert, 0, iCertFormat); if (SUCCESS != dwRet) { printf("%s is out of validity!", strRootCert); return dwRet; } if (NULL != strCaCert) { dwRet = CheckCertLife(strCaCert, 0, iCertFormat); if (SUCCESS != dwRet) { printf("%s is out of validity!", strCaCert); return dwRet; } } dwRet = CheckCertLife(strCert, 0, iCertFormat); if (SUCCESS != dwRet) { printf("%s is out of validity!", strCert); return dwRet; } } //通过CRL校验证书是否撤销,可选 if (NULL != strCrl) { //校验CRL签名 /*dwRet = VerifCrl(strCrl, strRootCert); if (SUCCESS != dwRet) { printf("verify %s with %s err!", strRootCert, strCrl); return dwRet; }*/ //校验证书是否撤销 dwRet = CheckCertWithCrl(strCert, 0, iCertFormat, strCrl, 0); if (SUCCESS != dwRet) { printf("%s has been revoked!", strCert); return dwRet; } } //校验证书签名 dwRet = VerifyCertSign(strRootCert, strCaCert, strCert); if (SUCCESS != dwRet) { printf("%s is not signed by %s!", strCert, strCaCert); return dwRet; } return SUCCESS; } LIBEXPORT_API DWORD VerifyUserCert(const char *strRootCert, const char *strCaCert, const char *strUserCert, const char *strCrl, const int iCertFormat) { //校验证书 DWORD dwRet = VerifyCert(strRootCert, strCaCert, strUserCert, strCrl, iCertFormat); if (SUCCESS != dwRet) { printf("Verify user cert err, %s!", strUserCert); return dwRet; } return SUCCESS; } LIBEXPORT_API DWORD VerifyOperatorCert(const char *strRootCert, const char *strCaCert, const char *strOperatorCert, const char *strCrl, const int iCertFormat) { //校验证书 DWORD dwRet = VerifyCert(strRootCert, strCaCert, strOperatorCert, strCrl, iCertFormat); if (SUCCESS != dwRet) { printf("Verify operator cert err, %s!", strOperatorCert); return dwRet; } return SUCCESS; } LIBEXPORT_API bool GetVerifyTypeFromCert(const char *strUserCert, const int iCertFormat, char *strVerifyType) { if (NULL == strUserCert) { printf("Input user cert is null"); return false; } //CLogFile* log = new CLogFile("log.txt"); //log->LOGERROR("start log, %s", strUserCert); //获取证书扩展项 string ext; int extLen; string extType; int extTypelen = strlen("VerifyType"); int extValuelen = 0; //获取证书扩展项 CERTEXT certExt[MAX_EXT_NUM]; int extNumber = GetCertExtent(strUserCert, 0, iCertFormat, certExt); //扩展项内容格式定义:类型 + "," + 值,例:"OperatorType=normal" for (int i=0; iLOGERROR("strVerifyType, %s", strVerifyType); return true; } } //log->LOGERROR("end log, %s", strUserCert); return false; } //LIBEXPORT_API bool CheckCertWithTerminalNumber(const char *strOperatorCert, const int iCertFormat, char *strTerminalNumber) //{ // if (NULL == strOperatorCert) // { // printf("Input operator cert is null"); // return false; // } // // string ext; // int extLen; // string extType; // int extTypelen = strlen("TerminalNoList"); // int extValuelen = 0; // // //获取证书扩展项 // /*CLogFile* log = new CLogFile("log.txt"); // log->LOGERROR("start log, %s", strOperatorCert);*/ // CERTEXT certExt[MAX_EXT_NUM]; // int extNumber = GetCertExtent(strOperatorCert, 0, iCertFormat, certExt); // // //扩展项内容格式定义:类型 + "," + 值,例:"TerminalNoList=normal" // for (int i=0; iLOGERROR("return ture log, %s", strOperatorCert); // return true; // } // } // } // //log->LOGERROR("return false log, %s", strOperatorCert); // return false; //} LIBEXPORT_API bool GetOperatorTypeFromCert(const char *strOperatorCert, const int iCertFormat, char *strOperatorType) { if (NULL == strOperatorCert) { printf("Input operator cert is null"); return false; } string ext; int extLen; string extType; int extTypelen = strlen("OperatorType"); int extValuelen = 0; //获取证书扩展项 CERTEXT certExt[MAX_EXT_NUM]; int extNumber = GetCertExtent(strOperatorCert, 0, iCertFormat, certExt); //扩展项内容格式定义:类型 + "," + 值,例:"OperatorType=normal" for (int i=0; i iVersionNoLen) { printf("the versionNo buf len is smaller than 8"); return false; } string ext; int extLen; string extType; int extTypelen = strlen("Version"); int extValuelen = 0; //获取证书扩展项 CERTEXT certExt[MAX_EXT_NUM]; int extNumber = GetCertExtent(strUserCert, 0, iCertFormat, certExt); //扩展项内容格式定义:类型 + "," + 值,例:"Version=100001" for (int i=0; idata); strcpy(strEndTime, (const char*)af->data); M_ASN1_UTCTIME_free(be); M_ASN1_UTCTIME_free(af); X509_free(x509); return true; } LIBEXPORT_API bool GetUserTypeFromCert(const char *strCert, const int iCertFormat, char *strUserType) { if (NULL == strCert || NULL == strUserType) { return false; } string ext; int extLen; string extType; int extTypelen = strlen("UserType"); int extValuelen = 0; //获取证书扩展项 CERTEXT certExt[MAX_EXT_NUM]; int extNumber = GetCertExtent(strCert, 0, iCertFormat, certExt); //扩展项内容格式定义:类型 + "," + 值,例:"UserType=0" for (int i=0; in->d)倒序 //因为openssl的字节序和pc的字节序不同,因此需要将openssl中的n(pRsa->n->d )值进行倒序 /*BYTE byN[128] = {0}; BYTE * pN = (BYTE*)pubkey->pkey.rsa->n->d; for (int k = 0; k < 128; k++) { byN[k] = pN[127-k]; } memcpy(pN, byN, 128);*/ RSA* rsa = EVP_PKEY_get1_RSA(pubkey); if (NULL == rsa) { return RSA_PUBKEY_ENC_ERR; } if (128 != RSA_size(rsa)) { return RSK_KEY_LEN_ERR; } //如果直接用pubkey->pkey.rsa,在自己机器上可以,但到其它环境上该值为空。怀疑是本机安装了openssl的原因 //int iRet = RSA_public_encrypt(srcDataLen, (unsigned char *)srcData, destData, pubkey->pkey.rsa, RSA_PKCS1_PADDING); int iRet = RSA_public_encrypt(srcDataLen, (unsigned char *)srcData, destData, rsa, RSA_PKCS1_PADDING); if (iRet < 0) { return RSA_PUBKEY_ENC_ERR; } return SUCCESS; } LIBEXPORT_API DWORD RsaPublicDecrypt(const unsigned char* srcData, unsigned int srcDataLen, unsigned char* destData,const char *strUserCert, const int iCertFormat) { //加载证书 X509 *cert = LoadCert(strUserCert, 0, NULL, iCertFormat); if (NULL == cert) { return LOAD_CERT_ERR; } //提取公钥 EVP_PKEY *pubkey = X509_get_pubkey(cert); if (NULL == pubkey) { return GET_PUBKEY_FROM_CERT_ERR; } //读取PEM文件后,需要将N值(pRsa->n->d)倒序 //因为openssl的字节序和pc的字节序不同,因此需要将openssl中的n(pRsa->n->d )值进行倒序 /*BYTE byN[128] = {0}; BYTE * pN = (BYTE*)pubkey->pkey.rsa->n->d; for (int k = 0; k < 128; k++) { byN[k] = pN[127-k]; } memcpy(pN, byN, 128);*/ RSA* rsa = EVP_PKEY_get1_RSA(pubkey); if (NULL == rsa) { return RSA_PUBKEY_ENC_ERR; } if (128 != RSA_size(rsa)) { return RSK_KEY_LEN_ERR; } //如果直接用pubkey->pkey.rsa,在自己机器上可以,但到其它环境上该值为空。怀疑是本机安装了openssl的原因 //int iRet = RSA_public_encrypt(srcDataLen, (unsigned char *)srcData, destData, pubkey->pkey.rsa, RSA_PKCS1_PADDING); int iRet = RSA_public_encrypt(srcDataLen, (unsigned char *)srcData, destData, rsa, RSA_PKCS1_PADDING); if (iRet < 0) { return RSA_PUBKEY_ENC_ERR; } return SUCCESS; } LIBEXPORT_API DWORD RsaPublicDecryptByKey(const unsigned char* srcData, unsigned int srcDataLen, unsigned char* destData,const char *strPubPath, const int iCertFormat) { BIO *bp = NULL; RSA* rsa = NULL; OpenSSL_add_all_algorithms(); bp = BIO_new_file(strPubPath,"rb"); if(NULL == bp) { return FALSE; } rsa = PEM_read_bio_RSAPublicKey(bp,NULL,NULL,NULL); if (rsa != NULL) { printf("PEM_read_bio_RSAPublicKey ok!\n"); } else { printf("PEM_read_bio_RSAPublicKey err!\n"); return FALSE; } BIO_free(bp); if (128 != RSA_size(rsa)) { return RSA_PUBKEY_ENC_ERR; } //读取PEM文件后,需要将N值(pRsa->n->d)倒序 //因为openssl的字节序和pc的字节序不同,因此需要将openssl中的n(pRsa->n->d )值进行倒序 BYTE byN[128] = {0}; BYTE * pN = (BYTE*)rsa->n->d; for (int k = 0; k < 128; k++) { byN[k] = pN[127-k]; } memcpy(pN, byN, 128); //如果直接用pubkey->pkey.rsa,在自己机器上可以,但到其它环境上该值为空。怀疑是本机安装了openssl的原因 int iRet = RSA_public_decrypt(srcDataLen, (unsigned char *)srcData, destData, rsa, RSA_PKCS1_PADDING); if (iRet < 0) { return RSA_PUBKEY_ENC_ERR; } return SUCCESS; } LIBEXPORT_API DWORD RsaPrivateDecrypt(const unsigned char* srcData, unsigned char* destData,const char *strPriKey) { if (NULL == strPriKey) { printf("Private key file name is null\n"); return INPUT_NULL_ERR; } BIO* in = NULL; RSA* rsaKey = RSA_new(); //读取私钥 OpenSSL_add_all_algorithms(); in=BIO_new_file(strPriKey,"rb"); if (NULL == in) { return LOAD_PRIKEY_ERR; } PEM_read_bio_RSAPrivateKey(in,&rsaKey,NULL,NULL); if ((rsaKey)->d!=NULL) { printf("PEM_read_bio_RSAPrivateKey ok!\n"); } else { printf("PEM_read_bio_RSAPrivateKey err!\n"); BIO_free(in); return LOAD_PRIKEY_ERR; } BIO_free(in); //unsigned char test[1024] = {0}; //int iRet = RSA_private_decrypt(RSA_size(rsaKey) , srcData , test , rsaKey , RSA_PKCS1_PADDING); int iRet = RSA_private_decrypt(RSA_size(rsaKey) , srcData , destData , rsaKey , RSA_PKCS1_PADDING); if (iRet < 0) { return RSA_PRIKEY_DEC_ERR; } return SUCCESS; } LIBEXPORT_API DWORD TDesEncrypt(const unsigned char* srcData, unsigned int srcDataLen, unsigned char* destData,const char *strKey) { int count; int i; unsigned char *data = (unsigned char *)srcData; /* 明文 */ int data_rest; unsigned char ch; unsigned char *src = NULL; /* 补齐后的明文 */ unsigned char *dst = NULL; /* 加密后的密文 */ int len; unsigned char in[8]; unsigned char out[8]; char *k = (char*)strKey; /* 原始密钥 */ int key_len; //#define LEN_OF_KEY 24 #define LEN_OF_KEY 16 unsigned char key[LEN_OF_KEY]; /* 补齐后的密钥 */ unsigned char block_key[9]; DES_key_schedule ks,ks2; /* 构造补齐后的密钥 */ key_len = strlen(k); memcpy(key, k, key_len); memset(key + key_len, 0x00, LEN_OF_KEY - key_len); /* 分析补齐明文所需空间及补齐填充数据 */ data_rest = srcDataLen % 8; len = srcDataLen + (8 - data_rest); ch = 8 - data_rest; src = (unsigned char*)malloc(len); if (NULL == src ) { if (NULL != src) { free(src); src = NULL; } return NEW_MEM_ERR; } else { /* 构造补齐后的加密内容 */ memset(src, 0, len); memcpy(src, data, srcDataLen); memset(src + srcDataLen, ch, 8 - data_rest); /* 密钥置换 */ memset(block_key, 0, sizeof(block_key)); memcpy(block_key, key + 0, 8); DES_set_key_unchecked((const_DES_cblock*)block_key, &ks); memcpy(block_key, key + 8, 8); DES_set_key_unchecked((const_DES_cblock*)block_key, &ks2); /*memcpy(block_key, key + 16, 8); DES_set_key_unchecked((const_DES_cblock*)block_key, &ks3);*/ /* 循环加密,每8字节一次 */ count = len / 8; for (i = 0; i < count; i++) { memset(in, 0, 8); memset(out, 0, 8); memcpy(in, src + 8 * i, 8); /* 加密 */ DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks, DES_ENCRYPT); /* 拷贝密文 */ memcpy(destData + 8 * i, out, 8); } printf("after encrypt :"); for (i = 0; i < len; i++) { printf("0x%.2X ", *(destData + i)); } printf("\n"); } if (NULL != src) { free(src); src = NULL; } return SUCCESS; } LIBEXPORT_API DWORD TDesDecrypt(const unsigned char* srcData, unsigned int srcDataLen, unsigned char* destData,const char *strKey) { unsigned int count; unsigned int i; unsigned char *dst = NULL; /* 解密后的明文 */ unsigned char in[8]; unsigned char out[8]; char *k = (char*)strKey; /* 原始密钥 */ int key_len; //#define LEN_OF_KEY 24 #define LEN_OF_KEY 16 unsigned char key[LEN_OF_KEY]; /* 补齐后的密钥 */ unsigned char block_key[9]; DES_key_schedule ks,ks2; /* 构造补齐后的密钥 */ key_len = strlen(k); memcpy(key, k, key_len); memset(key + key_len, 0x00, LEN_OF_KEY - key_len); /* 密钥置换 */ memset(block_key, 0, sizeof(block_key)); memcpy(block_key, key + 0, 8); DES_set_key_unchecked((const_DES_cblock*)block_key, &ks); memcpy(block_key, key + 8, 8); DES_set_key_unchecked((const_DES_cblock*)block_key, &ks2); /*memcpy(block_key, key + 16, 8); DES_set_key_unchecked((const_DES_cblock*)block_key, &ks3);*/ /* 循环解密,每8字节一次 */ count = srcDataLen / 8; for (i = 0; i < count; i++) { memset(in, 0, 8); memset(out, 0, 8); memcpy(in, srcData + 8 * i, 8); /* 解密 */ DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks, DES_DECRYPT); /* 将解密后的明文 */ memcpy(destData + 8 * i, out, 8); } /*printf("after decrypt :"); for (i = 0; i < srcDataLen; i++) { printf("0x%.2X ", *(destData + i)); } printf("\n");*/ return SUCCESS; } RSA* S_GetPubKey(char* pubPath) { RSA *rsaK = NULL; BIO *BP = NULL; // if(NULL == pubPath) return 0; // BP = BIO_new(BIO_s_file()); if(NULL == BP) return NULL; // BIO_read_filename(BP, pubPath); rsaK = PEM_read_bio_RSAPublicKey(BP, NULL, NULL, NULL); //rsaK = PEM_read_bio_RSA_PUBKEY(BP, NULL,NULL,NULL); // if(BP) BIO_free_all(BP); // return rsaK; } bool ReadPublicKeyFile(const char *pchPublicKeyFile, RSA** rsaKey) { if (NULL == pchPublicKeyFile) { printf("Public key file name is null\n"); return FALSE; } //读取公钥 BIO* in = NULL; OpenSSL_add_all_algorithms(); in = BIO_new_file(pchPublicKeyFile,"rb"); //RSA* read = RSA_new(); /*rsaKey=*/PEM_read_bio_RSAPublicKey(in,rsaKey,NULL,NULL); if (rsaKey != NULL) { printf("PEM_read_bio_RSAPublicKey ok!\n"); } else { printf("PEM_read_bio_RSAPublicKey err!\n"); BIO_free(in); return FALSE; } BIO_free(in); return TRUE; } //LIBEXPORT_API DWORD PEM_2_RSAPUBKEY(char* pPubFile, RSA_PUBLIC_KEY* pPubKey) //{ // BOOL result = FALSE; // int len; // RSA* pRSA = RSA_new(); // // if(pPubFile != NULL) // { // if(!ReadPublicKeyFile(pPubFile, &pRSA)) // { // return LOAD_PUBKEY_ERR; // } // // /*pRSA = S_GetPubKey(pPubFile); // if(pRSA == NULL) // { // return LOAD_PUBKEY_ERR; // }*/ // // len = pRSA->n->top*4; // memcpy(&pPubKey->modulus, pRSA->e->d, 4); // memcpy(&pPubKey->exponent, pRSA->n->d, len); // pPubKey->bits = len * 8; // } // // return SUCCESS; //} int GetCertExtent(const char *pubCert,const int pubCertLen,const int certFormat, LPCERTEXT ext) { if (NULL == pubCert) { printf("Input cert path is null"); return INPUT_NULL_ERR; } if (NULL == ext) { printf("Input cert extentions contain is null"); return INPUT_NULL_ERR; } X509_EXTENSION *ex; ASN1_OBJECT *obj; int fn_nid; string sn; string ln; BIO *bio; BUF_MEM *bptr; X509 *x509=LoadCert(pubCert,pubCertLen,NULL,certFormat); if (NULL == x509) { return LOAD_CERT_ERR; } STACK_OF(X509_EXTENSION) *exts=x509->cert_info->extensions; int count=sk_X509_EXTENSION_num(exts); for (int i=0; ivalue); BIO_get_mem_ptr(bio, &bptr); memcpy(ext[i].VALUE,bptr->data,bptr->length); //根据长度值的长度,截取实际扩展项值 //规律:长度<128,2个字节长度位;128<长度<256,3个字节长度位;长度>256,4个字节长度位 string str = ext[i].VALUE; string newstr = ""; int len = strlen(ext[i].VALUE); if (len >= 260) { newstr = str.substr(4,-1); strcpy_s(ext[i].VALUE, newstr.c_str()); } else if (len >= 131) { newstr = str.substr(3,-1); strcpy_s(ext[i].VALUE, newstr.c_str()); } else { newstr = str.substr(2,-1); strcpy_s(ext[i].VALUE, newstr.c_str()); } BIO_free(bio); } X509_free(x509); return count; } //DWORD GetUTCTimeFromUkey(DWORD* pdwUTCTime) //{ // DONGLE_INFO KeyInfo; // DONGLE_HANDLE handle; // int count = 0; // // DWORD dwRet = Dongle_Enum(&KeyInfo, &count); // if (dwRet != DONGLE_SUCCESS) // { // return dwRet; // } // // dwRet = Dongle_Open(&handle, 0); // if (dwRet != DONGLE_SUCCESS) // { // return dwRet; // } // // dwRet = Dongle_GetUTCTime(handle, pdwUTCTime); // if (dwRet != DONGLE_SUCCESS) // { // return dwRet; // } // // Dongle_Close(handle); // // return DONGLE_SUCCESS; //} // //DWORD GetArmHID(char *strHID) //{ // if (NULL == strHID) // { // return INPUT_NULL_ERR; // } // // DONGLE_INFO KeyInfo; // int count = 0; // DWORD dwRet = 0; // // dwRet = Dongle_Enum(&KeyInfo, &count); // if (dwRet != DONGLE_SUCCESS) // { // printf("Dongle_Enum failed!\n", dwRet); // return dwRet; // } // // for (int i = 0; i < 8; i++) // { // sprintf(strHID+2*i, "%02X ", KeyInfo.m_HID[i]); // } // // return DONGLE_SUCCESS; //} // //DWORD GetS4HID(char *strHID) //{ // if (NULL == strHID) // { // return INPUT_NULL_ERR; // } // // SENSE4_CONTEXT * s4CtxList =NULL ; // DWORD dwSize=0; // DWORD dwRet = 0; // // //枚举系统连接了多少个设备,这一步不用判断返回值,第一个参数输入NULL // dwRet = S4Enum(NULL,&dwSize); // if (S4_SUCCESS != dwRet && S4_INSUFFICIENT_BUFFER != dwRet) // { // printf("S4Enum failed!\n", dwRet); // return dwRet; // } // // //如果得到的设备上下文内存数量为0或者不为sizeof(SENSE4_CONTEXT)的倍数, // //说明没有找到设备或者列举设备出错。 // if ((0 == dwSize) || (dwSize % sizeof(SENSE4_CONTEXT))) // { // printf("S4Enum return size err!\n"); // return S4_NO_LIST; // } // // int nCount = dwSize / sizeof(SENSE4_CONTEXT); // // //根据返回的设备个数,分配空间给程序使用 // s4CtxList = (SENSE4_CONTEXT *)malloc(dwSize); // // //根据分配的空间,再次枚举设备,这次要判断函数返回值 // dwRet = S4Enum(s4CtxList,&dwSize); // if(S4_SUCCESS != dwRet) // { // free(s4CtxList); // s4CtxList = NULL; // printf("Enum device failed.\n", dwRet); // return dwRet; // } // // S4OPENINFO S4_OpenInfo; // S4_OpenInfo.dwS4OpenInfoSize = sizeof(S4OPENINFO); // S4_OpenInfo.dwShareMode = S4_EXCLUSIZE_MODE; // // dwRet = S4OpenEx(s4CtxList, &S4_OpenInfo); // if (S4_SUCCESS != dwRet) // { // if (S4_DEVICE_BUSY == dwRet) // { // printf("device is busy, start to close, and then open.\n"); // dwRet = S4Close(s4CtxList); // if(S4_SUCCESS != dwRet) // { // free(s4CtxList); // s4CtxList = NULL; // printf("S4Close failure.\n", dwRet); // return dwRet; // } // // dwRet = S4OpenEx(s4CtxList, &S4_OpenInfo); // if(S4_SUCCESS != dwRet) // { // free(s4CtxList); // s4CtxList = NULL; // printf("S4OpenEx failure.\n", dwRet); // return dwRet; // } // } // else // { // free(s4CtxList); // s4CtxList = NULL; // printf("S4OpenEx failure.\n", dwRet); // return dwRet; // } // } // // //获取设备序列号 // DWORD len = 0; // unsigned char cSerialNumber[8] = {0}; // dwRet = S4Control(s4CtxList, S4_GET_SERIAL_NUMBER, NULL, 0, (void*)cSerialNumber, 8, &len); // if (S4_SUCCESS != dwRet) // { // free(s4CtxList); // s4CtxList = NULL; // printf("Get Serial number failed!\n", dwRet); // return dwRet; // } // // for (int i = 0; i < 8; i++) // { // sprintf(strHID+2*i, "%02X ", cSerialNumber[i]); // } // // free(s4CtxList); // s4CtxList = NULL; // // return S4_SUCCESS; //} // //DWORD GetGM3000HID(char *strHID) //{ // DWORD dwRet = 0; // char szDevName[256] = {0}; // ULONG ulNameLen = 256; // DEVHANDLE hHandle = NULL; // // dwRet = SKF_EnumDev(1, szDevName, &ulNameLen); // if (SAR_OK != dwRet) // { // printf("SKF_EnumDev failed! \n", dwRet); // return dwRet; // } // // dwRet = SKF_ConnectDev(szDevName, &hHandle); // if (SAR_OK != dwRet) // { // printf("SKF_ConnectDev failed! \n", dwRet); // return dwRet; // } // // DEVINFO stDevInfo = {0}; // dwRet = SKF_GetDevInfo(hHandle, &stDevInfo); // if (SAR_OK != dwRet) // { // printf("SKF_GetDevInfo failed! \n", dwRet); // return dwRet; // } // // memcpy(strHID, stDevInfo.SerialNumber, 16); // // return SAR_OK; //} // //LIBEXPORT_API DWORD GetHIDFromUKey(char *strHID) //{ // if (NULL == strHID) // { // return INPUT_NULL_ERR; // } // // DWORD dwRet = 0; // // dwRet = GetArmHID(strHID); // if (DONGLE_SUCCESS == dwRet) // { // return DONGLE_SUCCESS; // } // else if(DONGLE_NOT_FOUND == dwRet) // { // dwRet = GetS4HID(strHID); // if (S4_SUCCESS == dwRet) // { // return S4_SUCCESS; // } // else if (S4_NO_LIST == dwRet) // { // dwRet = GetGM3000HID(strHID); // if (SAR_OK != dwRet) // { // return dwRet; // } // // return SAR_OK; // } // else // { // return dwRet; // } // } // else // { // return dwRet; // } // // return DONGLE_SUCCESS; //}