Class: Acmesmith::Certificate
- Inherits:
-
Object
- Object
- Acmesmith::Certificate
show all
- Defined in:
- lib/acmesmith/certificate.rb
Defined Under Namespace
Classes: CertificateExport, PassphraseRequired, PrivateKeyDecrypted
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(certificate, chain, private_key, key_passphrase = nil, csr = nil) ⇒ Certificate
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/acmesmith/certificate.rb', line 31
def initialize(certificate, chain, private_key, key_passphrase = nil, csr = nil)
@certificate = case certificate
when OpenSSL::X509::Certificate
certificate
when String
OpenSSL::X509::Certificate.new(certificate)
else
raise TypeError, 'certificate is expected to be a String or OpenSSL::X509::Certificate'
end
chain = case chain
when String
self.class.split_pems(chain)
when Array
chain
when nil
[]
else
raise TypeError, 'chain is expected to be an Array<String or OpenSSL::X509::Certificate> or nil'
end
@chain = chain.map { |cert|
case cert
when OpenSSL::X509::Certificate
cert
when String
OpenSSL::X509::Certificate.new(cert)
else
raise TypeError, 'chain is expected to be an Array<String or OpenSSL::X509::Certificate> or nil'
end
}
case private_key
when String
@raw_private_key = private_key
if key_passphrase
self.key_passphrase = key_passphrase
else
begin
@private_key = OpenSSL::PKey.read(@raw_private_key) { nil }
rescue OpenSSL::PKey::PKeyError
end
end
when OpenSSL::PKey::PKey
@private_key = private_key
else
raise TypeError, 'private_key is expected to be a String or OpenSSL::PKey::PKey'
end
@csr = case csr
when nil
nil
when String
OpenSSL::X509::Request.new(csr)
when OpenSSL::X509::Request
csr
end
end
|
Instance Attribute Details
#certificate ⇒ OpenSSL::X509::Certificate
91
92
93
|
# File 'lib/acmesmith/certificate.rb', line 91
def certificate
@certificate
end
|
#chain ⇒ Array<OpenSSL::X509::Certificate>
93
94
95
|
# File 'lib/acmesmith/certificate.rb', line 93
def chain
@chain
end
|
#csr ⇒ OpenSSL::X509::Request
95
96
97
|
# File 'lib/acmesmith/certificate.rb', line 95
def csr
@csr
end
|
Class Method Details
Return Acmesmith::Certificate by an issued certificate
21
22
23
24
|
# File 'lib/acmesmith/certificate.rb', line 21
def self.by_issuance(pem_chain, csr)
pems = split_pems(pem_chain)
new(pems[0], pems[1..-1], csr.private_key, nil, csr)
end
|
.split_pems(pems) ⇒ Array<String>
Split string containing multiple PEMs into Array of PEM strings.
13
14
15
|
# File 'lib/acmesmith/certificate.rb', line 13
def self.split_pems(pems)
pems.each_line.slice_before(/^-----BEGIN CERTIFICATE-----$/).map(&:join)
end
|
Instance Method Details
#common_name ⇒ String
132
133
134
|
# File 'lib/acmesmith/certificate.rb', line 132
def common_name
certificate.subject.to_a.assoc('CN')[1]
end
|
#export(passphrase, cipher: OpenSSL::Cipher.new('aes-256-cbc')) ⇒ CertificateExport
154
155
156
157
158
159
160
161
162
163
164
165
|
# File 'lib/acmesmith/certificate.rb', line 154
def export(passphrase, cipher: OpenSSL::Cipher.new('aes-256-cbc'))
CertificateExport.new.tap do |h|
h.certificate = certificate.to_pem
h.chain = issuer_pems
h.fullchain = fullchain
h.private_key = if passphrase
private_key.export(cipher, passphrase)
else
private_key.export
end
end
end
|
#fullchain ⇒ String
122
123
124
|
# File 'lib/acmesmith/certificate.rb', line 122
def fullchain
"#{certificate.to_pem}\n#{issuer_pems}".gsub(/\n+/,?\n)
end
|
#issuer_pems ⇒ String
127
128
129
|
# File 'lib/acmesmith/certificate.rb', line 127
def issuer_pems
chain.map(&:to_pem).join("\n")
end
|
#key_passphrase=(pw) ⇒ Object
Try to decrypt private_key if encrypted.
100
101
102
103
104
105
106
107
|
# File 'lib/acmesmith/certificate.rb', line 100
def key_passphrase=(pw)
raise PrivateKeyDecrypted, 'private_key already given' if @private_key
@private_key = OpenSSL::PKey.read(@raw_private_key, pw)
@raw_private_key = nil
nil
end
|
#pkcs12(passphrase) ⇒ OpenSSL::PKCS12
149
150
151
|
# File 'lib/acmesmith/certificate.rb', line 149
def pkcs12(passphrase)
OpenSSL::PKCS12.create(passphrase, common_name, private_key, certificate, chain)
end
|
#private_key ⇒ OpenSSL::PKey::PKey
111
112
113
114
|
# File 'lib/acmesmith/certificate.rb', line 111
def private_key
return @private_key if @private_key
raise PassphraseRequired, 'key_passphrase required'
end
|
#public_key ⇒ OpenSSL::PKey::PKey
117
118
119
|
# File 'lib/acmesmith/certificate.rb', line 117
def public_key
@certificate.public_key
end
|
#sans ⇒ Array<String>
137
138
139
140
141
|
# File 'lib/acmesmith/certificate.rb', line 137
def sans
certificate.extensions.select { |_| _.oid == 'subjectAltName' }.flat_map do |ext|
ext.value.split(/,\s*/).select { |_| _.start_with?('DNS:') }.map { |_| _[4..-1] }
end
end
|
#version ⇒ String
144
145
146
|
# File 'lib/acmesmith/certificate.rb', line 144
def version
"#{certificate.not_before.utc.strftime('%Y%m%d-%H%M%S')}_#{certificate.serial.to_i.to_s(16)}"
end
|