Skip to content

Commit

Permalink
fix: at_onboarding_cli : Consume different ivs for encryptionPrivateK…
Browse files Browse the repository at this point in the history
…ey and selfEncryptionKey in apkam flow
  • Loading branch information
sitaram-kalluri committed Dec 12, 2024
1 parent 607894d commit 657a405
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 17 deletions.
3 changes: 3 additions & 0 deletions packages/at_onboarding_cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 1.8.1
- fix: Replace legacy IVs with random IVs for encrypting "defaultEncryptionPrivateKey" and "selfEncryptionKey" in APKAM flow
- build[deps]: upgrade at_persistence_secondary_server to v3.1.0
## 1.8.0
- feat: add `unrevoke` command to the activate CLI
- feat: add `delete` command to the activate CLI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,33 +253,67 @@ class AtOnboardingServiceImpl implements AtOnboardingService {
logProgress: logProgress,
);

var decryptedEncryptionPrivateKey = EncryptionUtil.decryptValue(
// Fetches encrypted "defaultEncryptionPrivateKey" from server. The first
// argument holds the "defaultEncryptionPrivateKey" and the second argument
// hold the Initialization Vector(IV) to decrypt the data.
// Defaults to null to support legacy IV for backward compatibility.
(String, String?) encryptedPrivateKey =
await _getEncryptionPrivateKeyFromServer(
enrollmentResponse.enrollmentId, _atLookUp!),
enrollmentResponse.atAuthKeys!.apkamSymmetricKey!);
enrollmentResponse.enrollmentId, _atLookUp!);

var decryptedEncryptionPrivateKey = EncryptionUtil.decryptValue(
encryptedPrivateKey.$1,
enrollmentResponse.atAuthKeys!.apkamSymmetricKey!,
ivBase64: encryptedPrivateKey.$2);

// Fetches encrypted "selfEncryptionKey" from server. The first
// argument holds the "selfEncryptionKey" and the second argument
// hold the Initialization Vector(IV) to decrypt the data.
// Defaults to null to support legacy IV for backward compatibility.
(String, String?) selfEncryptionKey = await _getSelfEncryptionKeyFromServer(
enrollmentResponse.enrollmentId, _atLookUp!);
var decryptedSelfEncryptionKey = EncryptionUtil.decryptValue(
await _getSelfEncryptionKeyFromServer(
enrollmentResponse.enrollmentId, _atLookUp!),
enrollmentResponse.atAuthKeys!.apkamSymmetricKey!);
selfEncryptionKey.$1, enrollmentResponse.atAuthKeys!.apkamSymmetricKey!,
ivBase64: selfEncryptionKey.$2);

enrollmentResponse.atAuthKeys!.defaultEncryptionPrivateKey =
decryptedEncryptionPrivateKey;
enrollmentResponse.atAuthKeys!.defaultSelfEncryptionKey =
decryptedSelfEncryptionKey;
}

