示例#1
0
/** The verbosity level. */
static unsigned  g_cVerbosityLevel = 1;


static const char *errorToString(DWORD dwErr)
{
    switch (dwErr)
    {
#define MY_CASE(a_uConst)       case a_uConst: return #a_uConst;
        MY_CASE(CRYPT_E_MSG_ERROR);
        MY_CASE(CRYPT_E_UNKNOWN_ALGO);
        MY_CASE(CRYPT_E_OID_FORMAT);
        MY_CASE(CRYPT_E_INVALID_MSG_TYPE);
        MY_CASE(CRYPT_E_UNEXPECTED_ENCODING);
        MY_CASE(CRYPT_E_AUTH_ATTR_MISSING);
        MY_CASE(CRYPT_E_HASH_VALUE);
        MY_CASE(CRYPT_E_INVALID_INDEX);
        MY_CASE(CRYPT_E_ALREADY_DECRYPTED);
        MY_CASE(CRYPT_E_NOT_DECRYPTED);
        MY_CASE(CRYPT_E_RECIPIENT_NOT_FOUND);
        MY_CASE(CRYPT_E_CONTROL_TYPE);
        MY_CASE(CRYPT_E_ISSUER_SERIALNUMBER);
        MY_CASE(CRYPT_E_SIGNER_NOT_FOUND);
        MY_CASE(CRYPT_E_ATTRIBUTES_MISSING);
        MY_CASE(CRYPT_E_STREAM_MSG_NOT_READY);
        MY_CASE(CRYPT_E_STREAM_INSUFFICIENT_DATA);
        MY_CASE(CRYPT_I_NEW_PROTECTION_REQUIRED);
        MY_CASE(CRYPT_E_BAD_LEN);
        MY_CASE(CRYPT_E_BAD_ENCODE);
        MY_CASE(CRYPT_E_FILE_ERROR);
        MY_CASE(CRYPT_E_NOT_FOUND);
        MY_CASE(CRYPT_E_EXISTS);
        MY_CASE(CRYPT_E_NO_PROVIDER);
        MY_CASE(CRYPT_E_SELF_SIGNED);
        MY_CASE(CRYPT_E_DELETED_PREV);
        MY_CASE(CRYPT_E_NO_MATCH);
        MY_CASE(CRYPT_E_UNEXPECTED_MSG_TYPE);
        MY_CASE(CRYPT_E_NO_KEY_PROPERTY);
        MY_CASE(CRYPT_E_NO_DECRYPT_CERT);
        MY_CASE(CRYPT_E_BAD_MSG);
        MY_CASE(CRYPT_E_NO_SIGNER);
        MY_CASE(CRYPT_E_PENDING_CLOSE);
        MY_CASE(CRYPT_E_REVOKED);
        MY_CASE(CRYPT_E_NO_REVOCATION_DLL);
        MY_CASE(CRYPT_E_NO_REVOCATION_CHECK);
        MY_CASE(CRYPT_E_REVOCATION_OFFLINE);
        MY_CASE(CRYPT_E_NOT_IN_REVOCATION_DATABASE);
        MY_CASE(CRYPT_E_INVALID_NUMERIC_STRING);
        MY_CASE(CRYPT_E_INVALID_PRINTABLE_STRING);
        MY_CASE(CRYPT_E_INVALID_IA5_STRING);
        MY_CASE(CRYPT_E_INVALID_X500_STRING);
        MY_CASE(CRYPT_E_NOT_CHAR_STRING);
        MY_CASE(CRYPT_E_FILERESIZED);
        MY_CASE(CRYPT_E_SECURITY_SETTINGS);
        MY_CASE(CRYPT_E_NO_VERIFY_USAGE_DLL);
        MY_CASE(CRYPT_E_NO_VERIFY_USAGE_CHECK);
        MY_CASE(CRYPT_E_VERIFY_USAGE_OFFLINE);
        MY_CASE(CRYPT_E_NOT_IN_CTL);
        MY_CASE(CRYPT_E_NO_TRUSTED_SIGNER);
        MY_CASE(CRYPT_E_MISSING_PUBKEY_PARA);
        MY_CASE(CRYPT_E_OSS_ERROR);
        default:
        {
            PCRTCOMERRMSG pWinComMsg = RTErrCOMGet(dwErr);
            if (pWinComMsg)
                return pWinComMsg->pszDefine;

            static char s_szErr[32];
            RTStrPrintf(s_szErr, sizeof(s_szErr), "%#x (%d)", dwErr, dwErr);
            return s_szErr;
        }
    }
}

