11using System ;
22using System . Security . Cryptography ;
3- using ICSharpCode . SharpZipLib . Core ;
43
54namespace ICSharpCode . SharpZipLib . Encryption
65{
@@ -9,31 +8,6 @@ namespace ICSharpCode.SharpZipLib.Encryption
98 /// </summary>
109 internal class ZipAESTransform : ICryptoTransform
1110 {
12- #if NET45
13- class IncrementalHash : HMACSHA1
14- {
15- bool _finalised ;
16- public IncrementalHash ( byte [ ] key ) : base ( key ) { }
17- public static IncrementalHash CreateHMAC ( string n , byte [ ] key ) => new IncrementalHash ( key ) ;
18- public void AppendData ( byte [ ] buffer , int offset , int count ) => TransformBlock ( buffer , offset , count , buffer , offset ) ;
19- public byte [ ] GetHashAndReset ( )
20- {
21- if ( ! _finalised )
22- {
23- byte [ ] dummy = new byte [ 0 ] ;
24- TransformFinalBlock ( dummy , 0 , 0 ) ;
25- _finalised = true ;
26- }
27- return Hash ;
28- }
29- }
30-
31- static class HashAlgorithmName
32- {
33- public static string SHA1 = null ;
34- }
35- #endif
36-
3711 private const int PWD_VER_LENGTH = 2 ;
3812
3913 // WinZip use iteration count of 1000 for PBKDF2 key generation
@@ -137,91 +111,67 @@ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, b
137111 /// <summary>
138112 /// Returns the 2 byte password verifier
139113 /// </summary>
140- public byte [ ] PwdVerifier
141- {
142- get
143- {
144- return _pwdVerifier ;
145- }
146- }
114+ public byte [ ] PwdVerifier => _pwdVerifier ;
147115
148116 /// <summary>
149117 /// Returns the 10 byte AUTH CODE to be checked or appended immediately following the AES data stream.
150118 /// </summary>
151- public byte [ ] GetAuthCode ( )
152- {
153- if ( _authCode == null )
154- {
155- _authCode = _hmacsha1 . GetHashAndReset ( ) ;
156- }
157- return _authCode ;
158- }
119+ public byte [ ] GetAuthCode ( ) => _authCode ?? ( _authCode = _hmacsha1 . GetHashAndReset ( ) ) ;
159120
160121 #region ICryptoTransform Members
161122
162123 /// <summary>
163- /// Not implemented.
124+ /// Transform final block and read auth code
164125 /// </summary>
165126 public byte [ ] TransformFinalBlock ( byte [ ] inputBuffer , int inputOffset , int inputCount )
166127 {
167- if ( inputCount > 0 )
168- {
169- throw new NotImplementedException ( "TransformFinalBlock is not implemented and inputCount is greater than 0" ) ;
128+ var buffer = Array . Empty < byte > ( ) ;
129+
130+ // FIXME: When used together with `ZipAESStream`, the final block handling is done inside of it instead
131+ // This should not be necessary anymore, and the entire `ZipAESStream` class should be replaced with a plain `CryptoStream`
132+ if ( inputCount != 0 ) {
133+ if ( inputCount > ZipAESStream . AUTH_CODE_LENGTH )
134+ {
135+ // At least one byte of data is preceeding the auth code
136+ int finalBlock = inputCount - ZipAESStream . AUTH_CODE_LENGTH ;
137+ buffer = new byte [ finalBlock ] ;
138+ TransformBlock ( inputBuffer , inputOffset , finalBlock , buffer , 0 ) ;
139+ }
140+ else if ( inputCount < ZipAESStream . AUTH_CODE_LENGTH )
141+ throw new Zip . ZipException ( "Auth code missing from input stream" ) ;
142+
143+ // Read the authcode from the last 10 bytes
144+ _authCode = _hmacsha1 . GetHashAndReset ( ) ;
170145 }
171- return Empty . Array < byte > ( ) ;
146+
147+
148+ return buffer ;
172149 }
173150
174151 /// <summary>
175152 /// Gets the size of the input data blocks in bytes.
176153 /// </summary>
177- public int InputBlockSize
178- {
179- get
180- {
181- return _blockSize ;
182- }
183- }
154+ public int InputBlockSize => _blockSize ;
184155
185156 /// <summary>
186157 /// Gets the size of the output data blocks in bytes.
187158 /// </summary>
188- public int OutputBlockSize
189- {
190- get
191- {
192- return _blockSize ;
193- }
194- }
159+ public int OutputBlockSize => _blockSize ;
195160
196161 /// <summary>
197162 /// Gets a value indicating whether multiple blocks can be transformed.
198163 /// </summary>
199- public bool CanTransformMultipleBlocks
200- {
201- get
202- {
203- return true ;
204- }
205- }
164+ public bool CanTransformMultipleBlocks => true ;
206165
207166 /// <summary>
208167 /// Gets a value indicating whether the current transform can be reused.
209168 /// </summary>
210- public bool CanReuseTransform
211- {
212- get
213- {
214- return true ;
215- }
216- }
169+ public bool CanReuseTransform => true ;
217170
218171 /// <summary>
219172 /// Cleanup internal state.
220173 /// </summary>
221- public void Dispose ( )
222- {
223- _encryptor . Dispose ( ) ;
224- }
174+ public void Dispose ( ) => _encryptor . Dispose ( ) ;
225175
226176 #endregion ICryptoTransform Members
227177 }
0 commit comments