prosgarz35 opened a new pull request, #3240:
URL: https://github.com/apache/james-project/pull/3240

   ## Summary
   
   This pull request introduces support for configuring TLS on the JMAP server 
directly using `.pem` certificates and private keys, as well as Java Keystores 
(JKS / PKCS12), matching the existing PEM TLS support found in IMAP, POP3, and 
SMTP protocols.
   
   Prior to this change, JMAP relied on plain HTTP, requiring an external 
reverse proxy (such as Nginx or Traefik) to terminate TLS. With this 
enhancement, administrators can terminate TLS natively within Apache James JMAP 
using standard PEM certificates (e.g. Let's Encrypt certificates) or existing 
keystores.
   
   ## Key Changes
   
   1. **`server/protocols/jmap` (`pom.xml`):**
      - Added `ayza-for-pem` (`io.github.hakky54:ayza-for-pem`) dependency to 
parse PEM-encoded certificates and private keys (PKCS#1, PKCS#8, EC, RSA) via 
`PemUtils`, consistent with the rest of James.
      - Added `james-server-filesystem-api` dependency to resolve 
certificate/keystore resource locations (`file://`, `classpath://`, etc.).
   
   2. **`JMAPConfiguration.java`:**
      - Added TLS configuration options:
        - `tls.keystoreURL` / `keystore`
        - `tls.keystoreType` / `keystoreType` (optional, default: JKS)
        - `tls.privateKey` / `privateKey`
        - `tls.certificates` / `certificates`
        - `tls.secret` / `secret` (optional password for keystore or encrypted 
private key)
      - Added `isTlsEnabled()` helper method checking if keystore or PEM 
certificate/key pair is supplied.
      - Preserved backward compatibility for testing constructors 
(`@VisibleForTesting`).
   
   3. **`JMAPServer.java`:**
      - Injected `FileSystem` into the Guice constructor.
      - Configured Reactor Netty `HttpServer` with `.secure(...)` when TLS is 
enabled.
      - Built Netty `SslContext`:
        - **PEM Mode:** Parsed certificate chain via 
`PemUtils.loadCertificate(...)` and private key via 
`PemUtils.loadPrivateKey(...)`, configured via 
`SslContextBuilder.forServer(privateKey, certificates)`.
        - **Keystore Mode:** Loaded keystore via 
`KeyStoreUtils.loadKeyStore(...)`, configured via 
`SslContextBuilder.forServer(KeyManagerUtils.createKeyManager(keyStore, 
password))`.
        - **RFC Compliance:** Explicitly enforced TLS 1.2 and TLS 1.3 protocols 
(`RFC 5246` and `RFC 8446`), avoiding insecure older versions (SSLv3, TLS 1.0, 
TLS 1.1).
   
   4. **`JMAPModule.java`:**
      - Added parsing of TLS parameters from `jmap.properties`.
   
   5. **Tests:**
      - Added unit tests in `JMAPConfigurationTest` for verifying TLS 
properties and builder options.
      - Added integration test cases in `JMAPServerTest` verifying successful 
HTTPS startup and request handling with both PEM certificates/keys and Keystore 
configurations.
   
   ## Configuration Example (`jmap.properties`)
   
   ### Option A: PEM Certificates (e.g., Let's Encrypt)
   ```properties
   # Enable JMAP
   enabled=true
   port=8443
   
   # TLS with PEM files
   tls.certificates=file://conf/cert.pem
   tls.privateKey=file://conf/privkey.pem
   # tls.secret=optional_key_password
   ```
   
   ### Option B: Keystore
   ```properties
   # Enable JMAP
   enabled=true
   port=8443
   
   # TLS with Keystore
   tls.keystoreURL=file://conf/keystore
   tls.keystoreType=PKCS12
   tls.secret=mysecretpassword
   ```
   
   ## Adherence to Principles
   - **KISS:** Directly leverages Netty's 
`SslContextBuilder.forServer(PrivateKey, X509Certificate[])` without 
superfluous wrapper layers.
   - **DRY:** Reuses `ayza-for-pem` and `FileSystem` mechanisms already adopted 
across James protocols.
   - **YAGNI:** Only includes server-side TLS termination required for 
HTTPS/JMAP, omitting unnecessary client-certificate authentication or dynamic 
hot-swapping complexes.
   - **RFC:** Strictly restricts protocol negotiation to TLSv1.2 and TLSv1.3.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to