Skip to content

Commit

Permalink
Merge pull request #715 from atsign-foundation/604-support-password-p…
Browse files Browse the repository at this point in the history
…rotected-atkeys-at-auth-changes

feat: at_auth : Add "passPhrase" in "AtAuthRequest" to support password protected atKeys file
  • Loading branch information
sitaram-kalluri authored Nov 20, 2024
2 parents 8e7d450 + d600977 commit 0cba6c1
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 31 deletions.
8 changes: 8 additions & 0 deletions packages/at_auth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 2.0.8
- feat: Add "passPhrase" in "AtAuthRequest" to support password protected atKeys file
- build[deps]: Upgraded the following packages:
- at_commons to v5.0.2
- at_auth to v2.2.0
- lints to v5.0.0
- test to v1.25.8
- mocktail to v1.0.4
## 2.0.7
- build[deps]: Upgraded the following packages:
- at_commons to v5.0.0
Expand Down
12 changes: 2 additions & 10 deletions packages/at_auth/lib/at_auth.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,27 @@
/// The [AtAuth] package contains common logic for onboarding/authenticating an atSign to a secondary server
library at_auth;
library;

import 'package:at_auth/src/auth_interface.dart';
import 'package:at_auth/src/auth_interface_impl.dart';

export 'src/at_auth_base.dart';
export 'src/auth_constants.dart';

export 'src/auth/at_auth_request.dart';
export 'src/auth/at_auth_response.dart';

export 'src/auth_constants.dart';
// Contains method related to submit, approve and deny an enrollment.
export 'src/enroll/at_enrollment_base.dart';

// Contains fields related to enrollment response received from the secondary server
export 'src/enroll/at_enrollment_response.dart';

// The abstract class contains fields related to enrollment request
export 'src/enroll/base_enrollment_request.dart';

/// The class contains fields to submit enrollment request for APKAM keys which generate keys for
/// an application with restricted access to the namespaces.
export 'src/enroll/enrollment_request.dart';

/// This class serves as the entity responsible for either approving or denying an enrollment request
export 'src/enroll/enrollment_request_decision.dart';

/// The class stores enrollment request details. It notifies the approving app upon receiving a
/// request from the requesting app, for approval or denial.
export 'src/enroll/enrollment_server_response.dart';

export 'src/exception/at_auth_exceptions.dart';
export 'src/keys/at_auth_keys.dart';
export 'src/onboard/at_onboarding_request.dart';
Expand Down
53 changes: 38 additions & 15 deletions packages/at_auth/lib/src/at_auth_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@ class AtAuthImpl implements AtAuth {
AtAuthKeys? atAuthKeys;
var enrollmentIdFromRequest = atAuthRequest.enrollmentId;
if (atAuthRequest.atKeysFilePath != null) {
atAuthKeys = _decryptAtKeysFile(
await _readAtKeysFile(atAuthRequest.atKeysFilePath),
atAuthRequest.authMode);
atAuthKeys = await _prepareAtAuthKeysFromFilePath(atAuthRequest);
} else if (atAuthRequest.encryptedKeysMap != null) {
atAuthKeys = _decryptAtKeysFile(
atAuthKeys = _decryptAtKeysWithSelfEncKey(
atAuthRequest.encryptedKeysMap!, PkamAuthMode.keysFile);
} else {
atAuthKeys = atAuthRequest.atAuthKeys;
Expand Down Expand Up @@ -247,7 +245,7 @@ class AtAuthImpl implements AtAuth {
return enrollmentIdFromServer!;
}

AtAuthKeys _decryptAtKeysFile(
AtAuthKeys _decryptAtKeysWithSelfEncKey(
Map<String, dynamic> jsonData, PkamAuthMode authMode) {
var securityKeys = AtAuthKeys();
String decryptionKey = jsonData[auth_constants.defaultSelfEncryptionKey]!;
Expand Down Expand Up @@ -285,21 +283,46 @@ class AtAuthImpl implements AtAuth {

///method to read and return data from .atKeysFile
///returns map containing encryption keys
Future<Map<String, String>> _readAtKeysFile(String? atKeysFilePath) async {
if (atKeysFilePath == null || atKeysFilePath.isEmpty) {
Future<AtAuthKeys> _prepareAtAuthKeysFromFilePath(
AtAuthRequest atAuthRequest) async {
if (atAuthRequest.atKeysFilePath == null ||
atAuthRequest.atKeysFilePath!.isEmpty) {
throw AtException(
'atKeys filePath is empty. atKeysFile is required to authenticate');
}
if (!File(atKeysFilePath).existsSync()) {
if (!File(atAuthRequest.atKeysFilePath!).existsSync()) {
throw AtException(
'provided keys file does not exist. Please check whether the file path $atKeysFilePath is valid');
'provided keys file does not exist. Please check whether the file path ${atAuthRequest.atKeysFilePath} is valid');
}
String atAuthData = await File(atKeysFilePath).readAsString();
Map<String, String> jsonData = <String, String>{};
json.decode(atAuthData).forEach((String key, dynamic value) {
jsonData[key] = value.toString();
});
return jsonData;

String atAuthData =
await File(atAuthRequest.atKeysFilePath!).readAsString();
Map<String, dynamic> decodedAtKeysData = jsonDecode(atAuthData);
// If it contains "iv(InitializationVector)", it means the data is encrypted with a
// passphrase. Decrypt it.
if (decodedAtKeysData.containsKey('iv') &&
atAuthRequest.passPhrase.isNullOrEmpty) {
throw AtDecryptionException(
'Pass Phrase is required for password protected atKeys file');
}
if (decodedAtKeysData.containsKey('iv')) {
_logger.info(
'Found encrypted atKeys files. Decrypting with the given pass-phrase');
AtEncrypted atEncrypted = AtEncrypted.fromJson(decodedAtKeysData);

if (atEncrypted.hashingAlgoType == null) {
throw AtDecryptionException(
'Hashing algo type is required for decryption of password protected atKeys file');
}

String decryptedAtKeys =
await AtKeysCrypto.fromHashingAlgorithm(atEncrypted.hashingAlgoType!)
.decrypt(atEncrypted, atAuthRequest.passPhrase!);
decodedAtKeysData = jsonDecode(decryptedAtKeys);
}
// This is to decrypt the atKeys encrypted with self Encryption key.
return _decryptAtKeysWithSelfEncKey(
decodedAtKeysData, atAuthRequest.authMode);
}

AtAuthKeys _generateKeyPairs(PkamAuthMode authMode, {String? publicKeyId}) {
Expand Down
3 changes: 3 additions & 0 deletions packages/at_auth/lib/src/auth/at_auth_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ class AtAuthRequest {

/// Hashing algorithm to use for pkam authentication
HashingAlgoType hashingAlgoType = HashingAlgoType.sha256;

/// The pass phrase to password protect the AtKeys file.
String? passPhrase;
}
1 change: 1 addition & 0 deletions packages/at_auth/lib/src/keys/at_auth_keys.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AtAuthKeys {

AtAuthKeys();

@Deprecated('Use toJson()')
Map<String, String?> toMap() {
var keysMap = <String, String?>{};
keysMap[auth_constants.apkamPrivateKey] = apkamPrivateKey;
Expand Down
12 changes: 6 additions & 6 deletions packages/at_auth/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: at_auth
description: Package that implements common logic for onboarding/authenticating an atsign to a secondary server
version: 2.0.7
version: 2.0.8
homepage: https://atsign.com/
repository: https://github.com/atsign-foundation/at_libraries

Expand All @@ -9,15 +9,15 @@ environment:

dependencies:
args: ^2.4.1
at_commons: ^5.0.0
at_commons: ^5.0.2
at_lookup: ^3.0.49
at_chops: ^2.0.1
at_chops: ^2.2.0
at_utils: ^3.0.19
meta: ^1.8.0
at_demo_data: ^1.0.3
crypton: ^2.2.1

dev_dependencies:
lints: ^2.0.0
test: ^1.24.7
mocktail: ^0.3.0
lints: ^5.0.0
test: ^1.25.8
mocktail: ^1.0.4

0 comments on commit 0cba6c1

Please sign in to comment.