cliexplorer.cpp
来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C++ 代码 · 共 909 行 · 第 1/2 页
CPP
909 行
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
CLIExplorer.c - Internet Explorer token support functions
$Id: CLIExplorer.cpp,v 1.14 2002/09/28 20:51:10 ajivsov Exp $
____________________________________________________________________________*/
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <assert.h>
#include <stdio.h>
#include <rpc.h> /* For UUID support: */
#include <malloc.h>
#ifndef TEST
extern "C" {
#include "PGPclx.h"
}
#else
#define PGPclExport
#define pgpAssert assert
#define pgpDebugMsg OutputDebugString
#endif
#define PGP_IE_TRACE_CONT_REMOTE
typedef struct _PGP_CSP_PROV_INFO {
CRYPT_KEY_PROV_INFO prov_info;
wchar_t prov_name[80];
wchar_t container_name[80];
_PGP_CSP_PROV_INFO() {
memset( this, 0, sizeof(*this) );
this->prov_info.pwszContainerName = this->container_name;
this->prov_info.pwszProvName = this->prov_name;
}
} PGP_CSP_PROV_INFO;
/* Export to IE database */
extern "C" int PGPclExport
PGPclIEExportX509(
unsigned char *pCertEncoded, unsigned cbCertEncoded,
const char *szUserID, const char *keyIDstr,
const char *key_container, unsigned key_container_size,
const char *CSP)
{
int ret = -1;
const CSP_len = strlen(CSP)+1;
char pgpSuffix[32];
bool bUseKeyID = (keyIDstr && *keyIDstr);
if( !key_container || key_container_size == 0 )
return -1;
CERT_CONTEXT const *cert_context =
CertCreateCertificateContext(
X509_ASN_ENCODING,
pCertEncoded,
cbCertEncoded
);
HCERTSTORE hMyCertStore=NULL;
if( cert_context == NULL )
return -1;
/* Open MY store */
if( !(hMyCertStore = CertOpenSystemStore(
NULL,
"MY")) )
{
goto error;
}
/* Set information about the private key */
{
PGP_CSP_PROV_INFO csp_info;
csp_info.prov_info.dwProvType = PROV_RSA_FULL;
csp_info.prov_info.dwKeySpec = AT_KEYEXCHANGE;
mbstowcs( csp_info.container_name, key_container, key_container_size );
mbstowcs( csp_info.prov_name, CSP, CSP_len );
if( !CertSetCertificateContextProperty(
cert_context,
CERT_KEY_PROV_INFO_PROP_ID,
0,
&(csp_info.prov_info) ) )
{
goto error;
}
}
/* Set Friendly name */
{
char s[80] = "";
wchar_t ws[80];
CRYPT_DATA_BLOB Friendly_Name_Blob={0,(BYTE*)ws};
strncpy( s, szUserID, sizeof(s) );
s[sizeof(s)-1] = '\0';
assert( !bUseKeyID || strlen(keyIDstr) <= 4*2+2 );
sprintf( pgpSuffix, " (PGP%s%s)",
bUseKeyID ? " " : "", bUseKeyID ? keyIDstr : "" );
/* cut very long user ID */
const unsigned off = sizeof(s)-2 - strlen(pgpSuffix);
if( strlen(s) > off ) {
strcpy( s+off - 3, "..." );
}
strcat( s, pgpSuffix );
mbstowcs( ws, s, sizeof(s) );
Friendly_Name_Blob.cbData = (wcslen(ws)+1) * sizeof(wchar_t);
if( !CertSetCertificateContextProperty(
cert_context,
CERT_FRIENDLY_NAME_PROP_ID,
0,
&Friendly_Name_Blob ) )
{
goto error;
}
}
if( !CertAddCertificateContextToStore(
hMyCertStore,
cert_context,
CERT_STORE_ADD_ALWAYS,
NULL )
)
{
goto error;
}
ret = 0;
error:
CertCloseStore(hMyCertStore,0);
CertFreeCertificateContext( cert_context );
return ret;
}
/* Determine right CSP */
extern "C" int PGPclExport
PGPclIETokenProvToCSP( const char *tokenProv, char *CSP, int size )
{
memset( CSP, 0, size );
if( strstr( tokenProv, "Rainbow" )!=NULL ) {
strncpy( CSP, "Datakey RSA CSP", size );
}
else if( strstr( tokenProv, "Schlumberger" )!=NULL ) {
strncpy( CSP, "Schlumberger Cryptographic Service Provider", size );
}
else if( strstr( tokenProv, "Gemplus" )!=NULL ) {
/* Do nothing for Gemplus -- it doesn't like
when we mix CryptoAPI and PKCS11 calls
*/
/* strncpy( CSP, "Gemplus GemSAFE Card CSP", size ); */
return -1;
}
else if( strstr( tokenProv, "Aladdin" )!=NULL ) {
strncpy( CSP, "eToken Base Cryptographic Provider", size );
}
else {
assert(0);
return -1;
}
return 0;
}
/* Determine existing key containers for the given
Cryptographic Service Provider.
example: CSP = "Schlumberger Cryptographic Service Provider"
Key container name is a null-terminated string.
format of output parameter cont is as follows:
<key container 1> '\0'
...
<key ontainer x> '\0' '\0'
In this example output parameter n == x.
caller must free(cont).
*/
static int
sGetExistingKeyContainers( const char *CSP, char **cont, int *n )
{
HCRYPTPROV hCryptProv;
BOOL ret;
const char *container = NULL;
if( cont )
*cont = NULL;
if( n )
*n = 0;
if( *CSP == '\0' )
return -1;
if( !CryptAcquireContext(
&hCryptProv,
container, /* Container name: default */
CSP,
PROV_RSA_FULL,
CRYPT_SILENT )) /* Do not display any message boxes -
fail instead */
{
/* try with another flag */
if( !CryptAcquireContext(
&hCryptProv,
container,
CSP,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT ))
{
#if PGP_DEBUG && defined(PGP_IE_TRACE_CONT_REMOTE)
OutputDebugString(
"sGetExistingKeyContainers: CryptAcquireContext failed\n" );
#endif
return -1;
}
}
#if PGP_DEBUG && defined(PGP_IE_TRACE_CONT_REMOTE)
OutputDebugString( "sGetExistingKeyContainers: context acquired\n" );
#endif
/* Now get key containers */
{
DWORD flags = CRYPT_FIRST;
char *p = NULL;
int l=0;
unsigned char szCont[128];
int real_n=0;
do {
DWORD dwContLen = sizeof(szCont);
#if PGP_DEBUG && defined(PGP_IE_TRACE_CONT_REMOTE)
OutputDebugString( "sGetExistingKeyContainers: before CryptGetProvParam\n" );
#endif
ret = CryptGetProvParam(
hCryptProv, PP_ENUMCONTAINERS, (BYTE *)szCont, &dwContLen, flags);
flags &= (~CRYPT_FIRST);
#if PGP_DEBUG && defined(PGP_IE_TRACE_CONT_REMOTE)
OutputDebugString( "sGetExistingKeyContainers: after CryptGetProvParam\n" );
#endif
if( !ret )
dwContLen = 0;
else {
real_n++;
p = (char *)(( p == NULL ) ? malloc( dwContLen + 1 ) : realloc( p, l + dwContLen + 1));
if( p == NULL )
ret = FALSE;
else {
#if PGP_DEBUG && defined(PGP_IE_TRACE_CONT_REMOTE)
char s[128];
sprintf( s, "sGetExistingKeyContainers: cont=%s\n", szCont );
OutputDebugString( s );
#endif
memcpy( p+l, szCont, dwContLen );
l += dwContLen;
p[l] = '\0'; /* Always terminate */
}
}
} while(ret);
if(GetLastError() == ERROR_NO_MORE_ITEMS)
ret = TRUE;
if( ret ) {
if( cont )
*cont = p;
if( n )
*n = real_n;
}
#if 0
XXX it is wrong: real key container may be different
/* If we failed, try to look for defauld container:
possibly vendor doesn't implement PP_ENUMCONTAINERS flag
*/
if( real_n == 0 ) {
DWORD dwContLen = sizeof(szCont);
ret = CryptGetProvParam(
hCryptProv, PP_CONTAINER, (BYTE *)szCont, &dwContLen, 0);
if( ret && dwContLen ) {
if( cont ) {
*cont = (char*)calloc( dwContLen + 1, 1 ); /* zeroes memory */
if( *cont )
memcpy( *cont, szCont, dwContLen );
}
if( n )
*n = 1;
}
}
#endif
}
CryptReleaseContext(hCryptProv,0);
#if PGP_DEBUG && defined(PGP_IE_TRACE_CONT_REMOTE)
OutputDebugString( "sGetExistingKeyContainers: context released\n" );
#endif
return (ret == TRUE ? 0 : -1);
}
extern "C" int PGPclExport
pgpIEGetDefKeyContainer( const char *CSP, char **cont )
{
HCRYPTPROV hCryptProv;
BOOL ret;
unsigned char szCont[128];
if( cont )
*cont = NULL;
if( !CryptAcquireContext(
&hCryptProv,
NULL, /* Container name: default */
CSP,
PROV_RSA_FULL,
CRYPT_SILENT )) /* Do not display any message boxes -
fail instead */
{
return -1;
}
/* look for default container:
(possibly when vendor doesn't implement PP_ENUMCONTAINERS flag )
*/
{
DWORD dwContLen = sizeof(szCont);
ret = CryptGetProvParam(
hCryptProv, PP_CONTAINER, (BYTE *)szCont, &dwContLen, 0);
if( ret && dwContLen ) {
if( cont ) {
*cont = (char*)calloc( dwContLen + 1, 1 ); /* zeroes memory */
if( *cont )
memcpy( *cont, szCont, dwContLen );
}
}
}
CryptReleaseContext(hCryptProv,0);
return (ret == TRUE ? 0 : -1);
}
/* Get the diference between key container sets.
conts1 is assumed to be a subset of conts2 */
extern "C" int
CLIEDiffKeyContainers( const char *conts1, const char *conts2, char **out )
{
const char *p;
int conts1_n, conts2_n;
if( out == NULL )
return -1;
*out = NULL;
if( conts2 == NULL ) /* Conts2 > conts1, so this is a problem */
return -1;
/* See if we had nothing before */
if( conts1 == NULL ) {
if( conts2 != NULL )
*out = strdup( conts2 );
return 0;
}
/* We have non-empty conts1 bellow */
/* Count containers in smaller set */
conts1_n = 0;
for( p = conts1; *p; p += strlen(p)+1 ) {
conts1_n ++;
}
/* Count containers larger set */
conts2_n = 0;
for( p = conts2; *p; p += strlen(p)+1 ) {
conts2_n ++;
}
assert( conts1_n > 0 && conts2_n > 0 );
if( conts1_n >= conts2_n )
return -1; /* conts2 > conts1 */
if( conts2_n - conts1_n > 1 )
return -1; /* We expect only one more container.
Don't know how to pick up the right one */
/* Here, we have two non-empty sets of containers,
conts2 has one more container then conts2. Find it */
/* Go through the larger set */
for( p = conts2; *p; p += strlen(p)+1 ) {
const char *existing = conts1;
while( *existing ) {
if( strcmp( p, existing ) == 0 )
break;
existing += strlen( existing ) + 1;
}
if( *existing == '\0' ) /* could not find - must be new container */
break;
}
if( *p )
*out = strdup(p);
return 0;
}
extern "C" int
CLIEGenerateNewUUID( char **cont )
{
UUID uuid;
unsigned char *sUuid = NULL;
UuidCreate( &uuid );
assert( uuid.Data1 != 0 );
UuidToString( &uuid, &sUuid );
assert( sUuid && *sUuid != '\0' );
*cont = sUuid ? strdup( (const char*)sUuid ) : NULL;
RpcStringFree(&sUuid);
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?