2021-05-13 17:07:16 +02:00
using Serilog ;
using TINK.Model.Device ;
namespace TINK.Services.BluetoothLock.Crypto
{
2022-09-06 16:08:19 +02:00
public class AuthCryptoHelper
{
private ICipher Cipher { get ; }
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
/// <summary> Encrypted seed (random number) created inside ILOCKIT and passd to app.</summary>
private byte [ ] SeedLockEncrypted { get ; }
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
/// <summary> Contstructs a auth crypto helper object.</summary>
/// <param name="seedLockEncrypted">Encrypted seed to deocode using <see cref="KeyCopri"/>.</param>
/// <param name="keyCopri">Key used to to decrypt <see cref="SeedLockEncrypted"/>.</param>
public AuthCryptoHelper (
byte [ ] seedLockEncrypted ,
byte [ ] keyCopri ,
ICipher cipher )
{
KeyCopri = keyCopri ;
SeedLockEncrypted = seedLockEncrypted ;
Cipher = cipher ? ? new Cipher ( ) ;
}
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
/// <summary> Public for testing purposes only.</summary>
public byte [ ] GetSeedLock ( )
{
byte [ ] seedLockDecrypted ;
var seedLockEncrypted = SeedLockEncrypted ;
var keyCopri = KeyCopri ;
try
{
seedLockDecrypted = Cipher . Decrypt (
keyCopri ,
seedLockEncrypted ) ;
}
catch ( System . Exception exception )
{
Log . ForContext < AuthCryptoHelper > ( ) . Error ( "Decrypting seed from lock failed. {Exception}" , exception ) ;
throw ;
}
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
Log . ForContext < AuthCryptoHelper > ( ) . Verbose ( $"Lock random number decrypted from {string.Join(" , ", seedLockEncrypted)} to {string.Join(" , ", seedLockDecrypted)} using {string.Join(" , ", keyCopri)}." ) ;
return seedLockDecrypted ;
}
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
public byte [ ] GetAccessKeyEncrypted ( )
{
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
var accessKey = GetSeedLock ( ) ;
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
if ( accessKey = = null | | accessKey . Length < = 0 )
{
Log . ForContext < AuthCryptoHelper > ( ) . Error ( "Creating access key failed, Key must not be null or empty." ) ;
throw new System . Exception ( ) ;
}
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
accessKey [ accessKey . Length - 1 ] + = 1 ;
2022-08-30 15:42:25 +02:00
2022-09-06 16:08:19 +02:00
var keyCopri = KeyCopri ;
byte [ ] acccessKeyEncrypted ;
try
{
acccessKeyEncrypted = Cipher . Encrypt (
keyCopri ,
accessKey ) ;
}
catch ( System . Exception exception )
{
Log . ForContext < AuthCryptoHelper > ( ) . Error ( "Encrypting access key failed. {Exception}" , exception ) ;
throw ;
}
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
Log . ForContext < AuthCryptoHelper > ( ) . Verbose ( $"Access key encrypted from {string.Join(" , ", accessKey)} to {string.Join(" , ", acccessKeyEncrypted)} using {string.Join(" , ", keyCopri)}." ) ;
return acccessKeyEncrypted ;
}
2021-05-13 17:07:16 +02:00
2022-09-06 16:08:19 +02:00
public byte [ ] KeyCopri { get ; }
}
2021-05-13 17:07:16 +02:00
}