~ubuntu-branches/ubuntu/trusty/puppet/trusty

« back to all changes in this revision

Viewing changes to .pc/CVE-2011-3872.patch/lib/puppet/ssl/certificate_factory.rb

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2011-10-22 14:08:22 UTC
  • mfrom: (1.1.25) (3.1.32 sid)
  • Revision ID: package-import@ubuntu.com-20111022140822-odxde5lohc45yhuz
Tags: 2.7.6-1
* New upstream release (CVE-2011-3872)
* Remove cherry-picked "groupadd_aix_warning" patch
* Install all new manpages

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
require 'puppet/ssl'
2
 
 
3
 
# The tedious class that does all the manipulations to the
4
 
# certificate to correctly sign it.  Yay.
5
 
class Puppet::SSL::CertificateFactory
6
 
  # How we convert from various units to the required seconds.
7
 
  UNITMAP = {
8
 
    "y" => 365 * 24 * 60 * 60,
9
 
    "d" => 24 * 60 * 60,
10
 
    "h" => 60 * 60,
11
 
    "s" => 1
12
 
  }
13
 
 
14
 
  attr_reader :name, :cert_type, :csr, :issuer, :serial
15
 
 
16
 
  def initialize(cert_type, csr, issuer, serial)
17
 
    @cert_type, @csr, @issuer, @serial = cert_type, csr, issuer, serial
18
 
 
19
 
    @name = @csr.subject
20
 
  end
21
 
 
22
 
  # Actually generate our certificate.
23
 
  def result
24
 
    @cert = OpenSSL::X509::Certificate.new
25
 
 
26
 
    @cert.version = 2 # X509v3
27
 
    @cert.subject = @csr.subject
28
 
    @cert.issuer = @issuer.subject
29
 
    @cert.public_key = @csr.public_key
30
 
    @cert.serial = @serial
31
 
 
32
 
    build_extensions
33
 
 
34
 
    set_ttl
35
 
 
36
 
    @cert
37
 
  end
38
 
 
39
 
  private
40
 
 
41
 
  # This is pretty ugly, but I'm not really sure it's even possible to do
42
 
  # it any other way.
43
 
  def build_extensions
44
 
    @ef = OpenSSL::X509::ExtensionFactory.new
45
 
 
46
 
    @ef.subject_certificate = @cert
47
 
 
48
 
    if @issuer.is_a?(OpenSSL::X509::Request) # It's a self-signed cert
49
 
      @ef.issuer_certificate = @cert
50
 
    else
51
 
      @ef.issuer_certificate = @issuer
52
 
    end
53
 
 
54
 
    @subject_alt_name = []
55
 
    @key_usage = nil
56
 
    @ext_key_usage = nil
57
 
    @extensions = []
58
 
 
59
 
    method = "add_#{@cert_type.to_s}_extensions"
60
 
 
61
 
    begin
62
 
      send(method)
63
 
    rescue NoMethodError
64
 
      raise ArgumentError, "#{@cert_type} is an invalid certificate type"
65
 
    end
66
 
 
67
 
    @extensions << @ef.create_extension("nsComment", "Puppet Ruby/OpenSSL Generated Certificate")
68
 
    @extensions << @ef.create_extension("basicConstraints", @basic_constraint, true)
69
 
    @extensions << @ef.create_extension("subjectKeyIdentifier", "hash")
70
 
    @extensions << @ef.create_extension("keyUsage", @key_usage.join(",")) if @key_usage
71
 
    @extensions << @ef.create_extension("extendedKeyUsage", @ext_key_usage.join(",")) if @ext_key_usage
72
 
    @extensions << @ef.create_extension("subjectAltName", @subject_alt_name.join(",")) if ! @subject_alt_name.empty?
73
 
 
74
 
    @cert.extensions = @extensions
75
 
 
76
 
    # for some reason this _must_ be the last extension added
77
 
    @extensions << @ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") if @cert_type == :ca
78
 
  end
79
 
 
80
 
  # TTL for new certificates in seconds. If config param :ca_ttl is set,
81
 
  # use that, otherwise use :ca_days for backwards compatibility
82
 
  def ttl
83
 
    ttl = Puppet.settings[:ca_ttl]
84
 
 
85
 
    return ttl unless ttl.is_a?(String)
86
 
 
87
 
    raise ArgumentError, "Invalid ca_ttl #{ttl}" unless ttl =~ /^(\d+)(y|d|h|s)$/
88
 
 
89
 
    $1.to_i * UNITMAP[$2]
90
 
  end
91
 
 
92
 
  def set_ttl
93
 
    # Make the certificate valid as of yesterday, because
94
 
    # so many people's clocks are out of sync.
95
 
    from = Time.now - (60*60*24)
96
 
    @cert.not_before = from
97
 
    @cert.not_after = from + ttl
98
 
  end
99
 
 
100
 
  # Woot! We're a CA.
101
 
  def add_ca_extensions
102
 
    @basic_constraint = "CA:TRUE"
103
 
    @key_usage = %w{cRLSign keyCertSign}
104
 
  end
105
 
 
106
 
  # We're a terminal CA, probably not self-signed.
107
 
  def add_terminalsubca_extensions
108
 
    @basic_constraint = "CA:TRUE,pathlen:0"
109
 
    @key_usage = %w{cRLSign keyCertSign}
110
 
  end
111
 
 
112
 
  # We're a normal server.
113
 
  def add_server_extensions
114
 
    @basic_constraint = "CA:FALSE"
115
 
    dnsnames = Puppet[:certdnsnames]
116
 
    name = @name.to_s.sub(%r{/CN=},'')
117
 
    if dnsnames != ""
118
 
      dnsnames.split(':').each { |d| @subject_alt_name << 'DNS:' + d }
119
 
      @subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
120
 
    elsif name == Facter.value(:fqdn) # we're a CA server, and thus probably the server
121
 
      @subject_alt_name << 'DNS:' + "puppet" # Add 'puppet' as an alias
122
 
      @subject_alt_name << 'DNS:' + name # Add the fqdn as an alias
123
 
      @subject_alt_name << 'DNS:' + name.sub(/^[^.]+./, "puppet.") # add puppet.domain as an alias
124
 
    end
125
 
    @key_usage = %w{digitalSignature keyEncipherment}
126
 
    @ext_key_usage = %w{serverAuth clientAuth emailProtection}
127
 
  end
128
 
 
129
 
  # Um, no idea.
130
 
  def add_ocsp_extensions
131
 
    @basic_constraint = "CA:FALSE"
132
 
    @key_usage = %w{nonRepudiation digitalSignature}
133
 
    @ext_key_usage = %w{serverAuth OCSPSigning}
134
 
  end
135
 
 
136
 
  # Normal client.
137
 
  def add_client_extensions
138
 
    @basic_constraint = "CA:FALSE"
139
 
    @key_usage = %w{nonRepudiation digitalSignature keyEncipherment}
140
 
    @ext_key_usage = %w{clientAuth emailProtection}
141
 
 
142
 
    @extensions << @ef.create_extension("nsCertType", "client,email")
143
 
  end
144
 
end
145