Class: Puppet::SSLCertificates::Certificate

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/sslcertificates/certificate.rb

Constant Summary collapse

SSLCertificates =
Puppet::SSLCertificates
@@params2names =
{
  :name       => "CN",
  :state      => "ST",
  :country    => "C",
  :email      => "emailAddress",
  :org        => "O",
  :city       => "L",
  :ou         => "OU"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash) ⇒ Certificate

Returns a new instance of Certificate.

Raises:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/puppet/sslcertificates/certificate.rb', line 52

def initialize(hash)
  raise Puppet::Error, "You must specify the common name for the certificate" unless hash.include?(:name)
  @name = hash[:name]

  # init a few variables
  @cert = @key = @csr = nil

  if hash.include?(:cert)
    @certfile = hash[:cert]
    @dir = File.dirname(@certfile)
  else
    @dir = hash[:dir] || Puppet[:certdir]
    @certfile = File.join(@dir, @name)
  end

  @cacertfile ||= File.join(Puppet[:certdir], "ca.pem")

  Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)

  unless @certfile =~ /\.pem$/
    @certfile += ".pem"
  end
  @keyfile = hash[:key] || File.join(
    Puppet[:privatekeydir], [@name,"pem"].join(".")
  )
  Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)

  [@keyfile].each { |file|
    dir = File.dirname(file)

    Puppet.recmkdir(dir) unless FileTest.directory?(dir)
  }

  @ttl = hash[:ttl] || 365 * 24 * 60 * 60
  @selfsign = hash[:selfsign] || false
  @encrypt = hash[:encrypt] || false
  @replace = hash[:replace] || false
  @issuer = hash[:issuer] || nil

  if hash.include?(:type)
    case hash[:type]
    when :ca, :client, :server; @type = hash[:type]
    else
      raise "Invalid Cert type #{hash[:type]}"
    end
  else
    @type = :client
  end

  @params = {:name => @name}
  [:state, :country, :email, :org, :ou].each { |param|
    @params[param] = hash[param] if hash.include?(param)
  }

  if @encrypt
    if @encrypt =~ /^\//
      File.open(@encrypt) { |f|
        @password = f.read.chomp
      }
    else
      raise Puppet::Error, ":encrypt must be a path to a pass phrase file"
    end
  else
    @password = nil
  end

  @selfsign = hash.include?(:selfsign) && hash[:selfsign]
end

Instance Attribute Details

#cacertObject

Returns the value of attribute cacert.



5
6
7
# File 'lib/puppet/sslcertificates/certificate.rb', line 5

def cacert
  @cacert
end

#certObject

Returns the value of attribute cert.



5
6
7
# File 'lib/puppet/sslcertificates/certificate.rb', line 5

def cert
  @cert
end

#certfileObject

Returns the value of attribute certfile.



4
5
6
# File 'lib/puppet/sslcertificates/certificate.rb', line 4

def certfile
  @certfile
end

#csrObject

Returns the value of attribute csr.



5
6
7
# File 'lib/puppet/sslcertificates/certificate.rb', line 5

def csr
  @csr
end

#dirObject

Returns the value of attribute dir.



4
5
6
# File 'lib/puppet/sslcertificates/certificate.rb', line 4

def dir
  @dir
end

#hashObject

Returns the value of attribute hash.



4
5
6
# File 'lib/puppet/sslcertificates/certificate.rb', line 4

def hash
  @hash
end

#keyObject

Returns the value of attribute key.



5
6
7
# File 'lib/puppet/sslcertificates/certificate.rb', line 5

def key
  @key
end

#keyfileObject

Returns the value of attribute keyfile.



4
5
6
# File 'lib/puppet/sslcertificates/certificate.rb', line 4

def keyfile
  @keyfile
end

#nameObject

Returns the value of attribute name.



4
5
6
# File 'lib/puppet/sslcertificates/certificate.rb', line 4

def name
  @name
end

#typeObject

Returns the value of attribute type.



4
5
6
# File 'lib/puppet/sslcertificates/certificate.rb', line 4

def type
  @type
end

Instance Method Details

#certnameObject



17
18
19
# File 'lib/puppet/sslcertificates/certificate.rb', line 17

def certname
  OpenSSL::X509::Name.new self.subject
end

#deleteObject



21
22
23
24
25
26
27
28
29
# File 'lib/puppet/sslcertificates/certificate.rb', line 21

def delete
  [@certfile,@keyfile].each { |file|
    File.unlink(file) if FileTest.exists?(file)
  }

  if @hash
    File.unlink(@hash) if FileTest.symlink?(@hash)
  end
end

#exists?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/puppet/sslcertificates/certificate.rb', line 31

def exists?
  FileTest.exists?(@certfile)
end

#getkeyObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/puppet/sslcertificates/certificate.rb', line 35

def getkey
  self.mkkey unless FileTest.exists?(@keyfile)
  if @password

    @key = OpenSSL::PKey::RSA.new(

      File.read(@keyfile),

      @password
    )
  else
    @key = OpenSSL::PKey::RSA.new(
      File.read(@keyfile)
    )
  end
end

#mkcsrObject

this only works for servers, not for users

Raises:



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/puppet/sslcertificates/certificate.rb', line 122

def mkcsr
  self.getkey unless @key

  name = OpenSSL::X509::Name.new self.subject

  @csr = OpenSSL::X509::Request.new
  @csr.version = 0
  @csr.subject = name
  @csr.public_key = @key.public_key
  @csr.sign(@key, OpenSSL::Digest::SHA1.new)

  #File.open(@csrfile, "w") { |f|
  #    f << @csr.to_pem
  #}

  raise Puppet::Error, "CSR sign verification failed" unless @csr.verify(@key.public_key)

  @csr
end

#mkkeyObject



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/puppet/sslcertificates/certificate.rb', line 142

def mkkey
  # @key is the file

  @key = OpenSSL::PKey::RSA.new(1024)
#            { |p,n|
#                case p
#                when 0; Puppet.info "key info: ."  # BN_generate_prime
#                when 1; Puppet.info "key info: +"  # BN_generate_prime
#                when 2; Puppet.info "key info: *"  # searching good prime,
#                                          # n = #of try,
#                                          # but also data from BN_generate_prime
#                when 3; Puppet.info "key info: \n" # found good prime, n==0 - p, n==1 - q,
#                                          # but also data from BN_generate_prime
#                else;   Puppet.info "key info: *"  # BN_generate_prime
#                end
#            }

if @password
#        passwdproc = proc { @password }

  keytext = @key.export(

    OpenSSL::Cipher::DES.new(:EDE3, :CBC),

    @password
    )
    File.open(@keyfile, "w", 0400) { |f|
      f << keytext
    }
  else
    File.open(@keyfile, "w", 0400) { |f|
      f << @key.to_pem
    }
  end

  #cmd = "#{ossl} genrsa -out #{@key} 1024"
end

#mkselfsignedObject

Raises:



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/puppet/sslcertificates/certificate.rb', line 180

def mkselfsigned
  self.getkey unless @key

  raise Puppet::Error, "Cannot replace existing certificate" if @cert

  args = {
    :name => self.certname,
    :ttl => @ttl,
    :issuer => nil,
    :serial => 0x0,
    :publickey => @key.public_key
  }
  if @type
    args[:type] = @type
  else
    args[:type] = :server
  end
  @cert = SSLCertificates.mkcert(args)

  @cert.sign(@key, OpenSSL::Digest::SHA1.new) if @selfsign

  @cert
end

#subject(string = false) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/puppet/sslcertificates/certificate.rb', line 204

def subject(string = false)
  subj = @@params2names.collect { |param, name|
    [name, @params[param]] if @params.include?(param)
  }.reject { |ary| ary.nil? }

  if string
    return "/" + subj.collect { |ary|
      "%s=%s" % ary
    }.join("/") + "/"
  else
    return subj
  end
end

#verifyObject

verify that we can track down the cert chain or whatever



219
220
221
# File 'lib/puppet/sslcertificates/certificate.rb', line 219

def verify
  "openssl verify -verbose -CAfile /home/luke/.puppet/ssl/certs/ca.pem -purpose sslserver culain.madstop.com.pem"
end

#writeObject



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/puppet/sslcertificates/certificate.rb', line 223

def write
  files = {
    @certfile => @cert,
    @keyfile => @key,
  }
  files[@cacertfile] = @cacert if defined?(@cacert)

  files.each { |file,thing|
    if thing
      next if FileTest.exists?(file)

      text = nil

      if thing.is_a?(OpenSSL::PKey::RSA) and @password

        text = thing.export(

          OpenSSL::Cipher::DES.new(:EDE3, :CBC),

          @password
        )
      else
        text = thing.to_pem
      end

      File.open(file, "w", 0660) { |f| f.print text }
    end
  }

  SSLCertificates.mkhash(Puppet[:certdir], @cacert, @cacertfile) if defined?(@cacert)
end