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 + -
显示快捷键?