certtools.cpp

来自「用于处理证书请求,生成证书的CA服务器源码,」· C++ 代码 · 共 719 行 · 第 1/2 页

CPP
719
字号
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <wincrypt.h>
#include "certextern.h"
#include "certglobal.h"



char *bstr =
	"ABCDEFGHIJKLMNOPQ"
	"RSTUVWXYZabcdefgh"
	"ijklmnopqrstuvwxy"
	"z0123456789+/";

char rstr[] = {
	  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
	  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 
	  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  62,   0,   0,   0,  63, 
	 52,  53,  54,  55,  56,  57,  58,  59,  60,  61,   0,   0,   0,   0,   0,   0, 
	  0,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14, 
	 15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,   0,   0,   0,   0,   0, 
	  0,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40, 
	 41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,   0,   0,   0,   0,   0};


int queryobj();
int Decodepkcs10();


//base64 编码
void XFBase64encode(const unsigned char* input,size_t l,unsigned char* output, bool add_crlf)
{
	size_t i = 0;
	size_t o = 0;
	
//	output = "";
	unsigned char *p = output;
	while (i < l)
	{
		size_t remain = l - i;
		if (add_crlf && o && o % 76 == 0)
		{
			*p = '\n';
			p++;
		}
		switch (remain)
		{
		case 1:
			*p = bstr[ ((input[i] >> 2) & 0x3f) ];
			p++;
			*p = bstr[ ((input[i] << 4) & 0x30) ];
			p++;
			*p = '=';
			p++;
			*p = '=';
			p++;
			break;
		case 2:
			*p = bstr[ ((input[i] >> 2) & 0x3f) ];
			p++;
			*p = bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
			p++;
			*p = bstr[ ((input[i + 1] << 2) & 0x3c) ];
			p++;
			*p = '=';
			p++;
			break;
		default:
			*p = bstr[ ((input[i] >> 2) & 0x3f) ];
			p++;
			*p = bstr[ ((input[i] << 4) & 0x30) + ((input[i + 1] >> 4) & 0x0f) ];
			p++;
			*p = bstr[ ((input[i + 1] << 2) & 0x3c) + ((input[i + 2] >> 6) & 0x03) ];
			p++;
			*p = bstr[ (input[i + 2] & 0x3f) ];
			p++;
		}
		o += 4;
		i += 3;
	}
}


//base64 解码
void XFBase64decode(const unsigned char * input, unsigned char *output, unsigned long& sz)
{
	size_t i = 0;
	size_t l = strlen((char *)input);
	size_t j = 0;
	
	while (i < l)
	{
		while (i < l && (input[i] == 13 || input[i] == 10))
			i++;
		if (i < l)
		{
			unsigned char b1 = (rstr[(int)input[i]] << 2 & 0xfc) +
					(rstr[(int)input[i + 1]] >> 4 & 0x03);
			output[j++] = b1;
			if (input[i + 2] != '=')
			{
				unsigned char b2 = (rstr[(int)input[i + 1]] << 4 & 0xf0) +
						(rstr[(int)input[i + 2]] >> 2 & 0x0f);
				output[j++] = b2;
			}
			if (input[i + 3] != '=')
			{
				unsigned char b3 = (rstr[(int)input[i + 2]] << 6 & 0xc0) +
						rstr[(int)input[i + 3]];
				output[j++] = b3;
			}
			i += 4;
		}
	}
	sz = j;
}