#if 0 /* hacking */
static RTEXITCODE addToStore(const char *pszFilename, PCRTUTF16 pwszStore)
{
    /*
     * Open the source.
     */
    void   *pvFile;
    size_t  cbFile;
    int rc = RTFileReadAll(pszFilename, &pvFile, &cbFile);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileReadAll failed on '%s': %Rrc", pszFilename, rc);

    RTEXITCODE rcExit = RTEXITCODE_FAILURE;

    PCCERT_CONTEXT pCertCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                                           (PBYTE)pvFile,
                                                           (DWORD)cbFile);
    if (pCertCtx)
    {
        /*
         * Open the destination.
         */
        HCERTSTORE hDstStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
                                             PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
                                             NULL /* hCryptProv = default */,
                                             /*CERT_SYSTEM_STORE_LOCAL_MACHINE*/ CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG,
                                             pwszStore);
        if (hDstStore != NULL)
        {
#if 0
            DWORD dwContextType;
            if (CertAddSerializedElementToStore(hDstStore,
                                                pCertCtx->pbCertEncoded,
                                                pCertCtx->cbCertEncoded,
                                                CERT_STORE_ADD_NEW,
                                                0 /* dwFlags (reserved) */,
                                                CERT_STORE_ALL_CONTEXT_FLAG,
                                                &dwContextType,
                                                NULL))
            {
                RTMsgInfo("Successfully added '%s' to the '%ls' store (ctx type %u)", pszFilename, pwszStore, dwContextType);
                rcExit = RTEXITCODE_SUCCESS;
            }
            else
                RTMsgError("CertAddSerializedElementToStore returned %s", errorToString(GetLastError()));
#else
            if (CertAddCertificateContextToStore(hDstStore, pCertCtx, CERT_STORE_ADD_NEW, NULL))
            {
                RTMsgInfo("Successfully added '%s' to the '%ls' store", pszFilename, pwszStore);
                rcExit = RTEXITCODE_SUCCESS;
            }
            else
                RTMsgError("CertAddCertificateContextToStore returned %s", errorToString(GetLastError()));
#endif

            CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG);
        }
        else
            RTMsgError("CertOpenStore returned %s", errorToString(GetLastError()));
        CertFreeCertificateContext(pCertCtx);
    }
    else
        RTMsgError("CertCreateCertificateContext returned %s", errorToString(GetLastError()));
    RTFileReadAllFree(pvFile, cbFile);
    return rcExit;

#if 0

    CRYPT_DATA_BLOB Blob;
    Blob.cbData = (DWORD)cbData;
    Blob.pbData = (PBYTE)pvData;
    HCERTSTORE hSrcStore = PFXImportCertStore(&Blob, L"", )

