Skip to content
This repository has been archived by the owner on Aug 11, 2023. It is now read-only.

Commit

Permalink
fix: Made usage of SyncLock for disposal consistent, added a check fo…
Browse files Browse the repository at this point in the history
…r a maximum file size and changed some message creations.
  • Loading branch information
Frank Schwab committed Dec 16, 2020
1 parent b61ca25 commit eba568f
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 32 deletions.
43 changes: 32 additions & 11 deletions TUPWLib/Crypto/CounterModeCryptoTransform.vb
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
'
' Author: Frank Schwab, DB Systel GmbH
'
' Version: 2.0.1
' Version: 2.0.2
'
' Change history:
' 2020-04-30: V1.0.0: Created.
' 2020-05-12: V1.1.0: Corrected handling of 0 length final block.
' 2020-06-18: V1.1.1: Corrected handling of null parameters in constructors.
' 2020-12-10: V2.0.0: Added correct handling of disposed instance.
' 2020-12-11: V2.0.1: Put IsValid method where it belongs.
' 2020-12-16: V2.0.2: Made usage of SyncLock for disposal consistent.
'

Imports System.Security.Cryptography
Expand Down Expand Up @@ -54,6 +55,11 @@ Public Class CounterModeCryptoTransform : Implements ICryptoTransform, IDisposab
Private m_BlockSizeInBytes As Integer
Private m_XorMask As Byte()
Private m_XorMaskPosition As Integer

''' <summary>
''' Object only used for locking the call to Dispose.
''' </summary>
Private ReadOnly m_LockObject As New Object
#End Region

#Region "Constructor"
Expand Down Expand Up @@ -370,6 +376,26 @@ Public Class CounterModeCryptoTransform : Implements ICryptoTransform, IDisposab
ArrayHelper.Clear(m_Counter)
End Sub
#End Region

#Region "Data helpers"
''' <summary>
''' Clear all data.
''' </summary>
Private Sub ClearData()
m_XorMaskPosition = 0

ArrayHelper.Clear(m_Counter)
ArrayHelper.Clear(m_XorMask)

m_CounterEncryptor.Dispose()
m_SymmetricAlgorithm.Dispose()

m_Counter = Nothing
m_XorMask = Nothing
m_CounterEncryptor = Nothing
m_SymmetricAlgorithm = Nothing
End Sub
#End Region
#End Region

#Region "IDisposable Support"
Expand All @@ -389,16 +415,10 @@ Public Class CounterModeCryptoTransform : Implements ICryptoTransform, IDisposab
'
' Disposing of resources needs to be synchronized to prevent a race condition.
'
SyncLock m_SymmetricAlgorithm
SyncLock m_LockObject
m_IsDisposed = True

m_XorMaskPosition = 0

ArrayHelper.Clear(m_Counter)
ArrayHelper.Clear(m_XorMask)

m_CounterEncryptor.Dispose()
m_SymmetricAlgorithm.Dispose()
ClearData()
End SyncLock

' Free unmanaged resources (unmanaged objects) and override Finalize() below.
Expand Down Expand Up @@ -431,9 +451,10 @@ Public Class CounterModeCryptoTransform : Implements ICryptoTransform, IDisposab
''' <returns><c>true</c>, if this instance is in a valid state, <c>false</c>, if this instance has already been disposed of.</returns>
Public ReadOnly Property IsValid As Boolean
Get
Return Not m_IsDisposed
SyncLock m_LockObject
Return Not m_IsDisposed
End SyncLock
End Get
End Property

#End Region
End Class
46 changes: 38 additions & 8 deletions TUPWLib/Crypto/FileAndKeyEncryption.vb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
'
' Author: Frank Schwab, DB Systel GmbH
'
' Version: 2.0.1
' Version: 2.1.0
'
' Change history:
' 2020-05-05: V1.0.0: Created.
' 2020-12-10: V2.0.0: Correct handling of disposed instances.
' 2020-12-11: V2.0.1: Put IsValid method where it belongs.
' 2020-12-16: V2.1.0: Made usage of SyncLock for disposal consistent and added check for maximum file size.
'

Imports System.IO
Expand All @@ -32,6 +33,13 @@ Imports System.IO
''' Provides encryption by key generated from a file and a key
''' </summary>
Public Class FileAndKeyEncryption : Implements IDisposable
#Region "Private constants"
''' <summary>
''' Maximum allowed key file size
''' </summary>
Private Const MAX_KEY_FILE_SIZE As Long = 10_000_000L
#End Region

#Region "Instance variables"
'******************************************************************
' Instance variables
Expand All @@ -41,6 +49,11 @@ Public Class FileAndKeyEncryption : Implements IDisposable
''' Instance of <see cref="SplitKeyEncryption"/> to use behind this interface.
''' </summary>
Private ReadOnly m_SplitKeyEncryption As SplitKeyEncryption

''' <summary>
''' Object only used for locking the call to Dispose.
''' </summary>
Private ReadOnly m_LockObject As New Object
#End Region

#Region "Constructors"
Expand All @@ -53,11 +66,11 @@ Public Class FileAndKeyEncryption : Implements IDisposable
''' </summary>
''' <param name="hmacKey">Key for the HMAC of the file.</param>
''' <param name="keyFilePath">Path of key file.</param>
''' <exception cref="ArgumentException">Thrown if <paramref name="keyFilePath"/> contains invalid characters.</exception>
''' <exception cref="ArgumentException">Thrown if <paramref name="keyFilePath"/> contains invalid characters or the contents are too large.</exception>
''' <exception cref="ArgumentNullException">Thrown if any parameter is <c>Nothing</c>.</exception>
''' <exception cref="DirectoryNotFoundException">Thrown if the directory in <paramref name="keyFilePath"/> does not exist.</exception>
''' <exception cref="FileNotFoundException">Thrown if <paramref name="keyFilePath"/> is not found.</exception>
''' <exception cref="IOException">Thrown if an I/O error occurs during access to the file.</exception>
''' <exception cref="IOException">Thrown if an I/O error occurs during accessing the file.</exception>
''' <exception cref="NotSupportedException">Thrown if <paramref name="keyFilePath"/> is in an invalid format.</exception>
''' <exception cref="PathTooLongException">Thrown if <paramref name="keyFilePath"/> is too long.</exception>
''' <exception cref="UnauthorizedAccessException">Thrown if <paramref name="keyFilePath"/> specifies a directory or the caller
Expand Down Expand Up @@ -224,12 +237,23 @@ Public Class FileAndKeyEncryption : Implements IDisposable
#End Region

#Region "File helper methods"
''' <summary>
''' Get the length of a file.
''' </summary>
''' <param name="aFilePath">Path to the file.</param>
''' <returns>Length of the file.</returns>
Private Shared Function GetFileSize(aFilePath As String) As Long
Dim fi As New FileInfo(aFilePath)

Return fi.Length
End Function

''' <summary>
''' Get the content of the key file.
''' </summary>
''' <param name="keyFilePath">Key file to be used.</param>
''' <returns>Content of the key file.</returns>
''' <exception cref="ArgumentException">Thrown if <paramref name="keyFilePath"/> contains invalid characters.</exception>
''' <exception cref="ArgumentException">Thrown if <paramref name="keyFilePath"/> contains invalid characters or the file contents are too large.</exception>
''' <exception cref="DirectoryNotFoundException">Thrown if the directory in <paramref name="keyFilePath"/> does not exist.</exception>
''' <exception cref="FileNotFoundException">Thrown if <paramref name="keyFilePath"/> is not found.</exception>
''' <exception cref="IOException">Thrown if an I/O error occurs during access to the file.</exception>
Expand All @@ -241,9 +265,13 @@ Public Class FileAndKeyEncryption : Implements IDisposable
Dim result As Byte()

If File.Exists(keyFilePath) Then
result = File.ReadAllBytes(keyFilePath)
If GetFileSize(keyFilePath) <= MAX_KEY_FILE_SIZE Then
result = File.ReadAllBytes(keyFilePath)
Else
Throw New ArgumentException($"Key file is too large (maximum is {MAX_KEY_FILE_SIZE:#,##0} bytes)")
End If
Else
Throw New FileNotFoundException("File '" & keyFilePath & "' does not exist")
Throw New FileNotFoundException("Key file does not exist", keyFilePath)
End If

Return result
Expand Down Expand Up @@ -282,7 +310,7 @@ Public Class FileAndKeyEncryption : Implements IDisposable
'
' Disposing of resources needs to be synchronized to prevent a race condition.
'
SyncLock m_SplitKeyEncryption
SyncLock m_LockObject
m_SplitKeyEncryption.Dispose()
End SyncLock
End If
Expand Down Expand Up @@ -317,7 +345,9 @@ Public Class FileAndKeyEncryption : Implements IDisposable
''' <returns><c>true</c>, if this instance is in a valid state, <c>false</c>, if this instance has already been disposed of.</returns>
Public ReadOnly Property IsValid As Boolean
Get
Return Not m_IsDisposed
SyncLock m_LockObject
Return Not m_IsDisposed
End SyncLock
End Get
End Property
#End Region
Expand Down
17 changes: 14 additions & 3 deletions TUPWLib/Crypto/ProtectedByteArray.vb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
'
' Author: Frank Schwab, DB Systel GmbH
'
' Version: 2.0.1
' Version: 2.0.2
'
' Change history:
' 2020-04-23: V1.0.0: Created.
' 2020-12-10: V2.0.0: Throw ObjectDisposedException instead of InvalidOperationException.
' 2020-12-11: V2.0.1: Put IsValid method where it belongs.
' 2020-12-16: V2.0.2: Made usage of SyncLock for disposal consistent.
'

''' <summary>
Expand All @@ -44,6 +45,11 @@ Public Class ProtectedByteArray : Implements IDisposable

Private m_ProtectedArray As ShuffledByteArray
Private m_Obfuscation As ShuffledByteArray

''' <summary>
''' Object only used for locking the call to Dispose.
''' </summary>
Private ReadOnly m_LockObject As New Object
#End Region

#Region "Constructors"
Expand Down Expand Up @@ -285,13 +291,16 @@ Public Class ProtectedByteArray : Implements IDisposable
'
' Disposing of resources needs to be synchronized to prevent a race condition.
'
SyncLock m_ProtectedArray
SyncLock m_LockObject
If Not m_IsDisposed Then
m_IsDisposed = True

If disposeManagedResources Then
m_ProtectedArray.Dispose()
m_Obfuscation.Dispose()

m_ProtectedArray = Nothing
m_Obfuscation = Nothing
End If

' Free unmanaged resources (unmanaged objects) and override Finalize() below.
Expand Down Expand Up @@ -325,7 +334,9 @@ Public Class ProtectedByteArray : Implements IDisposable
''' <returns><c>True</c>, if this instance has not been disposed of, <c>false</c> otherwise.</returns>
Public ReadOnly Property IsValid() As Boolean
Get
Return m_ProtectedArray.IsValid
SyncLock m_LockObject
Return Not m_IsDisposed
End SyncLock
End Get
End Property
#End Region
Expand Down
10 changes: 8 additions & 2 deletions TUPWLib/Crypto/ShuffledByteArray.vb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
'
' Author: Frank Schwab, DB Systel GmbH
'
' Version: 2.0.2
' Version: 2.0.3
'
' Change history:
' 2020-04-23: V1.0.0: Created.
Expand All @@ -28,6 +28,7 @@
' 2020-12-10: V2.0.0: Throw ObjectDisposedException instead of InvalidOperationException.
' 2020-12-11: V2.0.1: Put IsValid method where it belongs.
' 2020-12-14: V2.0.2: Corrected some comments.
' 2020-12-16: V2.0.3: Made usage of SyncLock for disposal consistent.
'

''' <summary>
Expand Down Expand Up @@ -459,6 +460,9 @@ Public Class ShuffledByteArray : Implements IDisposable
m_HashCode = 0

m_StoredArrayLength = 0

m_ByteArray = Nothing
m_IndexArray = Nothing
End Sub
#End Region

