Puppet Function: cfweb::build_cert_chain

Defined in:
lib/puppet/functions/cfweb/build_cert_chain.rb
Function type:
Ruby 4.x API

Overview

cfweb::build_cert_chain(String[1] $raw_certs, String[1] $common_name)Any

Parameters:

  • raw_certs (String[1])
  • common_name (String[1])

Returns:

  • (Any)


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/puppet/functions/cfweb/build_cert_chain.rb', line 7

Puppet::Functions.create_function(:'cfweb::build_cert_chain') do
    dispatch :build_chain do
        param 'String[1]', :raw_certs
        param 'String[1]', :common_name
    end
    
    def build_chain(raw_certs, common_name)
        begin_cert = '-----BEGIN CERTIFICATE-----'
        end_cert = '-----END CERTIFICATE-----'
        certs = []
        raw_certs.split(end_cert).each do |v|
            v = v.strip()
            
            next if v.empty?
            
            if not v.start_with?(begin_cert)
                fail("Not a valid cert for #{common_name}: #{v}")
            end
            
            certs << OpenSSL::X509::Certificate.new("#{v}\n#{end_cert}")
        end
        
        # find root
        #---
        root_ca = certs.find do |v|
            v.issuer == v.subject
        end
        
        if root_ca.nil?
            fail("Failed to find Root CA for #{common_name}")
        end
        
        chain = []
        chain << root_ca.to_pem
        
        # build chain
        #---
        curr = root_ca
        found_subjects = []
        
        while true
            subj = curr.subject.to_a.find { |v| v[0] == 'CN' }
            subj = subj[1]
            found_subjects << subj
            
            break if subj == common_name
            
            curr = certs.find do |v|
                v.issuer == curr.subject and v.subject != curr.subject
            end
            
            if curr.nil?
                fail("Failed to build full chain for #{common_name}: #{found_subjects.to_s}")
            end
            
            chain << curr.to_pem
        end
        
        #---
        # Based on docs:
        # chained: cert -> Intermediate CA
        # trusted: RootCA -> Intermediate CA
        return {
            'chained' => chain.reverse[0, chain.size()-1], 
            'trusted' => chain[0, chain.size()-1], 
        }
    end
end