Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus CryptoAPI пара вопросов. / 19 сообщений из 19, страница 1 из 1
11.06.2015, 12:33
    #38982118
angel_zar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Работа с CryptoAPI используя модуль JwaWinCrypt.
Имеются открытые ключи, из них надо получить информацию:
Срок действия
Кому выдан
Кем выдан
Улучшенный ключ

По первым 3-м пунктам все хорошо, а вот где найти информацию как достать значение "Улучшенный ключ", не могу.
Пример кода подкатом.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, JwaWinCrypt, LazUTF8, JwaWinSta, JwaWinBase, JwaWinType;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.Button1Click(Sender: TObject);
var f: file;
    encCert: PByte;
    encCertLen: DWORD;
    //store: HCERTSTORE;
    context: PCCERT_CONTEXT;
    //n: PPCCERT_CONTEXT;
    encType: DWORD;
    nameBLOB: CERT_NAME_BLOB;
    size: DWORD;
    nameString: PChar;
    s:TStrings;
    FT:JwaWinBase.TFileTime;
begin
   s:=TStringList.Create;
   s.Clear;
   AssignFile(f, 'c:\temp\123.crt');
   reset(f, 1);
   encCertLen := FileSize(f);
   GetMem(encCert, encCertLen);
   BlockRead(f, encCert^, encCertLen);
   CloseFile(f);

   encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
   context := CertCreateCertificateContext(encType, encCert, encCertLen);

   if context = nil then
   begin
   MessageDlg('Error creating certificate context', mtError, [mbOK], 0);
   exit;
   end;

   nameString := StrAlloc(512);

   FT.dwLowDateTime:=context^.pCertInfo^.NotBefore.dwLowDateTime;
   FT.dwHighDateTime:=context^.pCertInfo^.NotBefore.dwHighDateTime;

   s.Add('context^.pCertInfo^.NotBefore: '+DateTimeToStr(FileTime2DateTime(FT)));

   s.Add('==========================');


   FT.dwLowDateTime:=context^.pCertInfo^.NotAfter.dwLowDateTime;
   FT.dwHighDateTime:=context^.pCertInfo^.NotAfter.dwHighDateTime;

   s.Add('context^.pCertInfo^.NotAfter: '+DateTimeToStr(FileTime2DateTime(FT)));

   s.Add('==========================');



   s.Add('context^.pCertInfo^.Subject');
   nameBLOB := context^.pCertInfo^.Subject;
   size := CertNameToStr(encType, @nameBlob, CERT_X500_NAME_STR,nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');

   s.Add('==========================');

   s.Add('context^.pCertInfo^.Issuer');
   nameBLOB := context^.pCertInfo^.Issuer;
   size := CertNameToStr(encType, @nameBlob, CERT_X500_NAME_STR, nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');

   s.Add('==========================');

   //context^.hCertStore;

   {nameBLOB := context^.pCertInfo^.rgExtension;
   size := CertNameToStr(encType, @nameBlob, CERT_SIMPLE_NAME_STR,nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');}

   //ShowMessage(s.Text);
   Memo1.Lines.Text:=s.Text;
   FreeMem(encCert, encCertLen);
   FreeAndNil(s);
end;

end.



Кто может подсказать, в какую сторону копать.
...
Рейтинг: 0 / 0
11.06.2015, 13:41
    #38982232
MrCat
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Речь про это ? (там key usage всё же, а не key)
...
Рейтинг: 0 / 0
11.06.2015, 13:53
    #38982252
angel_zar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
MrCatРечь про это ? (там key usage всё же, а не key)
Спасибо, это уже нашел тынц
Только не работает.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CertGetEnhancedKeyUsage(m_pCertContext, 0, nil, usageLength);
  usage := PCERT_ENHKEY_USAGE(AllocMem(usageLength));
  try
    if (CertGetEnhancedKeyUsage(m_pCertContext, 0, usage, usageLength)) then
    begin
      if (usage.cUsageIdentifier = 0) then
      begin
        StringGrid1.Cells[index, certNum] := '<All>';
      end else begin
        for I := 0 to usage.cUsageIdentifier - 1 do
        begin
          usageStr := usage.rgpszUsageIdentifier;
        end;
      end;
    end else begin
      //TODO: It might not exist.
    end;
  finally
    FreeMem(usage, usageLength);
  end;



Смущает это: usageStr := usage.rgpszUsageIdentifier;
Пробовал по этому примеру, не могу вернуть коды. Количество правильное. А вот дальше что попало.
...
Рейтинг: 0 / 0
11.06.2015, 14:28
    #38982303
MrCat
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Ну, что в цикле всё время одно значение берётся, это ладно, описка. Но по идее, во втором параметре структуры должен быть массив указателей на строки. Т.е. что-то типа PPChar, а Вы с ним как с PChar обращаетесь. Плюс я бы ещё насчёт кодировки озаботился. Когда шерстятся теги ASN.1, то кроме указателя возвращается и кодировка данных, а тут - указатель на строку и всё. Это всегда ANSI-строка? Хотя, логично - OID - это три точки и 4 числа, ему UNICODE не нужен.
...
Рейтинг: 0 / 0
11.06.2015, 14:38
    #38982314
angel_zar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
MrCatНу, что в цикле всё время одно значение берётся, это ладно, описка. Но по идее, во втором параметре структуры должен быть массив указателей на строки. Т.е. что-то типа PPChar, а Вы с ним как с PChar обращаетесь. Плюс я бы ещё насчёт кодировки озаботился. Когда шерстятся теги ASN.1, то кроме указателя возвращается и кодировка данных, а тут - указатель на строку и всё. Это всегда ANSI-строка? Хотя, логично - OID - это три точки и 4 числа, ему UNICODE не нужен.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
   If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add(FloatToStr(Usage^.cUsageIdentifier));
      for n := 1 to Usage^.cUsageIdentifier do
        begin
          s.Add(UTF8Encode(Usage[n].rgpszUsageIdentifier));
        end;


Сам до такого дошел, но массив не полный, на ключе который проверяю Usage^.cUsageIdentifier=12, а на 5 ке цикл вываливается :(.
Про это можно по подробней? Просто там был кусок кода из того что я нашел в сети для примера, пытаюсь под себя прикрутить.
...
Рейтинг: 0 / 0
11.06.2015, 14:43
    #38982320
angel_zar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Плюс я бы ещё насчёт кодировки озаботился. Когда шерстятся теги ASN.1, то кроме указателя возвращается и кодировка данных, а тут - указатель на строку и всё. Это всегда ANSI-строка?
Вот про это можно по подробней.
...
Рейтинг: 0 / 0
11.06.2015, 14:56
    #38982343
MrCat
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Я про CERT_RDN_ATTR.dwValueType , и сразу было понятно что делать с Value.
...
Рейтинг: 0 / 0
11.06.2015, 15:04
    #38982357
MrCat
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Я бы написал так. Не проверял, просто продемонстрировать идею. Насчёт кодировки, в которой возвращается OID - не в курсе, возможно, действительно надо ещё decode from UTF8
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
var 
  Count: Integer;
  pStrs: PPChar;
  pStr: PChar;
...
  if CertGetEnhancedKeyUsage(context, 0, Usage, size) then
  begin
     Count := Usage^.cUsageIdentifier;
     s.Add(IntToStr(Count));
 
     pStrs := Usage.rgpszUsageIdentifier;
     for n := 0 to Pred(Count) do
     begin
       pStr := pStrs^[n];
       s.Add(StrPas(pStr));
     end;
  end;
...
Рейтинг: 0 / 0
11.06.2015, 16:18
    #38982478
Ghost Writer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
angel_zar,

я когда-то тут подсказывал http://www.cryptopro.ru/forum2/default.aspx?g=posts&m=15919#post15919
попробуйте
...
Рейтинг: 0 / 0
15.06.2015, 08:37
    #38983679
angel_zar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Всем спасибо, получилось так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add('Count:'+FloatToStr(Usage^.cUsageIdentifier));
      for n := 0 to Usage^.cUsageIdentifier-1 do
        begin
         UsageT:=(PCharArr(Usage^.rgpszUsageIdentifier)[n])[0];
         s.Add(String(UsageT));
        end;       


Сейчас тестируем, на разных ключах.
...
Рейтинг: 0 / 0
16.06.2015, 06:23
    #38984378
sql2012
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
angel_zarВсем спасибо, получилось так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add('Count:'+FloatToStr(Usage^.cUsageIdentifier));
      for n := 0 to Usage^.cUsageIdentifier-1 do
        begin
         UsageT:=(PCharArr(Usage^.rgpszUsageIdentifier)[n])[0];
         s.Add(String(UsageT));
        end;       


Сейчас тестируем, на разных ключах.

Тестируешь, потому что не уверен в правильности расстановки begin\end или в криптографических функциях?
...
Рейтинг: 0 / 0
16.06.2015, 14:15
    #38984828
angel_zar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
[quot sql2012]angel_zarТестируешь, потому что не уверен в правильности расстановки begin\end или в криптографических функциях?
Что бы быть уверенным, что будет работать правильно, а так тут черновой вариант, просто разобраться, как это работает.
Весь код будет обернут в класс, с обработками ошибок.
...
Рейтинг: 0 / 0
16.06.2015, 16:37
    #38985009
sql2012
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
[quot angel_zar]sql2012пропущено...

Что бы быть уверенным, что будет работать правильно, а так тут черновой вариант, просто разобраться, как это работает.
Весь код будет обернут в класс, с обработками ошибок.

Когда CertGetEnhancedKeyUsage вернет false, будешь к Usage=nil обращаться и получишь AV...
...
Рейтинг: 0 / 0
17.06.2015, 06:28
    #38985346
angel_zar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
sql2012Когда CertGetEnhancedKeyUsage вернет false, будешь к Usage=nil обращаться и получишь AV...
Я это прекрасно вижу, это фактически копи-паст, с некоторыми изменениями.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
14.05.2019, 19:15
    #39813189
SQL-Talker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
angel_zarВсем спасибо, получилось так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add('Count:'+FloatToStr(Usage^.cUsageIdentifier));
      for n := 0 to Usage^.cUsageIdentifier-1 do
        begin
         UsageT:=(PCharArr(Usage^.rgpszUsageIdentifier)[n])[0];
         s.Add(String(UsageT));
        end;       


Сейчас тестируем, на разных ключах.

Привет, народ.

Мне нужно выяснить содержится ли в параметре "Улучшенный ключ" OID "Подписывание документа" - "1.3.6.1.4.1.311.10.3.12"
Насколько я понял, в процитированном коде, в
Код: pascal
1.
PCharArr(Usage^.rgpszUsageIdentifier)[n]

как раз и должен содержаться этот OID,
но у меня там получается строка типа автор#$2E31#$2E33#$2E36#$2E31#$2E34#$2E31'ㄳ'#$2E31'〱㌮'#$312E'2'#$2E31#$2E33#$2E36#$2E31#$2E35#$2E35#$2E37#$2E33'2' - по-видимому символы из юникода
а
Код: pascal
1.
Usage^.rgpszUsageIdentifier

содержит автор'а9›'#2'ш9›'#2'1.3.6.1.4.1.311.10.3.12'
хотя там должно быть два OID-а

Подскажите, как мне правильно получить OID-ы там содержащиеся?
...
Рейтинг: 0 / 0
14.05.2019, 19:18
    #39813192
SQL-Talker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
И да, использовал определения типа PCharArr (с форума КриптоПро):
Код: pascal
1.
2.
3.
type
  PCharArr = ^TCharArr;
  TCharArr = array[0..0] of PChar;
...
Рейтинг: 0 / 0
14.05.2019, 22:09
    #39813243
Ghost Writer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
SQL-TalkerИ да, использовал определения типа PCharArr (с форума КриптоПро):В какой среде пишите? тот код я писал под Delphi 7. В лазарусе всё также работает с маленькой поправкой:
Код: pascal
1.
PCharArr(pbEnhanced^.rgpszUsageIdentifier)^[I]
...
Рейтинг: 0 / 0
14.05.2019, 22:20
    #39813249
Ghost Writer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
В Delphi 10.2 (Токио вроде зовётся)
Код: pascal
1.
2.
3.
type
  PCharArr = ^TCharArr;
  TCharArr = array[0..0] of PAnsiChar;
...
Рейтинг: 0 / 0
15.05.2019, 10:29
    #39813384
SQL-Talker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Lazarus CryptoAPI пара вопросов.
Ghost Writer,

Все заработало, спасибо!
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus CryptoAPI пара вопросов. / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]