//
// Find Certificate with szCertName in the Subject name
//
/***************************************************************
* 函数名:			FindCertificate
* 功能:			用证书名查找证书.
* 输入/输出参数:	szCertName	in 证书名
*					szStore		in STORE名
*					dwFlags		in STORE标志
*					KeyId		out 密钥标识
*					hProv		out CSP句柄
*					dwKeyType	out 密钥类型
* 返回值:			正确返回指向证书上下文的指针,其他返回NULL。
* 程序员:		徐锋			编程日期:2004/09/10
* 修改人员:					修改日期:
* 修改原因:
*****************************************************************/
PCCERT_CONTEXT FindCertificate(LPSTR szCertName, LPSTR szStore,
                               DWORD dwFlags, PCRYPT_DATA_BLOB *KeyId,
                               HCRYPTPROV *hProv, LPDWORD dwKeyType)
{
	int dwError=0;
   HANDLE hHeap = GetProcessHeap();
   PCRYPT_KEY_PROV_INFO KeyProvInfo;
   PCCERT_CONTEXT pCertContext = NULL;
   PCERT_EXTENSION pExtension = NULL;
   HCERTSTORE hStore = 0;
   WCHAR szwStore[20];
   CHAR szContainer[160];
   CHAR szProvider[160];
   BOOL bResult, bSuccess = FALSE;
   DWORD dwSize, dwAcquireFlags = 0;
   int i;

   while(1)
   {
      *KeyId = NULL;
      *hProv = 0;

      if (dwFlags == CERT_SYSTEM_STORE_LOCAL_MACHINE)
         dwAcquireFlags = CRYPT_MACHINE_KEYSET;

      // Convert Store string to Unicode
      i = MultiByteToWideChar(0, 0, szStore, -1, szwStore, 20);
      if (i == 0)
      {
		 dwError = GetLastError();
         break;
      }

      // Open Certificate store
      hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
                           MYCODING_TYPE,
                           0, dwFlags, (LPVOID)szwStore);
      if (!hStore)
      {
		  dwError = GetLastError();
         break;
      }

      // Find Certificate with Subject name
      pCertContext = CertFindCertificateInStore(hStore,
                              MYCODING_TYPE,
                              0, CERT_FIND_SUBJECT_STR_A,
                              (LPVOID)szCertName, NULL);
      if (pCertContext)
      {
         // Get Key Provider Info size
         bResult = CertGetCertificateContextProperty(pCertContext,
                                             CERT_KEY_PROV_INFO_PROP_ID,
                                             NULL,
                                             &dwSize);
         if (!bResult)
         {
			 dwError = GetLastError();
            break;
         }

         // Allocate Key Provider Info
         KeyProvInfo = (PCRYPT_KEY_PROV_INFO)HeapAlloc(hHeap, 0, dwSize);
         if (!KeyProvInfo)
         {
			 dwError = GetLastError();
            break;
         }

         // Get Key Provider Info
         bResult = CertGetCertificateContextProperty(pCertContext,
                                             CERT_KEY_PROV_INFO_PROP_ID,
                                             (LPVOID)KeyProvInfo,
                                             &dwSize);
         if (!bResult)
         {
            break;
         }

         // Convert Container Name to ANSI
         i = WideCharToMultiByte(0, 0, KeyProvInfo->pwszContainerName,
                                 -1, szContainer, 160, NULL, NULL);
         if (i == 0)
         {
            break;
         }

         // Convert Provider Name to ANSI
         i = WideCharToMultiByte(0, 0, KeyProvInfo->pwszProvName, -1,
                                 szProvider, 160, NULL, NULL);
         if (i == 0)
         {
			dwError = GetLastError();
            break;
         }

         // Get Crypto Context of Certificate
 //        bResult = CryptAcquireContext(hProv, szContainer, szProvider,
 //                                      KeyProvInfo->dwProvType, dwAcquireFlags);
		 bResult = CryptAcquireContext(hProv, szContainer, szProvider,
                                      PROV_RSA_FULL, 0);
         if (!bResult)
         {
			 dwError = GetLastError();
            break;
         }

         // Return Key Spec
         *dwKeyType = KeyProvInfo->dwKeySpec;

         bSuccess = TRUE;

         // Find Subject Key Identifier Extension
         pExtension = CertFindExtension(szOID_SUBJECT_KEY_IDENTIFIER,
                                        pCertContext->pCertInfo->cExtension,
                                        pCertContext->pCertInfo->rgExtension);

         // If Subject Key Identifier Extension Exists
         if (pExtension)
         {

            // Get Size of Data Blob
            bResult = CryptDecodeObject(MYCODING_TYPE,
                                        szOID_SUBJECT_KEY_IDENTIFIER,
                                        pExtension->Value.pbData,
                                        pExtension->Value.cbData,
                                        0, NULL, &dwSize);
            if (!bResult)
            {
               break;
            }

            // Allocate Data Blob
            *KeyId = (PCRYPT_DATA_BLOB)HeapAlloc(hHeap, 0, dwSize);
            if (!(*KeyId))
            {
               break;
            }

            // Get Key Identifier Data Blob
            bResult = CryptDecodeObject(MYCODING_TYPE,
                                        szOID_SUBJECT_KEY_IDENTIFIER,
                                        pExtension->Value.pbData,
                                        pExtension->Value.cbData,
                                        0, (LPVOID)*KeyId, &dwSize);
            if (!bResult)
            {
               break;
            }
         }
      }
      else
      {
		 dwError = GetLastError();
         break;
      }

      bSuccess = TRUE;
	  break;
   }	//end while


   {
      // Clean up
      if (hStore) CertCloseStore(hStore, 0);
      if (KeyProvInfo) HeapFree(hHeap, 0, KeyProvInfo);
      if (!bSuccess)
      {
         if (pCertContext) CertFreeCertificateContext(pCertContext);
         pCertContext = NULL;
         if (*KeyId) HeapFree(hHeap, 0, *KeyId);
         *KeyId = NULL;
      }
   }

   return pCertContext;
}




/***************************************************************
* 函数名:			GetPubKeyFromP10
* 功能:			从PKCS#10内容中获取公钥信息.
* 输入/输出参数:	hHeap				in 堆指针
*					szP10				in PKCS#10内容
*					pvCertReqInfo		out 公钥信息
* 返回值:			正确返回0,其他返回NULL。
* 程序员:		徐锋			编程日期:2004/09/10
* 修改人员:					修改日期:
* 修改原因:
*****************************************************************/
int GetPubKeyFromP10(HANDLE hHeap,LPSTR szP10, CERT_REQUEST_INFO** pvCertReqInfo)
{

	BOOL bResult;
	int dwError;
	BYTE szBLOB[2048];
	DWORD pcbBinary=2048;
	DWORD pcbStructInfo;

	XFBase64decode((const unsigned char * )szP10, (unsigned char *)szBLOB, pcbBinary);

	bResult = CryptDecodeObjectEx(
	X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
	X509_CERT_REQUEST_TO_BE_SIGNED,//X509_CERT,
	(unsigned char *)szBLOB,
	pcbBinary,
	0,
	NULL,
	NULL,
	&pcbStructInfo
	);

	if (!bResult)
	{
		dwError = GetLastError();
		return -3001;
	}

	*pvCertReqInfo = (CERT_REQUEST_INFO*)HeapAlloc(hHeap, 0, pcbStructInfo);
	if(!(*pvCertReqInfo))
	{
		dwError = GetLastError();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?