Skip to content

Commit 709e42a

Browse files
committed
Added first helper routine for ZIP support
Added a new unit along with unit tests to create DEC instances for implementing support for encrypting/decrypting ZIP files.
1 parent 027d57e commit 709e42a

File tree

4 files changed

+233
-4
lines changed

4 files changed

+233
-4
lines changed

Source/DEC60.dpr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ uses
4545
DECUtilRawByteStringHelper in 'DECUtilRawByteStringHelper.pas',
4646
DECHashAuthentication in 'DECHashAuthentication.pas',
4747
DECHashBitBase in 'DECHashBitBase.pas',
48-
DECCipherModesGCM in 'DECCipherModesGCM.pas';
48+
DECCipherModesGCM in 'DECCipherModesGCM.pas',
49+
DECZIPHelper in 'DECZIPHelper.pas';
4950

5051
begin
5152
try

Source/DECZIPHelper.pas

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{*****************************************************************************
2+
The DEC team (see file NOTICE.txt) licenses this file
3+
to you under the Apache License, Version 2.0 (the
4+
"License"); you may not use this file except in compliance
5+
with the License. A copy of this licence is found in the root directory of
6+
this project in the file LICENCE.txt or alternatively at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing,
11+
software distributed under the License is distributed on an
12+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13+
KIND, either express or implied. See the License for the
14+
specific language governing permissions and limitations
15+
under the License.
16+
*****************************************************************************}
17+
18+
/// <summary>
19+
/// Routines etc. for use with encrypted ZIP files
20+
/// </summary>
21+
unit DECZIPHelper;
22+
23+
interface
24+
25+
uses
26+
DECCiphers,
27+
DECCipherFormats;
28+
29+
/// <summary>
30+
/// Creates an instance for encrypting or decrypting the algorithm specified
31+
/// by the ZIP Algorithm ID documented in chapter 7.2.3.2 found in
32+
/// https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
33+
/// </summary>
34+
/// <param name="AlgorithmID">
35+
/// Unique ID for a crypto algorithm as specified in the documentation
36+
/// </param>
37+
/// <returns>
38+
/// Created instance of the cipher class
39+
/// </returns>
40+
/// <exception cref="EDECClassNotRegisteredException">
41+
/// Exception raised if called with an unknown/unsupported AlgorithmID
42+
/// </exception>
43+
function CreateZIPCryptoAlgorithmInstance(AlgorithmID: UInt16):TDECFormattedCipher;
44+
45+
resourcestring
46+
/// <summary>
47+
/// Exception text for attempts to create an instance for an unknown
48+
/// algorithm ID
49+
/// </summary>
50+
rUnknownZIPAlgorithmID = 'Unknown ZIP cypher algorithm ID %0:d';
51+
52+
implementation
53+
54+
uses
55+
System.SysUtils,
56+
DECTypes,
57+
DECCipherBase;
58+
59+
function CreateZIPCryptoAlgorithmInstance(AlgorithmID: UInt16):TDECFormattedCipher;
60+
begin
61+
Result := nil;
62+
63+
case AlgorithmID of
64+
$6601 : Result := TCipher_1DES.Create;
65+
// $6602 : Result := TCipher_RC2.Create; // (version needed to extract < 5.2)
66+
// // This has to do with a faulty RC2
67+
// // implementation in XP SP1 and earlier
68+
// // Unsupported as we do not know the
69+
// // details of the fault
70+
$6603 : Result := TCipher_3DES.Create; // 3DES 168
71+
$6609 : Result := TCipher_2DES.Create; // 3DES 112
72+
$660E : Result := TCipher_AES128.Create;
73+
$660F : Result := TCipher_AES192.Create;
74+
$6610 : Result := TCipher_AES256.Create;
75+
$6702 : Result := TCipher_RC2.Create; // (version needed to extract >= 5.2)
76+
$6720 : Result := TCipher_Blowfish.Create;
77+
$6721 : Result := TCipher_Twofish.Create;
78+
$6801 : Result := TCipher_RC4.Create;
79+
$FFFF : raise EDECClassNotRegisteredException.Create(Format(rUnknownZIPAlgorithmID,
80+
[AlgorithmID]));
81+
else
82+
raise EDECClassNotRegisteredException.Create(Format(rUnknownZIPAlgorithmID,
83+
[AlgorithmID]));
84+
end;
85+
86+
if Assigned(Result) then
87+
Result.Mode := cmCBCx;
88+
end;
89+
90+
end.

Unit Tests/DECDUnitTestSuite.dpr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@ program DECDUnitTestSuite;
1616
{$ENDIF}
1717

1818
uses
19-
// FastMM4,
2019
Vcl.Forms,
2120
{$IFDEF TESTINSIGHT}
2221
TestInsight.Client,
23-
TestInsight.DUnit,
2422
{$ELSE}
2523
TestFramework,
2624
GUITestRunner,
@@ -40,7 +38,8 @@ uses
4038
TestDECCipherFormats in 'Tests\TestDECCipherFormats.pas',
4139
TestDECHashMAC in 'Tests\TestDECHashMAC.pas',
4240
TestDECHashSHA3 in 'Tests\TestDECHashSHA3.pas',
43-
TestDECCipherModesGCM in 'Tests\TestDECCipherModesGCM.pas';
41+
TestDECCipherModesGCM in 'Tests\TestDECCipherModesGCM.pas',
42+
TestDECZIPHelper in 'Tests\TestDECZIPHelper.pas';
4443

