Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / October 2003

Tip: Looking for answers? Try searching our database.

Calling CertCreateCertificateContext from C#

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Larry - 23 Oct 2003 00:43 GMT
I'm trying to use CryptoAPI to read in a certificate (.pfx) and put it
into a store.  I can open the store just fine, but I am having
problems creating the certificate context.  I think that is has to do
with how I am using DllImport.  Does anybody have any ideas?  Here is
my DllImport statement:

[DllImport("crypt32.dll", SetLastError=true)]
public static extern IntPtr CertCreateCertificateContext(
    int dwCertEncodingType,
    ref string pbCertEncoded, <--- line giving me problems???
       int cbCertEncoded);

Also, is there a preferred way to read in the certificate, or is
BinaryReader fine?

Thanks for your help!

Larry
Michel Gallant - 23 Oct 2003 01:01 GMT
Might want to try PFXImportCertStore() instead:

[DllImport("crypt32.dll", SetLastError=true)]
 public static extern IntPtr PFXImportCertStore(
ref CRYPT_DATA_BLOB pPfx,
[MarshalAs(UnmanagedType.LPWStr)] String szPassword,
uint dwFlags);

There is a forthcoming article (~ Dec 2003, MSDN Security Site)
on using PFX in .NET using Pinvoke as a kind of "soft" smard-card.

- Michel Gallant
  Visual Security   MVP

> I'm trying to use CryptoAPI to read in a certificate (.pfx) and put it
> into a store.  I can open the store just fine, but I am having
[quoted text clipped - 14 lines]
>
> Larry
Larry - 24 Oct 2003 00:06 GMT
I am trying to get the certificate into the "My" store.  From what I
understand, PFXImportCertStore imports the certificates in the pfx
file to a store of its own and return that store's handle.  Is there a
way using this function to get the certificates into the "My" store?

Larry

> Might want to try PFXImportCertStore() instead:
>
[quoted text clipped - 28 lines]
> >
> > Larry
Michel Gallant - 24 Oct 2003 01:28 GMT
You can use the capi CertAddCertificateContextToStore() to copy
the cert context from the memory store to the MY store (see samples
in MSDN/CryptoAPI for this).

However, CAPICOM makes this trivially easy. e.g. VBS:

Set oStore = CreateObject("CAPICOM.Store")
oStore.Open CAPICOM_CURRENT_USER_STORE, "MY", CAPICOM_STORE_OPEN_READ_WRITE
Store.Load pfxfile, pswd, keystoreflags

- Michel Gallant
  Visual Security  MVP

> I am trying to get the certificate into the "My" store.  From what I
> understand, PFXImportCertStore imports the certificates in the pfx
[quoted text clipped - 35 lines]
> > >
> > > Larry
- 24 Oct 2003 19:16 GMT
Under this project's constraints, I can't use CAPICOM.  
So, yes, I could use CertAddCertificateContextToStore(),
but that requires a context, which I would need to use
then CertCreateCertificateContext, which takes me back to
my original posting.  I need help with
CertCreateCertificateContext in C# (MSDN examples are in
C++).  Here is some of the code I am currently using:

// DllImport declaration
[DllImport("crypt32.dll", SetLastError=true)]
public static extern IntPtr CertCreateCertificateContext(
            int dwCertEncodingType,
            IntPtr pbCertEncoded,
            int cbCertEncoded);

// at this point, the "My" store is already opened
// read certificate
string fileName = @"C:\TestCert.pfx";
FileInfo fileinfo = new FileInfo(fileName);
BinaryReader br = new BinaryReader(fileinfo.OpenRead());
byte[] Bytes = new byte[fileinfo.Length];
br.Read(Bytes,0,(int)fileinfo.Length);
br.Close();

// We need to marshal the byte array Bytes into a pointer
IntPtr buffer = Marshal.AllocHGlobal(Bytes.Length);
Marshal.Copy(Bytes,0,buffer,Bytes.Length);

hCertCntxt = CertCreateCertificateContext
(X509_ASN_ENCODING, buffer, Bytes.Length);

if(hCertCntxt.ToInt32() != 0)
{
    System.Windows.Forms.MessageBox.Show("got
context");
}
else
{
    int iErrorCode = Marshal.GetLastWin32Error();   
    Win32Exception ex = new Win32Exception
(iErrorCode);
    string errMsg = ex.Message;
    System.Windows.Forms.MessageBox.Show
(errMsg, "Error Message");
}

Thanks for your time and help.

>-----Original Message-----
>You can use the capi CertAddCertificateContextToStore() to copy
[quoted text clipped - 55 lines]
>
>.
Michel Gallant - 24 Oct 2003 19:40 GMT
I don't think you can use CertCreateCertificateContext() directly
with a **pfx** blob.
What you need to do is:

(1) Use PFXImportCertStore() to get the certs into a transient memory store (which creates a
keycontainer for pfk automatically)
(2) Do a search on that memory store (using the returned memstore handle) by
      enumerating the certs therein using  CertEnumCertificatesInStore(..)
(3) Check if the enumerated cert has a matching private key (the pfx might contain several
root-subroot certs):
     CertGetCertificateContextProperty(hCertCntxt, CERT_KEY_PROV_INFO_PROP_ID ...)
(4) Add THAT cert context to the MY store using CertAddCertificateContextToStore(..)

- Michel Gallant
> Under this project's constraints, I can't use CAPICOM.
> So, yes, I could use CertAddCertificateContextToStore(),
[quoted text clipped - 122 lines]
> >
> >.
Larry - 29 Oct 2003 21:44 GMT
This is what I figured I would have to do and it works great!  Thanks
a lot for your time and help Michel!

Larry

> I don't think you can use CertCreateCertificateContext() directly
> with a **pfx** blob.
[quoted text clipped - 135 lines]
> > >
> > >.
Michel Gallant - 24 Oct 2003 19:49 GMT
An alternate easier declaration is to simply use a byte[] instead of a IntPtr.
Less code; no memory cleanup required.

  [DllImport("crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)]
   public static extern uint CertCreateCertificateContext(
   uint dwCertEncodingType,
   byte[] pbCertEncoded,
   uint cbCertEncoded) ;

- Mitch
> Under this project's constraints, I can't use CAPICOM.
> So, yes, I could use CertAddCertificateContextToStore(),
[quoted text clipped - 10 lines]
> IntPtr pbCertEncoded,
> int cbCertEncoded);

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.