From c6036988cd0c0ce0695c42cf9de79f3b00f2afe0 Mon Sep 17 00:00:00 2001 From: Murali Date: Thu, 5 Dec 2024 15:33:44 +0530 Subject: [PATCH 1/5] fix: apkam add IV to self encryption key and encryption private key data in keystore --- .../lib/src/verb/handler/enroll_verb_handler.dart | 6 ++++++ packages/at_secondary_server/pubspec.yaml | 7 +++++++ tests/at_functional_test/test/enroll_verb_test.dart | 9 ++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart b/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart index 0677432e0..b64b5bf65 100644 --- a/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart +++ b/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart @@ -409,12 +409,18 @@ class EnrollVerbHandler extends AbstractVerbHandler { String newEnrollmentId, EnrollParams enrollParams, String atSign) async { var privateKeyJson = {}; privateKeyJson['value'] = enrollParams.encryptedDefaultEncryptionPrivateKey; + if (enrollParams.encPrivateKeyIV != null) { + privateKeyJson['iv'] = enrollParams.encPrivateKeyIV; + } await keyStore.put( '$newEnrollmentId.${AtConstants.defaultEncryptionPrivateKey}.$enrollManageNamespace$atSign', AtData()..data = jsonEncode(privateKeyJson), skipCommit: true); var selfKeyJson = {}; selfKeyJson['value'] = enrollParams.encryptedDefaultSelfEncryptionKey; + if (enrollParams.selfEncKeyIV != null) { + selfKeyJson['iv'] = enrollParams.selfEncKeyIV; + } await keyStore.put( '$newEnrollmentId.${AtConstants.defaultSelfEncryptionKey}.$enrollManageNamespace$atSign', AtData()..data = jsonEncode(selfKeyJson), diff --git a/packages/at_secondary_server/pubspec.yaml b/packages/at_secondary_server/pubspec.yaml index e30b53f07..7fdb4786a 100644 --- a/packages/at_secondary_server/pubspec.yaml +++ b/packages/at_secondary_server/pubspec.yaml @@ -34,6 +34,13 @@ dependencies: yaml: 3.1.2 logging: 1.2.0 +dependency_overrides: + at_commons: + git: + url: https://github.com/atsign-foundation/at_libraries.git + path: packages/at_commons + ref: apkam_iv_issue_fix + dev_dependencies: build_runner: ^2.3.3 test: ^1.25.9 diff --git a/tests/at_functional_test/test/enroll_verb_test.dart b/tests/at_functional_test/test/enroll_verb_test.dart index 004a31a10..da84bbd87 100644 --- a/tests/at_functional_test/test/enroll_verb_test.dart +++ b/tests/at_functional_test/test/enroll_verb_test.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; +import 'package:at_chops/at_chops.dart'; import 'package:at_commons/at_commons.dart'; import 'package:at_demo_data/at_demo_data.dart' as at_demos; import 'package:at_demo_data/at_demo_data.dart'; @@ -387,8 +388,12 @@ void main() { var secondEnrollId = enrollJson['enrollmentId']; // connect to the first client to approve the enroll request + final encryptionPrivateKeyIV = + base64Encode(AtChopsUtil.generateRandomIV(16).ivBytes); + final selfEncryptionKeyIV = + base64Encode(AtChopsUtil.generateRandomIV(16).ivBytes); String approveResponse = (await firstAtSignConnection.sendRequestToServer( - 'enroll:approve:{"enrollmentId":"$secondEnrollId","encryptedDefaultEncryptionPrivateKey":"${apkamEncryptedKeysMap['encryptedDefaultEncPrivateKey']}","encryptedDefaultSelfEncryptionKey": "${apkamEncryptedKeysMap['encryptedSelfEncKey']}"}')) + 'enroll:approve:{"enrollmentId":"$secondEnrollId","encryptedDefaultEncryptionPrivateKey":"${apkamEncryptedKeysMap['encryptedDefaultEncPrivateKey']}","encPrivateKeyIV":"$encryptionPrivateKeyIV","encryptedDefaultSelfEncryptionKey": "${apkamEncryptedKeysMap['encryptedSelfEncKey']}","selfEncKeyIV":"$selfEncryptionKeyIV"}')) .replaceFirst('data:', ''); var approveJson = jsonDecode(approveResponse); expect(approveJson['status'], 'approved'); @@ -404,6 +409,7 @@ void main() { var selfKey = '$secondEnrollId.default_self_enc_key.__manage$firstAtSign'; String selfKeyResponse = await socketConnection2.sendRequestToServer('keys:get:self'); + print('** selfKeyResponse: $selfKeyResponse'); expect(selfKeyResponse.contains(selfKey), true); // keys:get:private should return private encryption key @@ -411,6 +417,7 @@ void main() { '$secondEnrollId.default_enc_private_key.__manage$firstAtSign'; String privateKeyResponse = await socketConnection2.sendRequestToServer('keys:get:private'); + print('** privateKeyResponse: $privateKeyResponse'); expect(privateKeyResponse.contains(privateKey), true); }); From 3dec0cb7e7421e8316a6be948edf4a73d07883ab Mon Sep 17 00:00:00 2001 From: Murali Date: Thu, 5 Dec 2024 15:46:48 +0530 Subject: [PATCH 2/5] fix: add check in functional test --- tests/at_functional_test/test/enroll_verb_test.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/at_functional_test/test/enroll_verb_test.dart b/tests/at_functional_test/test/enroll_verb_test.dart index da84bbd87..38172f8eb 100644 --- a/tests/at_functional_test/test/enroll_verb_test.dart +++ b/tests/at_functional_test/test/enroll_verb_test.dart @@ -409,15 +409,16 @@ void main() { var selfKey = '$secondEnrollId.default_self_enc_key.__manage$firstAtSign'; String selfKeyResponse = await socketConnection2.sendRequestToServer('keys:get:self'); - print('** selfKeyResponse: $selfKeyResponse'); expect(selfKeyResponse.contains(selfKey), true); + String selfKeyGetResponse = await socketConnection2 + .sendRequestToServer('keys:get:keyName:$selfKey'); + print('selfKeyGetResponse: $selfKeyGetResponse'); // keys:get:private should return private encryption key var privateKey = '$secondEnrollId.default_enc_private_key.__manage$firstAtSign'; String privateKeyResponse = await socketConnection2.sendRequestToServer('keys:get:private'); - print('** privateKeyResponse: $privateKeyResponse'); expect(privateKeyResponse.contains(privateKey), true); }); From 78d342bdfa0880c8a7001d250363e7658b11b46e Mon Sep 17 00:00:00 2001 From: Murali Date: Thu, 5 Dec 2024 16:02:00 +0530 Subject: [PATCH 3/5] fix: change to functional test --- .../at_functional_test/test/enroll_verb_test.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/at_functional_test/test/enroll_verb_test.dart b/tests/at_functional_test/test/enroll_verb_test.dart index 38172f8eb..b097a6b19 100644 --- a/tests/at_functional_test/test/enroll_verb_test.dart +++ b/tests/at_functional_test/test/enroll_verb_test.dart @@ -414,12 +414,26 @@ void main() { String selfKeyGetResponse = await socketConnection2 .sendRequestToServer('keys:get:keyName:$selfKey'); print('selfKeyGetResponse: $selfKeyGetResponse'); + selfKeyGetResponse = selfKeyGetResponse.replaceFirst('data:', ''); + var selfKeyResponseJson = jsonDecode(selfKeyGetResponse); + expect(selfKeyResponseJson['value'], + apkamEncryptedKeysMap['encryptedSelfEncKey']); + expect(selfKeyResponseJson['iv'], selfEncryptionKeyIV); + // keys:get:private should return private encryption key var privateKey = '$secondEnrollId.default_enc_private_key.__manage$firstAtSign'; String privateKeyResponse = await socketConnection2.sendRequestToServer('keys:get:private'); expect(privateKeyResponse.contains(privateKey), true); + String privateKeyGetResponse = await socketConnection2 + .sendRequestToServer('keys:get:keyName:$privateKey'); + print('**privateKeyGetResponse: $privateKeyGetResponse'); + privateKeyGetResponse = privateKeyGetResponse.replaceFirst('data:', ''); + var privateKeyResponseJson = jsonDecode(privateKeyGetResponse); + expect(privateKeyResponseJson['value'], + apkamEncryptedKeysMap['encryptedDefaultEncPrivateKey']); + expect(privateKeyResponseJson['iv'], encryptionPrivateKeyIV); }); test( From 7fec9be974bef3cc04031d59026955f8b4239534 Mon Sep 17 00:00:00 2001 From: Murali Date: Thu, 5 Dec 2024 19:10:35 +0530 Subject: [PATCH 4/5] fix: remove storing apkam encrypted keys for first enrollment --- .../lib/src/verb/handler/enroll_verb_handler.dart | 3 --- tests/at_functional_test/test/enroll_verb_test.dart | 2 -- 2 files changed, 5 deletions(-) diff --git a/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart b/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart index b64b5bf65..d74b98f36 100644 --- a/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart +++ b/packages/at_secondary_server/lib/src/verb/handler/enroll_verb_handler.dart @@ -249,9 +249,6 @@ class EnrollVerbHandler extends AbstractVerbHandler { final inboundConnectionMetadata = atConnection.metaData as InboundConnectionMetadata; inboundConnectionMetadata.enrollmentId = newEnrollmentId; - // Store default encryption private key and self encryption key(both encrypted) - // for future retrieval - await _storeEncryptionKeys(newEnrollmentId, enrollParams, currentAtSign); // store this apkam as default pkam public key for old clients // The keys with AT_PKAM_PUBLIC_KEY does not sync to client. await keyStore.put(AtConstants.atPkamPublicKey, diff --git a/tests/at_functional_test/test/enroll_verb_test.dart b/tests/at_functional_test/test/enroll_verb_test.dart index b097a6b19..17f6eb7b9 100644 --- a/tests/at_functional_test/test/enroll_verb_test.dart +++ b/tests/at_functional_test/test/enroll_verb_test.dart @@ -413,7 +413,6 @@ void main() { String selfKeyGetResponse = await socketConnection2 .sendRequestToServer('keys:get:keyName:$selfKey'); - print('selfKeyGetResponse: $selfKeyGetResponse'); selfKeyGetResponse = selfKeyGetResponse.replaceFirst('data:', ''); var selfKeyResponseJson = jsonDecode(selfKeyGetResponse); expect(selfKeyResponseJson['value'], @@ -428,7 +427,6 @@ void main() { expect(privateKeyResponse.contains(privateKey), true); String privateKeyGetResponse = await socketConnection2 .sendRequestToServer('keys:get:keyName:$privateKey'); - print('**privateKeyGetResponse: $privateKeyGetResponse'); privateKeyGetResponse = privateKeyGetResponse.replaceFirst('data:', ''); var privateKeyResponseJson = jsonDecode(privateKeyGetResponse); expect(privateKeyResponseJson['value'], From 84efa75ebe493ebee1914436ccabcaf9f6151a83 Mon Sep 17 00:00:00 2001 From: Murali Date: Thu, 5 Dec 2024 19:17:43 +0530 Subject: [PATCH 5/5] fix: removed test for storing apkam encrypted keys for first enrollment --- .../test/enroll_verb_test.dart | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/tests/at_functional_test/test/enroll_verb_test.dart b/tests/at_functional_test/test/enroll_verb_test.dart index 17f6eb7b9..aea2bf7fd 100644 --- a/tests/at_functional_test/test/enroll_verb_test.dart +++ b/tests/at_functional_test/test/enroll_verb_test.dart @@ -275,35 +275,6 @@ void main() { expect(llookupResponseMap['errorCode'], 'AT0009'); expect(llookupResponseMap['errorDescription'], 'UnAuthorized client in request : Connection with enrollment ID $enrollmentId is not authorized to llookup key: $enrollmentKey'); - - // keys:get:self should return default self encryption key - var selfKey = '$enrollmentId.default_self_enc_key.__manage$firstAtSign'; - String selfKeyResponse = - await socketConnection2.sendRequestToServer('keys:get:self'); - expect(selfKeyResponse.contains(selfKey), true); - - // keys:get:private should return private encryption key - var privateKey = - '$enrollmentId.default_enc_private_key.__manage$firstAtSign'; - String privateKeyResponse = - await socketConnection2.sendRequestToServer('keys:get:private'); - expect(privateKeyResponse.contains(privateKey), true); - - // keys:get:keyName should return the enrollment key with __manage namespace - String selfKeyGetResponse = await socketConnection2 - .sendRequestToServer('keys:get:keyName:$selfKey'); - expect( - selfKeyGetResponse - .contains('${apkamEncryptedKeysMap['encryptedSelfEncKey']}'), - true); - - // keys:get:keyName should return the enrollment key with __manage namespace - String privateKeyGetResponse = await socketConnection2 - .sendRequestToServer('keys:get:keyName:$privateKey'); - expect( - privateKeyGetResponse.contains( - '${apkamEncryptedKeysMap['encryptedDefaultEncPrivateKey']}'), - true); }); test(