#endif
}
/*****************************************************************************
 wmain

*****************************************************************************/
DWORD
__cdecl
wmain(
    int     argc,
    LPWSTR  argv[]
    )
{
    HRESULT                 hr = S_OK;
    HCERTSTORE              hStore = NULL;
    PCCERT_CHAIN_CONTEXT    *prgpSelection = 0;
    DWORD                   cSelection = 0;
    BYTE                    bDigSig = CERT_DIGITAL_SIGNATURE_KEY_USAGE; // in byte 0
    
	ULONG                 ulAuthPackage;
    BOOL                  bSave           = FALSE;
    DWORD                 cbAuthBuffer    = 0;
    DWORD                 dwError         = ERROR_SUCCESS;
    DWORD                 dwAuthError     = 0;
    void * pBuffer = NULL;
    ULONG ulSize = 0;  
    LPVOID                pbAuthBuffer;
    PCCERT_CONTEXT	  pCertContext = NULL;
    CREDUI_INFO           CredUiInfo;
    
    CredUiInfo.pszCaptionText = L"Select your credentials";
    CredUiInfo.pszMessageText = L"Please select a certificate";
    CredUiInfo.cbSize = sizeof(CredUiInfo);
    CredUiInfo.hbmBanner = NULL;
    CredUiInfo.hwndParent = NULL;

    ulAuthPackage = (ULONG) CERT_CREDENTIAL_PROVIDER_ID; 

    CERT_SELECTUI_INPUT certInput = {0};
       
    void* rgParaEKU[] =
    {
        szOID_PKIX_KP_EMAIL_PROTECTION
    };

    CERT_SELECT_CRITERIA EKUCriteria = 
    {
        CERT_SELECT_BY_ENHKEY_USAGE,
        ARRAYSIZE(rgParaEKU),
        rgParaEKU
    };

    CERT_EXTENSION extDigSig =
    {
        NULL, // pszObjId
        FALSE, // fCritical
        {1, &bDigSig} // Value
    };

    void* rgParaKU[] =
    {
        &extDigSig // digital signature key usage
    };

    CERT_SELECT_CRITERIA KUCriteria = 
    {
        CERT_SELECT_BY_KEY_USAGE,
        ARRAYSIZE(rgParaKU),
        rgParaKU
    };

   CERT_SELECT_CRITERIA rgCriteriaFilter[] =
    {
        EKUCriteria,
        KUCriteria
    };

    hStore = CertOpenStore(
                            CERT_STORE_PROV_SYSTEM_W,
                            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                            NULL,
                            CERT_SYSTEM_STORE_CURRENT_USER,
                            L"MY"
                            );
    
    if( NULL == hStore )
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        
        goto CleanUp;
    }

    wprintf( L"Looking for certificates in MY store ...\n" );

    if( !CertSelectCertificateChains(
                            NULL,
                            CERT_SELECT_TRUSTED_ROOT | CERT_SELECT_HAS_PRIVATE_KEY,
                            NULL,
                            ARRAYSIZE(rgCriteriaFilter),
                            rgCriteriaFilter,
                            hStore,
                            &cSelection,
                            &prgpSelection))
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        
        goto CleanUp;
    }

    if( cSelection < 1 )
    {
        wprintf( L"No certificates found matching the selection criteria.\n" );
        goto CleanUp;
    }
    
    wprintf( L"%u certificates found matching the selection criteria.\n", cSelection );

	//
	// show the selected cert in UI
	//

	certInput.prgpChain = prgpSelection;
    certInput.cChain = cSelection;
        
    hr = CertSelectionGetSerializedBlob(
                        &certInput,
                        &pBuffer,
                        &ulSize);

    if(S_OK != hr)
        goto CleanUp;
    
    dwError = CredUIPromptForWindowsCredentials(
                        &CredUiInfo, 
                        dwAuthError, 
                        (PULONG)&ulAuthPackage, 
                        pBuffer,
                        ulSize,
                        &pbAuthBuffer, 
                        &cbAuthBuffer, 
                        &bSave, 
                        CREDUIWIN_AUTHPACKAGE_ONLY);
    if(ERROR_SUCCESS != dwError)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
    }
    else
    {
		//get the selected cert context 
        if( !CertAddSerializedElementToStore( NULL,
                                          (BYTE *)pbAuthBuffer,
                                          cbAuthBuffer,
                                          CERT_STORE_ADD_ALWAYS,
                                          0, // flags
                                          CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
                                          NULL,
                                          reinterpret_cast<const void **>(&pCertContext)
                                          ))
        {
			 goto CleanUp;
		}

		//
		// pCertContext now is ready to use
		//
    }

CleanUp:

    if( FAILED( hr ))
    {
        ReportError( NULL, hr  );
    }

    if( NULL != pBuffer )
	{
        LocalFree(pBuffer);
	}

    if( NULL != pCertContext )
	{
        CertFreeCertificateContext(pCertContext);
	}
    
    return (DWORD)hr;

    UNREFERENCED_PARAMETER( argc );
    UNREFERENCED_PARAMETER( argv );
}