performInitialAuth method

  1. @override
Future<bool> performInitialAuth(
  1. String atSign,
  2. AtClientPreference atClientPreference
)
override

Implementation

@override
Future<bool> performInitialAuth(
    String atSign, AtClientPreference atClientPreference) async {
  var atLookupInitialAuth = AtLookupImpl(
      atSign, atClientPreference.rootDomain, atClientPreference.rootPort);
  // get existing keys from keychain
  final atsign = await _keyChainManager.readAtsign(name: atSign);
  var publicKey = atsign?.pkamPublicKey;
  var privateKey = atClientPreference.privateKey ??= atsign?.pkamPrivateKey;
  var encryptionPrivateKey = atsign?.encryptionPublicKey;

  // If cram secret is null, perform cram authentication
  if (atClientPreference.cramSecret != null) {
    logger.finer('private key is empty. Performing cram');
    var isCramSuccessful = await atLookupInitialAuth
        .authenticate_cram(atClientPreference.cramSecret);
    // If cram auth is not successful, return false.
    if (!isCramSuccessful) {
      return false;
    }

    RSAKeypair keypair;
    // If PKAM Authenticated is false, perform PKAM auth
    if (!_isPKAMAuthenticated) {
      // Generate keypair if not already generated
      if (privateKey == null || privateKey.isEmpty) {
        logger.finer('generating pkam key pair');
        keypair = _keyChainManager.generateKeyPair();
        privateKey = keypair.privateKey.toString();
        publicKey = keypair.publicKey.toString();
      }
      // send public key to remote Secondary server
      logger.finer('updating pkam public key to server');
      var updateCommand =
          'update:${AtConstants.atPkamPublicKey} $publicKey\n';
      // auth is false since already cram authenticated
      var pkamUpdateResult = await atLookupInitialAuth
          .executeCommand(updateCommand, auth: false);
      logger.finer('pkam update result:$pkamUpdateResult');
    } else {
      logger.finer('pkam auth already done');
      return true; //Auth already performed
    }
  }
  var pkamAuthResult = await atLookupInitialAuth.authenticate(privateKey);

  if (pkamAuthResult) {
    logger.finer('pkam auth is successful');
    _isPKAMAuthenticated = true;
    if (privateKey != null) {
      // Save pkam public/private key pair in keychain
      await _keyChainManager.storeCredentialToKeychain(atSign,
          secret: atClientPreference.cramSecret,
          privateKey: privateKey,
          publicKey: publicKey);
      // Generate key pair for encryption if not already present
      if (encryptionPrivateKey == null || encryptionPrivateKey == '') {
        logger
            .finer('generating encryption key pair and self encryption key');
        var encryptionKeyPair = _keyChainManager.generateKeyPair();
        var atSignItem = await _keyChainManager.readAtsign(name: atSign) ??
            AtsignKey(atSign: atSign);
        atSignItem = atSignItem.copyWith(
          encryptionPrivateKey: encryptionKeyPair.privateKey.toString(),
          encryptionPublicKey: encryptionKeyPair.publicKey.toString(),
          selfEncryptionKey: EncryptionUtil.generateAESKey(),
        );
        await _keyChainManager.storeAtSign(atSign: atSignItem);
      }
      var deleteBuilder = DeleteVerbBuilder()
        ..atKey = (AtKey()..key = AtConstants.atCramSecret);
      var deleteResponse =
          await atLookupInitialAuth.executeVerb(deleteBuilder);
      logger.finer('cram secret delete response : $deleteResponse');
    }
  }
  // Close the connection on atLookupInitalAuth.
  await atLookupInitialAuth.close();
  return true;
}