Expand Down Expand Up @@ -606,7 +610,9 @@ Public Class ShuffledByteArray : Implements IDisposable
''' <returns><c>true</c>, if this instance is in a valid state, <c>false</c>, if this instance has already been disposed of.</returns>
Public ReadOnly Property IsValid As Boolean
Get
Return Not m_IsDisposed
SyncLock m_LockObject
Return Not m_IsDisposed
End SyncLock
End Get
End Property
#End Region
Expand Down
27 changes: 19 additions & 8 deletions TUPWLib/Crypto/SplitKeyEncryption.vb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
'
' Author: Frank Schwab, DB Systel GmbH
'
' Version: 2.0.1
' Version: 2.0.2
'
' Change history:
' 2020-05-05: V1.0.0: Created.
Expand All @@ -34,6 +34,7 @@
' 2020-12-10: V1.3.1: Made hashing simpler and 2.5 times faster.
' 2020-12-10: V2.0.0: Correct handling of disposed instances.
' 2020-12-11: V2.0.1: Put IsValid method where it belongs.
' 2020-12-16: V2.0.2: Made usage of SyncLock for disposal consistent and changed some message creations.
'

Imports System.IO
Expand Down Expand Up @@ -89,7 +90,7 @@ Public Class SplitKeyEncryption : Implements IDisposable
''' <summary>
''' Maximum length for source bytes.
''' </summary>
Private Const MAXIMUM_SOURCE_BYTES_LENGTH As UInteger = 10000000
Private Const MAXIMUM_SOURCE_BYTES_LENGTH As UInteger = 10_000_000

''' <summary>
''' Minimum entropy for source bytes.
Expand Down Expand Up @@ -209,6 +210,11 @@ Public Class SplitKeyEncryption : Implements IDisposable
''' HMAC key to use.
''' </summary>
Private m_HMACKey As ProtectedByteArray

''' <summary>
''' Object only used for locking the call to Dispose.
''' </summary>
Private ReadOnly m_LockObject As New Object
#End Region

#Region "Constructors"
Expand Down Expand Up @@ -449,10 +455,10 @@ Public Class SplitKeyEncryption : Implements IDisposable
RequireNonNull(aHMACKey, NameOf(aHMACKey))

If aHMACKey.Length < MINIMUM_HMAC_KEY_LENGTH Then _
Throw New ArgumentException("HMAC key length is less than " & MINIMUM_HMAC_KEY_LENGTH.ToString())
Throw New ArgumentException($"HMAC key length is less than {MINIMUM_HMAC_KEY_LENGTH}")

If aHMACKey.Length > MAXIMUM_HMAC_KEY_LENGTH Then _
Throw New ArgumentException("HMAC key length is larger than " & MAXIMUM_HMAC_KEY_LENGTH.ToString())
Throw New ArgumentException($"HMAC key length is larger than {MAXIMUM_HMAC_KEY_LENGTH}")
End Sub

''' <summary>
Expand Down Expand Up @@ -491,10 +497,10 @@ Public Class SplitKeyEncryption : Implements IDisposable
End If

If ec.Count < MINIMUM_SOURCE_BYTES_LENGTH Then _
Throw New ArgumentException("There are less than " & MINIMUM_SOURCE_BYTES_LENGTH.ToString() & " source bytes")
Throw New ArgumentException($"There are less than {MINIMUM_SOURCE_BYTES_LENGTH} source bytes")

If ec.Count > MAXIMUM_SOURCE_BYTES_LENGTH Then _
Throw New ArgumentException("There are more than " & MAXIMUM_SOURCE_BYTES_LENGTH.ToString() & " source bytes")
Throw New ArgumentException($"There are more than {MAXIMUM_SOURCE_BYTES_LENGTH:#,##0} source bytes")
End Sub
#End Region

Expand Down Expand Up @@ -1201,9 +1207,12 @@ Public Class SplitKeyEncryption : Implements IDisposable
'
' Disposing of resources needs to be synchronized to prevent a race condition.
'
SyncLock m_EncryptionKey
SyncLock m_LockObject
m_EncryptionKey.Dispose()
m_HMACKey.Dispose()

m_EncryptionKey = Nothing
m_HMACKey = Nothing
End SyncLock
End If

Expand Down Expand Up @@ -1237,7 +1246,9 @@ Public Class SplitKeyEncryption : Implements IDisposable
''' <returns><c>true</c>, if this instance is in a valid state, <c>false</c>, if this instance has already been disposed of.</returns>
Public ReadOnly Property IsValid As Boolean
Get
Return Not m_IsDisposed
SyncLock m_LockObject
Return Not m_IsDisposed
End SyncLock
End Get
End Property
#End Region
Expand Down

0 comments on commit eba568f

Please sign in to comment.