Генерация файла запроса на сертификат

Тема в разделе "WASM.CRYPTO", создана пользователем Keva, 26 мар 2007.

  1. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    Требуется программно сгенерировать запрос на сертификат, кто занимался подскажите как, заранее благодарен.
     
  2. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    Код (Text):
    1. procedure TCreateReqForm.OKBtnClick(Sender: TObject);
    2. var nameAttr: CERT_RDN_ATTR;
    3.     nameString: PChar;
    4.     rdn: CERT_RDN;
    5.     nameInfo: CERT_NAME_INFO;
    6.     certReqInfo: CERT_REQUEST_INFO;
    7.     subjNameBlob: CERT_NAME_BLOB;
    8.     encNameLen: DWORD;
    9.     encName: PBYTE;
    10.     prov: HCRYPTPROV;
    11.     pubKeyInfoLen: DWORD;
    12.     pubKeyInfo: PCERT_PUBLIC_KEY_INFO;
    13.     encCertReqLen: DWORD;
    14.     params: CRYPT_OBJID_BLOB;
    15.     sigAlg: CRYPT_ALGORITHM_IDENTIFIER;
    16.     signedEncCertReq: PBYTE;
    17.     cont: PChar;
    18.     err: string;
    19.     encType: DWORD;
    20.     f: file;
    21. begin
    22. encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
    23. nameString := StrAlloc(length(SubjectEdit.text)+1);
    24. StrPCopy(nameString, SubjectEdit.Text);
    25. nameAttr.pszObjId := '2.5.4.3';
    26. nameAttr.dwValueType := CERT_RDN_PRINTABLE_STRING;
    27. nameAttr.Value.cbData := length(SubjectEdit.text);
    28. nameAttr.Value.pbData := PBYTE(nameString);
    29. rdn.cRDNAttr := 1;
    30. rdn.rgRDNAttr := @nameAttr;
    31. nameInfo.cRDN := 1;
    32. nameInfo.rgRDN := @rdn;
    33. if not CryptEncodeObject(encType, X509_NAME,
    34.        @nameInfo, nil, @encNameLen) or (encNameLen < 1) then
    35.    begin
    36.    MessageDlg('CryptEncodeObject error ' + inttostr(GetLastError), mtError, [mbOK], 0);
    37.    StrDispose(nameString);
    38.    exit;
    39.    end;
    40. GetMem(encName, encNameLen);
    41. if not CryptEncodeObject(PKCS_7_ASN_ENCODING or X509_ASN_ENCODING, X509_NAME,
    42.        @nameInfo, encName, @encNameLen) or (encNameLen < 1) then
    43.    begin
    44.    MessageDlg('2nd CryptEncodeObject error ' + inttostr(GetLastError), mtError, [mbOK], 0);
    45.    StrDispose(nameString);
    46.    FreeMem(encName, encNameLen);
    47.    exit;
    48.    end;
    49. subjNameBlob.cbData := encNameLen;
    50. subjNameBlob.pbData := encName;
    51. certReqInfo.Subject := subjNameBlob;
    52. certReqInfo.cAttribute := 0;
    53. certReqInfo.rgAttribute := nil;
    54. certReqInfo.dwVersion := CERT_REQUEST_V1;
    55. if length(ContainerEdit.Text) = 0
    56. then cont := nil
    57. else
    58.     begin
    59.     err := ContainerEdit.Text;
    60.     cont := StrAlloc(length(err) + 1);
    61.     StrPCopy(cont, err);
    62.     end;
    63. if not CryptAcquireContext(@prov, cont, nil, PROV_RSA_FULL, 0)
    64. then
    65.     begin
    66.     case int64(GetLastError) of
    67.     ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER';
    68.     ERROR_NOT_ENOUGH_MEMORY: err := 'ERROR_NOT_ENOUGH_MEMORY';
    69.     NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS';
    70.     NTE_BAD_KEYSET: err := 'NTE_BAD_KEYSET';
    71.     NTE_BAD_KEYSET_PARAM: err := 'NTE_BAD_KEYSET_PARAM';
    72.     NTE_BAD_PROV_TYPE: err := 'NTE_BAD_PROV_TYPE';
    73.     NTE_BAD_SIGNATURE: err := 'NTE_BAD_SIGNATURE';
    74.     NTE_EXISTS: err := 'NTE_EXISTS';
    75.     NTE_KEYSET_ENTRY_BAD: err := 'NTE_KEYSET_ENTRY_BAD';
    76.     NTE_KEYSET_NOT_DEF: err := 'NTE_KEYSET_NOT_DEF';
    77.     NTE_NO_MEMORY: err := 'NTE_NO_MEMORY';
    78.     NTE_PROV_DLL_NOT_FOUND: err := 'NTE_PROV_DLL_NOT_FOUND';
    79.     NTE_PROV_TYPE_ENTRY_BAD: err := 'NTE_PROV_TYPE_ENTRY_BAD';
    80.     NTE_PROV_TYPE_NO_MATCH: err := 'NTE_PROV_TYPE_NO_MATCH';
    81.     NTE_PROV_TYPE_NOT_DEF: err := 'NTE_PROV_TYPE_NOT_DEF';
    82.     NTE_PROVIDER_DLL_FAIL: err := 'NTE_PROVIDER_DLL_FAIL';
    83.     NTE_SIGNATURE_FILE_BAD: err := 'NTE_SIGNATURE_FILE_BAD';
    84.     else err := 'Unknown error';
    85.     end;
    86.     MessageDlg('Ошибка создания контейнера: ' + err, mtError, [mbOK], 0);
    87.     StrDispose(nameString);
    88.     FreeMem(encName, encNameLen);
    89.     if cont <> nil then StrDispose(cont);
    90.     exit;
    91.     end;
    92. if not CryptExportPublicKeyInfo (prov, AT_SIGNATURE, encType, nil, @pubKeyInfoLen) then
    93.    begin
    94.    MessageDlg('Ошибка экспорта открытого ключа', mtError, [mbOK], 0);
    95.    StrDispose(nameString);
    96.    FreeMem(encName, encNameLen);
    97.    if cont <> nil then StrDispose(cont);
    98.    exit;
    99.    end;
    100. GetMem(pubKeyInfo, pubKeyInfoLen);
    101. if not CryptExportPublicKeyInfo (prov, AT_SIGNATURE, encType, pubKeyInfo, @pubKeyInfoLen) then
    102.    begin
    103.    MessageDlg('Ошибка экспорта открытого ключа', mtError, [mbOK], 0);
    104.    StrDispose(nameString);
    105.    FreeMem(encName, encNameLen);
    106.    if cont <> nil then StrDispose(cont);
    107.    FreeMem(pubKeyInfo, pubKeyInfoLen);
    108.    exit;
    109.    end;
    110. certReqInfo.SubjectPublicKeyInfo := pubKeyInfo^;
    111. FillChar(params, sizeof(params), 0);
    112. sigAlg.pszObjId := szOID_OIWSEC_sha1RSASign;
    113. sigAlg.Parameters := params;
    114. if not CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType,
    115.    X509_CERT_REQUEST_TO_BE_SIGNED, @certReqInfo, @sigAlg, nil, nil,
    116.    @encCertReqLen) then
    117.    begin
    118.    MessageDlg('Ошибка получения длины подписанного запроса', mtError, [mbOK], 0);
    119.    StrDispose(nameString);
    120.    FreeMem(encName, encNameLen);
    121.    if cont <> nil then StrDispose(cont);
    122.    FreeMem(pubKeyInfo, pubKeyInfoLen);
    123.    exit;
    124.    end;
    125. GetMem(signedEncCertReq, encCertReqLen);
    126. if not CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType, X509_CERT_REQUEST_TO_BE_SIGNED,
    127.    @certReqInfo, @sigAlg, nil, signedEncCertReq, @encCertReqLen) then
    128.    begin
    129.    MessageDlg('Ошибка получения подписанного запроса', mtError, [mbOK], 0);
    130.    StrDispose(nameString);
    131.    FreeMem(encName, encNameLen);
    132.    if cont <> nil then StrDispose(cont);
    133.    FreeMem(pubKeyInfo, pubKeyInfoLen);
    134.    FreeMem(signedEncCertReq, encCertReqLen);
    135.    exit;
    136.    end;
    137. if SaveDlg.Execute then
    138.    begin
    139.    AssignFile(f, SaveDlg.FileName);
    140.    rewrite(f, 1);
    141.    BlockWrite(f, signedEncCertReq^, encCertReqLen);
    142.    CloseFile(f);
    143.    end;
    144. StrDispose(nameString);
    145. FreeMem(encName, encNameLen);
    146. if cont <> nil then StrDispose(cont);
    147. FreeMem(pubKeyInfo, pubKeyInfoLen);
    148. FreeMem(signedEncCertReq, encCertReqLen);
    149. if not CryptReleaseContext(prov, 0) then
    150.    begin
    151.    MessageDlg('Ошибка освобождения контекста', mtError, [mbOK], 0);
    152.    end;
    153. end;
     
  3. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    Сделал запрос как было предложено в предыдущем посте, использую криптопрошный криптопровайдер. Но размер создаваемого запроса меньше чем если сохранять запрос в файле через интерфейс УЦ, и запрос отклонятся и выводится следующая ошибка: Your Request Id is 0. The disposition message is "Error Parsing Request ASN1 bad tag value met. 0x8009310b (ASN: 267)". В чем может быть дело?
     
  4. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    Может, где-то напутано в коде. Сходи на форум криптопро и поищи там
     
  5. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    slow
    А у тебя работает твой код?
     
  6. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    Ну да, но это было так давно... сейчас уже не помню. Код не мой, а из статьи какой-то, я его проверил - работало, может при копипасте чего нарушилось.
     
  7. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    Нет я на С делал, сервер ругается на запрос.
     
  8. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    532
    Адрес:
    Russia
  9. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    а где они там?
     
  10. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    Каким должен быть этот параметр если я генрю запрос для MS CA с криптоПРО? И что за структура CRYPT_OBJID_BLOBа?
     
  11. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    532
    Адрес:
    Russia
    http://sourceforge.net/project/showfiles.php?group_id=139293&package_id=152766&release_id=333681