Skip to content

Conversation

@kongadurgesh
Copy link
Contributor

@kongadurgesh kongadurgesh commented Jan 6, 2026

  • Merge KeyGenerationUtil and JwtGeneratorUtil into SigningKeyUtil
  • Implement Strategy pattern with algorithm-specific handlers (RS256, ES256, ES256K, ED25519)
  • Add SigningAlgorithmHandlerFactory for handler management
  • Create BouncyCastleProviderUtil for centralized provider access
  • Add comprehensive test suite for all handlers and utilities
  • Remove deprecated ProofSigningKeyFactory, KeyGenerationUtil, and JwtGeneratorUtil

Summary by CodeRabbit

  • Refactor

    • Centralized and reorganized cryptographic key generation and JWT signing into a unified utility and algorithm handlers for clearer, consistent signing behavior.
  • Tests

    • Added and updated unit tests covering multiple signing algorithms, provider handling, JWK/JWSSigner creation, key reconstruction, and proof-signing key creation to improve reliability.

✏️ Tip: You can customize this high-level summary in your review settings.

… proof Signing Key utilities using factory pattern

- Merge KeyGenerationUtil and JwtGeneratorUtil into SigningKeyUtil
- Implement Strategy pattern with algorithm-specific handlers (RS256, ES256, ES256K, ED25519)
- Add SigningAlgorithmHandlerFactory for handler management
- Create BouncyCastleProviderUtil for centralized provider access
- Add comprehensive test suite for all handlers and utilities
- Remove deprecated ProofSigningKeyFactory, KeyGenerationUtil, and JwtGeneratorUtil

Signed-off-by: Durgesh Konga <kongadurgesh20@gmail.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

Walkthrough

Consolidates JWT and key-generation utilities into a single SigningKeyUtil backed by a SigningAlgorithmHandler strategy factory; removes legacy JwtGeneratorUtil/KeyGenerationUtil/ProofSigningKeyFactory; adds algorithm-specific handlers, a BouncyCastle provider util, and updates services/tests to use the new APIs. (50 words)

Changes

