Статус: Новичок
Группы: Участники
Зарегистрирован: 07.11.2018(UTC) Сообщений: 8   Откуда: Пермь Сказал «Спасибо»: 2 раз
|
Вот весь код кнопки:Цитата:procedure TForm1.Button3Click(Sender: TObject); var nameAttr: CERT_RDN_ATTR; nameString: PChar; rdn: CERT_RDN; nameInfo: CERT_NAME_INFO; certReqInfo: CERT_REQUEST_INFO; subjNameBlob: CERT_NAME_BLOB; encNameLen: DWORD; encName: PBYTE; prov: HCRYPTPROV; pubKeyInfoLen: DWORD; pubKeyInfo: PCERT_PUBLIC_KEY_INFO; encCertReqLen: DWORD; params: CRYPT_OBJID_BLOB; sigAlg: CRYPT_ALGORITHM_IDENTIFIER; signedEncCertReq: PBYTE; cont: PChar; err: string; encType: DWORD; f: file; CertRDN: array [0 .. 5] of CERT_RDN_ATTR; CertRDNPtr: array [0 .. 5] of pointer; rdnptr: array [0 .. 0] of pointer; begin encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
{ nameString := StrAlloc(length(LabeledEdit1.Text) + 1); StrPCopy(nameString, LabeledEdit1.Text); nameAttr.pszObjId := '2.5.4.3'; nameAttr.dwValueType := CERT_RDN_UTF8_STRING; // CERT_RDN_PRINTABLE_STRING nameAttr.Value.cbData := length(LabeledEdit1.Text); nameAttr.Value.pbData := PBYTE(nameString); rdn.cRDNAttr := 1; rdn.rgRDNAttr := @nameAttr; nameInfo.cRDN := 1; nameInfo.rgRDN := @rdn; }
nameString := StrAlloc(length(LabeledEdit1.Text) + 1); StrPCopy(nameString, LabeledEdit1.Text); CertRDN[0].pszObjId := '2.5.4.3'; // Имя CertRDN[0].dwValueType := CERT_RDN_UTF8_STRING; CertRDN[0].Value.cbData := length(LabeledEdit1.Text); CertRDN[0].Value.pbData := PBYTE(nameString); CertRDNPtr[0] := @(CertRDN[0]);
nameString := StrAlloc(length(LabeledEdit6.Text) + 1); StrPCopy(nameString, LabeledEdit6.Text); CertRDN[1].pszObjId := '2.5.4.6'; // Страна CertRDN[1].dwValueType := CERT_RDN_PRINTABLE_STRING; CertRDN[1].Value.cbData := 2; CertRDN[1].Value.pbData := PBYTE(nameString); CertRDNPtr[1] := @(CertRDN[1]);
nameString := StrAlloc(length(LabeledEdit5.Text) + 1); StrPCopy(nameString, LabeledEdit5.Text); CertRDN[2].pszObjId := '2.5.4.7'; // Город CertRDN[2].dwValueType := CERT_RDN_UTF8_STRING; CertRDN[2].Value.cbData := length(LabeledEdit5.Text); CertRDN[2].Value.pbData := PBYTE(nameString); CertRDNPtr[2] := @(CertRDN[2]);
nameString := StrAlloc(length(LabeledEdit2.Text) + 1); StrPCopy(nameString, LabeledEdit2.Text); CertRDN[3].pszObjId := '2.5.4.10'; // Организация CertRDN[3].dwValueType := CERT_RDN_UTF8_STRING; CertRDN[3].Value.cbData := length(LabeledEdit2.Text); CertRDN[3].Value.pbData := PBYTE(nameString); CertRDNPtr[3] := @(CertRDN[3]);
nameString := StrAlloc(length(LabeledEdit3.Text) + 1); StrPCopy(nameString, LabeledEdit3.Text); CertRDN[4].pszObjId := '2.5.4.11'; // Подразделение CertRDN[4].dwValueType := CERT_RDN_UTF8_STRING; CertRDN[4].Value.cbData := length(LabeledEdit3.Text); CertRDN[4].Value.pbData := PBYTE(nameString); CertRDNPtr[4] := @(CertRDN[4]);
nameString := StrAlloc(length(LabeledEdit1.Text) + 1); StrPCopy(nameString, LabeledEdit1.Text); CertRDN[5].pszObjId := '2.5.4.13'; // Инфо CertRDN[5].dwValueType := CERT_RDN_UTF8_STRING; CertRDN[5].Value.cbData := length(LabeledEdit1.Text); CertRDN[5].Value.pbData := PBYTE(nameString); CertRDNPtr[5] := @(CertRDN[5]);
rdn.rgRDNAttr := @CertRDNPtr; rdnptr[0] := @rdn; nameInfo.rgRDN := @rdnptr;
subjNameBlob.cbData := encNameLen; subjNameBlob.pbData := encName; certReqInfo.Subject := subjNameBlob; certReqInfo.cAttribute := 0; certReqInfo.rgAttribute := nil; certReqInfo.dwVersion := CERT_REQUEST_V1; if length(LabeledEdit10.Text) = 0 then cont := nil else begin err := LabeledEdit10.Text; cont := StrAlloc(length(err) + 1); StrPCopy(cont, err); end; if not CryptAcquireContext(prov, cont, nil, PROV_RSA_FULL, 0) then begin case int64(GetLastError) of ERROR_INVALID_PARAMETER: err := 'ERROR_INVALID_PARAMETER'; ERROR_NOT_ENOUGH_MEMORY: err := 'ERROR_NOT_ENOUGH_MEMORY'; NTE_BAD_FLAGS: err := 'NTE_BAD_FLAGS'; NTE_BAD_KEYSET: err := 'NTE_BAD_KEYSET'; NTE_BAD_KEYSET_PARAM: err := 'NTE_BAD_KEYSET_PARAM'; NTE_BAD_PROV_TYPE: err := 'NTE_BAD_PROV_TYPE'; NTE_BAD_SIGNATURE: err := 'NTE_BAD_SIGNATURE'; NTE_EXISTS: err := 'NTE_EXISTS'; NTE_KEYSET_ENTRY_BAD: err := 'NTE_KEYSET_ENTRY_BAD'; NTE_KEYSET_NOT_DEF: err := 'NTE_KEYSET_NOT_DEF'; NTE_NO_MEMORY: err := 'NTE_NO_MEMORY'; NTE_PROV_DLL_NOT_FOUND: err := 'NTE_PROV_DLL_NOT_FOUND'; NTE_PROV_TYPE_ENTRY_BAD: err := 'NTE_PROV_TYPE_ENTRY_BAD'; NTE_PROV_TYPE_NO_MATCH: err := 'NTE_PROV_TYPE_NO_MATCH'; NTE_PROV_TYPE_NOT_DEF: err := 'NTE_PROV_TYPE_NOT_DEF'; NTE_PROVIDER_DLL_FAIL: err := 'NTE_PROVIDER_DLL_FAIL'; NTE_SIGNATURE_FILE_BAD: err := 'NTE_SIGNATURE_FILE_BAD'; else err := 'Unknown error'; end; MessageDlg('Ошибка создания контейнера: ' + err, mtError, [mbOK], 0); StrDispose(nameString); FreeMem(encName, encNameLen); if cont <> nil then StrDispose(cont); exit; end; if not CryptExportPublicKeyInfo(prov, AT_SIGNATURE, encType, nil, pubKeyInfoLen) then begin MessageDlg('Ошибка экспорта открытого ключа', mtError, [mbOK], 0); StrDispose(nameString); FreeMem(encName, encNameLen); if cont <> nil then StrDispose(cont); exit; end; GetMem(pubKeyInfo, pubKeyInfoLen); if not CryptExportPublicKeyInfo(prov, AT_SIGNATURE, encType, pubKeyInfo, pubKeyInfoLen) then begin MessageDlg('Ошибка экспорта открытого ключа', mtError, [mbOK], 0); StrDispose(nameString); FreeMem(encName, encNameLen); if cont <> nil then StrDispose(cont); FreeMem(pubKeyInfo, pubKeyInfoLen); exit; end; certReqInfo.SubjectPublicKeyInfo := pubKeyInfo^; FillChar(params, sizeof(params), 0); sigAlg.pszObjId := szOID_OIWSEC_sha1RSASign; sigAlg.Parameters := params; if not CryptSignAndEncodeCertificate(prov, AT_SIGNATURE, encType, X509_CERT_REQUEST_TO_BE_SIGNED, @certReqInfo, @sigAlg, nil, nil, encCertReqLen) then begin MessageDlg('Ошибка получения длины подписанного запроса', mtError, [mbOK], 0); StrDispose(nameString); FreeMem(encName, encNameLen); if cont <> nil then StrDispose(cont); FreeMem(pubKeyInfo, pubKeyInfoLen); exit; end; GetMem(signedEncCertReq, encCertReqLen); if not CryptSignAndEncodeCertificate(prov, AT_SIGNATURE, encType, X509_CERT_REQUEST_TO_BE_SIGNED, @certReqInfo, @sigAlg, nil, signedEncCertReq, encCertReqLen) then begin MessageDlg('Ошибка получения подписанного запроса', mtError, [mbOK], 0); StrDispose(nameString); FreeMem(encName, encNameLen); if cont <> nil then StrDispose(cont); FreeMem(pubKeyInfo, pubKeyInfoLen); FreeMem(signedEncCertReq, encCertReqLen); exit; end; SaveDialog1.Title := 'Укажите файл для сохранения запроса'; SaveDialog1.Filter := 'Файл запроса|*.p10'; SaveDialog1.DefaultExt := '.p10'; if SaveDialog1.Execute then begin AssignFile(f, SaveDialog1.FileName); Rewrite(f, 1); BlockWrite(f, signedEncCertReq^, encCertReqLen); CloseFile(f); end; StrDispose(nameString); FreeMem(encName, encNameLen); if cont <> nil then StrDispose(cont); FreeMem(pubKeyInfo, pubKeyInfoLen); FreeMem(signedEncCertReq, encCertReqLen); if not CryptReleaseContext(prov, 0) then begin MessageDlg('Ошибка освобождения контекста', mtError, [mbOK], 0); end; end;
|
Всё намного проще, чем есть на самом деле... |