From ceb50d012de1b218792f62fbf32e92984bb0e8ed Mon Sep 17 00:00:00 2001 From: murali-shris Date: Thu, 20 Jul 2023 23:02:38 +0530 Subject: [PATCH] feat: new app onboarding flow --- .../onboard/at_onboarding_service_impl.dart | 131 ++++++++++++------ .../src/util/at_onboarding_exceptions.dart | 6 - packages/at_onboarding_cli/pubspec.yaml | 4 +- 3 files changed, 89 insertions(+), 52 deletions(-) diff --git a/packages/at_onboarding_cli/lib/src/onboard/at_onboarding_service_impl.dart b/packages/at_onboarding_cli/lib/src/onboard/at_onboarding_service_impl.dart index 5f5910c21..fddf30376 100644 --- a/packages/at_onboarding_cli/lib/src/onboard/at_onboarding_service_impl.dart +++ b/packages/at_onboarding_cli/lib/src/onboard/at_onboarding_service_impl.dart @@ -108,45 +108,92 @@ class AtOnboardingServiceImpl implements AtOnboardingService { } try { - // authenticate into secondary using cram secret + //1. authenticate into secondary using cram secret bool isAtsignCramAuthenticated = (await atLookUpImpl .authenticate_cram(atOnboardingPreference.cramSecret)); - if (isAtsignCramAuthenticated) { - logger.info('Cram authentication successful'); - - /// 1. get pkam public key to be saved in secondary - final pkamKeyPair = await _getPkamKeyPair(); - - if (pkamKeyPair == null || - pkamKeyPair.publicKey == null || - pkamKeyPair.publicKey!.isEmpty) { - throw AtOnboardingException( - 'unable to generate pkam keypair/unable to fetch public key from secure element. Authmode ${atOnboardingPreference.authMode}'); - } - final enrollmentResult = await _enrollClient(atLookUpImpl, pkamKeyPair); - if (enrollmentResult == null || enrollmentResult.status != 'success') { - throw AtEnrollmentException( - 'initial enrollment failed. Enrollment status ${enrollmentResult.status}'); - } - if (enrollmentResult.status == 'success') { - logger.info('initial enrollment successful.Trying pkam with enrollmentId'); - await atLookUpImpl.close(); - atChops ??= _initAtChops(pkamKeyPair); - atLookUpImpl.atChops = atChops; - final pkamAuthResult = await atLookUpImpl.pkamAuthenticate( - enrollmentId: enrollmentResult.enrollmentId); - logger.finer('pkamAuthResult :$pkamAuthResult'); - } - } else { + if (!isAtsignCramAuthenticated) { throw AtActivateException( 'Cram authentication failed. Please check the cram key' ' and try again \n(or) contact support@atsign.com'); } + logger.info('Cram authentication successful'); + + // 2. get pkam public key to be saved in secondary + final pkamKeyPair = await _getPkamKeyPair(); + + if (pkamKeyPair == null || + pkamKeyPair.publicKey == null || + pkamKeyPair.publicKey!.isEmpty) { + throw AtOnboardingException( + 'unable to generate pkam keypair/unable to fetch public key from secure element. Authmode ${atOnboardingPreference.authMode}'); + } + + // 3. update pkam public key to server + String updatePkamPublicKeyCommand = + 'update:$AT_PKAM_PUBLIC_KEY ${pkamKeyPair.publicKey}\n'; + // set auth to false since connection is already cram authenticated + String? pkamUpdateResult = await atLookUpImpl + .executeCommand(updatePkamPublicKeyCommand, auth: false); + logger.info('PkamPublicKey update result: $pkamUpdateResult'); + + // 4. first enroll request + final enrollmentResult = await _enrollClient(atLookUpImpl, pkamKeyPair); + logger.info('enrollment result: $enrollmentResult'); + if (enrollmentResult == null || enrollmentResult.status != 'success') { + throw AtEnrollmentException( + 'initial enrollment failed. Enrollment status ${enrollmentResult.status}'); + } + + // 5. pkam auth with enroll id + var pkamAuthResult = false; + if (enrollmentResult.status == 'success') { + logger + .info('Initial enrollment success. Trying pkam with enrollmentId'); + await atLookUpImpl.close(); + atChops ??= _initAtChops(pkamKeyPair); + atLookUpImpl.atChops = atChops; + pkamAuthResult = await atLookUpImpl.pkamAuthenticate( + enrollmentId: enrollmentResult.enrollmentId); + logger.info('pkamAuthResult after enrollment:$pkamAuthResult'); + } + if (!pkamAuthResult) { + throw AtOnboardingException('pkam auth failed after enrollment'); + } + + // 6. generate encryption key pair and update public key to server + var encryptionKeyPair = _generateRsaKeypair(); + var encryptionPublicKeyVerbBuilder = KeysVerbBuilder('put') + ..visibility = 'public' + ..namespace = '__global' + ..keyType = EncryptionKeyType.rsa2048.name + ..keyName = 'encryption_${enrollmentResult.enrollmentId}' + ..value = encryptionKeyPair.publicKey.toString(); + // set auth to false since connection is already cram authenticated + logger.finer( + 'encryption public key command: ${encryptionPublicKeyVerbBuilder.buildCommand()}'); + // await atLookUpImpl.executeCommand(encryptionPublicKeyVerbBuilder.buildCommand(), auth: false); + // logger.info('encryption public key update result: $pkamUpdateResult'); + + // 7. generate self encryption key + var selfEncryptionKey = _generateAESKey(); + var encryptedSelfEncryptionKey = EncryptionUtil.encryptKey( + selfEncryptionKey, encryptionKeyPair.publicKey.toString()); + var selfEncryptionKeyVerbBuilder = KeysVerbBuilder('put') + ..visibility = 'self' + ..namespace = '__global' + ..appName = atOnboardingPreference.appName + ..deviceName = atOnboardingPreference.deviceName + ..keyType = EncryptionKeyType.aes256.name + ..encryptionKeyName = 'encryption_${enrollmentResult.enrollmentId}' + ..keyName = 'selfEncryption' + ..value = encryptedSelfEncryptionKey; + logger.finer( + 'self encryption key command: ${selfEncryptionKeyVerbBuilder.buildCommand()}'); } on Exception catch (e) { if (e.toString().contains('Auth failed')) { throw AtActivateException( - 'Cram authentication failed. Please check the cram key' + 'Authentication failed. Please check the cram key' ' and try again \n(or) contact support@atsign.com'); } logger.severe('Caught exception: $e'); @@ -164,13 +211,6 @@ class AtOnboardingServiceImpl implements AtOnboardingService { AtLookupImpl atLookUpImpl, PkamKeyPair pkamKeyPair) async { logger.info('inside _enrollClient'); - /// 1. update public key to secondary - String updateCommand = - 'update:$AT_PKAM_PUBLIC_KEY ${pkamKeyPair.publicKey}\n'; - String? pkamUpdateResult = - await atLookUpImpl.executeCommand(updateCommand, auth: false); - logger.info('PkamPublicKey update result: $pkamUpdateResult'); - var enrollNamespaces = ''; if (atOnboardingPreference.namespace != null) { enrollNamespaces = '${atOnboardingPreference.namespace},rw'; @@ -195,10 +235,10 @@ class AtOnboardingServiceImpl implements AtOnboardingService { Future> _generateKeyPairs() async { // generate user encryption keypair logger.info('Generating encryption keypair'); - var encryptionKeyPair = generateRsaKeypair(); + var encryptionKeyPair = _generateRsaKeypair(); //generate selfEncryptionKey - var selfEncryptionKey = generateAESKey(); + var selfEncryptionKey = _generateAESKey(); stdout.writeln( '[Information] Generating your encryption keys and .atKeys file\n'); @@ -208,7 +248,7 @@ class AtOnboardingServiceImpl implements AtOnboardingService { //generating pkamKeyPair only if authMode is keysFile if (atOnboardingPreference.authMode == PkamAuthMode.keysFile) { logger.info('Generating pkam keypair'); - var pkamRsaKeypair = generateRsaKeypair(); + var pkamRsaKeypair = _generateRsaKeypair(); atKeysMap[AuthKeyType.pkamPublicKey] = pkamRsaKeypair.publicKey.toString(); atKeysMap[AuthKeyType.pkamPrivateKey] = @@ -417,18 +457,18 @@ class AtOnboardingServiceImpl implements AtOnboardingService { return PkamKeyPair.create(pkamPublicKey); } logger.info('Generating pkam keypair'); - var pkamRsaKeypair = generateRsaKeypair(); + var pkamRsaKeypair = _generateRsaKeypair(); return PkamKeyPair.create(pkamRsaKeypair.publicKey.toString()) ..privateKey = pkamRsaKeypair.privateKey.toString(); } - ///generates random RSA keypair - RSAKeypair generateRsaKeypair() { + ///generates random RSA keypair with key size 2048 + RSAKeypair _generateRsaKeypair() { return RSAKeypair.fromRandom(); } ///generate random AES key - String generateAESKey() { + String _generateAESKey() { return AES(Key.fromSecureRandom(32)).key.base64; } @@ -581,4 +621,9 @@ class EnrollmentResult { String enrollmentId; String status; EnrollmentResult(this.enrollmentId, this.status); + + @override + String toString() { + return 'EnrollmentResult{enrollmentId: $enrollmentId, status: $status}'; + } } diff --git a/packages/at_onboarding_cli/lib/src/util/at_onboarding_exceptions.dart b/packages/at_onboarding_cli/lib/src/util/at_onboarding_exceptions.dart index 258715087..2329ecb28 100644 --- a/packages/at_onboarding_cli/lib/src/util/at_onboarding_exceptions.dart +++ b/packages/at_onboarding_cli/lib/src/util/at_onboarding_exceptions.dart @@ -24,9 +24,3 @@ class InvalidResourceException extends AtOnboardingException { {Intent? intent, ExceptionScenario? exceptionScenario}) : super(message, intent: intent, exceptionScenario: exceptionScenario); } - -class AtEnrollmentException extends AtOnboardingException { - AtEnrollmentException(message, - {Intent? intent, ExceptionScenario? exceptionScenario}) - : super(message, intent: intent, exceptionScenario: exceptionScenario); -} diff --git a/packages/at_onboarding_cli/pubspec.yaml b/packages/at_onboarding_cli/pubspec.yaml index 4fb607162..07d05727d 100644 --- a/packages/at_onboarding_cli/pubspec.yaml +++ b/packages/at_onboarding_cli/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: zxing2: ^0.2.0 image: ^4.0.17 crypton: ^2.0.3 - at_commons: ^3.0.45 + at_commons: ^3.0.51 encrypt: ^5.0.1 at_server_status: ^1.0.3 path: ^1.8.1 @@ -28,8 +28,6 @@ dependencies: at_chops: ^1.0.3 dependency_overrides: - at_commons: - path: ../../../at_tools/packages/at_commons at_chops: path: ../../packages/at_chops at_lookup: