?
Solved

code sample: CertGetNameStringW CryptQueryObject

Posted on 2002-07-02
10
Medium Priority
?
3,365 Views
Last Modified: 2009-12-16
I need a Delphi code sample for this function:
 CertGetNameStringW
 CryptQueryObject

(Perhaps you can simple translate this C source:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=ut69uoT1BHA.2380%40tkmsftngp04&rnum=2 )

Thank you!
0
Comment
Question by:Kann
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
10 Comments
 
LVL 3

Expert Comment

by:raidos
ID: 7124405
I suggest you try using this:
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=17597

Regards
//raidos
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7124526
Here's one example of CertGetNameStringW:

program crypttest;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  JwaWinCrypt; // download from http://delphi-jedi.org or http://members.chello.nl/m.vanbrakel2

procedure DisplayCertContext(CertContext: PCertContext);
var
  CertName: array[0..255] of WideChar;
begin
  Writeln;
  if CertGetNameStringW(CertContext, CERT_NAME_EMAIL_TYPE, 0, nil,
    CertName, 256) = 0 then
    RaiseLastOSError;
  Writeln('Subject CERT_NAME_EMAIL_TYPE: ''', CertName, '''');
  if CertGetNameStringW(CertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil,
    CertName, 256) = 0 then
    RaiseLastOSError;
  Writeln('Subject CERT_NAME_SIMPLE_DISPLAY_TYPE: ''', CertName, '''');
  if CertGetNameStringW(CertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, nil,
    CertName, 256) = 0 then
    RaiseLastOSError;
  Writeln('Subject CERT_NAME_FRIENDLY_DISPLAY_TYPE: ''', CertName, '''');

  if CertGetNameStringW(CertContext, CERT_NAME_EMAIL_TYPE, CERT_NAME_ISSUER_FLAG, nil,
    CertName, 256) = 0 then
    RaiseLastOSError;
  Writeln('Issuer CERT_NAME_EMAIL_TYPE: ''', CertName, '''');
  if CertGetNameStringW(CertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, nil,
    CertName, 256) = 0 then
    RaiseLastOSError;
  Writeln('Issuer CERT_NAME_SIMPLE_DISPLAY_TYPE: ''', CertName, '''');
  if CertGetNameStringW(CertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, nil,
    CertName, 256) = 0 then
    RaiseLastOSError;
  Writeln('Issuer CERT_NAME_FRIENDLY_DISPLAY_TYPE: ''', CertName, '''');
end;

var
  StoreName: array[0..255] of Char;
  Store: HCERTSTORE;
  CertContext: PCertContext;

begin
  try
    Writeln('Enter certificate store name:');
    Readln(StoreName);
    if (StoreName <> 'CA') and (StoreName <> 'MY') and (StoreName <> 'ROOT') and (StoreName <> 'SPC') then
      raise Exception.Create('Valid certificate store names are: ''CA'', ''MY'', ''ROOT'' and ''SPC''');

    Store := CertOpenSystemStore(0, StoreName);
    if Store = nil then
      RaiseLastOSError;
    try
      CertContext := CertEnumCertificatesInStore(Store, nil);
      while CertContext <> nil do
      begin
        DisplayCertContext(CertContext);

        CertContext := CertEnumCertificatesInStore(Store, CertContext);
      end;
    finally
      CertCloseStore(Store, 0);
    end;
  except
    on E: Exception do
      ShowException(E, ExceptAddr);
  end;
end.

0
 
LVL 8

Accepted Solution

by:
TOndrej earned 1600 total points
ID: 7124528
A very loose translation of the above-mentioned sample:

program crypttest2;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows,
  JwaWinCrypt; // download from http://delphi-jedi.org or http://members.chello.nl/m.vanbrakel2

procedure DisplayCertContext(CertContext: PCertContext);
... same as in the previous example
end;

var
  FileName: string;
  ContentType: DWORD = 0;
  Store: HCERTSTORE;
  Msg: HCRYPTMSG;
  DataSize: Cardinal = 0;
  SignerInfo: PCmsgSignerInfo;
  CertInfo: TCertInfo;
  CertContext: PCertContext;

begin
  try
    FileName := ParamStr(1);
    if FileName = '' then
      raise Exception.Create('No file name specified');

    if not CryptQueryObject(CERT_QUERY_OBJECT_FILE, @FileName[1], CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
      CERT_QUERY_FORMAT_FLAG_BINARY, 0, nil, @ContentType, nil, @Store, @Msg, nil) then
      RaiseLastOSError;
    try
      if ContentType <> CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED then
        raise Exception.Create('Unexpected content type');

      if not CryptMsgGetParam(Msg, CMSG_SIGNER_INFO_PARAM, 0, nil, DataSize) then
        RaiseLastOSError;
      SignerInfo := AllocMem(DataSize);
      try
        if not CryptMsgGetParam(Msg, CMSG_SIGNER_INFO_PARAM, 0, SignerInfo, DataSize) then
          RaiseLastOSError;

        // find signer's cert in store
        FillChar(CertInfo, SizeOf(TCertInfo), 0);
        CertInfo.Issuer := SignerInfo^.Issuer;
        CertInfo.SerialNumber := SignerInfo^.SerialNumber;

        CertContext := CertFindCertificateInStore(Store, X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, 0,
          CERT_FIND_SUBJECT_CERT, @CertInfo, nil);
        if CertContext = nil then
          RaiseLastOSError;

        DisplayCertContext(CertContext);
      finally
        FreeMem(SignerInfo);
      end;
    finally
      CertCloseStore(Store, 0);
      CryptMsgClose(Msg);
    end;
  except
    on E: Exception do
      ShowException(E, ExceptAddr);
  end;
end.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:Kann
ID: 7124763
TOndrej, thank you! You will get the points.
Perhaps you can help me: I get on error message in crypttest2:
CryptQueryObject() fails allways and the error "system can not find the file" (GetLastError=2147942402).

0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7124787
It seems the system cannot find the file you specified on the command line.

One reason for this could be that the file path contains spaces. (Command line parameters are separated by spaces, so the executable gets in fact several parameters.) If that's your case you'll have to enclose the path in quotes, e.g.
crypttest2 "C:\Program Files\MyDir\bin\MyApp.exe"

That way the OS will pass the whole string including spaces to the executable as one single parameter.

HTH
TOndrej
0
 

Author Comment

by:Kann
ID: 7125027
I inserted the source line:
 FileName:='C:\signed.exe';
and
 FileName:='"C:\signed.exe"';
and
 FileName:='signed.exe';
but I get allways this error. (The file really exists.)
Do you get this error?
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7125180
I've never tried the code because I couldn't quickly find a signed executable to check.

Looking at the documentation, it seems that FileName should be a wide string.
Change the declaration of FileName to:

var
  FileName: WideString;

and see if it helps.
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7126110
OK, I've finally downloaded some signed executables from Microsoft so I could try out the code. I've found two mistakes in the original posting.

Please make the following two fixes:

1. "File not found"
(As I've suggested before) Change the declaration of FileName to WideString:

var
  FileName: WideString;

2. "Unexpected content type"
Change the ContentType check line (replace  CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED with CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED):

  if ContentType <> CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED then
    raise Exception.Create('Unexpected content type');

This should solve the problems.

HTH
TOndrej
0
 

Author Comment

by:Kann
ID: 7126195
Thank you!
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7126202
Glad to help.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

800 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question