fpspreadsheet: Refactor TsCryptoInfo record.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5788 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2017-03-05 12:25:29 +00:00
parent ffceb1932b
commit 6126788bec
5 changed files with 101 additions and 43 deletions

View File

@ -3,12 +3,50 @@ unit fpsCrypto;
interface interface
uses uses
SysUtils; SysUtils, fpsTypes;
function AlgorithmToStr(Algorithm: TsCryptoAlgorithm): String;
function StrToAlgorithm(const AName: String): TsCryptoAlgorithm;
function ExcelPasswordHash(const APassword: String): String; function ExcelPasswordHash(const APassword: String): String;
implementation implementation
function AlgorithmToStr(Algorithm: TsCryptoAlgorithm): String;
begin
case Algorithm of
caExcel : Result := 'EXCEL';
caMD2 : Result := 'MD2';
caMD4 : Result := 'MD4';
caMD5 : Result := 'MD5';
caRIPEMD128 : Result := 'RIPEMD-128';
caRIPEMD160 : Result := 'RIPEMD-160';
caSHA1 : Result := 'SHA-1';
caSHA256 : Result := 'SHA-256';
caSHA384 : Result := 'SHA-384';
caSHA512 : Result := 'SHA-512';
caWHIRLPOOL : Result := 'WHIRLPOOL';
else Result := '';
end;
end;
function StrToAlgorithm(const AName: String): TsCryptoAlgorithm;
begin
case AName of
'MD2' : Result := caMD2;
'MD4' : Result := caMD4;
'MD5' : Result := caMD5;
'RIPEMD-128' : Result := caRIPEMD128;
'RIPEMD-160' : Result := caRIPEMD160;
'SHA-1' : Result := caSHA1;
'SHA-256' : Result := caSHA256;
'SHA-384' : Result := caSHA384;
'SHA-512' : Result := caSHA512;
'WHIRLPOOL' : Result := caWHIRLPOOL;
else Result := caUnknown;
end;
end;
{@@ This is the code for generating Excel 2010 and earlier password's hash } {@@ This is the code for generating Excel 2010 and earlier password's hash }
function ExcelPasswordHash(const APassword: string): string; function ExcelPasswordHash(const APassword: string): string;
const const

View File

@ -638,10 +638,18 @@ type
{@@ Switch a cell from left-to-right to right-to-left orientation } {@@ Switch a cell from left-to-right to right-to-left orientation }
TsBiDiMode = (bdDefault, bdLTR, bdRTL); TsBiDiMode = (bdDefault, bdLTR, bdRTL);
{@@ } {@@ Algorithm used for encryption/decryption }
TsCryptoAlgorithm = (caUnknown,
caExcel, // Excel <= 2010
caMD2, caMD4, caMD5, caRIPEMD128, caRIPEMD160,
caSHA1, caSHA256, caSHA384, caSHA512,
caWHIRLPOOL
);
{@@ Record collection information for encryption/decryption }
TsCryptoInfo = record TsCryptoInfo = record
AlgorithmName: string; PasswordHash: String;
Password: string; // For old version of Excel (2010 and earlier) Algorithm: TsCryptoAlgorithm;
HashValue: string; HashValue: string;
SaltValue: string; SaltValue: string;
SpinCount: Integer; SpinCount: Integer;

View File

@ -2085,8 +2085,8 @@ end;
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure InitCryptoInfo(out AValue: TsCryptoInfo); procedure InitCryptoInfo(out AValue: TsCryptoInfo);
begin begin
AValue.Password := ''; AValue.PasswordHash := '';
AValue.AlgorithmName := ''; AValue.Algorithm := caUnknown;
AValue.HashValue := ''; AValue.HashValue := '';
AValue.SaltValue := ''; AValue.SaltValue := '';
AValue.SpinCount := 0; AValue.SpinCount := 0;

View File

