clsmimemessage.pas
来自「Clever_Internet_Suite_6.2的代码 Clever_Int」· PAS 代码 · 共 1,030 行 · 第 1/3 页
PAS
1,030 行
{$IFDEF LOGGER}clPutLogMessage(Self, edInside, 'GetEmailCertificate before FInternalCertStore');{$ENDIF}
FInternalCertStore.LoadFromSystemStore(AStoreName);
Result := GetCertificateByStore(FInternalCertStore, email);
end;
{$IFDEF LOGGER}clPutLogMessage(Self, edInside, 'GetEmailCertificate before return, Result: %d', nil, [Integer(Result)]);{$ENDIF}
{$IFDEF LOGGER}clPutLogMessage(Self, edLeave, 'GetEmailCertificate'); except on E: Exception do begin clPutLogMessage(Self, edLeave, 'GetEmailCertificate', E); raise; end; end;{$ENDIF}
end;
function TclSMimeMessage.GetRecipientCertificate(const AStoreName: string;
AEmailList: TStrings): TclCertificate;
var
i: Integer;
begin
for i := 0 to AEmailList.Count - 1 do
begin
Result := GetEmailCertificate(AEmailList[i], AStoreName);
if (Result <> nil) then Exit;
end;
Result := nil;
end;
function TclSMimeMessage.GetCertificate(const AStoreName: string; IsUseSender: Boolean): TclCertificate;
var
handled: Boolean;
begin
{$IFDEF LOGGER}try clPutLogMessage(Self, edEnter, 'GetCertificate, storename: %s, usesender %d', nil, [AStoreName, Integer(IsUseSender)]);{$ENDIF}
Result := nil;
handled := False;
DoGetCertificate(Result, handled);
if (Result = nil) then
begin
if IsUseSender then
begin
Result := GetEmailCertificate(From, AStoreName);
end else
begin
Result := GetRecipientCertificate(AStoreName, ToList);
if (Result = nil) then
begin
Result := GetRecipientCertificate(AStoreName, CcList);
end;
if (Result = nil) then
begin
Result := GetRecipientCertificate(AStoreName, BccList);
end;
end;
end;
if (Result = nil) then
begin
raise EclMailMessageError.Create(cCertificateRequired);
end;
{$IFDEF LOGGER}clPutLogMessage(Self, edLeave, 'GetCertificate'); except on E: Exception do begin clPutLogMessage(Self, edLeave, 'GetCertificate', E); raise; end; end;{$ENDIF}
end;
function TclSMimeMessage.GetIsEncrypted: Boolean;
begin
Result := (Pos('pkcs7-mime', LowerCase(ContentType)) > 0)
and (not SameText(SMimeContentType, 'signed-data'));
end;
function TclSMimeMessage.GetIsMultiPartContent: Boolean;
begin
Result := inherited GetIsMultiPartContent() and not IsEncrypted;
if IsParse then
begin
Result := Result and not (IsSigned and (LowerCase(ContentType) <> 'multipart/signed'));
end else
begin
Result := Result and not (IsSigned and not IsDetachedSignature);
end;
end;
function TclSMimeMessage.GetIsSigned: Boolean;
begin
Result := SameText(ContentType, 'multipart/signed')
or ((Pos('pkcs7-mime', LowerCase(ContentType)) > 0) and SameText(SMimeContentType, 'signed-data'));
end;
function TclSMimeMessage.CreateSingleBody(ASource: TStrings; ABodies: TclMessageBodies): TclMessageBody;
begin
if IsEncrypted or (IsSigned and (LowerCase(ContentType) <> 'multipart/signed')) then
begin
Result := TclEnvelopedBody.Create(ABodies);
end else
begin
Result := inherited CreateSingleBody(ASource, ABodies);
end;
end;
procedure TclSMimeMessage.ParseContentType(ASource, AFieldList: TStrings);
var
s: string;
begin
inherited ParseContentType(ASource, AFieldList);
s := GetHeaderFieldValue(ASource, AFieldList, 'Content-Type');
SMimeContentType := GetHeaderFieldValueItem(s, 'smime-type=');
end;
procedure TclSMimeMessage.SetIsDetachedSignature(const Value: Boolean);
begin
if (FIsDetachedSignature <> Value) then
begin
FIsDetachedSignature := Value;
Update();
end;
end;
procedure TclSMimeMessage.SetIsIncludeCertificate(const Value: Boolean);
begin
if (FIsIncludeCertificate <> Value) then
begin
FIsIncludeCertificate := Value;
Update();
end;
end;
procedure TclSMimeMessage.SetSMimeContentType(const Value: string);
begin
if (FSMimeContentType <> Value) then
begin
FSMimeContentType := Value;
Update();
end;
end;
procedure TclSMimeMessage.SignEnveloped(ACertificate: TclCertificate);
var
srcData, signedData: TclCryptData;
begin
{$IFDEF LOGGER}try clPutLogMessage(Self, edEnter, 'SignEnveloped');{$ENDIF}
srcData := TclCryptData.Create();
try
srcData.AssignByStrings(MessageSource);
signedData := ACertificate.Sign(srcData, IsDetachedSignature, IsIncludeCertificate);
try
Bodies.Clear();
TclEnvelopedBody.Create(Bodies).Data := signedData;
except
signedData.Free();
raise;
end;
ContentType := 'application/x-pkcs7-mime';
SMimeContentType := 'signed-data';
Encoding := cmMIMEBase64;
finally
srcData.Free();
end;
{$IFDEF LOGGER}clPutLogMessage(Self, edLeave, 'SignEnveloped'); except on E: Exception do begin clPutLogMessage(Self, edLeave, 'SignEnveloped', E); raise; end; end;{$ENDIF}
end;
procedure TclSMimeMessage.SignDetached(ACertificate: TclCertificate);
var
i, ind: Integer;
srcData, signedData: TclCryptData;
oldIncludeRFC822: Boolean;
srcStrings, FieldList: TStrings;
cryptBody: TclSMimeBody;
begin
{$IFDEF LOGGER}try clPutLogMessage(Self, edEnter, 'SignDetached');{$ENDIF}
srcData := nil;
srcStrings := nil;
FieldList := nil;
oldIncludeRFC822 := IncludeRFC822Header;
try
srcData := TclCryptData.Create();
srcStrings := TStringList.Create();
IncludeRFC822Header := False;
InternalAssignHeader(srcStrings);
InternalAssignBodies(srcStrings);
srcStrings.Add('');
srcData.AssignByStrings(srcStrings);
srcStrings.Delete(srcStrings.Count - 1);
signedData := ACertificate.Sign(srcData, IsDetachedSignature, IsIncludeCertificate);
try
Bodies.Clear();
cryptBody := TclSMimeBody.Create(Bodies);
FieldList := TStringList.Create();
ind := GetHeaderFieldList(0, srcStrings, FieldList);
cryptBody.ParseBodyHeader(ind, srcStrings, FieldList);
ind := ParseAllHeaders(0, srcStrings, cryptBody.Header);
ParseExtraFields(cryptBody.Header, cryptBody.KnownFields, cryptBody.ExtraFields);
for i := ind + 1 to srcStrings.Count - 1 do
begin
cryptBody.Source.Add(srcStrings[i]);
end;
TclEnvelopedBody.Create(Bodies).Data := signedData;
except
signedData.Free();
raise;
end;
finally
IncludeRFC822Header := oldIncludeRFC822;
FieldList.Free();
srcStrings.Free();
srcData.Free();
end;
ContentType := 'multipart/signed';
SMimeContentType := '';
Encoding := cmNone;
{$IFDEF LOGGER}clPutLogMessage(Self, edLeave, 'SignDetached'); except on E: Exception do begin clPutLogMessage(Self, edLeave, 'SignDetached', E); raise; end; end;{$ENDIF}
end;
procedure TclSMimeMessage.Sign;
var
cert: TclCertificate;
begin
{$IFDEF DEMO}
{$IFNDEF STANDALONEDEMO}
if FindWindow('TAppBuilder', nil) = 0 then
begin
MessageBox(0, 'This demo version can be run under Delphi/C++Builder IDE only. ' +
'Please visit www.clevercomponents.com to purchase your ' +
'copy of the library.', 'Information', MB_ICONEXCLAMATION or MB_TASKMODAL or MB_TOPMOST);
ExitProcess(1);
end else
{$ENDIF}
begin
{$IFNDEF IDEDEMO}
if (not IsMailMessageDemoDisplayed) and (not IsEncoderDemoDisplayed)
and (not IsCertDemoDisplayed) then
begin
MessageBox(0, 'Please visit www.clevercomponents.com to purchase your ' +
'copy of the library.', 'Information', MB_ICONEXCLAMATION or MB_TASKMODAL or MB_TOPMOST);
end;
IsMailMessageDemoDisplayed := True;
IsEncoderDemoDisplayed := True;
IsCertDemoDisplayed := True;
{$ENDIF}
end;
{$ENDIF}
{$IFDEF LOGGER}try clPutLogMessage(Self, edEnter, 'Sign');{$ENDIF}
if IsSigned then
begin
raise EclMailMessageError.Create(cMessageSigned);
end;
FIsSecuring := True;
BeginUpdate();
try
cert := GetCertificate('MY', True);
if IsDetachedSignature then
begin
SignDetached(cert);
end else
begin
SignEnveloped(cert);
end;
finally
EndUpdate();
FIsSecuring := False;
end;
{$IFDEF LOGGER}clPutLogMessage(Self, edLeave, 'Sign'); except on E: Exception do begin clPutLogMessage(Self, edLeave, 'Sign', E); raise; end; end;{$ENDIF}
end;
procedure TclSMimeMessage.Verify;
begin
{$IFDEF DEMO}
{$IFNDEF STANDALONEDEMO}
if FindWindow('TAppBuilder', nil) = 0 then
begin
MessageBox(0, 'This demo version can be run under Delphi/C++Builder IDE only. ' +
'Please visit www.clevercomponents.com to purchase your ' +
'copy of the library.', 'Information', MB_ICONEXCLAMATION or MB_TASKMODAL or MB_TOPMOST);
ExitProcess(1);
end else
{$ENDIF}
begin
{$IFNDEF IDEDEMO}
if (not IsMailMessageDemoDisplayed) and (not IsEncoderDemoDisplayed)
and (not IsCertDemoDisplayed) then
begin
MessageBox(0, 'Please visit www.clevercomponents.com to purchase your ' +
'copy of the library.', 'Information', MB_ICONEXCLAMATION or MB_TASKMODAL or MB_TOPMOST);
end;
IsMailMessageDemoDisplayed := True;
IsEncoderDemoDisplayed := True;
IsCertDemoDisplayed := True;
{$ENDIF}
end;
{$ENDIF}
InternalVerify();
end;
function TclSMimeMessage.CreateBody(ABodies: TclMessageBodies;
const AContentType, ADisposition: string): TclMessageBody;
begin
if IsSigned then
begin
if (LowerCase(ADisposition) = 'attachment')
and (system.Pos('-signature', LowerCase(AContentType)) > 1) then
begin
Result := TclEnvelopedBody.Create(ABodies);
end else
begin
Result := TclSMimeBody.Create(ABodies);
end;
end else
begin
Result := inherited CreateBody(ABodies, AContentType, ADisposition);
end;
end;
procedure TclSMimeMessage.VerifyDetached;
var
cert: TclCertificate;
msg: TStrings;
mimeBody: TclSMimeBody;
srcData: TclCryptData;
begin
{$IFDEF LOGGER}try clPutLogMessage(Self, edEnter, 'VerifyDetached');{$ENDIF}
srcData := nil;
msg := nil;
try
srcData := TclCryptData.Create();
msg := TStringList.Create();
Assert(Bodies.Count = 2);
mimeBody := (Bodies[0] as TclSMimeBody);
msg.AddStrings(mimeBody.Header);
msg.Add('');
msg.AddStrings(mimeBody.Source);
srcData.AssignByStrings(msg);
Certificates.AddFromBinary((Bodies[1] as TclEnvelopedBody).Data);
cert := GetCertificate('addressbook', True);
cert.VerifyDetached(srcData, (Bodies[1] as TclEnvelopedBody).Data);
ContentType := mimeBody.ContentType;
SetBoundary(mimeBody.Boundary);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?