From 130febb3d328a63417d42c58bcc119cb55433eaf Mon Sep 17 00:00:00 2001
From: Fabien COMBERNOUS <fabien.combernous@adullact.org>
Date: Wed, 30 Nov 2022 19:40:29 +0100
Subject: [PATCH] add crl_url for intermediate CA

---
 REFERENCE.md                  | 24 +++++++++++++++++++++---
 manifests/ca/intermediate.pp  | 18 ++++++++++++------
 spec/acceptance/cfssl_spec.rb | 20 ++++++++++++++++++--
 3 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/REFERENCE.md b/REFERENCE.md
index 1e1b01b..4a5314f 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -444,9 +444,9 @@ Creates an intermediate authority signed by root authority
 ```puppet
 cfssl::ca::intermediate { 'MYEXEMPLE INTERMDIATE CA':
   subject => {
-    'C' => 'FR',
-    'L' => 'MONTPELLIER',
-    'O' => 'MYEXEMPLE ORG',
+    'C'   => 'FR',
+    'L'   => 'MONTPELLIER',
+    'O'   => 'MYEXEMPLE ORG',
   },
 }
 ```
@@ -458,6 +458,8 @@ The following parameters are available in the `cfssl::ca::intermediate` defined
 * [`subject`](#subject)
 * [`expiry`](#expiry)
 * [`key`](#key)
+* [`crl_url`](#crl_url)
+* [`ocsp_url`](#ocsp_url)
 
 ##### <a name="subject"></a>`subject`
 
@@ -483,6 +485,22 @@ Cryptographic algorithm used for creating key pairs.
 
 Default value: `{ algo => 'rsa', size => 2048 }`
 
+##### <a name="crl_url"></a>`crl_url`
+
+Data type: `Optional[Stdlib::HTTPUrl]`
+
+The CRL url of the Root CA that issued intermediate CA.
+
+Default value: ``undef``
+
+##### <a name="ocsp_url"></a>`ocsp_url`
+
+Data type: `Optional[Stdlib::HTTPUrl]`
+
+The OCSP responder of the Root CA that issued intermediate CA.
+
+Default value: ``undef``
+
 ## Data types
 
 ### <a name="cfsslauthkey"></a>`Cfssl::Authkey`
diff --git a/manifests/ca/intermediate.pp b/manifests/ca/intermediate.pp
index 68f1d20..2c4ad1c 100644
--- a/manifests/ca/intermediate.pp
+++ b/manifests/ca/intermediate.pp
@@ -5,20 +5,24 @@
 # @example
 #   cfssl::ca::intermediate { 'MYEXEMPLE INTERMDIATE CA':
 #     subject => {
-#       'C' => 'FR',
-#       'L' => 'MONTPELLIER',
-#       'O' => 'MYEXEMPLE ORG',
+#       'C'   => 'FR',
+#       'L'   => 'MONTPELLIER',
+#       'O'   => 'MYEXEMPLE ORG',
 #     },
 #   }
 #
 # @param subject Hash like Subject in X509 that identifies the entity associated
 # @param expiry Duration of authority
 # @param key Cryptographic algorithm used for creating key pairs.
+# @param crl_url The CRL url of the Root CA that issued intermediate CA.
+# @param ocsp_url The OCSP responder of the Root CA that issued intermediate CA.
 #
 define cfssl::ca::intermediate (
   Hash $subject = { 'C' => 'FR', 'L' => 'MONTPELLIER', 'O' => 'EXEMPLE ORG', },
   String[1] $expiry = '26280h',
   Cfssl::Ca::Key $key = { algo => 'rsa', size => 2048 },
+  Optional[Stdlib::HTTPUrl] $crl_url = undef,
+  Optional[Stdlib::HTTPUrl] $ocsp_url = undef,
 ) {
   require cfssl::ca::root
 
@@ -29,9 +33,9 @@ define cfssl::ca::intermediate (
   $_intermediatecn = $name
   $_intermediateca_name = regsubst($name, '\s', '', 'G')
   $_intermediateca_csr = {
-    cn    => $_intermediatecn,
-    names => [$subject],
-    key   => $key,
+    cn       => $_intermediatecn,
+    names    => [$subject],
+    key      => $key,
   }
   $_intermediateca_csr_json = to_json($_intermediateca_csr)
 
@@ -39,6 +43,8 @@ define cfssl::ca::intermediate (
     signing => {
       'default' => {
         expiry        => $expiry,
+        crl_url       => $crl_url,
+        ocsp_url      => $ocsp_url,
         ca_constraint => {
           is_ca        => true,
           max_path_len => 1,
diff --git a/spec/acceptance/cfssl_spec.rb b/spec/acceptance/cfssl_spec.rb
index b89aa7e..4d2305f 100644
--- a/spec/acceptance/cfssl_spec.rb
+++ b/spec/acceptance/cfssl_spec.rb
@@ -89,6 +89,14 @@ describe 'cfssl' do
               'O' => 'MYEXEMPLE ORG',
             },
           },
+          'MYEXEMPLE2 INTERMDIATE CA' => {
+            subject => {
+              'C' => 'FR',
+              'L' => 'MONTPELLIER',
+              'O' => 'MYEXEMPLE2 ORG',
+            },
+            crl_url => 'http://crl.exemple2.org/crl-MYEXEMPLE2INTERMDIATECA.crl',
+          },
         },
         serve_ca   => 'MYEXEMPLE INTERMDIATE CA',
         crl_manage => true,
@@ -110,12 +118,20 @@ describe 'cfssl' do
       its(:stdout) { is_expected.to match %r{BEGIN CERTIFICATE} }
     end
 
+    # rubocop:disable RSpec/RepeatedDescription
     describe command('openssl x509 -in /etc/cfssl/ca/MYEXEMPLEINTERMDIATECA.pem -text -noout') do
-      # rubocop:disable RSpec/RepeatedDescription
       its(:stdout) { is_expected.to match %r{Certificate:} }
       its(:stdout) { is_expected.to match %r{Issuer: C = FR, L = MONTPELLIER, O = MYEXEMPLE ORG, CN = MYEXEMPLE ROOT CA} }
       its(:stdout) { is_expected.to match %r{Subject: C = FR, L = MONTPELLIER, O = MYEXEMPLE ORG, CN = MYEXEMPLE INTERMDIATE CA} }
       its(:stdout) { is_expected.to match %r{CA:TRUE, pathlen:1} }
+      its(:stdout) { is_expected.not_to match %r{X509v3 CRL Distribution Points:} }
+    end
+    describe command('openssl x509 -in /etc/cfssl/ca/MYEXEMPLE2INTERMDIATECA.pem -text -noout') do
+      its(:stdout) { is_expected.to match %r{Certificate:} }
+      its(:stdout) { is_expected.to match %r{Issuer: C = FR, L = MONTPELLIER, O = MYEXEMPLE ORG, CN = MYEXEMPLE ROOT CA} }
+      its(:stdout) { is_expected.to match %r{Subject: C = FR, L = MONTPELLIER, O = MYEXEMPLE2 ORG, CN = MYEXEMPLE2 INTERMDIATE CA} }
+      its(:stdout) { is_expected.to match %r{CA:TRUE, pathlen:1} }
+      its(:stdout) { is_expected.to match %r{X509v3 CRL Distribution Points:} }
     end
 
     describe command('openssl crl -in /var/cfssl/crl-MYEXEMPLEROOTCA.pem -text -noout') do
@@ -127,7 +143,7 @@ describe 'cfssl' do
       its(:stdout) { is_expected.to match %r{Certificate Revocation List } }
       its(:stdout) { is_expected.to match %r{Issuer: C = FR, L = MONTPELLIER, O = MYEXEMPLE ORG, CN = MYEXEMPLE INTERMDIATE CA} }
       its(:stdout) { is_expected.to match %r{No Revoked Certificates} }
-      # rubocop:enable RSpec/RepeatedDescription
     end
+    # rubocop:enable RSpec/RepeatedDescription
   end
 end
-- 
GitLab