Link to home
Start Free TrialLog in
Avatar of Kann
Kann

asked on

code sample: CertGetNameStringW CryptQueryObject

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!
Avatar of raidos
raidos

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

Regards
//raidos
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.

ASKER CERTIFIED SOLUTION
Avatar of TOndrej
TOndrej

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Kann

ASKER

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).

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
Avatar of Kann

ASKER

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?
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.
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
Avatar of Kann

ASKER

Thank you!
Glad to help.