Class: Acmesmith::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/acmesmith/client.rb

Instance Method Summary collapse

Constructor Details

#initialize(config: nil) ⇒ Client

Returns a new instance of Client.



10
11
12
# File 'lib/acmesmith/client.rb', line 10

def initialize(config: nil)
  @config ||= config
end

Instance Method Details

#add_san(common_name, *add_sans) ⇒ Object



138
139
140
141
142
143
144
# File 'lib/acmesmith/client.rb', line 138

def add_san(common_name, *add_sans)
  puts "=> reissuing CN=#{common_name} with new SANs #{add_sans.join(?,)}"
  cert = storage.get_certificate(common_name)
  sans = cert.sans + add_sans
  puts " * SANs will be: #{sans.join(?,)}"
  order_with_private_key(cert.common_name, *sans, private_key: regenerate_private_key(cert.public_key))
end

#authorize(*identifiers) ⇒ Object

Raises:

  • (NotImplementedError)


29
30
31
# File 'lib/acmesmith/client.rb', line 29

def authorize(*identifiers)
  raise NotImplementedError, "Domain authorization in advance is still not available in acme-client (v2). Required authorizations will be performed when ordering certificates"
end

#autorenew(days: 7, common_names: nil) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/acmesmith/client.rb', line 125

def autorenew(days: 7, common_names: nil)
  (common_names || storage.list_certificates).each do |cn|
    puts "=> #{cn}"
    cert = storage.get_certificate(cn)
    not_after = cert.certificate.not_after.utc

    puts "   Not valid after: #{not_after}"
    next unless (cert.certificate.not_after.utc - Time.now.utc) < (days.to_i * 86400)
    puts " * Renewing: CN=#{cert.common_name}, SANs=#{cert.sans.join(',')}"
    order_with_private_key(cert.common_name, *cert.sans, private_key: regenerate_private_key(cert.public_key))
  end
end

#certificate_versions(common_name) ⇒ Object



48
49
50
# File 'lib/acmesmith/client.rb', line 48

def certificate_versions(common_name)
  storage.list_certificate_versions(common_name).sort
end

#certificates_listObject



52
53
54
# File 'lib/acmesmith/client.rb', line 52

def certificates_list
  storage.list_certificates.sort
end

#current(common_name) ⇒ Object



56
57
58
# File 'lib/acmesmith/client.rb', line 56

def current(common_name)
  storage.get_current_certificate_version(common_name)
end

#execute_post_issue_hooks(certificate) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'lib/acmesmith/client.rb', line 38

def execute_post_issue_hooks(certificate)
  hooks = config.post_issuing_hooks(certificate.common_name)
  return if hooks.empty?
  puts "=> Executing post issuing hooks for CN=#{certificate.common_name}"
  hooks.each do |hook|
    hook.run(certificate: certificate)
  end
  puts
end

#get_certificate(common_name, version: 'current', type: 'text') ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/acmesmith/client.rb', line 60

def get_certificate(common_name, version: 'current', type: 'text')
  cert = storage.get_certificate(common_name, version: version)

  certs = []
  case type
  when 'text'
    certs << cert.certificate.to_text
    certs << cert.certificate.to_pem
  when 'certificate'
    certs << cert.certificate.to_pem
  when 'chain'
    certs << cert.chain
  when 'fullchain'
    certs << cert.fullchain
  end

  certs
end

#get_private_key(common_name, version: 'current') ⇒ Object



93
94
95
96
97
98
# File 'lib/acmesmith/client.rb', line 93

def get_private_key(common_name, version: 'current')
  cert = storage.get_certificate(common_name, version: version)
  cert.key_passphrase = certificate_key_passphrase if certificate_key_passphrase

  cert.private_key.to_pem
end

#new_account(contact, tos_agreed: true) ⇒ Object



14
15
16
17
18
19
20
21
22
# File 'lib/acmesmith/client.rb', line 14

def (contact, tos_agreed: true)
  key = AccountKey.generate
  acme = Acme::Client.new(private_key: key.private_key, directory: config.directory, connection_options: config.connection_options, bad_nonce_retry: config.bad_nonce_retry)
  acme.(contact: contact, terms_of_service_agreed: tos_agreed)

  storage.(key, )

  key
end

#order(*identifiers, key_type: 'rsa', rsa_key_size: 2048, elliptic_curve: 'prime256v1', not_before: nil, not_after: nil) ⇒ Object



24
25
26
27
# File 'lib/acmesmith/client.rb', line 24

def order(*identifiers, key_type: 'rsa', rsa_key_size: 2048, elliptic_curve: 'prime256v1', not_before: nil, not_after: nil)
  private_key = generate_private_key(key_type: key_type, rsa_key_size: rsa_key_size, elliptic_curve: elliptic_curve)
  order_with_private_key(*identifiers, private_key: private_key, not_before: not_before, not_after: not_after)
end

#post_issue_hooks(common_name) ⇒ Object



33
34
35
36
# File 'lib/acmesmith/client.rb', line 33

def post_issue_hooks(common_name)
  cert = storage.get_certificate(common_name)
  execute_post_issue_hooks(cert)
end

#save(common_name, version: 'current', **kwargs) ⇒ Object



118
119
120
121
122
123
# File 'lib/acmesmith/client.rb', line 118

def save(common_name, version: 'current', **kwargs)
  cert = storage.get_certificate(common_name, version: version)
  cert.key_passphrase = certificate_key_passphrase if certificate_key_passphrase

  SaveCertificateService.new(cert, **kwargs).perform!
end

#save_certificate(common_name, version: 'current', mode: '0600', output:, type: 'fullchain') ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/acmesmith/client.rb', line 79

def save_certificate(common_name, version: 'current', mode: '0600', output:, type: 'fullchain')
  cert = storage.get_certificate(common_name, version: version)
  File.open(output, 'w', mode.to_i(8)) do |f|
    case type
    when 'certificate'
      f.puts cert.certificate.to_pem
    when 'chain'
      f.puts cert.chain
    when 'fullchain'
      f.puts cert.fullchain
    end
  end
end

#save_pkcs12(common_name, version: 'current', mode: '0600', output:, passphrase:) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/acmesmith/client.rb', line 108

def save_pkcs12(common_name, version: 'current', mode: '0600', output:, passphrase:)
  cert = storage.get_certificate(common_name, version: version)
  cert.key_passphrase = certificate_key_passphrase if certificate_key_passphrase
  
  p12 = cert.pkcs12(passphrase)
  File.open(output, 'w', mode.to_i(8)) do |f|
    f.puts p12.to_der
  end
end

#save_private_key(common_name, version: 'current', mode: '0600', output:) ⇒ Object



100
101
102
103
104
105
106
# File 'lib/acmesmith/client.rb', line 100

def save_private_key(common_name, version: 'current', mode: '0600', output:)
  cert = storage.get_certificate(common_name, version: version)
  cert.key_passphrase = certificate_key_passphrase if certificate_key_passphrase
  File.open(output, 'w', mode.to_i(8)) do |f|
    f.puts(cert.private_key)
  end
end