Skip to content

Conversation

@nagendra0721
Copy link
Contributor

@nagendra0721 nagendra0721 commented Nov 18, 2025

Summary by CodeRabbit

  • Tests
    • Added comprehensive tests for client crypto manager service: signature validation, asymmetric encrypt/decrypt, TPM and non‑TPM flows, facade/manager interactions, static-state resets and reflection-based wiring.
    • Enhanced crypto core tests with X.509 certificate signing/verification and test boot integration.
    • Added Argon2 hash service tests covering controller/service/DTOs, validation and error paths.
    • Added symmetric key converter mapping tests.
    • Expanded key generator tests for SecureRandom caching, provider enable/disable and fallback.

@coderabbitai
Copy link

coderabbitai bot commented Nov 18, 2025

Walkthrough

Adds multiple new and expanded unit/integration test classes in kernel-keymanager-service covering client crypto, crypto core, Argon2 hashing, symmetric key conversion, and key generation; changes are test-only and do not modify production code or public APIs.

Changes

Cohort / File(s) Change Summary
Client Crypto Tests
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java
New comprehensive test class (~25 tests) exercising AndroidClientCryptoServiceImpl, ClientCryptoFacade, and ClientCryptoManagerServiceImpl with extensive mocks, reflection-based wiring, TPM/non-TPM variants, signature/encrypt/decrypt flows, and static-state resets.
Crypto Core Tests
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/crypto/jce/test/CryptoCoreTest.java
Adds X509 certificate usage, injects KeymanagerUtil, a certificate payload field, updates @SpringBootTest to specify boot class, and adds tests for signing and signature verification including exception paths.
Argon2 Hashing Tests
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/service/Argon2HashServiceTest.java
New test class validating Argon2 hash generation at controller and service layers: success with/without salt, error/null/invalid inputs, DTO constructor/getter/setter tests, reflection-based private-method checks, and mocked validation error scenarios.
Symmetric Key Converter Tests
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/util/KeymanagerSymmetricKeyConverterTest.java
New unit tests for mapping CryptomanagerRequestDtoKeymanagerSymmetricKeyRequestDto, covering normal conversion, null/empty inputs, preservation of destination values, and special-character handling.
Key Generator Tests
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/keygenerator/bouncycastle/test/KeyGeneratorTest.java
Expands tests with @Before init and multiple new methods for symmetric/asymmetric key retrieval, Ed25519 private-key building, SecureRandom caching and RNG provider enabled/disabled/fallback behaviors; uses ReflectionTestUtils and provider mocking.

Sequence Diagram(s)

