Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PFXImportCertStore - working example?

2,397 views
Skip to first unread message

ma...@prosapia.com

unread,
Aug 27, 2002, 6:55:40 PM8/27/02
to
I'm looking for a working example of using PFXImportCertStore (or any
other method of importing p12 certificates) into the Local Computer >
Personal Certificates store and Local Computer > Trusted Root
Certificates store.

If anyone has any non-MMC method of importing p12 certificates, please
let me know (I'll take even command line methods if any are known.)

Thanks,

-Matt

krish shenoy[MS]

unread,
Aug 28, 2002, 12:57:07 PM8/28/02
to
Can you let us know how you obtained the PFX in the first place.
If it is Base64 encoded then you will have to first convert it to Binary
using
CryptStringToBinary.
_CRYPTOAPIBLOB pfxBlob;
pfxBlob.pbData = myCryptStringToBinaryW(bstrPFX,&dwcbData);
pfxBlob.cbData = dwcbData;
if ( FALSE == PFXIsPFXBlob(&pfxBlob) ) // Check to see if it is a blob
{
MlogFail(myLog,L"PFXIsPFXBlob() failed. hr=0x%x\n",0);
goto error;
}

dwImportFlags = CRYPT_EXPORTABLE | CRYPT_USER_PROTECTED ;

// Exportable means that the key should be marked as exportable
//**********************************************************************
//* CRYPT_USER_PROTECTED documentation ---
//* If this flag is set, the user is notified through a dialog box or
another
//* method when certain actions are attempting to use this key. The
precise
//* behavior is specified by the CSP being used..

//**************************************************************************

hPFXtoStore = PFXImportCertStore( &pfxBlob ,L"password", dwImportFlags );
if ( hPFXtoStore == NULL ) {
hr = GetLastError();
MlogFail(myLog,L"PFXImportCertStore failed. hr=0x%x\n",hr);
goto error;
}

// Open My Store
if ( NULL == (hMyStore = CertOpenStore( CERT_STORE_PROV_SYSTEM,
0, // The encoding type is not
needed.
NULL, // Use the default
HCRYPTPROV.
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"))) {
hr = GetLastError();
MlogFail(myLog,L"CertOpenStore 0x%x\n",hr);
goto error;
}

while ( pCertContext = CertEnumCertificatesInStore( hPFXtoStore,
pCertContext))
{
// Now add the certificate context to My Store
CertAddCertificateContextToStore()

}


<ma...@prosapia.com> wrote in message
news:jh0omu0j59nvfgb41...@4ax.com...

Matt

unread,
Aug 28, 2002, 1:52:59 PM8/28/02
to
Well, its actually a p12 certificate obtained from openssl on a linux
box. I need an easier way to import this cert for VPN (IPSEC) usage
with windows 2000/XP without using MMC. Ideally, I need to get the
contained CA cert into the Local Computer / Trusted Root Certificates
and an included private key into Local Computer / Personal
Certificates.

Unfortunately the MMC import method is too complex and error prone for
users to successfully complete.

-Matt

krish shenoy[MS]

unread,
Aug 28, 2002, 2:14:20 PM8/28/02
to
The code that I described should do the job. You would also need to open the
Local Machine Root store

"Matt" <ma...@prosapia.com> wrote in message
news:a53qmu0hjnb7cf9l5...@4ax.com...

Shreeniwas Kelkar [MS]

unread,
Aug 28, 2002, 2:43:43 PM8/28/02
to
Why do you think that the MMC import method too complex and error prone? Can
you provide details of what errors you got or operations you could not
perform?

You can start MMC Certificates Snapin for the local machine and import the
PFX using Certificate Import Wizard. It will import the cert(s) into the
local machine\personal store.

--
Shreeniwas Kelkar,
Microsoft Corp.

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included samples is subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm"
--
"Matt" <ma...@prosapia.com> wrote in message
news:a53qmu0hjnb7cf9l5...@4ax.com...

Matt

unread,
Aug 28, 2002, 3:42:56 PM8/28/02
to
If you know what you are doing, its not too bad. But for the average
end user, its not something that they know about (or should even be
messing with.)

And, unfortunately, just double-clicking on the p12 file usually puts
the certificate in some odd mode where it won't work for use with the
VPN.

-Matt

Matt

unread,
Aug 28, 2002, 4:17:19 PM8/28/02
to
Ok.. I've gotten things to work were it imports the two certs
(CA/personal) into the Current User's Personal Certificates.

How do I put these in the Local Computer's store instead?

And I'm guessing I change "My" to "Root" to get the CA cert into the
Trusted Root CA.

Thanks for the help!

-Matt

On Wed, 28 Aug 2002 11:14:20 -0700, "krish shenoy[MS]"

Matt

unread,
Aug 28, 2002, 8:03:45 PM8/28/02
to
Ah, nevermind. I figured it out:

hRootCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE, L"ROOT")

Thanks for all the help!

-Matt

Matt

unread,
Aug 28, 2002, 10:37:09 PM8/28/02
to
Just for jollies, I will post the code I have that imports
certificates from a p12 file into the Local Computer Personal and Root
shares (based on the name of the cert.) If the cert has "ca" in the
name, it puts it under the Root, otherwise Personal. Not the most
universal solution, but works fine for my particular problem.

----
certimport.cpp
----

#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <cryptuiapi.h>
#include <string.h>
#include "stdafx.h"

void main(int argc, char* argv[])
{
if (argc < 3)
{
printf("Usage: certimport <filename.p12> <export
passwd>\n");
exit(1);
}

printf("Reading certificate file: %s\n", argv[1]);

// read cert file
BY_HANDLE_FILE_INFORMATION fileInfo;
HANDLE hFile =
CreateFile(argv[1],GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Error: Couldn't open file (%s)\n", argv[1]);
exit(1);
}

GetFileInformationByHandle(hFile,&fileInfo);
long fileSize=fileInfo.nFileSizeLow;

// make buffer for cert data
PBYTE pbBuffer = NULL;
if (!(pbBuffer=(PBYTE)malloc(fileSize)))
{
printf("Error: malloc failed (%l)\n", fileSize);
exit (1);
}

unsigned long bytesRead;
ReadFile (hFile,pbBuffer,fileSize,&bytesRead,NULL);

// create pfx blob
CRYPT_DATA_BLOB cryptBlob;
cryptBlob.cbData=fileSize;
cryptBlob.pbData=pbBuffer;

// is it actually a pfx blob?
if (FALSE == PFXIsPFXBlob(&cryptBlob) )
{
printf("Error: PFXIsPFXBlob failed\n");
exit(1);
}

// convert argv[2] to WCHAR pw
WCHAR pw[256];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, argv[2], -1, pw,
sizeof(pw)/sizeof(WCHAR) );
mbstowcs(pw, argv[2], strlen(argv[2]));

HCERTSTORE hCertStore;

hCertStore=PFXImportCertStore(&cryptBlob,(LPCWSTR)pw,CRYPT_USER_KEYSET);
if (hCertStore == NULL)
{
printf("Error: PFXImportCertStore failed\n");
exit(1);
}

PCCERT_CONTEXT pCertContext = NULL;
pCertContext=
CertEnumCertificatesInStore(hCertStore,pCertContext);

HCERTSTORE hMyCertStore;
if (!(hMyCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0,
NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY")))
{
printf("Error: CertOpenStore(MY) failed\n");
exit(1);
}

HCERTSTORE hRootCertStore;
if (!(hRootCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
0, NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE, L"ROOT")))
{
printf("Error: CertOpenStore(ROOT) failed\n");
exit(1);
}

HCERTSTORE thisStore;

char pszNameString[256];
CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
0, NULL, pszNameString, 128);
printf("Certificate name: %s\n", pszNameString);

if (strstr(pszNameString, "ca"))
{
thisStore = hRootCertStore;
}
else
{
thisStore = hMyCertStore;
}

CertAddCertificateContextToStore(thisStore, pCertContext,
CERT_STORE_ADD_ALWAYS, NULL);

while (NULL != (pCertContext =
CertEnumCertificatesInStore(hCertStore, pCertContext)))
{
CertGetNameString(pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, 128);
printf("Certificate name: %s\n", pszNameString);

if (strstr(pszNameString, "ca"))
{
thisStore = hRootCertStore;
}
else
{
thisStore = hMyCertStore;
}

CertAddCertificateContextToStore(thisStore,
pCertContext, CERT_STORE_ADD_ALWAYS, NULL);
}

// close stores
CertCloseStore(hMyCertStore,0);
CertCloseStore(hRootCertStore,0);
CertCloseStore(hCertStore,0);

printf("Successfully imported certificates.\n");
exit(0);

}

----

Matt

unread,
Aug 29, 2002, 10:53:21 AM8/29/02
to
Ok, here's a fun one:

If I import the p12 cert manually using MMC, IPSEC works. If I do it
with PFXImportCertStore, IPSEC doesn't work (it keeps negotiating
security, but never finishes). My code for importing programmatically
is in the previous message in this thread.

The manual method is right clicking on Certificates (Local Computer) /
Personal and selecting All Tasks > Import. I select the p12 (the same
as used for the code) and enter the password. I select "automatically
select the certificate store based on the type of certificate."

This method places the personal certificate under Local Computer /
Personal and the CA cert under Local Computer / Trsuted Root CAs.

My code also places the certs in those very same places. I can't see
anything different from within MMC.

Anyone know why this is? (Or exactly what the import command does in
MMC / Certificates?)

Thanks!

-Matt

Matt

unread,
Aug 29, 2002, 11:13:41 AM8/29/02
to
Nevermind.. I found the problem..

hCertStore=PFXImportCertStore(&cryptBlob,(LPCWSTR)pw,CRYPT_USER_KEYSET);

needed to be:

hCertStore=PFXImportCertStore(&cryptBlob,(LPCWSTR)pw,CRYPT_MACHINE_KEYSET);

so the private keys are stored under local machine and not the current
user..

-Matt

0 new messages