@ -235,7 +235,7 @@ implementation
uses uses
variants, strutils, math, lazutf8, LazFileUtils, uriparser, variants, strutils, math, lazutf8, LazFileUtils, uriparser,
{%H-}fpsPatches, {%H-}fpsPatches, fpsCrypto,
fpsStrings, fpsStreams, fpsClasses, fpsImages; fpsStrings, fpsStreams, fpsClasses, fpsImages;
const const
@ -2013,16 +2013,19 @@ begin
InitCryptoInfo(shc); InitCryptoInfo(shc);
s := GetAttrValue(ANode, 'password'); s := GetAttrValue(ANode, 'password');
if s <> '' then if s <> '' then begin
shc.Password := s shc.PasswordHash := s;
else shc.Algorithm := caExcel;
end else
begin begin
s := GetAttrValue(ANode, 'hashValue'); s := GetAttrValue(ANode, 'hashValue');
if s <> '' then begin if s <> '' then begin
shc.HashValue := s; shc.PasswordHash := s;
s := GetAttrValue(ANode, 'algorithmName'); s := GetAttrValue(ANode, 'algorithmName');
shc.AlgorithmName := s; shc.Algorithm := StrToAlgorithm(s);
if shc.Algorithm = caUnknown then
Workbook.AddErrorMsg('Found unknown encryption algorithm "%s" for worksheet protection', [s]);
s := GetAttrValue(ANode, 'saltValue'); s := GetAttrValue(ANode, 'saltValue');
shc.SaltValue := s; shc.SaltValue := s;
@ -2290,14 +2293,20 @@ begin
InitCryptoInfo(wbc); InitCryptoInfo(wbc);
s := GetAttrValue(ANode, 'workbookPassword'); s := GetAttrValue(ANode, 'workbookPassword');
if s <> '' then if s <> '' then
wbc.Password := s wbc.PasswordHash := s
else else
begin begin
s := GetAttrValue(ANode, 'workbookHashVal'); s := GetAttrValue(ANode, 'workbookHashVal');
if s <> '' then begin if s <> '' then begin
wbc.HashValue := s; wbc.PasswordHash := s;
wbc.AlgorithmName := GetAttrValue(ANode, 'workbookAlgorithmName');
s := GetAttrValue(ANode, 'workbookAlgorithmName');
wbc.Algorithm := StrToAlgorithm(s);
if wbc.Algorithm = caUnknown then
Workbook.AddErrorMsg('Found unknown encryption algorithm "%s" for workbook protection', [s]);
wbc.SaltValue := GetAttrValue(ANode, 'workbookSaltValue'); wbc.SaltValue := GetAttrValue(ANode, 'workbookSaltValue');
wbc.SpinCount := StrToIntDef(GetAttrValue(ANode, 'workbookSpinCount'), 0); wbc.SpinCount := StrToIntDef(GetAttrValue(ANode, 'workbookSpinCount'), 0);
end; end;
end; end;
@ -3435,15 +3444,15 @@ begin
else else
Exit; //exit if sheet not protected Exit; //exit if sheet not protected
if AWorksheet.CryptoInfo.Password <> '' then if AWorksheet.CryptoInfo.PasswordHash <> '' then begin
s := s + ' password="' + AWorksheet.CryptoInfo.Password + '"' if AWorksheet.CryptoInfo.Algorithm = caExcel then
s := s + ' password="' + AWorksheet.CryptoInfo.PasswordHash + '"'
else else
if AWorksheet.CryptoInfo.HashValue <> '' then
begin begin
s := s + ' hashValue="' + AWorksheet.CryptoInfo.HashValue + '"'; s := s + ' hashValue="' + AWorksheet.CryptoInfo.HashValue + '"';
if AWorksheet.CryptoInfo.AlgorithmName <> '' then if AWorksheet.CryptoInfo.Algorithm <> caUnknown then
s := s + ' algorithmName="' + AWorksheet.CryptoInfo.AlgorithmName + '"'; s := s + ' algorithmName="' + AlgorithmToStr(AWorksheet.CryptoInfo.Algorithm) + '"';
if AWorksheet.CryptoInfo.SaltValue <> '' then if AWorksheet.CryptoInfo.SaltValue <> '' then
s := s + ' saltValue="' + AWorksheet.CryptoInfo.SaltValue + '"'; s := s + ' saltValue="' + AWorksheet.CryptoInfo.SaltValue + '"';
@ -3451,6 +3460,7 @@ begin
if AWorksheet.CryptoInfo.SpinCount <> 0 then if AWorksheet.CryptoInfo.SpinCount <> 0 then
s := s + ' spinCount="' + IntToStr(AWorksheet.CryptoInfo.SpinCount) + '"'; s := s + ' spinCount="' + IntToStr(AWorksheet.CryptoInfo.SpinCount) + '"';
end; end;
end;
{ {
if spObjects in AWorksheet.Protection then // to do: Remove from default above if spObjects in AWorksheet.Protection then // to do: Remove from default above
@ -4675,14 +4685,15 @@ var
begin begin
s := ''; s := '';
if Workbook.CryptoInfo.Password <> '' then if Workbook.CryptoInfo.PasswordHash <> '' then
s := s + ' workbookPassword="' + Workbook.CryptoInfo.Password + '"'
else
if Workbook.CryptoInfo.HashValue <> '' then
begin begin
s:= s + ' workbookHashVal="' + Workbook.CryptoInfo.HashValue + '"'; if Workbook.CryptoInfo.Algorithm = caExcel then
if Workbook.CryptoInfo.AlgorithmName <> '' then s := s + ' workbookPassword="' + Workbook.CryptoInfo.PasswordHash + '"'
s:= s + ' workbookAlgorithmName="' + Workbook.CryptoInfo.AlgorithmName + '"'; else
begin
s:= s + ' workbookHashVal="' + Workbook.CryptoInfo.PasswordHash + '"';
if Workbook.CryptoInfo.Algorithm <> caUnknown then
s:= s + ' workbookAlgorithmName="' + AlgorithmToStr(Workbook.CryptoInfo.Algorithm) + '"';
if Workbook.CryptoInfo.SaltValue <> '' then if Workbook.CryptoInfo.SaltValue <> '' then
s:= s + ' workbookSaltValue="' + Workbook.CryptoInfo.SaltValue + '"'; s:= s + ' workbookSaltValue="' + Workbook.CryptoInfo.SaltValue + '"';
@ -4690,6 +4701,7 @@ begin
if Workbook.CryptoInfo.SpinCount <> 0 then if Workbook.CryptoInfo.SpinCount <> 0 then
s:= s + ' workbookSpinCount="' + IntToStr(Workbook.CryptoInfo.SpinCount) + '"'; s:= s + ' workbookSpinCount="' + IntToStr(Workbook.CryptoInfo.SpinCount) + '"';
end; end;
end;
{ {
if Workbook.RevisionsCrypto.Password <> '' then if Workbook.RevisionsCrypto.Password <> '' then

View File

@ -584,7 +584,7 @@ implementation
uses uses
Types, Math, StrUtils, TypInfo, LCLType, LCLIntf, LCLProc, Types, Math, StrUtils, TypInfo, LCLType, LCLIntf, LCLProc,
Dialogs, Forms, Clipbrd, Dialogs, Forms, Clipbrd,
fpsStrings, fpsReaderWriter, fpsUtils, fpsNumFormat, fpsImages, fpsStrings, fpsCrypto, fpsReaderWriter, fpsUtils, fpsNumFormat, fpsImages,
fpsHTMLUtils, fpsCSV; fpsHTMLUtils, fpsCSV;
var var
@ -3653,8 +3653,8 @@ begin
if (ienCryptoInfo in FExpanded) then begin if (ienCryptoInfo in FExpanded) then begin
AStrings.Add('(-) CryptoInfo='); AStrings.Add('(-) CryptoInfo=');
AStrings.Add(Format(' Password=%s', [Workbook.CryptoInfo.Password])); AStrings.Add(Format(' PasswordHash=%s', [Workbook.CryptoInfo.PasswordHash]));
AStrings.Add(Format(' AlgorithmName=%s', [Workbook.CryptoInfo.AlgorithmName])); AStrings.Add(Format(' Algorithm=%s', [AlgorithmToStr(Workbook.CryptoInfo.Algorithm)]));
AStrings.Add(Format(' HashValue=%s', [Workbook.CryptoInfo.HashValue])); AStrings.Add(Format(' HashValue=%s', [Workbook.CryptoInfo.HashValue]));
AStrings.Add(Format(' SaltValue=%s', [Workbook.CryptoInfo.SaltValue])); AStrings.Add(Format(' SaltValue=%s', [Workbook.CryptoInfo.SaltValue]));
AStrings.Add(Format(' SplinCount=%d', [Workbook.CryptoInfo.SpinCount])); AStrings.Add(Format(' SplinCount=%d', [Workbook.CryptoInfo.SpinCount]));
@ -3837,8 +3837,8 @@ begin
if (ienCryptoInfo in FExpanded) then begin if (ienCryptoInfo in FExpanded) then begin
AStrings.Add('(-) CryptoInfo='); AStrings.Add('(-) CryptoInfo=');
AStrings.Add(Format(' Password=%s', [Worksheet.CryptoInfo.Password])); AStrings.Add(Format(' PasswordHash=%s', [Worksheet.CryptoInfo.PasswordHash]));
AStrings.Add(Format(' AlgorithmName=%s', [Worksheet.CryptoInfo.AlgorithmName])); AStrings.Add(Format(' Algorithm=%s', [AlgorithmToStr(Worksheet.CryptoInfo.Algorithm)]));
AStrings.Add(Format(' HashValue=%s', [Worksheet.CryptoInfo.HashValue])); AStrings.Add(Format(' HashValue=%s', [Worksheet.CryptoInfo.HashValue]));
AStrings.Add(Format(' SaltValue=%s', [Worksheet.CryptoInfo.SaltValue])); AStrings.Add(Format(' SaltValue=%s', [Worksheet.CryptoInfo.SaltValue]));
AStrings.Add(Format(' SplinCount=%d', [Worksheet.CryptoInfo.SpinCount])); AStrings.Add(Format(' SplinCount=%d', [Worksheet.CryptoInfo.SpinCount]));