Cohort / File(s) Summary
Removed monolith utilities
src/main/java/io/mosip/mimoto/util/JwtGeneratorUtil.java, src/main/java/io/mosip/mimoto/util/KeyGenerationUtil.java, src/main/java/io/mosip/mimoto/util/ProofSigningKeyFactory.java
Deleted legacy classes that handled JWT creation, key generation, and proof key factory logic.
New central utility
src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java
Added unified API for key pair generation/reconstruction, encryption key creation, JWT creation, JWK/JWSSigner creation, and proof-signing key creation; delegates to algorithm handlers.
Algorithm handler interface & factory
src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandler.java, src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactory.java
New interface and factory mapping SigningAlgorithm → concrete handler implementations.
Algorithm handler implementations
src/main/java/io/mosip/mimoto/util/factory/RS256AlgorithmHandler.java, .../ES256AlgorithmHandler.java, .../ES256KAlgorithmHandler.java, .../ED25519AlgorithmHandler.java
New concrete handlers implementing key generation, JWK creation, and JWSSigner creation per algorithm (RS256, ES256, ES256K, ED25519).
BouncyCastle provider util
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java
Singleton provider utility that conditionally registers and returns the BouncyCastle Provider.
Service usage updates
src/main/java/io/mosip/mimoto/service/impl/CredentialRequestServiceImpl.java, src/main/java/io/mosip/mimoto/service/impl/KeyPairRetrievalServiceImpl.java, src/main/java/io/mosip/mimoto/service/impl/WalletPresentationServiceImpl.java, src/main/java/io/mosip/mimoto/util/WalletUtil.java
Replaced usages of JwtGeneratorUtil/KeyGenerationUtil/ProofSigningKeyFactory with SigningKeyUtil calls.
Tests migrated / updated
src/test/java/io/mosip/mimoto/service/*, src/test/java/io/mosip/mimoto/util/*
Updated mocks and calls in service tests to use SigningKeyUtil; replaced deleted util tests with new tests for SigningKeyUtil and handler classes.
New handler & util tests
src/test/java/io/mosip/mimoto/util/factory/*, src/test/java/io/mosip/mimoto/util/SigningKeyUtilTest.java, src/test/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtilTest.java, src/test/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactoryTest.java
Added unit tests covering key generation, JWK/signer creation, provider singleton, and factory resolution.
Deleted tests
src/test/java/io/mosip/mimoto/util/JwtGeneratorUtilTest.java, src/test/java/io/mosip/mimoto/util/KeyGenerationUtilTest.java
Removed tests for the deleted utility classes.
Repo metadata
.talismanrc
Updated ignore checksums and added entries for newly introduced files.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Service as Wallet/Credential Service
  participant SigningKeyUtil
  participant Handler as SigningAlgorithmHandler
  participant BC as BouncyCastleProviderUtil

  Note over Service,SigningKeyUtil: Request to create JWT / keypair
  Client->>Service: submit request (audience, clientId, cNonce, algorithm)
  Service->>SigningKeyUtil: generateJwt(algorithm, audience, clientId, cNonce, keyPair?)
  alt New key pair required
    SigningKeyUtil->>Handler: generateKeyPair()
    Handler->>BC: getProvider() (if handler needs BC)
    BC-->>Handler: Provider
    Handler-->>SigningKeyUtil: KeyPair
  else Key pair from bytes
    SigningKeyUtil->>Handler: getKeyFactory() / reconstruct keys
  end
  SigningKeyUtil->>Handler: createJWK(KeyPair)
  Handler-->>SigningKeyUtil: JWK
  SigningKeyUtil->>Handler: createSigner(JWK)
  Handler-->>SigningKeyUtil: JWSSigner
  SigningKeyUtil->>Service: serialized Signed JWT
  Service->>Client: return JWT
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 In burrows of code I scurried near,
Old utils folded, new paths clear.
Handlers hop, provider hums,
Keys and tokens beat like drums.
One SigningKey—swift and bright—keeps crypto snug tonight. 🥕🔐

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.94% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main refactoring effort: consolidating multiple utility classes (KeyGeneration, JWTGeneration, Proof Signing Key) using the factory pattern, which aligns with the substantial architectural changes throughout the codebase.
✨ Finishing touches
  • 📝 Generate docstrings

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

🤖 Fix all issues with AI Agents
In @src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java:
- Around line 15-27: The current static block may not register the BC_PROVIDER
and getProvider() returns the local BC_PROVIDER regardless, causing
inconsistency; change getProvider() to fetch the globally registered provider
via Security.getProvider(BouncyCastleProvider.PROVIDER_NAME), and if that
returns null register BC_PROVIDER (using Security.addProvider(BC_PROVIDER)) and
then return the now-registered provider; this ensures the returned Provider
matches the Security context and references BC_PROVIDER, keeping the static
block and getProvider() behavior consistent.

In @src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java:
- Around line 167-170: The catch block in SigningKeyUtil (catching
NoSuchAlgorithmException | InvalidAlgorithmParameterException |
NoSuchProviderException) logs exception e but rethrows a KeyGenerationException
without preserving the original cause and uses the wrong ENCRYPTION_FAILED code;
update the throw to pass e as the cause into KeyGenerationException (so the
stacktrace is preserved) and replace ENCRYPTION_FAILED with a dedicated
key-generation error code (e.g., KEY_GENERATION_FAILED) defined in your error
codes enum/constant, ensuring the message still includes the algorithm context.
🧹 Nitpick comments (10)
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java (1)

15-19: Consider adding error handling for static initialization.

The static block could potentially throw exceptions during class initialization (e.g., if Security.addProvider fails), which would result in an ExceptionInInitializerError that's difficult to debug. While unlikely in practice, consider adding defensive error handling or at least logging.

🔎 Suggested improvement
 static {
-    if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
-        Security.addProvider(BC_PROVIDER);
+    try {
+        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
+            Security.addProvider(BC_PROVIDER);
+        }
+    } catch (Exception e) {
+        // Log error or handle gracefully
+        throw new ExceptionInInitializerError("Failed to register BouncyCastle provider: " + e.getMessage());
     }
 }
src/test/java/io/mosip/mimoto/util/factory/ES256KAlgorithmHandlerTest.java (1)

69-76: Consider improving exception handling for invalid JWK.

The test expects ClassCastException when an invalid (non-ECKey) JWK is passed to createSigner. While this tests defensive behavior, it relies on implementation details. Consider:

  1. The handler should validate the JWK type and throw a more specific exception (e.g., IllegalArgumentException or JOSEException) with a clear message
  2. Update the test to expect the specific exception

This makes the API contract clearer and the test less brittle.

🔎 Suggested improvement

In ES256KAlgorithmHandler.createSigner:

public JWSSigner createSigner(JWK jwk) throws JOSEException {
    if (!(jwk instanceof ECKey)) {
        throw new IllegalArgumentException("JWK must be an ECKey for ES256K algorithm");
    }
    return new ECDSASigner((ECKey) jwk);
}

Then update the test:

-@Test(expected = ClassCastException.class)
+@Test(expected = IllegalArgumentException.class)
 public void shouldThrowExceptionWhenJWKIsInvalid() throws Exception {
     // Create invalid JWK (not ECKey)
     KeyPair rsaKeyPair = new RS256AlgorithmHandler().generateKeyPair();
     JWK invalidJwk = new RS256AlgorithmHandler().createJWK(rsaKeyPair);
     
     handler.createSigner(invalidJwk);
 }
src/test/java/io/mosip/mimoto/util/factory/ES256AlgorithmHandlerTest.java (1)

24-30: Redundant BouncyCastle provider registration.

The BouncyCastleProviderUtil already registers the provider in its static initializer. Since ES256AlgorithmHandler.createSigner() uses BouncyCastleProviderUtil.getProvider(), triggering class loading will register the provider automatically. This manual registration is harmless but redundant.

🔎 Suggested simplification
     @Before
     public void setUp() {
-        // Ensure BouncyCastle provider is registered (required for signing operations)
-        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
-            Security.addProvider(new BouncyCastleProvider());
-        }
+        // Trigger BouncyCastleProviderUtil class loading to ensure provider registration
+        BouncyCastleProviderUtil.getProvider();
     }
src/test/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtilTest.java (1)

16-52: Good test coverage with minor redundancy.

The tests correctly verify:

  • Provider instance is non-null and correct type
  • Singleton pattern (same instance on multiple calls)
  • Provider is registered with Security
  • Provider name matches expected value

Note: shouldNotReturnNullProvider (lines 47-52) duplicates the null check in shouldReturnProviderInstance (lines 16-22). Consider consolidating.

src/main/java/io/mosip/mimoto/util/factory/RS256AlgorithmHandler.java (1)

20-27: Consider upgrading RSA key size from 2048-bit to 3072-bit for long-term credential security.

NIST recommends 3072-bit RSA for credentials with multi-year lifetimes. Since identity systems typically issue long-lived credentials, the current 2048-bit key size may not provide sufficient security margin beyond 2030 without periodic re-issuance. Update RSA_KEY_SIZE to 3072 and document the reasoning if 2048-bit is retained.

src/main/java/io/mosip/mimoto/util/factory/ED25519AlgorithmHandler.java (1)

44-52: Consider using proper key specs instead of raw byte extraction.

The current implementation extracts the last 32 bytes from encoded keys (lines 48-49), which assumes specific encoding formats (X.509 for public, PKCS#8 for private). This approach is fragile and may break if encoding formats change.

Consider using EdECPublicKey.getPoint() and proper EdEC key parameters for more robust key material extraction, or at minimum document the encoding format assumptions.

Alternative approach

A more robust implementation could use the key interfaces directly:

// For newer JDK versions with full EdEC support
EdECPublicKey edECPublicKey = (EdECPublicKey) keyPair.getPublic();
EdECPrivateKey edECPrivateKey = (EdECPrivateKey) keyPair.getPrivate();

// Extract using proper methods if available, or document the encoding assumption
byte[] x = edECPublicKey.getPoint().getY().toByteArray(); // May need adjustment
byte[] d = edECPrivateKey.getBytes().orElseThrow();

If the current byte slicing approach is retained, add a comment explaining the encoding format dependency.

src/test/java/io/mosip/mimoto/util/factory/RS256AlgorithmHandlerTest.java (2)

24-30: Consider using BouncyCastleProviderUtil for consistency.

The PR introduces BouncyCastleProviderUtil to centralize provider access. Using it here would maintain consistency with other algorithm handler tests and the production code.

🔎 Suggested refactor
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import io.mosip.mimoto.util.factory.BouncyCastleProviderUtil;
 import org.junit.Before;
 import org.junit.Test;
 
 import java.security.KeyFactory;
 import java.security.KeyPair;
-import java.security.Security;
 
 ...
 
     @Before
     public void setUp() {
-        // Ensure BouncyCastle provider is registered (required for signing operations)
-        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
-            Security.addProvider(new BouncyCastleProvider());
-        }
+        // Ensure BouncyCastle provider is registered
+        BouncyCastleProviderUtil.ensureRegistered();
     }

69-76: Minor: Avoid redundant handler instantiation.

Two ES256AlgorithmHandler instances are created when one would suffice.

🔎 Suggested fix
     @Test(expected = ClassCastException.class)
     public void shouldThrowExceptionWhenJWKIsInvalid() throws Exception {
         // Create invalid JWK (not RSAKey)
-        KeyPair ecKeyPair = new ES256AlgorithmHandler().generateKeyPair();
-        JWK invalidJwk = new ES256AlgorithmHandler().createJWK(ecKeyPair);
+        ES256AlgorithmHandler ecHandler = new ES256AlgorithmHandler();
+        KeyPair ecKeyPair = ecHandler.generateKeyPair();
+        JWK invalidJwk = ecHandler.createJWK(ecKeyPair);
         
         handler.createSigner(invalidJwk);
     }
src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java (2)

35-35: Consider making JWT expiration configurable.

The 5-hour expiration is hardcoded. For proof JWTs in OpenID4VCI flows, this may be longer than necessary and could be a security concern. Consider externalizing this as a configuration property.


176-182: Consider formatting the claims builder for readability.

The single-line builder chain is hard to scan. Breaking it across lines improves maintainability.

🔎 Suggested formatting
     private static JWTClaimsSet createClaims(String clientId, String audience, String cNonce) {
         long nowSeconds = System.currentTimeMillis() / 1000;
         Date issuedAt = new Date(nowSeconds * 1000);
         Date expiresAt = new Date((nowSeconds + JWT_EXPIRATION_SECONDS) * 1000);
 
-        return new JWTClaimsSet.Builder().subject(clientId).audience(audience).issuer(clientId).issueTime(issuedAt).expirationTime(expiresAt).claim("nonce", cNonce).build();
+        return new JWTClaimsSet.Builder()
+                .subject(clientId)
+                .audience(audience)
+                .issuer(clientId)
+                .issueTime(issuedAt)
+                .expirationTime(expiresAt)
+                .claim("nonce", cNonce)
+                .build();
     }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84f1790 and e11bb8b.

📒 Files selected for processing (30)
  • .talismanrc
  • src/main/java/io/mosip/mimoto/service/impl/CredentialRequestServiceImpl.java
  • src/main/java/io/mosip/mimoto/service/impl/KeyPairRetrievalServiceImpl.java
  • src/main/java/io/mosip/mimoto/service/impl/WalletPresentationServiceImpl.java
  • src/main/java/io/mosip/mimoto/util/JwtGeneratorUtil.java
  • src/main/java/io/mosip/mimoto/util/KeyGenerationUtil.java
  • src/main/java/io/mosip/mimoto/util/ProofSigningKeyFactory.java
  • src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java
  • src/main/java/io/mosip/mimoto/util/WalletUtil.java
  • src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java
  • src/main/java/io/mosip/mimoto/util/factory/ED25519AlgorithmHandler.java
  • src/main/java/io/mosip/mimoto/util/factory/ES256AlgorithmHandler.java
  • src/main/java/io/mosip/mimoto/util/factory/ES256KAlgorithmHandler.java
  • src/main/java/io/mosip/mimoto/util/factory/RS256AlgorithmHandler.java
  • src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandler.java
  • src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactory.java
  • src/test/java/io/mosip/mimoto/service/CredentialRequestServiceTest.java
  • src/test/java/io/mosip/mimoto/service/KeyPairServiceTest.java
  • src/test/java/io/mosip/mimoto/service/WalletPresentationServiceTest.java
  • src/test/java/io/mosip/mimoto/util/EncryptionDecryptionUtilTest.java
  • src/test/java/io/mosip/mimoto/util/JwtGeneratorUtilTest.java
  • src/test/java/io/mosip/mimoto/util/KeyGenerationUtilTest.java
  • src/test/java/io/mosip/mimoto/util/SigningKeyUtilTest.java
  • src/test/java/io/mosip/mimoto/util/WalletUtilTest.java
  • src/test/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtilTest.java
  • src/test/java/io/mosip/mimoto/util/factory/ED25519AlgorithmHandlerTest.java
  • src/test/java/io/mosip/mimoto/util/factory/ES256AlgorithmHandlerTest.java
  • src/test/java/io/mosip/mimoto/util/factory/ES256KAlgorithmHandlerTest.java
  • src/test/java/io/mosip/mimoto/util/factory/RS256AlgorithmHandlerTest.java
  • src/test/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactoryTest.java
💤 Files with no reviewable changes (5)
  • src/main/java/io/mosip/mimoto/util/JwtGeneratorUtil.java
  • src/test/java/io/mosip/mimoto/util/JwtGeneratorUtilTest.java
  • src/test/java/io/mosip/mimoto/util/KeyGenerationUtilTest.java
  • src/main/java/io/mosip/mimoto/util/ProofSigningKeyFactory.java
  • src/main/java/io/mosip/mimoto/util/KeyGenerationUtil.java
🧰 Additional context used
🧬 Code graph analysis (7)
src/main/java/io/mosip/mimoto/util/factory/RS256AlgorithmHandler.java (1)
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java (1)
  • BouncyCastleProviderUtil (11-28)
src/test/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtilTest.java (1)
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java (1)
  • BouncyCastleProviderUtil (11-28)
src/test/java/io/mosip/mimoto/util/SigningKeyUtilTest.java (1)
src/main/java/io/mosip/mimoto/exception/KeyGenerationException.java (1)
  • KeyGenerationException (3-13)
src/test/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactoryTest.java (1)
src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactory.java (1)
  • SigningAlgorithmHandlerFactory (13-39)
src/main/java/io/mosip/mimoto/util/factory/ES256KAlgorithmHandler.java (1)
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java (1)
  • BouncyCastleProviderUtil (11-28)
src/main/java/io/mosip/mimoto/util/factory/ES256AlgorithmHandler.java (1)
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java (1)
  • BouncyCastleProviderUtil (11-28)
src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java (2)
src/main/java/io/mosip/mimoto/exception/KeyGenerationException.java (1)
  • KeyGenerationException (3-13)
src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactory.java (1)
  • SigningAlgorithmHandlerFactory (13-39)
🪛 ast-grep (0.40.3)
src/main/java/io/mosip/mimoto/util/factory/ES256KAlgorithmHandler.java

[warning] 27-27: Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES.
Context: KeyPairGenerator.getInstance("EC", PROVIDER)
Note: [CWE-326]: Inadequate Encryption Strength [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures [REFERENCES]
- https://find-sec-bugs.github.io/bugs.htm#TDES_USAGE
- https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA

(desede-is-deprecated-java)


[warning] 35-35: Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES.
Context: KeyFactory.getInstance("EC", PROVIDER)
Note: [CWE-326]: Inadequate Encryption Strength [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures [REFERENCES]
- https://find-sec-bugs.github.io/bugs.htm#TDES_USAGE
- https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA

(desede-is-deprecated-java)


[warning] 27-27: Use of AES with ECB mode detected. ECB doesn't provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.
Context: KeyPairGenerator.getInstance("EC", PROVIDER)
Note: [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures [REFERENCES]
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
- https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html

(use-of-aes-ecb-java)


[warning] 35-35: Use of AES with ECB mode detected. ECB doesn't provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.
Context: KeyFactory.getInstance("EC", PROVIDER)
Note: [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures [REFERENCES]
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
- https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html

(use-of-aes-ecb-java)

⏰ 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-maven-apitest-mimoto / maven-build
🔇 Additional comments (41)
src/test/java/io/mosip/mimoto/util/EncryptionDecryptionUtilTest.java (2)

95-96: Consistent refactoring in test method.

The same SigningKeyUtil replacements in the test method maintain consistency with the setUp method.


51-52: Code is correct, but KeyGenerationUtil replacement claim is unfounded.

The test correctly uses SigningKeyUtil for key generation. However, KeyGenerationUtil does not exist in the repository—there is no replacement occurring. The methods SigningKeyUtil.generateEncryptionKey(String algorithm, int keySize) (returning SecretKey) and SigningKeyUtil.generateKeyPair(SigningAlgorithm algorithm) (returning KeyPair) are properly defined and used correctly at lines 51-52 and 95-96.

Likely an incorrect or invalid review comment.

src/test/java/io/mosip/mimoto/util/WalletUtilTest.java (1)

53-53: LGTM! Consistent with refactoring pattern.

The replacement of KeyGenerationUtil with SigningKeyUtil for encryption key generation aligns with the refactoring across other test files.

src/main/java/io/mosip/mimoto/service/impl/KeyPairRetrievalServiceImpl.java (2)

10-10: Import updated correctly.

The import change from KeyGenerationUtil to SigningKeyUtil aligns with the PR's consolidation objectives.


77-77: Verify method signature and behavior equivalence.

The method name changed from getKeyPairFromDBStoredKeys to generateKeyPairFromBytes, which better describes the operation (generating a KeyPair from byte arrays rather than implying DB access).

Please verify that the new method has the same signature and behavior, and that the old method is removed.

src/test/java/io/mosip/mimoto/service/CredentialRequestServiceTest.java (3)

50-50: MockedStatic updated correctly.

The static mock target has been properly updated from KeyGenerationUtil to SigningKeyUtil, consistent with the refactoring.


63-67: Proper cleanup of mocked static.

The @After method correctly closes the MockedStatic instance, preventing test interference. Good practice!


171-171: Verification calls updated consistently.

All static method verifications have been consistently updated to reference SigningKeyUtil.generateKeyPair instead of KeyGenerationUtil.generateKeyPair. The test logic correctly validates algorithm selection based on issuer support.

Also applies to: 200-200, 228-228, 256-256

src/main/java/io/mosip/mimoto/util/WalletUtil.java (2)

42-42: No action required. The SigningKeyUtil.generateEncryptionKey("AES", 256) method is properly implemented and tested. Verification confirms the method exists with the correct signature, generates AES-256 keys correctly, and includes appropriate exception handling for unsupported algorithms.


80-80: ProofSigningKey creation method verified.

SigningKeyUtil.createProofSigningKey exists and correctly generates proof signing keys for all supported algorithms (RS256, ES256, ES256K, ED25519). The method properly wraps key pairs with metadata and is comprehensively tested.

src/main/java/io/mosip/mimoto/service/impl/WalletPresentationServiceImpl.java (1)

259-263: No concerns identified. Both SigningKeyUtil.generateJwk() and SigningKeyUtil.createSigner() methods exist with correct signatures and compatible implementations. The refactoring properly delegates to the handler pattern for algorithm-specific behavior.

src/main/java/io/mosip/mimoto/service/impl/CredentialRequestServiceImpl.java (1)

58-60: SigningKeyUtil methods verified and properly implemented.

The refactoring consolidates cryptographic operations into SigningKeyUtil:

  • Line 58: generateKeyPair(signingAlgorithm) ✓ exists with matching signature
  • Lines 60, 113: generateJwt(signingAlgorithm, issuer, clientId, nonce, keyPair) ✓ exists with matching signature

Both methods are public static, properly documented, and all call sites use correct parameter types and order. The consolidation from KeyGenerationUtil and JwtGeneratorUtil is complete.

src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactory.java (1)

13-38: LGTM! Clean factory pattern implementation.

Good use of EnumMap for efficient enum-keyed storage. The static initialization ensures thread-safe reads since the map is never modified after class loading. The design correctly relies on handler implementations being stateless (as documented in the interface).

src/test/java/io/mosip/mimoto/util/factory/ES256AlgorithmHandlerTest.java (1)

69-76: Test validates correct exception behavior for type mismatch.

Good defensive test ensuring createSigner properly fails when given an incompatible JWK type (RSA instead of EC).

src/main/java/io/mosip/mimoto/util/factory/RS256AlgorithmHandler.java (1)

34-47: Implementation is correct and follows the handler pattern.

The handler correctly:

  • Creates JWK with RS256 algorithm and SIGNATURE use
  • Configures the signer with BouncyCastle provider for consistency
src/test/java/io/mosip/mimoto/service/KeyPairServiceTest.java (1)

11-11: Migration to SigningKeyUtil is consistent and complete.

The test file correctly migrates from KeyGenerationUtil to SigningKeyUtil, updating all mock references and method calls from getKeyPairFromDBStoredKeys to generateKeyPairFromBytes. The test coverage remains comprehensive across all signing algorithms.

Also applies to: 87-94

src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandler.java (1)

20-30: Well-designed strategy interface.

The interface correctly abstracts algorithm-specific operations. The @implNote documenting thread-safety and statelessness requirements is helpful for implementers.

One consideration: createJWK performs unchecked casts internally in implementations (e.g., to ECPublicKey or RSAPublicKey). Consider whether documenting the expected key types in the Javadoc would improve usability.

src/main/java/io/mosip/mimoto/util/factory/ES256KAlgorithmHandler.java (2)

26-32: Static analysis warnings are false positives - ignore them.

The ast-grep warnings about "Triple DES" and "AES with ECB mode" are incorrect. This code uses "EC" (Elliptic Curve) for ECDSA key generation, not encryption. The secp256k1 curve correctly requires the BouncyCastle provider as it's not available in the default JCE.


39-52: Correct ES256K implementation using secp256k1.

The handler properly:

  • Uses Curve.SECP256K1 for the JWK builder
  • Sets JWSAlgorithm.ES256K
  • Configures the signer with BouncyCastle provider
src/main/java/io/mosip/mimoto/util/factory/ES256AlgorithmHandler.java (4)

26-31: LGTM: Key pair generation correctly uses secp256r1 curve.

The implementation properly initializes the EC key pair generator with the P-256 curve parameters. The method relies on the default JCA provider for key generation, which is acceptable as BouncyCastle is explicitly used for signing operations (line 49).


34-36: LGTM: KeyFactory retrieval is correct.


39-44: LGTM: JWK creation is correctly configured.

The method properly constructs an ECKey with the P-256 curve, ES256 algorithm, and signature key use, matching the key generation parameters.


47-51: LGTM: Signer creation correctly uses BouncyCastle provider.

The implementation properly instantiates an ECDSASigner and explicitly configures it to use the BouncyCastle provider for cryptographic operations.

src/test/java/io/mosip/mimoto/service/WalletPresentationServiceTest.java (2)

24-24: LGTM: Import updated to SigningKeyUtil.

The import change from JwtGeneratorUtil to SigningKeyUtil aligns with the PR's consolidation objective.


232-236: LGTM: Mock static contexts consistently updated.

All MockedStatic blocks and method calls have been systematically updated from JwtGeneratorUtil to SigningKeyUtil. The test logic and assertions remain unchanged, confirming this is a clean refactoring.

Also applies to: 306-310, 420-421, 448-452, 490-494, 529-534, 626-627, 649-650, 678-682, 733-734, 762-763, 774-778, 813-817, 857-860, 900-904, 947-951, 991-995, 1034-1038

src/test/java/io/mosip/mimoto/util/factory/ED25519AlgorithmHandlerTest.java (5)

22-29: LGTM: Key pair generation test is comprehensive.

The test properly validates key pair generation, including non-null checks and algorithm verification.


32-37: LGTM: KeyFactory test is correct.


40-47: LGTM: JWK creation test validates type and algorithm.

The test correctly verifies that the JWK is an OctetKeyPair with Ed25519 algorithm.


50-56: LGTM: Signer creation test covers the happy path.


59-65: LGTM: Negative test validates type safety.

The test correctly verifies that attempting to create a signer with a mismatched JWK type throws ClassCastException, ensuring type safety in the handler.

src/test/java/io/mosip/mimoto/util/SigningKeyUtilTest.java (7)

23-61: LGTM: Test setup and key generation tests are comprehensive.

The test suite properly initializes the BouncyCastle provider and validates key generation for all supported algorithms with correct algorithm assertions.


64-85: LGTM: Key reconstruction tests cover positive and negative cases.

The tests properly validate key pair reconstruction from bytes and exception handling for invalid input.


87-98: LGTM: Encryption key generation tests are appropriate.


100-118: LGTM: JWT generation test validates structure and claims.

The test properly verifies JWT creation, parsing, and claim extraction including subject, audience, and nonce.


120-127: LGTM: JWK generation test covers the basics.


129-145: LGTM: Signer creation tests validate functionality and type safety.

The tests properly cover successful signer creation and verify that mismatched JWK types throw the expected exception.


147-171: LGTM: ProofSigningKey tests provide excellent coverage.

The tests validate ProofSigningKey creation for RS256 specifically and comprehensively for all algorithms, ensuring consistency across all supported signing algorithms.

src/main/java/io/mosip/mimoto/util/factory/ED25519AlgorithmHandler.java (2)

55-84: LGTM: Custom JWSSigner implementation is correct.

The custom JWSSigner implementation properly uses BouncyCastle's Ed25519Signer for signing operations. Creating a new signer instance on each sign() call (line 65) ensures thread-safety, though it sacrifices some performance. This is an acceptable trade-off for correctness.


33-41: No action required. The project is configured with Java 21 (both maven.compiler.source and maven.compiler.target), which fully supports Ed25519. The Ed25519 algorithm was introduced in Java 15, and Java 21 exceeds this requirement by a significant margin.

src/test/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactoryTest.java (1)

1-55: LGTM!

The test suite comprehensively covers the factory behavior - validating correct handler type resolution for all supported algorithms and proper exception handling for null input.

src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java (1)

46-141: Well-structured consolidation of key management operations.

The factory-based delegation pattern cleanly abstracts algorithm-specific details. The public API is cohesive and follows the single-responsibility principle for signing key operations.

…ecurity

Check Security.getProvider() before creating new BouncyCastleProvider
to ensure BC_PROVIDER matches the registered provider instance.
Make class final and add private constructor for utility class pattern.

Signed-off-by: Durgesh Konga <kongadurgesh20@gmail.com>
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

🧹 Nitpick comments (1)
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java (1)

33-35: Consider single-line constructor for consistency.

The empty private constructor could be simplified to a single line for consistency with standard utility class patterns.

🔎 Proposed refactor
-    private BouncyCastleProviderUtil(){
-
-    }
+    private BouncyCastleProviderUtil() {}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e11bb8b and 0b08091.

📒 Files selected for processing (5)
  • .talismanrc
  • src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java
  • src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java
  • src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactory.java
  • src/test/java/io/mosip/mimoto/util/WalletUtilTest.java
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/test/java/io/mosip/mimoto/util/WalletUtilTest.java
  • src/main/java/io/mosip/mimoto/util/SigningKeyUtil.java
  • .talismanrc
  • src/main/java/io/mosip/mimoto/util/factory/SigningAlgorithmHandlerFactory.java
⏰ 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). (2)
  • GitHub Check: build-mimoto / maven-build
  • GitHub Check: build-maven-apitest-mimoto / maven-build
🔇 Additional comments (2)
src/main/java/io/mosip/mimoto/util/factory/BouncyCastleProviderUtil.java (2)

15-23: LGTM! Previous provider registration inconsistency resolved.

The static initialization now correctly ensures BC_PROVIDER always references a provider that is registered in the Security context. By reusing an existing provider (line 18) or registering a new one (line 21), this addresses the concern from the previous review where the returned provider could be inconsistent with the global Security context.


29-31: LGTM! Provider access is consistent.

The getProvider() method correctly returns the singleton BC_PROVIDER instance, which is guaranteed to be registered by the static block logic.

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.

1 participant