Skip to main content

Getting started with Domino AppDev Pack Java API - Part 2

In my previous post I've shown how to quickly start coding with Domino AppDev Pack Java API. I used an insecure connection to avoid dealing with certificates, now it's time to fix this. If you are testing the new Java API, which is marked as a preview, you probably enjoy living on the edge and may also have a V12 EAP Domino server somewhere. This may help us see how the future may look.

Domino AppDev Pack series:
2. Certificates (this)


The AppDev Pack distribution contains sample files that generate ca, certificates and kyr file using openssl, but this is a one-time operation that is pretty hard to repeat or even use in production. If you want to use this in production, you should use a proper certificate authority. Last week Daniel Nashed posted info about nice enhancements coming to V12 that can help us here Domino V12 ACME for company CAs using smallstep and Easy kyr file creation with Early Access V12 in production.

smallstep ca

step-ca is an open source online certificate authority that can be easily hosted in Docker and supports ACME protocol (know primarily from Let'sEncrypt). It makes it very easy to run your own PKI and automate the certificate management. 

Domino V12 now has support for ACME and it works with step-ca too. Now we just need to connect the pieces. 

Goal

The primary goal of this part is to secure the communication between the Java client and the Proton server and authenticating the app using a certificate.

I'll be mixing V12 and V11.0.1 environments here as V12 is currently available only in Docker and I have my Proton task running on different Windows VM. I think once V12 is out, all this will work together nicely.

Steps:
  1. Setup the CA
  2. Get a Domino kyr using ACME
  3. Configure the kyr in Proton
  4. Create a user certificate
  5. Import the certificate to Domino Directory
  6. Use the certificate from Java API
Sounds pretty easy, but there are few issues when doing this with current versions.

Setup the CA

I won't cover the full setup of the smallstep ca here as the project has nice tutorials, including docker installation. Basically, it's about running 

step ca init 

and answering few questions.

Once you have the default setup in place, you need to do 2 configuration adjustments:

1. Add support for ACME
Done simply by executing

step ca provisioner add my-acme-provisioner --type ACME

2. Extend the default certificate duration
The default expiration is set to 1 day and we don't want to change the certs every day now. Add the claims to config/ca.json, - e.g.

 "claims": {
                        "maxTLSCertDuration": "17520h0m0s",
                        "defaultTLSCertDuration": "17520h0m0s"
                }
See documentation for details. 

Don't forget to restart the ca, e.g. kill -1 1 if running in Docker.

Get the kyr file for Domino

Now it's getting more interesting.  Daniel explained that it's possible to generate the kyr file for Domino servers probably starting with version 9.0.1, but to do it properly, you'd have to install the DSAPI filter on that server too. 

For now, I just temporarily changed my DNS record to point to my V12 server using my Proton server address, this way I was able to get the certificate/kyr, which I could just copy to the server manually. Once everything is running on V12, this all will be fully automated, including renewals (and maybe we can go back to the 1 day certificates).

You need to do follow the standard setup procedure for Let's Encrypt integration - https://help.hcltechsw.com/domino/earlyaccess/secu_le_preparing.html

Then copy the PEM from the root certificate of the CA - it's in certs/root_ca.crt and then create the ACME Account configuration document in the Certificate Store.

Enter the following information:
  • Account Name - some meaningful name
  • ACME Directory URL - based on the information you used to create the ca
    https://<ca_host>:<ca_port>/acme/acme/directory
    e.g. https://ca.pris.to:9999/acme/acme/directory
  • Key Algorithm - set to RSA
  • On Security/Keys tab - paste the root_ca.crt content



Now you should be ready to request the certificate. Create new Key File document and select the account that you've just configured.


Leave the Domino Server Names empty, the CertMgr then should not try to copy the kyr file to the server and restart the HTTP, which you normally want to happen if you would use it on the current server. 

If everything works well .....

you get the kyr file at the bottom of the form.

Few comments ...

The key must but RSA, not ECDSA as ECDSA support was added in V12 and is probably still being improved. 

If you are running the test Domino server behind some reverse proxy, e.g. like me on a Synology NAS, you may have a problem with /.well-known/acme-challenge being used by the proxy to handle its certificate requests. It's easy to test as it's returning "Challenge NOT found" for unknown ids



Configure the kyr in Proton

Now just copy the kyr and sth file to Data directory of your Proton server. Then open the Proton settings and insert the name of the kyr file.


Last step, enable the Client Certificate authentication. When saving the configuration, the Proton will ask for a restart. If all is good you should see

PROTON: Listening on 0.0.0.0:3003, SSL-ENABLED
PROTON: Server initialized

Create a user certificate

The easiest way to create a user certificate is go directly to the ca and use step ca certificate command.
Just make sure the common name matches the name of the user you want to use. E.g.




Then select the JWK provisioner and you should get a certificate and a key.


This should work fine for the Node.js domino-db module, but with the Java API I had a problem that the key file was not consumed correctly. I had to create a pkcs#8 version of the key file, which allowed the Java API to use it just fine.

You can use the step crypt key command to do the conversion, e.g. if you don't want to use a password.

step crypto key format protonapp1.key --pem --pkcs8 --no-password --insecure --out protonapp1-pkcs8.key

Then copy the files to your workstation, where the Notes client and your Java program can access them.

Import the certificate to Domino Directory


Register a user for the connection as usual (no mailfile is needed). Once it's registered, open the person document, and from the Actions menu choose Import Internet Certificates.

Select All Files, pick the .crt file and confirm the import.

Re-open the person document and you should see the certificate.


Use the certificate from the Java API

Now is time for the last step. Using the certificates from the Java API. 

Currently, there seems to be an issue with handling of the trust chain in Java, so we need to make few adjustments. Node.js domino-db module seems to work just fine with these files. I've already mentioned the different key file format. 

The second issue requires combining the root_ca.crt and intermediate_ca.crt to a trust.crt file. You can also grab the intermediate certificate from the user.crt. I'll need to check this with HCL. For now just open the root_ca.crt, prepend it with the certificate for intermediate ca. Save the file as trust.crt.


Now you should be ready to use everything from your code.


If you run my sample, you should see that the document is now created by the new user.



Summary

It was a bit painful process to get this to work, but I know that Java API is in preview and V12 is in the Early access program. Daniel Nashed tried to help me and I've learned many things about smallstep ca, cryptography and Domino along the way. This setup should be good for use in production when you e.g. want to do system-to-system data integration, e.g. batch processing of Domino data from external Java-based system.

I hope that future versions will remove those manual workarounds, namely:
  • problem with the trust chain 
  • problem with the key file handling
  • ECDSA support for kyr - should be in V12 already where it works for HTTP task just fine.

Code is available in github - https://github.com/mpradny/appdevpack-java-helloworld/tree/part-2, certs are loaded from the resources folder. I've also removed the dependencies from the pom.xml, so if you want to use it directly, you need to add the artifact manually to your maven repository.

Comments

Popular posts from this blog

Microsoft Word black box in numbering issue

This is awkward post, primarily to save the solution for future me. I have seen many people mentioning this problem over years and as I've struggled with it several times, I needed to find final and permanent solution. All editions of Microsoft Word from time to time suffer from bug in numbering. Instead of a number, black box is displayed. Sometimes it happens right after document is opened, sometimes during editing. Probably some internal structure of document gets corrupted, so based on level of corruption, different fixes could help. Many of them are listed at  https://answers.microsoft.com/en-us/office/forum/office_2010-word/ms-word-header-styles-are-showing-black-boxes/c427b21c-dcda-46ce-a506-b9a16c9f2f3f I took different approach. Since docx is just standard zip package with xml files, I decided to try if I can fix it manually. And it worked. When I extracted the docx, there was file called numbering.xml in word folder. When I examined that file, I found strange se

WSL, HCL Volt and some Docker

My list of new technologies to try was growing fast in past months, but now I finally can try to catch up with all the cool improvements that can be used to enhance my/your dev experience. Microsoft has enhanced the Windows Subsystem for Linux this year and Docker completely changed the way Docker Desktop for Windows is integrated into the operating system. The most important change for me was that I can finally run Docker Desktop and VMWare Workstation on my machine in parallel. When I was looking for some good use cases to try how it works, HCL Domino was a logical choice. HCL started to even publish official Docker images for every release and some pre-releases are only available as Docker images. I have many test Domino machines running in VMs, but I had no HCL Volt. If you don't know that HCL Volt is - it's a new low-code platform that brings HCL Form Builder experience, now know as HCL Leap, to HCL Domino, which then serves as a data store and application server. Whe

XPages ${} risk of code injection

While working on app optimization I experimented a bit more with 'Compute on page load' vs. 'Compute dynamically' behavior. There have been several discussions in past about possible combination of ${} and #{}, for example posts from  Marky Roden ,  Sven Hasselbach  and  Paul Withers  . What struck me today was risk of code injection. In this app many elements are read from configuration documents that are loaded into beans and later used using ${} binding. This is recommended way as it is static information, so it's efficient. It works nicely until you insert expressions into your data. This way I realized that a lot of code is prone to code injection that can be contained either in configuration documents or any string that is stored and later read this way. To simulate the issue I created simple page with one field, one button and one text: All it does is saving entered value into applicationScope and then displaying it. Since the text uses ${} Compute o