(Skipped — changes are test additions and do not introduce new control-flow behavior requiring sequence diagrams.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Focus review on:
    • ClientCryptoManagerServiceTest.java — complex Mockito setups, reflection-based field injections, and static-state resets.
    • Argon2HashServiceTest.java — controller vs service wiring and validation/error assertions.
    • CryptoCoreTest.java — certificate initialization and test boot class change.
    • Reflection and provider-mocking usage in KeyGeneratorTest.java for side effects.

Possibly related PRs

Suggested reviewers

  • mahammedtaheer

Poem

🐰 I hopped through tests both wide and deep,

With mocks and certs and secrets to keep,
Keys that shimmer, hashes that sing,
Each assertion a tiny spring,
May CI smile and green builds leap.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.90% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title is vague and generic, using a non-descriptive term 'test case coverage' without conveying specific details about which components or features are being tested. Replace with a more specific title describing the primary focus, e.g., 'Add comprehensive unit tests for ClientCrypto, CryptoCore, and KeyGenerator components' to clarify the scope of test additions.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/util/KeymanagerSymmetricKeyConverterTest.java (1)

60-73: Clarify test intent and tighten timestamp assertion

  • In testConvert_PreservesExistingDestinationValues (Lines 75–84) the assertions verify that destination fields are overwritten with source values, which contradicts the method name (“Preserves…”). Consider renaming to something like testConvert_OverridesDestinationValues (or adjusting assertions if the intended behavior is to preserve existing values).
  • In testConvert_WithEmptyStrings (Lines 60–73) you only assert that timeStamp is non-null while using LocalDateTime.now() on the source. If you want stronger guarantees, you could mirror the pattern from setUp() and use a fixed LocalDateTime for that test as well, then assert equality rather than just non-null.

Also applies to: 75-84

kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/service/Argon2HashServiceTest.java (1)

125-191: Service-level tests currently only exercise Mockito stubbing, not real service logic

The tests testGenerateArgon2Hash_Service_Success, testGenerateArgon2Hash_Service_WithProvidedSalt, testGenerateArgon2Hash_Service_InvalidInput, testGenerateArgon2Hash_Service_NullInput, and testGenerateArgon2Hash_Service_EmptyInput operate entirely on the mocked cryptomanagerService: they stub generateArgon2Hash(...) on the mock and then call the same mock, asserting the stubbed outcome or expected exception.

This gives coverage for the test class and Mockito interactions, but it doesn’t exercise CryptomanagerServiceImpl or any real Argon2/validation behavior. If the goal is to increase functional coverage:

  • Prefer constructing a real CryptomanagerServiceImpl with its dependencies (similar to what you did in testGenerateArgon2Hash_RealService_ValidationError) and invoking that.
  • Or, if you only intend to verify controller–service wiring, keep the controller tests and consider dropping the direct “Service_*” mock tests to avoid a false sense of coverage.
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/keygenerator/bouncycastle/test/KeyGeneratorTest.java (1)

33-43: Reduce redundancy and be conscious of reflection coupling to KeyGenerator internals

The new tests generally look correct and useful (especially the buildPrivateKey and getSecureRandom scenarios), but there are a couple of maintainability points:

  • testGetSymmetricKey vs getSymmetricKeyTest, and testGetAsymmetricKey vs getAsymmetricKeyTest, are largely overlapping. You could merge each pair into a single test that asserts both type and basic properties (non-null, non-empty key material) to keep the suite leaner.
  • The SecureRandom tests rely on private fields secureRandom, rngProviderEnabled, and rngProviderName via ReflectionTestUtils. That’s reasonable for coverage, but it does tightly couple the tests to the current field names and implementation. If those internals change, these tests will silently break at compile-time or via reflection. Consider adding at least one higher-level test that only uses the public API but would fail if the RNG configuration behavior regressed.

Also applies to: 44-77, 78-108

kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (3)

110-146: Instance-level Android service tests currently lock in placeholder behavior

Tests such as:

  • testAndroidAsymmetricEncrypt_Instance
  • testAndroidSignData
  • testAndroidGetSigningPublicPart
  • testAndroidGetEncryptionPublicPart

assert that the instance methods return zero-length arrays (and isTPMInstance() is false), which matches the current stubbed implementation (new byte[0], false).

If the plan is to later implement these instance methods with real crypto behavior, these tests will start failing and will then need to be completely rewritten. You may want to:

  • Either update the implementation now and assert the desired “real” behavior (non-empty signature/ciphertext, etc.), or
  • Clearly document in test names/comments that these are temporary stubs meant only to guard against regression to null/exceptions, so they’re easier to revisit when the implementation matures.

172-190: Broad try/catch blocks with minimal assertions weaken several tests

In multiple tests you wrap the core call in a broad try { ... } catch (Exception e) { assertNotNull(e); }, e.g.:

  • testFacadeValidateSignature_NullClientType
  • testFacadeValidateSignature_DefaultMethod
  • testFacadeEncrypt_DefaultMethod
  • testManagerServiceVerify
  • testLocalClientCryptoService_Reflection
  • testTPMClientCryptoService_Reflection

This pattern means the test passes whether the call returns a value or throws any exception; you’re effectively only asserting “something happened”.

For more robust tests:

  • Decide whether each path is expected to succeed or to throw a specific exception and encode that explicitly via @Test(expected = ...) or explicit fail(...) + specific catch.
  • For reflection-based tests, if the class/method is expected to exist, let unexpected reflection failures fail the test instead of swallowing them.

This will make these tests much more effective at detecting real regressions in facade/manager wiring and reflection-based instantiation.

Also applies to: 198-206, 237-251, 309-339


221-305: Manager service tests could assert more on behavior, not just non-null responses

The ClientCryptoManagerServiceImpl tests (testManagerServiceSign, testManagerServiceEncrypt, testManagerServiceDecrypt, testManagerServiceGetSigningPublicKey, testManagerServiceGetEncPublicKey) correctly wire in a mocked ClientCryptoService via the ClientCryptoFacade field and assert that responses are non-null.

To strengthen these without much extra effort, consider also asserting:

  • That the expected mocked methods were invoked with the decoded values (e.g., using Mockito verify on clientCryptoService.signData(...), asymmetricDecrypt(...), etc.).
  • That the DTOs returned by the manager service contain the expected Base64-encoded representations of the mocked outputs.

This would validate that the manager is applying the correct Base64 transformations and delegating to the facade/service as intended, rather than only asserting “no exception and some object returned”.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c76e9b7 and 1d0aa9f.

📒 Files selected for processing (5)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (1 hunks)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/crypto/jce/test/CryptoCoreTest.java (5 hunks)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/service/Argon2HashServiceTest.java (1 hunks)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/util/KeymanagerSymmetricKeyConverterTest.java (1 hunks)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/keygenerator/bouncycastle/test/KeyGeneratorTest.java (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/util/KeymanagerSymmetricKeyConverterTest.java (1)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/cryptomanager/util/KeymanagerSymmetricKeyConverter.java (1)
  • KeymanagerSymmetricKeyConverter (15-31)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/service/Argon2HashServiceTest.java (1)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/cryptomanager/exception/CryptoManagerSerivceException.java (1)
  • CryptoManagerSerivceException (11-39)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/crypto/jce/test/CryptoCoreTest.java (1)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/keymanagerservice/test/util/KeymanagerUtilTest.java (1)
  • SpringBootTest (38-340)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (2)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/clientcrypto/exception/ClientCryptoException.java (1)
  • ClientCryptoException (10-35)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/clientcrypto/service/impl/AndroidClientCryptoServiceImpl.java (1)
  • AndroidClientCryptoServiceImpl (20-105)
🔇 Additional comments (1)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/cryptomanager/test/service/Argon2HashServiceTest.java (1)

261-310: Good use of reflection to cover private helpers and validation path

The tests testGetLongBytes_PrivateMethod, testGetSaltBytes_PrivateMethod_WithValidKey, and testGenerateArgon2Hash_RealService_ValidationError are a reasonable compromise to get coverage on internal helpers and the validation hook in CryptomanagerServiceImpl without over-complicating the setup.

One thing to keep in mind is that these tests assume:

  • The private method signatures (getLongBytes(long), getSaltBytes(byte[], SecretKey)) stay stable.
  • The field name cryptomanagerUtil remains unchanged.

If those internals are likely to evolve, consider adding at least one public API–level test that would fail if the validation logic stopped being invoked, so you’re not relying solely on reflection to catch regressions.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (1)

155-158: testAndroidValidateSignature_InvalidSignature expectation contradicts implementation

The static AndroidClientCryptoServiceImpl.validateSignature(...) method returns the boolean result of sign.verify(signature) and only throws ClientCryptoException when a JCA operation fails inside the try block (e.g., bad key format), not for a normal signature mismatch. With the current implementation, passing "invalid".getBytes() as the signature is expected to yield a boolean result (typically false), not a ClientCryptoException.

The test currently uses @Test(expected = ClientCryptoException.class), which will fail once the method behaves as designed for invalid signatures.

Consider asserting on the boolean return instead of expecting an exception, for example:

-    @Test(expected = ClientCryptoException.class)
-    public void testAndroidValidateSignature_InvalidSignature() throws Exception {
-        AndroidClientCryptoServiceImpl.validateSignature(testPublicKey, "invalid".getBytes(), testData);
-    }
+    @Test
+    public void testAndroidValidateSignature_InvalidSignature() throws Exception {
+        boolean result = AndroidClientCryptoServiceImpl
+                .validateSignature(testPublicKey, "invalid".getBytes(), testData);
+        assertFalse(result);
+    }

This keeps the test aligned with the current contract of validateSignature.

🧹 Nitpick comments (4)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (4)

91-113: Static reset helpers are overly aggressive and may null out constants/loggers

Both resetStaticFields and resetAllStaticFields iterate all declared static fields and blindly set booleans, ints, and reference types to default values. This has a few drawbacks:

  • It may mutate static constants and loggers (including final fields), making later behavior harder to reason about and fragile against future changes in these classes.
  • Any new static added to ClientCryptoFacade or AndroidClientCryptoServiceImpl will be silently reset, which can mask issues or introduce spurious NPEs in tests.

You can keep the intent (cleaning mutable static state) while avoiding collateral damage by skipping final fields and narrowing what you reset. For example:

-            Field[] fields = ClientCryptoFacade.class.getDeclaredFields();
+            Field[] fields = ClientCryptoFacade.class.getDeclaredFields();
             for (Field field : fields) {
-                if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
+                int modifiers = field.getModifiers();
+                if (java.lang.reflect.Modifier.isStatic(modifiers)
+                        && !java.lang.reflect.Modifier.isFinal(modifiers)) {
                     field.setAccessible(true);
                     if (field.getType() == boolean.class) {
                         field.set(null, false);
                     } else if (!field.getType().isPrimitive()) {
                         field.set(null, null);
                     }
                 }
             }

and similarly in resetAllStaticFields:

-                for (Field field : fields) {
-                    if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
+                for (Field field : fields) {
+                    int modifiers = field.getModifiers();
+                    if (java.lang.reflect.Modifier.isStatic(modifiers)
+                            && !java.lang.reflect.Modifier.isFinal(modifiers)) {
                         field.setAccessible(true);
                         if (field.getType() == boolean.class) {
                             field.set(null, false);
                         } else if (field.getType() == int.class) {
                             field.set(null, 0);
                         } else if (!field.getType().isPrimitive()) {
                             field.set(null, null);
                         }
                     }
                 }

If there are only a small number of mutable static fields that truly need resetting, an explicit whitelist would be even safer.

Also applies to: 115-141


172-199: Instance-method tests for Android service correctly mirror current stub behavior

The instance-oriented tests (testAndroidValidateSignature_Instance, testAndroidAsymmetricEncrypt_Instance, testAndroidAsymmetricDecrypt_Instance, testAndroidSignData) are consistent with the present stubbed implementation:

  • validateSignature and asymmetricDecrypt are expected to fail due to missing key material, resulting in ClientCryptoException.
  • asymmetricEncrypt and signData currently return empty byte arrays.

These tests are useful as guardrails while the implementation is still incomplete, but will need revisiting if/when the instance methods gain full functionality (e.g., start returning real signatures/ciphertexts instead of empty arrays).


228-287: Facade tests cover multiple branches, but some assertions are weak

The ClientCryptoFacade tests hit several important paths:

  • Android client validate/signature and encrypt success cases.
  • Null ClientType and default-method overloads.
  • Random-byte generation and TPM flag toggling.

However, for methods like testFacadeValidateSignature_NullClientType, testFacadeValidateSignature_DefaultMethod, and testFacadeEncrypt_DefaultMethod, the pattern:

try {
    boolean result = ...;
    assertFalse(result); // or assertNotNull(result);
} catch (Exception e) {
    assertNotNull(e);
}

allows both “expected value” and “any exception” as success, which weakens the tests; they will pass under a wide range of behaviors.

If possible, it would be better to decide on one contract per path and assert it explicitly: either expect a specific exception type or a concrete return value, not “one of the above”. That will make these tests more meaningful as behavioral specifications rather than just coverage tools.


375-389: Mock-only tests for Local/TPM services don’t exercise real implementations

testLocalClientCryptoService_Mock and testTPMClientCryptoService_Mock only assert behavior on Mockito mocks of ClientCryptoService (isTPMInstance() returning true/false). They don’t touch LocalClientCryptoServiceImpl or TPMClientCryptoServiceImpl themselves, so they mainly verify Mockito rather than your code.

If you want meaningful coverage of those implementations, consider instantiating the real classes (or a thin wrapper) where feasible, or remove these tests if they’re only present for coverage metrics.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d0aa9f and b9c3daa.

📒 Files selected for processing (1)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (2)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/clientcrypto/exception/ClientCryptoException.java (1)
  • ClientCryptoException (10-35)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/clientcrypto/service/impl/AndroidClientCryptoServiceImpl.java (1)
  • AndroidClientCryptoServiceImpl (20-105)
🔇 Additional comments (5)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (5)

52-77: Setup/teardown and reflection-based wiring look appropriate for isolated tests

Using a generated RSA keypair, constructing ClientCryptoFacade/ClientCryptoManagerServiceImpl directly, and injecting cryptoCore and clientCryptoFacade via reflection gives you good isolation from Spring wiring while keeping tests realistic. The symmetric encrypt/decrypt stubs on cryptoCore are also straightforward and readable.

Also applies to: 79-83


143-153: Valid-signature path test is clear and aligned with implementation

testAndroidValidateSignature_Static correctly exercises the “happy path” using a real RSA keypair and Signature instance, then delegates to AndroidClientCryptoServiceImpl.validateSignature(...) and asserts the result is true. This gives solid coverage of the static validation behavior with realistic crypto primitives.


160-170: Static asymmetric-encryption tests exercise both success and failure paths

The two tests:

  • testAndroidAsymmetricEncrypt_Static with a real RSA public key, and
  • testAndroidAsymmetricEncrypt_InvalidKey with an invalid key byte array expecting ClientCryptoException

nicely cover the main branches of the static asymmetricEncrypt helper (normal encryption vs. key-spec failure). Assertions on non-null/length for the success case and exception for the invalid-key case look appropriate.


200-227: Getter and lifecycle tests for Android service are lightweight but fine

The tests for getSigningPublicPart, getEncryptionPublicPart, isTPMInstance, and closeSecurityInstance simply assert the current stub semantics (zero-length arrays, false TPM flag, no exception on close). This is adequate smoke coverage and provides some protection against accidental signature changes.


289-373: Manager-service tests provide good end-to-end DTO flow coverage

The tests for ClientCryptoManagerServiceImpl (testManagerServiceSign, testManagerServiceVerify, testManagerServiceEncrypt, testManagerServiceDecrypt, testManagerServiceGetSigningPublicKey, testManagerServiceGetEncPublicKey) add valuable coverage:

  • They exercise base64 encoding/decoding via the request/response DTOs.
  • They verify reflection-based wiring of clientCryptoService into ClientCryptoFacade.
  • They validate that responses are non-null under both mocked-success paths (e.g., sign/decrypt) and current default behavior.

Overall, these tests look consistent with the manager’s role as an adapter around the facade and crypto service.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/crypto/jce/test/CryptoCoreTest.java (1)

257-280: Clarify verifySignatureTest as a negative/key‑mismatch scenario or add a positive one‑arg verify test

Here you deliberately sign with rsaPair.getPrivate() while embedding a different X.509 certificate, so cryptoCore.verifySignature(signature) returning false is correct for a key‑mismatch case. The current method name (verifySignatureTest) reads like a positive/happy‑path test, which can be confusing.

Consider either:

  • Renaming to something like verifySignatureMismatchedCertificateReturnsFalse and adding a brief comment about the intentional key mismatch, and/or
  • Adding a complementary test where the signing key matches the certificate so verifySignature(String) returns true, clearly documenting both sides of the contract.
🧹 Nitpick comments (5)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (5)

128-145: Android validateSignature tests align with implementation; consider also covering the “invalid signature → false” case

These two tests nicely pin down:

  • Happy path with a real RSA key/signature (true result), and
  • Error path where an invalid public key triggers ClientCryptoException.

Given AndroidClientCryptoServiceImpl.validateSignature currently returns the underlying signature‑verification boolean and only throws on key/JCA failures, it would be valuable to add a third test where:

  • The public key is valid,
  • The signature is deliberately corrupted,
  • And the method is asserted to return false (not throw).

That locks in the distinction between “cryptographic mismatch” and “runtime failure” for future refactors.


88-115: Reflection + static field wiring makes tests tightly coupled to implementation details

The setup wires ClientCryptoFacade, LocalClientCryptoServiceImpl, and their collaborators by:

  • Injecting private fields via reflection, and
  • Mutating multiple static fields (clientCryptoService, secureRandom, LocalClientCryptoServiceImpl.cryptoCore).

This gives good coverage with the current design, but it’s brittle:

  • Renaming private fields or changing constructor signatures will silently break tests.
  • Static state makes these tests unsafe for parallel execution with other suites touching the same classes.

If feasible, consider longer‑term refactors like:

  • Adding package‑visible or test‑only constructors that accept dependencies directly, or
  • Reducing static state in the production classes so tests can rely on normal DI wiring instead of reflection.

166-185: Minor: payload construction could more faithfully mirror the real envelope format

In testClientCryptoFacadeDecryptUsesClientSecurity, the first segment of payload is initialized with new byte[secret.length] rather than the secret array you later expect from clientCryptoService.asymmetricDecrypt(...). Because the mock ignores the input and always returns secret, the test still passes, but it no longer validates that the envelope layout matches production expectations.

Consider using secret instead of a zeroed array for the first copy, mirroring the structure you already use in the fallback test.


503-511: Ensure cleanKeysDirectory only touches test‑scoped key material

cleanKeysDirectory() recursively deletes everything under ClientCryptoManagerConstant.KEY_PATH/KEYS_DIR. That’s fine if those constants resolve to a test‑only directory (e.g., under target), but risky if they can ever point at a shared or production‑like location on a developer machine or CI.

If there’s any chance of overlap, consider:

  • Overriding KEY_PATH/KEYS_DIR via test configuration to a temp directory, or
  • Using JUnit/temporary directories explicitly rather than shared constants.

547-555: Key‑size assumption in rsaModulusBytes is implicitly 2048‑bit

rsaModulusBytes() normalizes the modulus to 256 bytes by either truncating or left‑padding. That’s consistent with a 2048‑bit RSA modulus (as used by the TPM helpers), but would silently misbehave if the key size ever changed.

Given this is test‑only code, it’s acceptable, but you might want to:

  • Assert the modulus bit length is 2048 before normalization, or
  • Derive the target length from the actual modulus size instead of hard‑coding 256.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9c3daa and 90b6624.

📒 Files selected for processing (2)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (1 hunks)
  • kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/crypto/jce/test/CryptoCoreTest.java (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (2)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/clientcrypto/exception/ClientCryptoException.java (1)
  • ClientCryptoException (10-35)
kernel/kernel-keymanager-service/src/main/java/io/mosip/kernel/clientcrypto/service/impl/AndroidClientCryptoServiceImpl.java (1)
  • AndroidClientCryptoServiceImpl (20-105)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-kernel / maven-build
🔇 Additional comments (2)
kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/crypto/jce/test/CryptoCoreTest.java (1)

53-73: LGTM: Certificate wiring for certificate-based sign/verify tests

Inline PEM plus KeymanagerUtil.convertToCertificate and the dedicated test boot app give you a realistic certificate context for the new sign/verify tests without touching production wiring. This is a good pattern for exercising cert-based flows in isolation.

kernel/kernel-keymanager-service/src/test/java/io/mosip/kernel/clientcrypto/test/service/ClientCryptoManagerServiceTest.java (1)

220-313: LGTM: TPM client crypto tests give strong coverage of caching, error paths, and random generation

The TPM tests here exercise:

  • Primary response caching for signing/encryption public parts,
  • Happy‑path sign/decrypt/random operations via a mocked Tpm,
  • Behavior when tpm is null and when Sign returns null,
  • closeSecurityInstance both with and without a real TPM instance.

This is a solid set of tests for a tricky, stateful integration point.

@mahammedtaheer mahammedtaheer merged commit 5c0adde into mosip:develop Nov 19, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants