Skip to content

Commit

Permalink
fix!: Fixed incorrect TOTP generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Skyost committed Jul 8, 2024
1 parent a34df82 commit 42c6801
Show file tree
Hide file tree
Showing 21 changed files with 52 additions and 1,730 deletions.
12 changes: 12 additions & 0 deletions bin/generate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,17 @@ class AppContributorPlan {
static const String stripeCustomerPortalLink = kDebugMode ? 'https://billing.stripe.com/p/login/test_28o5mbdMd6K5dQAcMM' : 'https://billing.stripe.com/p/login/dR65lCdFwb7d7ledQQ';
}
/// Contains all Argon2 parameters.
class Argon2Parameters {
/// The number of iterations to perform.
static const int iterations = 3;
/// The degree of parallelism (ie. number of threads).
static const int parallelism = 8;
/// The amount of memory (in kibibytes) to use.
static const int memorySize = 1 << 18;
}
''');
}
2 changes: 1 addition & 1 deletion lib/model/backup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class BackupStore extends AsyncNotifier<List<Backup>> {
result.add(Backup._(ref: ref, dateTime: dateTime));
}
}
return result;
return result..sort((a, b) => a.dateTime.compareTo(b.dateTime));
}

/// Returns the backup directory.
Expand Down
18 changes: 11 additions & 7 deletions lib/model/crypto.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import 'dart:typed_data';

import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hashlib/hashlib.dart';
import 'package:open_authenticator/app.dart';
import 'package:open_authenticator/model/app_unlock/method.dart';
import 'package:open_authenticator/model/settings/app_unlock_method.dart';
import 'package:open_authenticator/utils/argon2/base.dart';
import 'package:open_authenticator/utils/argon2/parameters.dart';
import 'package:open_authenticator/utils/utils.dart';
import 'package:simple_secure_storage/simple_secure_storage.dart';
import 'package:webcrypto/webcrypto.dart';
Expand Down Expand Up @@ -109,11 +109,13 @@ class CryptoStore {
/// Generates a derived key from the given [password] and save it to the device secure storage.
/// Also returns the salt that has been used.
static Future<Uint8List> _deriveKey(String password, Salt salt) async {
Argon2BytesGenerator argon2 = Argon2BytesGenerator();
argon2.init(Argon2Parameters(Argon2Parameters.argon2ID, salt.value));
Uint8List key = Uint8List(_keyLength);
argon2.generateBytesFromString(password, key);
return key;
Argon2 argon2 = Argon2(
iterations: Argon2Parameters.iterations,
memorySizeKB: Argon2Parameters.memorySize,
parallelism: Argon2Parameters.parallelism,
salt: salt.value,
);
return argon2.convert(utf8.encode(password)).bytes;
}

/// Encrypts the given text.
Expand Down Expand Up @@ -145,6 +147,8 @@ class CryptoStore {
/// Checks if the given password is valid.
Future<bool> checkPasswordValidity(String password) async {
Uint8List derivedKey = await _deriveKey(password, salt);
print('Original : ${await key.exportRawKey()}');
print('Derived key : ${derivedKey}');
return memEquals(derivedKey, await key.exportRawKey());
}

Expand Down
10 changes: 5 additions & 5 deletions lib/model/totp/algorithm.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import 'package:hashlib/hashlib.dart' as hashlib;
import 'package:open_authenticator/utils/utils.dart';
import 'package:totp/totp.dart' as totp_lib;

/// Allows to avoid conflicts with [totp_lib.Algorithm].
enum Algorithm {
/// The SHA1 algorithm.
sha1(totp_lib.Algorithm.sha1),
sha1(hashlib.sha1),

/// The SHA256 algorithm.
sha256(totp_lib.Algorithm.sha256),
sha256(hashlib.sha256),

/// The SHA512 algorithm.
sha512(totp_lib.Algorithm.sha512);
sha512(hashlib.sha512);

/// The corresponding [totp_lib.Algorithm] enum entry.
final totp_lib.Algorithm mapsTo;
final hashlib.BlockHashBase mapsTo;

/// Creates a new algorithm instance.
const Algorithm(this.mapsTo);
Expand Down
9 changes: 5 additions & 4 deletions lib/model/totp/decrypted.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:hashlib/hashlib.dart' as hashlib;
import 'package:hashlib_codecs/hashlib_codecs.dart';
import 'package:open_authenticator/model/crypto.dart';
import 'package:open_authenticator/model/totp/algorithm.dart';
import 'package:open_authenticator/model/totp/totp.dart';
import 'package:totp/totp.dart' as totp_lib;
import 'package:uuid/uuid.dart';

/// Represents a TOTP, in its decrypted state.
Expand Down Expand Up @@ -45,9 +46,9 @@ class DecryptedTotp extends Totp {
String? get imageUrl => decryptedData.decryptedImageUrl;

/// Returns the [totp_lib.Totp] instance.
totp_lib.Totp get generator => totp_lib.Totp.fromBase32(
secret: secret,
algorithm: (algorithm ?? Totp.kDefaultAlgorithm).mapsTo,
hashlib.TOTP get generator => hashlib.TOTP(
fromBase32(secret),
algo: (algorithm ?? Totp.kDefaultAlgorithm).mapsTo,
digits: digits ?? Totp.kDefaultDigits,
period: validity ?? Totp.kDefaultValidity,
);
Expand Down
2 changes: 1 addition & 1 deletion lib/model/totp/totp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Totp extends Equatable implements Comparable<Totp> {
static const String kDigitsKey = 'digits';

/// The validity key.
static const String kValidityKey = 'validity';
static const String kValidityKey = 'period';

/// The image URL key.
static const String kImageUrlKey = 'imageUrl';
Expand Down
Loading

0 comments on commit 42c6801

Please sign in to comment.