io7m | single-page | multi-page | Canonmill User Manual
1. Introduction
Previous
Front Matter
Up
Front Matter
Next

# 2. Usage

- 2.1. Maven
- 2.2. Index
- 2.3. Loading A Keystore
- 2.4. Reloading A Keystore
- 2.5. Schema

## 2.1. Maven

1
Use the following Maven dependency:

### 2.1.2. Maven Dependency

    <dependency>
      <groupId>com.io7m.canonmill</groupId>
      <artifactId>com.io7m.canonmill.core</artifactId>
      <version>2.1.1-SNAPSHOT</version>
    </dependency>

## 2.2. Index

1
To use the canonmill keystore, it's first necessary to create a directory that will contain PEM-encoded private keys and certificates. It's then necessary to create an index file that maps aliases to keys/certificates.
2
An an example, assume the following files exist:

### 2.2.3. Example Keys/Certificates

Name | Description
--- | ---
www.key | The private key for www.example.com
www.crt | The public certificate for www.example.com
mail.key | The private key for mail.example.com
mail.crt | The public certificate for mail.example.com

4
Now, all of these files could be placed in a directory /etc/certs. We can now create the index file and place it anywhere the application wants it to be. The index file has a strictly-defined XML format with a schema. An example index file might look like this:

### 2.2.5. Example Index

    <?xml version="1.0" encoding="UTF-8" ?>

    <Keystore xmlns="urn:com.io7m.canonmill.keystore:1"
              BaseDirectory="/etc/certs">
      <Key Name="www.example.com"
           File="www.key"/>
      <Key Name="mail.example.com"
           File="mail.key"/>
      <Certificate Name="www.example.com"
                   File="www.crt"/>
      <Certificate Name="mail.example.com"
                   File="mail.crt"/>
    </Keystore>

6
Each Key and Certificate entry assigns an alias to a key or certificate, respectively. The filenames given are resolved relative to the directory given by the BaseDirectory attribute.

## 2.3. Loading A Keystore

1
To load a keystore, the standard Keystore API should be used. Assuming that the keystore's XML index file exists at file:

### 2.3.2. Example Load

    final var ks =
      KeyStore.getInstance("CANONMILL", new CMKeyStoreProvider());

    try (var stream = Files.newInputStream(file)) {
      ks.load(stream, null);
    }

3
The CMKeyStoreProvider class is registered using the name CANONMILL as service of type java.security.Provider and so can be used in the same manner as any other provider in the JDK security API.

## 2.4. Reloading A Keystore

1
The standard keystore API provides methods to reload KeyStore values at any time. Unfortunately, other parts of the security API such as the SSLContext will cache the keys and certificates internally and so reloading the KeyStore is ineffective.
2
The CMKeyStores class contains convenience methods to construct an SSLContext for use in applications, and to reload any given SSLContext.

### 2.4.3. Example Reload

    final KeyStore ks =
      CMKeyStores.openKeyStore(Paths.get("ServerKeyStore.xml"));
    final KeyStore ts =
      CMKeyStores.openKeyStore(Paths.get("ServerTrustStore.xml"));

    final SSLContext context =
      CMKeyStores.createSSLContext(ks, ts, "TLSv1.3");

    // Open server sockets, etc

    CMKeyStores.reloadKeystoreFromFile(ks, Paths.get("ServerKeyStore.xml"));
    CMKeyStores.reloadKeystoreFromFile(ts, Paths.get("ServerTrustStore.xml"));
    CMKeyStores.reloadSSLContext(ks, ts, context);

## 2.5. Schema

1
The XML schema for the keystore's index file is as follows:

### 2.5.2. Keystore Schema

    <?xml version="1.0" encoding="UTF-8" ?>

    <!--
      Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com

      Permission to use, copy, modify, and/or distribute this software for any
      purpose with or without fee is hereby granted, provided that the above
      copyright notice and this permission notice appear in all copies.

      THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
      SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
      IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    -->

    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                targetNamespace="urn:com.io7m.canonmill.keystore:1"
                xmlns:cm="urn:com.io7m.canonmill.keystore:1">

      <xsd:complexType name="KeystoreElementType"
                       abstract="true">
        <xsd:annotation>
          <xsd:documentation>
            The base type of elements that can appear in a keystore.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:attribute name="Name"
                       type="xsd:string"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The name of the keystore element.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>

        <xsd:attribute name="File"
                       type="xsd:string"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The file containing data for the keystore element.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:complexType>

      <xsd:complexType name="CertificateType">
        <xsd:annotation>
          <xsd:documentation>
            The type of certificates within a keystore.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:complexContent>
          <xsd:extension base="cm:KeystoreElementType"/>
        </xsd:complexContent>
      </xsd:complexType>

      <xsd:element name="Certificate"
                   type="cm:CertificateType"/>

      <xsd:complexType name="KeyType">
        <xsd:annotation>
          <xsd:documentation>
            The type of keys within a keystore.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:complexContent>
          <xsd:extension base="cm:KeystoreElementType"/>
        </xsd:complexContent>
      </xsd:complexType>

      <xsd:element name="Key"
                   type="cm:KeyType"/>

      <xsd:group name="KeystoreElementGroup">
        <xsd:annotation>
          <xsd:documentation>
            The group containing elements that can appear within a keystore.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:choice>
          <xsd:element ref="cm:Certificate"/>
          <xsd:element ref="cm:Key"/>
        </xsd:choice>
      </xsd:group>

      <xsd:element name="Keystore">
        <xsd:annotation>
          <xsd:documentation>
            The keystore element.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:complexType>
          <xsd:sequence minOccurs="0"
                        maxOccurs="unbounded">
            <xsd:group ref="cm:KeystoreElementGroup"/>
          </xsd:sequence>

          <xsd:attribute name="BaseDirectory"
                         use="required"
                         type="xsd:anyURI">
            <xsd:annotation>
              <xsd:documentation>
                The absolute path of the keystore directory.
              </xsd:documentation>
            </xsd:annotation>
          </xsd:attribute>
        </xsd:complexType>

        <xsd:key name="KeyUnique">
          <xsd:selector xpath="cm:Key"/>
          <xsd:field xpath="@Name"/>
        </xsd:key>

        <xsd:key name="CertificateUnique">
          <xsd:selector xpath="cm:Certificate"/>
          <xsd:field xpath="@Name"/>
        </xsd:key>
      </xsd:element>

    </xsd:schema>

1. Introduction
Previous
Front Matter
Up
Front Matter
Next
io7m | single-page | multi-page | Canonmill User Manual