Future<String> _getEncryptionPrivateKeyFromServer(
/// Retrieves the encryption private key and its associated initialization vector (IV)
/// from the server for a given enrollment.
///
/// The `privateKeyCommand` is constructed using the `enrollmentIdFromServer` and
/// `AtConstants.defaultEncryptionPrivateKey` with the format:
/// `'keys:get:keyName:<enrollmentId>.<defaultPrivateKey>.__manage$_atSign'`.
///
/// This method sends a command to the `atLookUp` service to retrieve the private key data
/// from the server, then parses the JSON result to extract the private key (`value`) and
/// the IV (`iv`).
///
/// Throws an [AtEnrollmentException] if:
/// - The private key returned from the server is `null` or empty.
/// - There is an exception during command execution.
///
/// Returns:
/// - A tuple containing:
/// - `encryptionPrivateKeyFromServer` - The encrypted private key string from the server.
/// - `encryptionPrivateKeyIV` - The associated IV string, if present.
Future<(String, String?)> _getEncryptionPrivateKeyFromServer(
String enrollmentIdFromServer, AtLookUp atLookUp) async {
var privateKeyCommand =
'keys:get:keyName:$enrollmentIdFromServer.${AtConstants.defaultEncryptionPrivateKey}.__manage$_atSign\n';
String encryptionPrivateKeyFromServer;
String? encryptionPrivateKeyIV;
try {
var getPrivateKeyResult =
await atLookUp.executeCommand(privateKeyCommand, auth: true);
getPrivateKeyResult = getPrivateKeyResult?.replaceFirst('data:', '');
var privateKeyResultJson = jsonDecode(getPrivateKeyResult!);
encryptionPrivateKeyFromServer = privateKeyResultJson['value'];
encryptionPrivateKeyIV = privateKeyResultJson['iv'];
if (encryptionPrivateKeyFromServer == null ||
encryptionPrivateKeyFromServer.isEmpty) {
throw AtEnrollmentException('$privateKeyCommand returned null/empty');
Expand All @@ -288,21 +322,46 @@ class AtOnboardingServiceImpl implements AtOnboardingService {
throw AtEnrollmentException(
'Exception while getting encrypted private key/self key from server: $e');
}
return encryptionPrivateKeyFromServer;
return (encryptionPrivateKeyFromServer, encryptionPrivateKeyIV);
}

Future<String> _getSelfEncryptionKeyFromServer(
/// Retrieves the self-encryption key and its associated initialization vector (IV)
/// from the server for a given enrollment.
///
/// The `selfEncryptionKeyCommand` is constructed using the `enrollmentIdFromServer`
/// and `AtConstants.defaultSelfEncryptionKey` in the format:
/// `'keys:get:keyName:<enrollmentId>.<defaultSelfEncryptionKey>.__manage$_atSign'`.
///
/// This method sends a command to the `atLookUp` service to retrieve the self-encryption key data
/// from the server, then parses the JSON result to extract the key (`value`) and
/// the IV (`iv`).
///
/// Throws an [AtEnrollmentException] if:
/// - The self-encryption key returned from the server is `null` or empty.
/// - There is an exception during the command execution.
///
/// Parameters:
/// - `enrollmentIdFromServer` - The enrollment ID used to request the self-encryption key.
/// - `atLookUp` - The [AtLookUp] instance to execute the server command.
///
/// Returns:
/// - A tuple containing:
/// - `selfEncryptionKeyFromServer` - The self-encryption key string retrieved from the server.
/// - `selfEncryptionKeyIV` - The associated IV string, if present.
Future<(String, String?)> _getSelfEncryptionKeyFromServer(
String enrollmentIdFromServer, AtLookUp atLookUp) async {
var selfEncryptionKeyCommand =
'keys:get:keyName:$enrollmentIdFromServer.${AtConstants.defaultSelfEncryptionKey}.__manage$_atSign\n';
String selfEncryptionKeyFromServer;
String? selfEncryptionKeyIV;
try {
var getSelfEncryptionKeyResult =
await atLookUp.executeCommand(selfEncryptionKeyCommand, auth: true);
getSelfEncryptionKeyResult =
getSelfEncryptionKeyResult?.replaceFirst('data:', '');
var selfEncryptionKeyResultJson = jsonDecode(getSelfEncryptionKeyResult!);
selfEncryptionKeyFromServer = selfEncryptionKeyResultJson['value'];
selfEncryptionKeyIV = selfEncryptionKeyResultJson['iv'];
if (selfEncryptionKeyFromServer == null ||
selfEncryptionKeyFromServer.isEmpty) {
throw AtEnrollmentException(
Expand All @@ -312,7 +371,7 @@ class AtOnboardingServiceImpl implements AtOnboardingService {
throw AtEnrollmentException(
'Exception while getting encrypted private key/self key from server: $e');
}
return selfEncryptionKeyFromServer;
return (selfEncryptionKeyFromServer, selfEncryptionKeyIV);
}

/// Pkam auth will be retried until server approves/denies/expires the enrollment
Expand Down
6 changes: 3 additions & 3 deletions packages/at_onboarding_cli/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: at_onboarding_cli
description: Dart tools for initial client onboarding, subsequent client enrollment, and enrollment management.
version: 1.8.0
version: 1.8.1
repository: https://github.com/atsign-foundation/at_libraries
homepage: https://atsign.com
documentation: https://docs.atsign.com/
Expand All @@ -21,14 +21,14 @@ dependencies:
meta: ^1.14.0
path: ^1.9.0
zxing2: ^0.2.0
at_auth: ^2.0.9
at_auth: ^2.0.10
at_chops: ^2.2.0
at_client: ^3.3.0
at_commons: ^5.0.2
at_lookup: ^3.0.49
at_server_status: ^1.0.5
at_utils: ^3.0.19
at_persistence_secondary_server: ^3.0.66
at_persistence_secondary_server: ^3.1.0
duration: ^4.0.3
crypto: ^3.0.5
chalkdart: ^2.0.9
Expand Down
5 changes: 1 addition & 4 deletions tests/at_onboarding_cli_functional_tests/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ dependency_overrides:
at_auth:
path: ../../packages/at_auth
at_onboarding_cli:
git:
url: https://github.com/atsign-foundation/at_libraries.git
path: packages/at_onboarding_cli
ref: at-onboarding-cli-apkam-different-ivs
path: ../../packages/at_onboarding_cli
at_commons:
path: ../../packages/at_commons
at_chops:
Expand Down

0 comments on commit 657a405

Please sign in to comment.