📄 cert-installer.c
字号:
/** \file cert-installer.c * $Id: cert-installer.c,v 1.12 2004/12/07 14:12:37 rchantereau Exp $ * * CSP #11 -- Cryptographic Service Provider PKCS #11 certificate installer. * * This file contains CSP-eleven X.509 certificate installer source code. * The used hash algorithm is SHA1. * * Copyright © 2004 Entr'ouvert * http://csp11.labs.libre-entreprise.org * * \author Romain Chantereau <rchantereau@entrouvert.com> * \author Benjamin Sonntag <benjamin@mailfr.com>. His certificate storing code * really helped me. I did a adapted copy&paste. Great. * \author Fabio Petagna <fabpet@gmail.com> who corrected with Gambin a serious * cName conversion bug. * \date 2004 * \version 0.1 * * \ingroup cert-installer * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * * \todo A lot of key pair founded on a certificate could be used to * AT_SIGNATURE and AT_KEYEXCHANGE. The main problem is that the cert-installer * behavior has to be user settable. If this key has to be AT_KEYEXCHANGE or * not for example, and when a cert is store, it can certify multiple keys, and * AT_KEYXECHANGE AND AT_SIGNATURE key, where theses two keys are differents... * This is typicaly a Windows UI fanatic works. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//** \defgroup cert-installer CSP #11 certificate installer. * * Grab certificates on SC and install it in the user store. * */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <windows.h>#include <wincrypt.h>#ifdef _MSC_VER#define CERT_INSTALLER#include <cspdk.h>#include "../opensc/pkcs11.h"#include "../missdef.h"#else#include "opensc/pkcs11.h"#include "misscrypt.h"#endif#define ENTRYPOINT APIENTRY /**< define the WinMain type.*/#ifndef NO_SLOT#define NO_SLOT ((CK_SLOT_ID) -1) /**< A -1 slot number means no choosen slot. */#endif#define IDL_CERTLIST 1009 /**< ID of the certificates list.*/static HINSTANCE module; /**< The program windows instance.*/static HCRYPTKEY hUserKey; /**< The handler to the user key set.*/static HCRYPTHASH hHash; /**< Handle to the test hash.*/static HWND hMainWnd; /**< Handle the main window.*/static CK_FUNCTION_LIST_PTR p11 = NULL; /**< The PKCS #11 API functions pointers.*/HANDLE heapHandle; /**< handle to the test heap.*/#define DER_LENGTH 8192 /**< Length of a Der encoded certificate.*//** \brief Certificate information structure. */typedef struct _CERTIFICATE_INFO { char tokenLabel[33]; /**< The label of the token containing the certificate.*/ unsigned char keyId; /**< The public key object ID.*/ char keyHash[129]; /**< key description part of CSP container name.*/ char * label; /**< Label of the certificate.*/ char * derCert; /**< DER encoded certificate.*/ CK_ULONG certLen; /**< DER encoded certificate length.*/ CK_SESSION_HANDLE hSession; /* Handle to the session used to access the cert.*/ CK_OBJECT_HANDLE hCert; /* Handle to the certificate object.*/} CERTIFICATE_INFO;/** \brief key specifications structure. * * Permits to bind a index in the certificates list to a key specification. */typedef struct _CERTIFICATE_KEY_SPEC { int index; /**< The index in the certificates list. [0,MAX_CERTS[ */ DWORD dwKeySpec; /**< The CAPI key specification.*/} CERTIFICATE_KEY_SPEC;#define MAX_CERTS 512 /**< Maximum 512 certificates handled simult.*/CERTIFICATE_INFO certificatesList[MAX_CERTS]; /**< 512 CERTIFICATE_INFO.*/BOOL initializeP11(){ CK_RV rv; /* PKCS #11 API return value. */ CK_C_GetFunctionList pC_GetFunctionList = NULL; /* Pointer to the PKCS #11 C_GetFunctionList function.*/ //LPCSTR dllName = "csp11-pkcs11.dll"; //LPCSTR dllName = "opensc-pkcs11.dll"; LPCSTR dllName = "pkcs11-spy.dll"; /** Test if p11 is already initialized.*/ if (p11) { return TRUE; } /** - Load PKCS11 module.*/ module = LoadLibrary(dllName); if (module == NULL) { SetLastError(NTE_PROVIDER_DLL_FAIL); return FALSE; } /** - Get pointer to the C_GetFunctionList function.*/ pC_GetFunctionList = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList"); if (pC_GetFunctionList == NULL) { SetLastError(NTE_PROVIDER_DLL_FAIL); return FALSE; } /** - Get pointer to the PKCS11 function list. */ rv = (*pC_GetFunctionList)(&p11); if (rv != CKR_OK) { SetLastError(NTE_PROVIDER_DLL_FAIL); return FALSE; } /** - Initialize PKCS 11 library.*/ rv = p11->C_Initialize(NULL); if (rv != CKR_OK) { /** \bug ERROR_APP_INIT_FAILURE not recognized ?. */ /*SetLastError(ERROR_APP_INIT_FAILURE);*/ SetLastError(NTE_PROVIDER_DLL_FAIL); return FALSE; } return TRUE;}/** \brief Load the DER encoded certificate. * * \param certInfo Certificate information structure. * * \return TRUE if ok. */BOOL loadDerCert(CERTIFICATE_INFO *pCertInfo){ CK_ATTRIBUTE forDER = {CKA_VALUE, NULL, 0}; /* Attribute template for getting the DER value of the certificate Object.*/ CK_RV rv; /* PKCS #11 API return value. */ /** - Get the first object Value attribute size.*/ rv = p11->C_GetAttributeValue(pCertInfo->hSession, pCertInfo->hCert, &forDER, 1); if(rv != CKR_OK) { return FALSE; } /** - Allocate memory for the wanted attribute.*/ pCertInfo->derCert = HeapAlloc(heapHandle, HEAP_ZERO_MEMORY, forDER.ulValueLen+1); forDER.pValue = pCertInfo->derCert; pCertInfo->certLen = forDER.ulValueLen; /** - Get the first object ID attribute.*/ rv = p11->C_GetAttributeValue(pCertInfo->hSession, pCertInfo->hCert, &forDER, 1); return TRUE;}/** \brief Test public key object presence. * * \return TRUE if an associated public key is present. */BOOL pubKeyPresent(CK_TOKEN_INFO tokenInfo, CERTIFICATE_INFO *pCertInfo){ CK_ATTRIBUTE template[2]; /* Research attributes template.*/ CK_ATTRIBUTE forObjectId = {CKA_ID, NULL, 0}; /* Attribute for object ID.*/ CK_ATTRIBUTE forObjectLabel = {CKA_LABEL, NULL, 0}; /* Attribute for object LABEL.*/ CK_ATTRIBUTE forObjectModulus = {CKA_MODULUS, NULL, 0}; /* Attribute for object MODULUS.*/ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; /* Public key object class.*/ CK_RV rv; /* PKCS #11 API return value. */ CK_OBJECT_HANDLE hPubKey; /* Handle to the associated public key.*/ unsigned char buffer[64]; /* Hash buffer*/ BYTE *modulus; /* Getted modulus typed variable.*/ CK_ULONG modulusLen; /* The modulus length.*/ DWORD hashLen = 0; /* Lenth of the hash.*/ BYTE * result; /* Hash result.*/ CK_ULONG objectsFoundNumber; /* Number of founded public key.*/ CK_MECHANISM mechanism = {CKM_SHA_1,0,0}; /* Used hash mechanism.*/ int i,j; /* Iterators.*/ char byteChar[3]; BYTE byte; CK_OBJECT_HANDLE hCert; /* Handle to the certificate object.*/ hCert = pCertInfo->hCert; /** - Get the first object ID attribute size.*/ rv = p11->C_GetAttributeValue(pCertInfo->hSession, hCert, &forObjectId, 1); if(rv != CKR_OK) { return FALSE; } /** - Allocate memory for the wanted attribute.*/ forObjectId.pValue = HeapAlloc(heapHandle, HEAP_ZERO_MEMORY, forObjectId.ulValueLen+1); /** - Get the first object ID attribute.*/ rv = p11->C_GetAttributeValue(pCertInfo->hSession, hCert, &forObjectId, 1); /** - Looking for a object object ID certID.*/ template[0].type =CKA_ID; template[0].pValue = (unsigned char *) forObjectId.pValue; template[0].ulValueLen=sizeof(unsigned char); /** and public key.*/ template[1].type = CKA_CLASS; template[1].pValue = &pubClass; template[1].ulValueLen = sizeof(pubClass); /** - Initiate the certificate research.*/ rv = p11->C_FindObjectsInit(pCertInfo->hSession, template, 2); if (rv != CKR_OK) { return FALSE; } /** - Find the first corresponding object.*/ rv = p11->C_FindObjects(pCertInfo->hSession, &hPubKey, 1, &objectsFoundNumber); if (rv != CKR_OK) { return FALSE; } /** - Close the certificate research.*/ rv = p11->C_FindObjectsFinal(pCertInfo->hSession); if (rv != CKR_OK) { SetLastError(NTE_BAD_KEYSET); return 0; } /** - If one object found,*/ if(objectsFoundNumber != 1) { return FALSE; } /** then there is a public key associated to the certificate (same object * ID).*/ /** - Copy token label into certinfo.*/ strncpy(pCertInfo->tokenLabel,tokenInfo.label,32); pCertInfo->tokenLabel[32] = '\0'; /** - Store the pointer to the key ID uchar in the certificate information structure.*/ pCertInfo->keyId = *((unsigned char *)forObjectId.pValue); /** - Get the public Key modulus.*/ /** - Get the first object MODULUS attribute size.*/ rv = p11->C_GetAttributeValue(pCertInfo->hSession, hPubKey, &forObjectModulus, 1); if(rv != CKR_OK) { return FALSE; } /** - Allocate memory for the wanted attribute.*/ forObjectModulus.pValue = HeapAlloc(heapHandle, HEAP_ZERO_MEMORY, forObjectModulus.ulValueLen+1); /** - Get the first object Modulus attribute.*/ rv = p11->C_GetAttributeValue(pCertInfo->hSession, hPubKey, &forObjectModulus, 1); modulus = (BYTE *)forObjectModulus.pValue; modulusLen = (CK_ULONG) forObjectModulus.ulValueLen; /** - Hash it.*/ /** - Initiate PKCS #11 digest.*/ rv = p11->C_DigestInit(pCertInfo->hSession, &mechanism); if (rv != CKR_OK) { return FALSE; } i = 0; /** - Feed digest with to be hashed data while iterator < t-b-hashed lenth.*/ while(i<modulusLen) { /** - Copy 64 bytes by 64 bytes in the buffer.*/ for(j = 0; j<64 && i<modulusLen;j++) { buffer[j] = modulus[i]; i++; } /** - If less than 64 bytes have been copied, use i for update lenth.*/ if(j<64) { rv = p11->C_DigestUpdate(pCertInfo->hSession, buffer,j); } else { rv = p11->C_DigestUpdate(pCertInfo->hSession, buffer, 64); } if (rv != CKR_OK) { p11->C_DigestFinal(pCertInfo->hSession, NULL, &hashLen); return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -