-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: modified examples for apkam enrollment
- Loading branch information
1 parent
5b07733
commit 1fcd19d
Showing
8 changed files
with
228 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
List of steps to run the examples for checking apkam enrollment | ||
|
||
1. Onboard an atsign which has privilege to approve/deny enrollments | ||
dart example/onboard.dart <atsign> <path_store_keys_file> | ||
e.g. dart example/onboard.dart @alice🛠 /home/alice/.atsign/@alice🛠_wavikey.atKeys | ||
2. Authenticate using the onboarded atsign | ||
dart example/apkam_authenticate.dart <atsign> <path_of_keys_file_from_#1> | ||
e.g. dart example/apkam_authenticate.dart @alice🛠 /home/alice/.atsign/@alice🛠_wavikey.atKeys | ||
3. Run client to approve enrollments | ||
dart example/enroll_app_listen.dart <atsign> <path_of_keys_file_from_#1> | ||
e.g dart example/enroll_app_listen.dart @alice🛠 /home/alice/.atsign/@alice🛠_wavikey.atKeys | ||
4. Get OTP for enrollment | ||
- 4.1 Pkam through ssl client | ||
pkam:enrollmentId:<enrollmentId>:<pkamSignature> | ||
enrollmentId - get from the .atKeys file | ||
pkamChallenge - generate using the below commnd | ||
at_tools/packages/at_pkam> | ||
dart bin/main.dart -p <keys_file_path> <from_response> | ||
e.g dart bin/main.dart -p /home/alice/.atsign/@alice🛠_wavikey.atKeys -r _70138292-07b5-4e47-8c94-e02e38220775@alice🛠:883ea0aa-c526-400a-926e-48cae9281de9 | ||
- 4.2 Once authenticated run otp:get | ||
5. Request enrollment | ||
- 5.1 Submit enrollment from new client | ||
dart example/apkam_enroll.dart <atsign> <path_to_store_keys_file> <otp> | ||
e.g. dart example/apkam_enroll.dart @alice🛠 /home/murali/.atsign/@alice🛠_buzzkey.atKeys DY4UT4 | ||
- 5.2 Approve the enrollment from the client from #3 | ||
- 5.3 Enrollment should be successful and keys file stored in the path specified | ||
6. Authenticate using the enrolled keys file | ||
- 6.1 dart example/onboard.dart <atsign> <path_of_keys_file_from_#5.1> | ||
|
||
|
23 changes: 17 additions & 6 deletions
23
packages/at_onboarding_cli/example/apkam_authenticate.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,32 @@ | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
|
||
import 'package:at_commons/at_commons.dart'; | ||
import 'package:at_onboarding_cli/at_onboarding_cli.dart'; | ||
import 'package:at_utils/at_logger.dart'; | ||
|
||
Future<void> main() async { | ||
// final enrollIdFromServer = '867307c7-53bd-4736-8fe7-1520de58ce78'; | ||
AtSignLogger.root_level = 'finest'; | ||
final atSign = '@alice🛠'; | ||
Future<void> main(List<String> args) async { | ||
AtSignLogger.root_level = 'info'; | ||
final atSign = args[0]; | ||
AtOnboardingPreference atOnboardingPreference = AtOnboardingPreference() | ||
..namespace = | ||
'wavi' // unique identifier that can be used to identify data from your app | ||
..atKeysFilePath = '/home/murali/.atsign/@alice🛠_key.atKeys' | ||
..atKeysFilePath = args[1] | ||
..rootDomain = 'vip.ve.atsign.zone'; | ||
AtOnboardingService? onboardingService = AtOnboardingServiceImpl( | ||
atSign, atOnboardingPreference); | ||
atSign, atOnboardingPreference, | ||
enrollmentId: _getEnrollmentIdFromKeysFile(args[1])); | ||
await onboardingService.authenticate(); // when authenticating | ||
// AtLookUp? atLookup = onboardingService.atLookUp; | ||
// AtClient? client = onboardingService.atClient; | ||
// print(await client?.getKeys()); | ||
// print(await atLookup?.scan(regex: 'publickey')); | ||
// await onboardingService.close(); | ||
} | ||
|
||
String _getEnrollmentIdFromKeysFile(String keysFilePath) { | ||
String atAuthData = File(keysFilePath).readAsStringSync(); | ||
final enrollmentId = jsonDecode(atAuthData)[AtConstants.enrollmentId]; | ||
print('**** enrollmentId: $enrollmentId'); | ||
return enrollmentId; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,33 @@ | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
|
||
import 'package:at_client/at_client.dart'; | ||
import 'package:at_onboarding_cli/at_onboarding_cli.dart'; | ||
import 'package:at_utils/at_logger.dart'; | ||
|
||
Future<void> main() async { | ||
Future<void> main(List<String> args) async { | ||
AtSignLogger.root_level = 'finer'; | ||
final atSign = '@alice'; | ||
final atSign = args[0]; | ||
AtOnboardingPreference atOnboardingPreference = AtOnboardingPreference() | ||
..namespace = | ||
'buzz' // unique identifier that can be used to identify data from your app | ||
..atKeysFilePath = '/home/user/atsign/alice_buzzkey.atKeys' | ||
..atKeysFilePath = args[1] | ||
..appName = 'buzz' | ||
..deviceName = 'iphone' | ||
..rootDomain = 'vip.ve.atsign.zone'; | ||
..rootDomain = 'vip.ve.atsign.zone' | ||
..apkamAuthRetryDurationMins = 3; | ||
AtOnboardingService? onboardingService = | ||
AtOnboardingServiceImpl(atSign, atOnboardingPreference); | ||
Map<String, String> namespaces = {"buzz": "rw"}; | ||
// run totp:get from enrolled client and pass the otp | ||
var enrollmentResponse = | ||
await onboardingService.enroll('buzz', 'iphone', "068881", namespaces); | ||
await onboardingService.enroll('buzz', 'iphone', args[2], namespaces); | ||
print('enrollmentResponse: $enrollmentResponse'); | ||
} | ||
|
||
String _getEnrollmentIdFromKeysFile(String keysFilePath) { | ||
String atAuthData = File(keysFilePath).readAsStringSync(); | ||
final enrollmentId = jsonDecode(atAuthData)[AtConstants.enrollmentId]; | ||
print('**** enrollmentId: $enrollmentId'); | ||
return enrollmentId; | ||
} |
137 changes: 137 additions & 0 deletions
137
packages/at_onboarding_cli/example/enroll_app_listen.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import 'dart:convert'; | ||
|
||
import 'package:at_auth/at_auth.dart'; | ||
import 'package:at_chops/at_chops.dart'; | ||
import 'package:at_client/at_client.dart'; | ||
import 'dart:io'; | ||
import 'package:at_auth/src/auth_constants.dart' as auth_constants; | ||
|
||
import 'atsign_preference.dart'; | ||
|
||
/// dart enroll_app_listen.dart <atsign> <path_to_key_file> | ||
void main(List<String> arguments) async { | ||
var aliceAtSign = arguments[0]; | ||
try { | ||
var atAuthKeys = _decryptAtKeysFile(await _readAtKeysFile(arguments[1])); | ||
var atChops = _createAtChops(atAuthKeys); | ||
final atClientManager = await AtClientManager.getInstance() | ||
.setCurrentAtSign( | ||
aliceAtSign, | ||
'wavi', | ||
AtSignPreference.getAlicePreference( | ||
aliceAtSign, atAuthKeys.enrollmentId!), | ||
atChops: atChops, | ||
enrollmentId: atAuthKeys.enrollmentId); | ||
|
||
// alice - listen for notification | ||
atClientManager.atClient.notificationService | ||
.subscribe(regex: '.__manage') | ||
.listen((notification) { | ||
_notificationCallback(notification, atClientManager.atClient, atAuthKeys); | ||
}); | ||
} on Exception catch (e, trace) { | ||
print(e.toString()); | ||
print(trace); | ||
} | ||
|
||
print('end of test'); | ||
} | ||
|
||
Future<void> _notificationCallback(AtNotification notification, | ||
AtClient atClient, AtAuthKeys atAuthKeys) async { | ||
print('alice enroll notification received: ${notification.toString()}'); | ||
final notificationKey = notification.key; | ||
final enrollmentId = | ||
notificationKey.substring(0, notificationKey.indexOf('.new.enrollments')); | ||
print('Approve enrollmentId $enrollmentId?'); | ||
String? approveResponse = stdin.readLineSync(); | ||
print('approved?: $approveResponse'); | ||
var enrollRequest; | ||
var enrollParamsJson = {}; | ||
enrollParamsJson['enrollmentId'] = enrollmentId; | ||
if (approveResponse == 'yes') { | ||
final encryptedApkamSymmetricKey = | ||
jsonDecode(notification.value!)['encryptedApkamSymmetricKey']; | ||
final apkamSymmetricKey = EncryptionUtil.decryptKey( | ||
encryptedApkamSymmetricKey, atAuthKeys.defaultEncryptionPrivateKey!); | ||
print('decrypted apkam symmetric key: $apkamSymmetricKey'); | ||
var encryptedDefaultPrivateEncKey = EncryptionUtil.encryptValue( | ||
atAuthKeys.defaultEncryptionPrivateKey!, apkamSymmetricKey); | ||
var encryptedDefaultSelfEncKey = EncryptionUtil.encryptValue( | ||
atAuthKeys.defaultSelfEncryptionKey!, apkamSymmetricKey); | ||
enrollParamsJson['encryptedDefaultEncryptedPrivateKey'] = | ||
encryptedDefaultPrivateEncKey; | ||
enrollParamsJson['encryptedDefaultSelfEncryptionKey'] = | ||
encryptedDefaultSelfEncKey; | ||
enrollRequest = 'enroll:approve:${jsonEncode(enrollParamsJson)}\n'; | ||
} else { | ||
enrollRequest = 'enroll:deny:${jsonEncode(enrollParamsJson)}\n'; | ||
} | ||
print('enroll request to server: $enrollRequest'); | ||
String? enrollResponse = await atClient | ||
.getRemoteSecondary()! | ||
.executeCommand(enrollRequest, auth: true); | ||
print('enrollResponse: $enrollResponse'); | ||
} | ||
|
||
AtAuthKeys _decryptAtKeysFile(Map<String, String> jsonData) { | ||
var securityKeys = AtAuthKeys(); | ||
String decryptionKey = jsonData[auth_constants.defaultSelfEncryptionKey]!; | ||
var atChops = | ||
AtChopsImpl(AtChopsKeys()..selfEncryptionKey = AESKey(decryptionKey)); | ||
securityKeys.defaultEncryptionPublicKey = atChops | ||
.decryptString(jsonData[auth_constants.defaultEncryptionPublicKey]!, | ||
EncryptionKeyType.aes256, | ||
keyName: 'selfEncryptionKey', iv: AtChopsUtil.generateIVLegacy()) | ||
.result; | ||
securityKeys.defaultEncryptionPrivateKey = atChops | ||
.decryptString(jsonData[auth_constants.defaultEncryptionPrivateKey]!, | ||
EncryptionKeyType.aes256, | ||
keyName: 'selfEncryptionKey', iv: AtChopsUtil.generateIVLegacy()) | ||
.result; | ||
securityKeys.defaultSelfEncryptionKey = decryptionKey; | ||
securityKeys.apkamPublicKey = atChops | ||
.decryptString( | ||
jsonData[auth_constants.apkamPublicKey]!, EncryptionKeyType.aes256, | ||
keyName: 'selfEncryptionKey', iv: AtChopsUtil.generateIVLegacy()) | ||
.result; | ||
securityKeys.apkamPrivateKey = atChops | ||
.decryptString( | ||
jsonData[auth_constants.apkamPrivateKey]!, EncryptionKeyType.aes256, | ||
keyName: 'selfEncryptionKey', iv: AtChopsUtil.generateIVLegacy()) | ||
.result; | ||
securityKeys.apkamSymmetricKey = jsonData[auth_constants.apkamSymmetricKey]; | ||
securityKeys.enrollmentId = jsonData[AtConstants.enrollmentId]; | ||
return securityKeys; | ||
} | ||
|
||
Future<Map<String, String>> _readAtKeysFile(String? atKeysFilePath) async { | ||
if (atKeysFilePath == null || atKeysFilePath.isEmpty) { | ||
throw AtException( | ||
'atKeys filePath is empty. atKeysFile is required to authenticate'); | ||
} | ||
if (!File(atKeysFilePath).existsSync()) { | ||
throw AtException( | ||
'provided keys file does not exist. Please check whether the file path $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; | ||
} | ||
|
||
AtChops _createAtChops(AtAuthKeys atKeysFile) { | ||
final atEncryptionKeyPair = AtEncryptionKeyPair.create( | ||
atKeysFile.defaultEncryptionPublicKey!, | ||
atKeysFile.defaultEncryptionPrivateKey!); | ||
final atPkamKeyPair = AtPkamKeyPair.create( | ||
atKeysFile.apkamPublicKey!, atKeysFile.apkamPrivateKey!); | ||
final atChopsKeys = AtChopsKeys.create(atEncryptionKeyPair, atPkamKeyPair); | ||
if (atKeysFile.apkamSymmetricKey != null) { | ||
atChopsKeys.apkamSymmetricKey = AESKey(atKeysFile.apkamSymmetricKey!); | ||
} | ||
atChopsKeys.selfEncryptionKey = AESKey(atKeysFile.defaultSelfEncryptionKey!); | ||
return AtChopsImpl(atChopsKeys); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters