Implementing A Linux Root CA In A Windows Domain

There are many steps and procedures to follow when implementing a public key infrastructure that are imperative to its success that fall outside the scope of this write up. Specifics on topics such as adding A records to a DNS server for domain name resolution will not be covered.

Before Starting: The planning and designing phase of this process is the most important to ensuring the success of your efforts. A good resource to help with understanding the design and planning of a PKI can be found here here. Although Microsoft focused, this was a valuable resource in my PKI implementation.



  1. Configure a Linux server as a root CA
  2. Add the IIS role to a Windows server and set up a virtual directory as the CDP
  3. Add the Active Directory Certificate Services role to the Windows server that will act as the subordinate CA
  4. Sign the subordinate CA’s CSR on the Linux root CA
  5. Issue a CRL from the Linux root CA
  6. Import and install certificates on subordinate CA and IIS CDP
    1. Components

      • Windows Domain Controller
      • Linux offline root CA
      • Windows intermediate CA (Server 2012 R2 or later)
      • Windows IIS server

      Configure the Linux Offline Root CA

      First install the openssl package if it is not already installed.

      create the following directories and files

      mkdir -p ca/{certs,csr,private}
      touch ca/index.txt
      echo 0001 > ca/serial
      echo 0001 > ca/crlnumber
      chmod 700 ca/private

      Create and modify an openssl config file

      Copy the following configuration file to the ca directory. And modify the ROOT_CA_FILENAME, HTTP_HOST, and HTTP_HOST_DIR variables to suit your environment

      # OpenSSL Configuration File
      [ ca ]
      # `man ca`
      default_ca = CA_default
      [ CA_default ]
      # Directory and file locations.
      dir               = /root/ca
      certs             = $dir/certs
      new_certs_dir     = $dir/newcerts
      database          = $dir/index.txt
      serial            = $dir/serial
      RANDFILE          = $dir/private/.rand
      # The root key and root certificate.
      private_key       = $dir/private/$ROOT_CA_FILENAME.key.pem
      certificate       = $dir/certs/$ROOT_CA_FILENAME.cert.pem
      # For certificate revocation lists.
      crlnumber         = $dir/crlnumber
      crl               = $dir/$ROOT_CA_FILENAME.crl.pem
      crl_extensions    = crl_ext
      default_crl_days  = 30
      # SHA-1 is deprecated, so use SHA-2 instead.
      default_md        = sha256
      name_opt          = ca_default
      cert_opt          = ca_default
      default_days      = 375
      preserve          = no
      policy            = policy_any
      [ policy_any ]
      # Allow the intermediate CA to sign a more diverse range of certificates.
      # See the POLICY FORMAT section of the `ca` man page.
      countryName             = optional
      stateOrProvinceName     = optional
      localityName            = optional
      organizationName        = optional
      organizationalUnitName  = optional
      commonName              = supplied
      emailAddress            = optional
      [ req ]
      # Options for the `req` tool (`man req`).
      default_bits        = 4096
      distinguished_name  = req_distinguished_name
      string_mask         = utf8only
      # SHA-1 is deprecated, so use SHA-2 instead.
      default_md          = sha256
      # Extension to add when the -x509 option is used.
      x509_extensions     = v3_ca
      [ req_distinguished_name ]
      # See .
      countryName                     = Country Name (2 letter code)
      stateOrProvinceName             = State or Province Name
      localityName                    = Locality Name
      0.organizationName              = Organization Name
      organizationalUnitName          = Organizational Unit Name
      commonName                      = Common Name
      emailAddress                    = Email Address
      # Optionally, specify some defaults.
      countryName_default             = 
      stateOrProvinceName_default     = 
      localityName_default            =
      0.organizationName_default      = 
      organizationalUnitName_default  =
      emailAddress_default            =
      [ v3_ca ]
      # Extensions for a typical CA (`man x509v3_config`).
      subjectKeyIdentifier = hash
      authorityKeyIdentifier = keyid:always,issuer
      basicConstraints = critical, CA:true
      keyUsage = critical, digitalSignature, cRLSign, keyCertSign
      [ v3_intermediate_ca ]
      # Extensions for a typical intermediate CA (`man x509v3_config`).
      subjectKeyIdentifier = hash
      authorityKeyIdentifier = keyid:always,issuer
      basicConstraints = critical, CA:true, pathlen:0
      keyUsage = critical, digitalSignature, cRLSign, keyCertSign
      authorityInfoAccess = caIssuers;URI:http://$HTTP_HOST/$HTTP_HOST_DIR/$ROOT_CA_FILENAME.crt
      crlDistributionPoint = URI:http://$HTTP_HOST/$HTTP_HOST_DIR/$ROOT_CA_FILENAME.crl
      [ usr_cert ]
      # Extensions for client certificates (`man x509v3_config`).
      basicConstraints = CA:FALSE
      nsCertType = client, email
      nsComment = "OpenSSL Generated Client Certificate"
      subjectKeyIdentifier = hash
      authorityKeyIdentifier = keyid,issuer
      keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
      extendedKeyUsage = clientAuth, emailProtection
      [ server_cert ]
      # Extensions for server certificates (`man x509v3_config`).
      basicConstraints = CA:FALSE
      nsCertType = server
      nsComment = "OpenSSL Generated Server Certificate"
      subjectKeyIdentifier = hash
      authorityKeyIdentifier = keyid,issuer:always
      keyUsage = critical, digitalSignature, keyEncipherment
      extendedKeyUsage = serverAuth
      [ crl_ext ]
      # Extension for CRLs (`man x509v3_config`).
      [ ocsp ]
      # Extension for OCSP signing certificates (`man ocsp`).
      basicConstraints = CA:FALSE
      subjectKeyIdentifier = hash
      authorityKeyIdentifier = keyid,issuer
      keyUsage = critical, digitalSignature
      extendedKeyUsage = critical, OCSPSigning

      Generate the key pair

      openssl genrsa -aes256 -out ca/private/rootca.key.pem 4096
      chmod 400 ca/private/rootca.key.pem 

      Create the root certificate

      openssl req -config ca.cnf \
            -key private/rootca.key.pem \
            -new -x509 -days 3600 -sha256 -extensions v3_ca \
            -out certs/rootca.cert.pem
      chmod 444 ca/certs/rootca.cert.pem

      You will be prompted for some information following the above command. You can pass a period (.) to answer with a blank line. Be sure to use a descriptive name for the CN prompt such as “Company INC Root Certificate Authority”

      Setup virtual directory in IIS

      On the Windows server that will act as the CDP install the IIS role if it is not already. The FQDN of the IIS server must resolve to what ever you used for the HTTP_HOST variable in the openssl config file.

      To set up the virtual directory

      1. Open IIS Manger
      2. Enpand the containers in the left hand pane to “Default Site”, right click “Default Site” and select “add virtual directory”
      3. For the alias enter what you used for the HTTP_HOST_DIR variable in the openssl config file (crld in the example config).
      4. For the physical path either select or make a new directory you’d like to use as the CDP
      5. click ok
      6. Back in IIS manager with the new virtual directory selected in the left pane, select directory browsing from the middle pane
      7. click enable in the right pane
      8. With the virtual directory still selected in the middle pane select configuration editor
      9. In the drop down menu select system.WebServer>>Security>>requestFiltering
      10. Set allow double escape to True

      You may be required to modify the permissions on the new virtual directory if revocation checking fails when you start the intermediate Windows CA

      Set up the Windows intermediate CA

      Before continuing if you have not already set up DNS records for the IIS server and Windows intermediate CA do so now.

      This is a good time to import the root CA certificate we created to the intermediate CA

      To import the root ca certifcate:

      1. after copying over the root certificate rename it with the .crt extension. Be sure to use the extension that was used in the openssl config file for the authorityInfoAccess.
      2. open a new mmc
      3. add the certificates snap-in for the computer account
      4. right click the trusted root certificate authority container and select import
      5. browse to where you copied over the root ca certificate.
      6. click ok

      Install and configure AD CS

      1. Install the “Active Directory Certifiacate Services” role on the Windows server that will act as the intermediate CA
      2. Install the management features as well
      3. When configuring the CA select Enterprise CA, then select subordinate CA
      4. When prompted select generate a new key pair and generate a Microsoft RSA key using SHA256 and set the key length to 4096. This will generate a CSR file (*.req) on the C: drive.
      5. copy the CSR over to the root CA

      On the root CA run the following to sign the CSR

      openssl ca -out subca.crt -notext -days 1825  -extensions v3_issuing_ca -config ./ca.cnf -infiles your-sub-ca-csr.req

      Now generate a CRL

      openssl ca -gencrl -out rootca.crl -config ca.cnf

      Now copy the CRL over to the IIS server saving it to the virtual directory created earlier. Also copy the signed sub CA certificate to the Windows certificate authority. Be sure to change the extension of the CRL file after copying it over to the IIS server to match what you used for the crlDistribuionPoint varibale in the openssl config fle.

      Back on the Windows intermediate CA

      1. Open the certificate authority tool
      2. Right click the CA in the left hand pane and select install CA certificate
      3. Navigate to sub CA certificate and click ok.

      The AD CS role should now be active on the Windows intermediate CA.

Ubuntu 16.04.2 LTS released, Arch Linux ending i686 support, AnC side-channel attack, and OpenSSL update.

Arch Linux’s February ISO is to be the last release with i686 support, and will only receive updates for the next nine months. According to it is due to a decreasing lack of popularity among devs and the community. The people at Arch are encouraging anyone still interested to “keep it alive” with some guidance from the Arch team.

Arch:Phasing out i686

Over at Vusec they document a side-channel attack, which can detect which locations in the page table are accessed by the memory management unit. The attack takes advantage of the cache hierarchy of modern processors being shared by untrusted applications. More details in the link below.

Vusec:AnC attack

OpenSSL 1.1.0 updates to 1.1.0e.

OpenSSL:1.1.0e update

Ubuntu releases 16.04.2 LTS.

Ubuntu:16.04.2 released