4544
{$R *.RES}
4645

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
{*****************************************************************************
2+
The DEC team (see file NOTICE.txt) licenses this file
3+
to you under the Apache License, Version 2.0 (the
4+
"License"); you may not use this file except in compliance
5+
with the License. A copy of this licence is found in the root directory of
6+
this project in the file LICENCE.txt or alternatively at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing,
11+
software distributed under the License is distributed on an
12+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13+
KIND, either express or implied. See the License for the
14+
specific language governing permissions and limitations
15+
under the License.
16+
*****************************************************************************}
17+
18+
{$M+} // DUnitX would add it anyway
19+
unit TestDECZIPHelper;
20+
21+
interface
22+
23+
// Needs to be included before any other statements
24+
{$INCLUDE TestDefines.inc}
25+
26+
uses
27+
System.SysUtils, System.Classes,
28+
{$IFDEF DUnitX}
29+
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
30+
{$ELSE}
31+
TestFramework,
32+
{$ENDIF}
33+
DECUtil;
34+
35+
type
36+
/// <summary>
37+
/// Test cases for the various helper functions
38+
/// </summary>
39+
TestZIPHelpers = class(TTestCase)
40+
strict private
41+
/// <summary>
42+
/// Perform a signle algorithm create test
43+
/// </summary>
44+
/// <param name="AlgorithmID">
45+
/// ID of the algorithm instance to create
46+
/// </param>
47+
/// <param name="Name">
48+
/// Short class name of the instance to be created, must match to pass
49+
/// </param>
50+
procedure DoTestCreateZIPCryptoAlgorithmInstance(AlgorithmID: UInt16;
51+
const Name : string);
52+
/// <summary>
53+
/// Test for the "unknown" algorithm ID as parameter
54+
/// </summary>
55+
procedure DoTestCreateZIPUnknownCryptoAlgorithmException;
56+
/// <summary>
57+
/// Test for an arbitrary unknown algorithm ID as parameter
58+
/// </summary>
59+
procedure DoTestCreateZIPUnknCryptoAlgorithmException;
60+
published
61+
procedure TestCreateZIPCryptoAlgorithmInstance;
62+
procedure TestCreateZIPUnknownCryptoAlgorithmInstanceException;
63+
procedure TestCreateZIPUnknCryptoAlgorithmInstanceException;
64+
end;
65+
66+
implementation
67+
68+
uses
69+
DECTypes,
70+
DECCipherFormats,
71+
DECZIPHelper;
72+
73+
procedure TestZIPHelpers.DoTestCreateZIPUnknCryptoAlgorithmException;
74+
var
75+
Instance : TDECFormattedCipher;
76+
begin
77+
Instance := CreateZIPCryptoAlgorithmInstance($1000);
78+
Instance.Free; // Should not be reached but suppresses compiler warning
79+
end;
80+
81+
procedure TestZIPHelpers.DoTestCreateZIPUnknownCryptoAlgorithmException;
82+
var
83+
Instance : TDECFormattedCipher;
84+
begin
85+
Instance := CreateZIPCryptoAlgorithmInstance($FFFF);
86+
Instance.Free; // Should not be reached but suppresses compiler warning
87+
end;
88+
89+
procedure TestZIPHelpers.DoTestCreateZIPCryptoAlgorithmInstance(AlgorithmID: UInt16;
90+
const Name: string);
91+
var
92+
Instance : TDECFormattedCipher;
93+
begin
94+
Instance := CreateZIPCryptoAlgorithmInstance(AlgorithmID);
95+
try
96+
CheckEquals(Name, Instance.GetShortClassName);
97+
finally
98+
Instance.Free;
99+
end;
100+
end;
101+
102+
procedure TestZIPHelpers.TestCreateZIPCryptoAlgorithmInstance;
103+
begin
104+
DoTestCreateZIPCryptoAlgorithmInstance($6601, '1DES');
105+
DoTestCreateZIPCryptoAlgorithmInstance($6603, '3DES');
106+
DoTestCreateZIPCryptoAlgorithmInstance($6609, '2DES');
107+
DoTestCreateZIPCryptoAlgorithmInstance($660E, 'AES128');
108+
DoTestCreateZIPCryptoAlgorithmInstance($660F, 'AES192');
109+
DoTestCreateZIPCryptoAlgorithmInstance($6610, 'AES256');
110+
DoTestCreateZIPCryptoAlgorithmInstance($6702, 'RC2');
111+
DoTestCreateZIPCryptoAlgorithmInstance($6720, 'Blowfish');
112+
DoTestCreateZIPCryptoAlgorithmInstance($6721, 'Twofish');
113+
DoTestCreateZIPCryptoAlgorithmInstance($6801, 'RC4');
114+
115+
// $6602 : Result := TCipher_RC2.Create; // (version needed to extract < 5.2)
116+
// // This has to do with a faulty RC2
117+
// // implementation in XP SP1 and earlier
118+
// // Unsupported as we do not know the
119+
// // details of the fault
120+
end;
121+
122+
procedure TestZIPHelpers.TestCreateZIPUnknCryptoAlgorithmInstanceException;
123+
begin
124+
CheckException(DoTestCreateZIPUnknCryptoAlgorithmException, EDECClassNotRegisteredException);
125+
end;
126+
127+
procedure TestZIPHelpers.TestCreateZIPUnknownCryptoAlgorithmInstanceException;
128+
begin
129+
CheckException(DoTestCreateZIPUnknownCryptoAlgorithmException, EDECClassNotRegisteredException);
130+
end;
131+
132+
initialization
133+
// Register any test cases with the test runner
134+
{$IFDEF DUnitX}
135+
TDUnitX.RegisterTestFixture(TestZIPHelpers);
136+
{$ELSE}
137+
RegisterTest('DECZIPHelper', TestZIPHelpers.Suite);
138+
{$ENDIF}
139+
end.

0 commit comments

Comments
 (0)