1
class Puppet::SSLCertificates::Certificate
2
SSLCertificates = Puppet::SSLCertificates
4
attr_accessor :certfile, :keyfile, :name, :dir, :hash, :type
5
attr_accessor :key, :cert, :csr, :cacert
11
:email => "emailAddress",
18
OpenSSL::X509::Name.new self.subject
22
[@certfile,@keyfile].each { |file|
23
File.unlink(file) if FileTest.exists?(file)
27
File.unlink(@hash) if FileTest.symlink?(@hash)
32
FileTest.exists?(@certfile)
36
self.mkkey unless FileTest.exists?(@keyfile)
39
@key = OpenSSL::PKey::RSA.new(
46
@key = OpenSSL::PKey::RSA.new(
53
raise Puppet::Error, "You must specify the common name for the certificate" unless hash.include?(:name)
56
# init a few variables
57
@cert = @key = @csr = nil
59
if hash.include?(:cert)
60
@certfile = hash[:cert]
61
@dir = File.dirname(@certfile)
63
@dir = hash[:dir] || Puppet[:certdir]
64
@certfile = File.join(@dir, @name)
67
@cacertfile ||= File.join(Puppet[:certdir], "ca.pem")
69
Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
71
unless @certfile =~ /\.pem$/
74
@keyfile = hash[:key] || File.join(
75
Puppet[:privatekeydir], [@name,"pem"].join(".")
77
Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
79
[@keyfile].each { |file|
80
dir = File.dirname(file)
82
Puppet.recmkdir(dir) unless FileTest.directory?(dir)
85
@ttl = hash[:ttl] || 365 * 24 * 60 * 60
86
@selfsign = hash[:selfsign] || false
87
@encrypt = hash[:encrypt] || false
88
@replace = hash[:replace] || false
89
@issuer = hash[:issuer] || nil
91
if hash.include?(:type)
93
when :ca, :client, :server; @type = hash[:type]
95
raise "Invalid Cert type #{hash[:type]}"
101
@params = {:name => @name}
102
[:state, :country, :email, :org, :ou].each { |param|
103
@params[param] = hash[param] if hash.include?(param)
108
File.open(@encrypt) { |f|
109
@password = f.read.chomp
112
raise Puppet::Error, ":encrypt must be a path to a pass phrase file"
118
@selfsign = hash.include?(:selfsign) && hash[:selfsign]
121
# this only works for servers, not for users
123
self.getkey unless @key
125
name = OpenSSL::X509::Name.new self.subject
127
@csr = OpenSSL::X509::Request.new
130
@csr.public_key = @key.public_key
131
@csr.sign(@key, OpenSSL::Digest::SHA1.new)
133
#File.open(@csrfile, "w") { |f|
137
raise Puppet::Error, "CSR sign verification failed" unless @csr.verify(@key.public_key)
145
@key = OpenSSL::PKey::RSA.new(1024)
148
# when 0; Puppet.info "key info: ." # BN_generate_prime
149
# when 1; Puppet.info "key info: +" # BN_generate_prime
150
# when 2; Puppet.info "key info: *" # searching good prime,
152
# # but also data from BN_generate_prime
153
# when 3; Puppet.info "key info: \n" # found good prime, n==0 - p, n==1 - q,
154
# # but also data from BN_generate_prime
155
# else; Puppet.info "key info: *" # BN_generate_prime
160
# passwdproc = proc { @password }
162
keytext = @key.export(
164
OpenSSL::Cipher::DES.new(:EDE3, :CBC),
168
File.open(@keyfile, "w", 0400) { |f|
172
File.open(@keyfile, "w", 0400) { |f|
177
#cmd = "#{ossl} genrsa -out #{@key} 1024"
181
self.getkey unless @key
183
raise Puppet::Error, "Cannot replace existing certificate" if @cert
186
:name => self.certname,
190
:publickey => @key.public_key
195
args[:type] = :server
197
@cert = SSLCertificates.mkcert(args)
199
@cert.sign(@key, OpenSSL::Digest::SHA1.new) if @selfsign
204
def subject(string = false)
205
subj = @@params2names.collect { |param, name|
206
[name, @params[param]] if @params.include?(param)
207
}.reject { |ary| ary.nil? }
210
return "/" + subj.collect { |ary|
218
# verify that we can track down the cert chain or whatever
220
"openssl verify -verbose -CAfile /home/luke/.puppet/ssl/certs/ca.pem -purpose sslserver culain.madstop.com.pem"
228
files[@cacertfile] = @cacert if defined?(@cacert)
230
files.each { |file,thing|
232
next if FileTest.exists?(file)
236
if thing.is_a?(OpenSSL::PKey::RSA) and @password
240
OpenSSL::Cipher::DES.new(:EDE3, :CBC),
248
File.open(file, "w", 0660) { |f| f.print text }
252
SSLCertificates.mkhash(Puppet[:certdir], @cacert, @cacertfile) if defined?(@cacert)