const Password: String;
ValidDays: Integer; KeySize: Integer; const ExtendedKeyUsage: String;
const CommonName, Email, Organization, OrganizationalUnit, Country: String;
const CAFileSpec, CAPFXFileSpec, CAPrivateKeyPassword: String;
ARandomFileSpec: String = '';
ProgressProc: TProgressProc = nil; LogMsgProc: TLogMsgProc = nil);
var
TmpPrivateKeyFileSpec, TmpPublicKeyFileSpec: String;
TmpCerFileSpec, TmpPfxFileSpec, TmpCsrFileSpec, TmpCASerialFileSpec, TmpExtFileSpec, TmpPemFileSpec: String;
TmpCAPrivateKeyFileSpec: String;
Subj: String;
TempDir: String;
Aborted: Boolean;
WasError: Boolean;
OutPublicKeyFileSpec: String;
begin
WasError := True;
TempDir := GetTempDir;
try
CheckIsFileExists(CAFileSpec);
// Извлекаем приватный ключ из корневого сертификата
TmpCAPrivateKeyFileSpec := TempDir + ChangeFileExt(ExtractFileName(CAPFXFileSpec), '') + '.privateKey.pem';
ExportPrivateKeyFromPfx(CAPFXFileSpec, TmpCAPrivateKeyFileSpec, CAPrivateKeyPassword);
// Все файлы создаем во временном каталоге, и только после успешного создания всех — // переносим на место постоянного хранения
TmpPrivateKeyFileSpec := TempDir + FileName + '.privateKey.pem';
TmpPublicKeyFileSpec := TempDir + FileName + '.publicKey.pem';
TmpCerFileSpec := TempDir + FileName + '.cer';
TmpPemFileSpec := TempDir + FileName + '.pem';
TmpPfxFileSpec := TempDir + FileName + '.pfx';
TmpCsrFileSpec := TempDir + FileName + '.csr';
TmpCASerialFileSpec := TempDir + FileName + '.srl';
Subj := GetSubj(CommonName, Email, Organization, OrganizationalUnit, Country);
Aborted := False;
if Assigned(ProgressProc) then
ProgressProc(13, 4, Aborted, Format('%s (%d %s)...'{'Generate Keys (%d bits)...'}, [StKeysGenerate, KeySize, StBit]));
if Aborted then
Exit;
CreatePrivateKey(TmpPrivateKeyFileSpec, TmpPublicKeyFileSpec, KeySize, ARandomFileSpec);
if Assigned(ProgressProc) then
ProgressProc(13, 5, Aborted, Format('%s...', [StGenerateCertificate]){'Generate certificate...'});
if Aborted then
Exit;
if Assigned(ProgressProc) then
ProgressProc(13, 6, Aborted, Format('%s...', [StCreateCertificateRequest]){'Create the certificate request...'});
// Создаем запрос — .csr
RunOpenSSLConsole(Format(
'req -new -key "%s" -out "%s" -days %d -subj %s',
[TmpPrivateKeyFileSpec, TmpCsrFileSpec, ValidDays, Subj]
), True, nil, nil);
if Assigned(ProgressProc) then
ProgressProc(13, 7, Aborted, Format('%s...', [StCreateExtensionsFile]){'Create the extensions file...'});
// http://ift.tt/1c1nQTc
TmpExtFileSpec := StrToFile(
// 'keyUsage=digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSign' +
'keyUsage=digitalSignature, keyEncipherment' +
iif(ExtendedKeyUsage <> '', #13#10'extendedKeyUsage=' + ExtendedKeyUsage, ''),
TempDir + FileName + '.extensions.cfg'
);
if Assigned(ProgressProc) then
ProgressProc(13, 8, Aborted, Format('%s...', [StCreateSignedCertificate]){'Create the signed certificate...'});
// На основе запроса создаем сертификат, подписаный корневым сертификатом
RunOpenSSLConsole(Format(
'x509 -req -days %d -passin pass:%s -in "%s" -CAform DER -CA "%s" -CAkey "%s" -CAserial "%s" -CAcreateserial -out "%s" -outform DER -extfile "%s"',
[ValidDays, Password, TmpCsrFileSpec, CAFileSpec, TmpCAPrivateKeyFileSpec, TmpCASerialFileSpec, TmpCerFileSpec, TmpExtFileSpec]
), False, nil, nil);
if Assigned(ProgressProc) then
ProgressProc(13, 9, Aborted, Format('%s...', [StConvertCertificate]){'Convert the certificate from the CER to the PEM format...'});
// Конвертируем cer => pem для следующей крманды экспорта в pfx
RunOpenSSLConsole(Format(
'x509 -in "%s" -inform DER -out "%s" -outform PEM',
[TmpCerFileSpec, TmpPemFileSpec]
), False, nil, nil);
if Assigned(ProgressProc) then
ProgressProc(13, 10, Aborted, Format('%s...', [StCreatePFX]){'Create the PFX certificate file...'});
// Делаем pfx из полученного pem и ключей
RunOpenSSLConsole(Format(
'pkcs12 -password pass:%s -export -in "%s" -inkey "%s" -name "%s" -out "%s"',
[Password, TmpPemFileSpec, TmpPrivateKeyFileSpec, FileName, TmpPfxFileSpec]
), False, nil, nil);
OutPublicKeyFileSpec := TmpPublicKeyFileSpec + '.signed';
if Assigned(ProgressProc) then
ProgressProc(13, 11, Aborted, Format('%s...', [StExportPublicKey]){'Export public keys from the PFX certificate file...'});
ExportPublicKeyFromPfx(TmpPfxFileSpec, OutPublicKeyFileSpec, Password);
// А результат добавляем в список файлов
OutFiles.Add(TmpCerFileSpec);
OutFiles.Add(TmpPfxFileSpec);
OutFiles.Add(TmpPrivateKeyFileSpec);
OutFiles.Add(TmpPublicKeyFileSpec);
OutFiles.Add(OutPublicKeyFileSpec);
WasError := False;
finally
// Удаляем временные файлы
if WasError then
begin
CheckDeleteFile(TmpCerFileSpec);
CheckDeleteFile(TmpPfxFileSpec);
CheckDeleteFile(TmpPrivateKeyFileSpec);
CheckDeleteFile(TmpPublicKeyFileSpec);
CheckDeleteFile(OutPublicKeyFileSpec);
end;
CheckDeleteFile(TmpCsrFileSpec);
CheckDeleteFile(TmpCASerialFileSpec);
CheckDeleteFile(TmpExtFileSpec);
CheckDeleteFile(TmpPemFileSpec);
CheckDeleteFile(TmpCAPrivateKeyFileSpec);
end;
end;
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий