bullion 0.10.3 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a737e0d1993b367c9166a9532835ff440c1b73ee2f32ed00911de3223088bbd
4
- data.tar.gz: cfc77406aa3ecd9ed8baf0a2df139cd55088640bf3d4209479af14d7116ef49a
3
+ metadata.gz: 8821e563a9452dbd524f1bdfbd2f944ee4a3d0c071e57bab6d5f9b2c61e18555
4
+ data.tar.gz: d31913ae560676de68a57ea6aa308126a6d3c92c7a3da69d4d882e032ed56196
5
5
  SHA512:
6
- metadata.gz: aa1baf722ec612144cbd7fa4d440c938590d3f9e5bb11d48cd1474c54b127994fbe7d47ca6508cd0f4d330d68093e818c5da146e942a8358edde2f218bb3cf85
7
- data.tar.gz: 14b11cbeca6044a196416963ce44456ae8db92afa377c2d24b1cb3bf90f0cd97c4ccf2f53bff47142128de12d1744658925d85784507006a74f84f972ee13407
6
+ metadata.gz: 4bcabcb78421e92a48fbd5485631de98bee3bf0d4452ba5d9c08eb04d34ac171934b073e0a441b5dc95aeeb353765a5445188ca7011b98d3e2f376d130aaf2d4
7
+ data.tar.gz: 5541be539b018f62d1e466e51ada7985f5e37ee460eb98c4e344f79c443aa60fa3f8b2bf1d26d169a15c0b8efef38c7523c4023a416436e85654b585a5fcae6c
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.10.3"
2
+ ".": "0.11.1"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.11.1](https://github.com/jgnagy/bullion/compare/bullion/v0.11.0...bullion/v0.11.1) (2025-08-24)
4
+
5
+
6
+ ### Features
7
+
8
+ * add support for ECDSA CAs ([49b752e](https://github.com/jgnagy/bullion/commit/49b752ef6fde2b0543b59fb1c5977073f21b6731))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * improve detection of SANS for cert-manager ([605f80d](https://github.com/jgnagy/bullion/commit/605f80d97135727ab9a962d6c3078b2b4a74b533))
14
+ * loading required bigdecimal gem ([98d1668](https://github.com/jgnagy/bullion/commit/98d1668da600bba890dd0eb035af4a363fa79eef))
15
+
16
+ ## [0.11.0](https://github.com/jgnagy/bullion/compare/bullion/v0.10.3...bullion/v0.11.0) (2025-08-23)
17
+
18
+
19
+ ### ⚠ BREAKING CHANGES
20
+
21
+ * **db:** switch to Trilogy, update db indexes
22
+
23
+ ### Features
24
+
25
+ * **db:** switch to Trilogy, update db indexes ([42b90b5](https://github.com/jgnagy/bullion/commit/42b90b5977cd497b46654ecf17085715fa6db080))
26
+
3
27
  ## [0.10.3](https://github.com/jgnagy/bullion/compare/bullion/v0.10.2...bullion/v0.10.3) (2025-08-23)
4
28
 
5
29
 
data/Gemfile.lock CHANGED
@@ -1,25 +1,25 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bullion (0.10.3)
4
+ bullion (0.11.1)
5
5
  benchmark (~> 0.4)
6
6
  dry-configurable (~> 1.1)
7
7
  httparty (~> 0.21)
8
8
  itsi (~> 0.2)
9
9
  json (~> 2.6)
10
10
  jwt (~> 2.7)
11
- mysql2 (~> 0.5)
12
11
  openssl (~> 3.0)
13
12
  prometheus-client (~> 4.2)
14
13
  sinatra (~> 3.1)
15
14
  sinatra-activerecord (~> 2.0)
16
15
  sinatra-contrib (~> 3.1)
17
16
  sqlite3 (~> 2.7)
17
+ trilogy (~> 2.9)
18
18
 
19
19
  GEM
20
20
  remote: https://rubygems.org/
21
21
  specs:
22
- acme-client (2.0.22)
22
+ acme-client (2.0.25)
23
23
  base64 (~> 0.2)
24
24
  faraday (>= 1.0, < 3.0.0)
25
25
  faraday-retry (>= 1.0, < 3.0.0)
@@ -61,7 +61,7 @@ GEM
61
61
  concurrent-ruby (~> 1.0)
62
62
  logger
63
63
  zeitwerk (~> 2.6)
64
- faraday (2.13.2)
64
+ faraday (2.13.4)
65
65
  faraday-net_http (>= 2.0, < 3.5)
66
66
  json
67
67
  logger
@@ -75,18 +75,18 @@ GEM
75
75
  multi_xml (>= 0.5.2)
76
76
  i18n (1.14.7)
77
77
  concurrent-ruby (~> 1.0)
78
- itsi (0.2.18)
79
- itsi-scheduler (~> 0.2.18)
80
- itsi-server (~> 0.2.18)
81
- itsi-scheduler (0.2.18)
78
+ itsi (0.2.19)
79
+ itsi-scheduler (~> 0.2.19)
80
+ itsi-server (~> 0.2.19)
81
+ itsi-scheduler (0.2.19)
82
82
  rb_sys (~> 0.9.91)
83
- itsi-server (0.2.18)
83
+ itsi-server (0.2.19)
84
84
  json (~> 2)
85
85
  prism (~> 1.4)
86
86
  rack (>= 1.6)
87
87
  rb_sys (~> 0.9.91)
88
88
  jaro_winkler (1.6.1)
89
- json (2.12.2)
89
+ json (2.13.2)
90
90
  jwt (2.10.2)
91
91
  base64
92
92
  kramdown (2.5.1)
@@ -98,39 +98,38 @@ GEM
98
98
  logger (1.7.0)
99
99
  mini_mime (1.1.5)
100
100
  minitest (5.25.5)
101
- multi_json (1.15.0)
101
+ multi_json (1.17.0)
102
102
  multi_xml (0.7.2)
103
103
  bigdecimal (~> 3.1)
104
- mustermann (3.0.3)
104
+ mustermann (3.0.4)
105
105
  ruby2_keywords (~> 0.0.1)
106
- mysql2 (0.5.6)
107
106
  net-http (0.6.0)
108
107
  uri
109
- nokogiri (1.18.8-aarch64-linux-gnu)
108
+ nokogiri (1.18.9-aarch64-linux-gnu)
110
109
  racc (~> 1.4)
111
- nokogiri (1.18.8-aarch64-linux-musl)
110
+ nokogiri (1.18.9-aarch64-linux-musl)
112
111
  racc (~> 1.4)
113
- nokogiri (1.18.8-arm-linux-gnu)
112
+ nokogiri (1.18.9-arm-linux-gnu)
114
113
  racc (~> 1.4)
115
- nokogiri (1.18.8-arm-linux-musl)
114
+ nokogiri (1.18.9-arm-linux-musl)
116
115
  racc (~> 1.4)
117
- nokogiri (1.18.8-arm64-darwin)
116
+ nokogiri (1.18.9-arm64-darwin)
118
117
  racc (~> 1.4)
119
- nokogiri (1.18.8-x86_64-darwin)
118
+ nokogiri (1.18.9-x86_64-darwin)
120
119
  racc (~> 1.4)
121
- nokogiri (1.18.8-x86_64-linux-gnu)
120
+ nokogiri (1.18.9-x86_64-linux-gnu)
122
121
  racc (~> 1.4)
123
- nokogiri (1.18.8-x86_64-linux-musl)
122
+ nokogiri (1.18.9-x86_64-linux-musl)
124
123
  racc (~> 1.4)
125
124
  observer (0.1.2)
126
125
  openssl (3.3.0)
127
- ostruct (0.6.2)
126
+ ostruct (0.6.3)
128
127
  parallel (1.27.0)
129
- parser (3.3.8.0)
128
+ parser (3.3.9.0)
130
129
  ast (~> 2.4.1)
131
130
  racc
132
131
  prism (1.4.0)
133
- prometheus-client (4.2.4)
132
+ prometheus-client (4.2.5)
134
133
  base64
135
134
  racc (1.8.1)
136
135
  rack (2.2.17)
@@ -142,11 +141,11 @@ GEM
142
141
  rainbow (3.1.1)
143
142
  rake (13.3.0)
144
143
  rake-compiler-dock (1.9.1)
145
- rb_sys (0.9.116)
144
+ rb_sys (0.9.117)
146
145
  rake-compiler-dock (= 1.9.1)
147
146
  rbs (3.9.4)
148
147
  logger
149
- regexp_parser (2.10.0)
148
+ regexp_parser (2.11.2)
150
149
  reverse_markdown (3.0.0)
151
150
  nokogiri
152
151
  rexml (3.4.1)
@@ -162,8 +161,8 @@ GEM
162
161
  rspec-mocks (3.13.5)
163
162
  diff-lcs (>= 1.2.0, < 2.0)
164
163
  rspec-support (~> 3.13.0)
165
- rspec-support (3.13.4)
166
- rubocop (1.77.0)
164
+ rspec-support (3.13.5)
165
+ rubocop (1.80.0)
167
166
  json (~> 2.3)
168
167
  language_server-protocol (~> 3.17.0.2)
169
168
  lint_roller (~> 1.1.0)
@@ -171,10 +170,10 @@ GEM
171
170
  parser (>= 3.3.0.2)
172
171
  rainbow (>= 2.2.2, < 4.0)
173
172
  regexp_parser (>= 2.9.3, < 3.0)
174
- rubocop-ast (>= 1.45.1, < 2.0)
173
+ rubocop-ast (>= 1.46.0, < 2.0)
175
174
  ruby-progressbar (~> 1.7)
176
175
  unicode-display_width (>= 2.4.0, < 4.0)
177
- rubocop-ast (1.45.1)
176
+ rubocop-ast (1.46.0)
178
177
  parser (>= 3.3.7.2)
179
178
  prism (~> 1.4)
180
179
  rubocop-rake (0.7.1)
@@ -193,7 +192,7 @@ GEM
193
192
  simplecov-cobertura (2.1.0)
194
193
  rexml
195
194
  simplecov (~> 0.19)
196
- simplecov-html (0.13.1)
195
+ simplecov-html (0.13.2)
197
196
  simplecov_json_formatter (0.1.4)
198
197
  sinatra (3.2.0)
199
198
  mustermann (~> 3.0)
@@ -229,20 +228,21 @@ GEM
229
228
  tilt (~> 2.0)
230
229
  yard (~> 0.9, >= 0.9.24)
231
230
  yard-solargraph (~> 0.1)
232
- sqlite3 (2.7.1-aarch64-linux-gnu)
233
- sqlite3 (2.7.1-aarch64-linux-musl)
234
- sqlite3 (2.7.1-arm-linux-gnu)
235
- sqlite3 (2.7.1-arm-linux-musl)
236
- sqlite3 (2.7.1-arm64-darwin)
237
- sqlite3 (2.7.1-x86_64-darwin)
238
- sqlite3 (2.7.1-x86_64-linux-gnu)
239
- sqlite3 (2.7.1-x86_64-linux-musl)
240
- thor (1.3.2)
241
- tilt (2.6.0)
231
+ sqlite3 (2.7.3-aarch64-linux-gnu)
232
+ sqlite3 (2.7.3-aarch64-linux-musl)
233
+ sqlite3 (2.7.3-arm-linux-gnu)
234
+ sqlite3 (2.7.3-arm-linux-musl)
235
+ sqlite3 (2.7.3-arm64-darwin)
236
+ sqlite3 (2.7.3-x86_64-darwin)
237
+ sqlite3 (2.7.3-x86_64-linux-gnu)
238
+ sqlite3 (2.7.3-x86_64-linux-musl)
239
+ thor (1.4.0)
240
+ tilt (2.6.1)
242
241
  timeout (0.4.3)
242
+ trilogy (2.9.0)
243
243
  tzinfo (2.0.6)
244
244
  concurrent-ruby (~> 1.0)
245
- unicode-display_width (3.1.4)
245
+ unicode-display_width (3.1.5)
246
246
  unicode-emoji (~> 4.0, >= 4.0.4)
247
247
  unicode-emoji (4.0.4)
248
248
  uri (1.0.3)
data/README.md CHANGED
@@ -36,7 +36,7 @@ Whether run locally or via Docker, the following environment variables configure
36
36
  | `CA_CERT_PATH` | `$CA_DIR/tls.crt` | Public cert for Bullion. If Bullion is an intermediate CA, you'll want to include the root CA's public cert in this file as well the signed cert for Bullion. |
37
37
  | `CA_DOMAINS` | `example.com` | A comma-delimited list of domains for which Bullion will sign certificate requests. Subdomains are automatically allowed. Certificates containing other domains will be rejected. |
38
38
  | `CERT_VALIDITY_DURATION` | `7776000` | How long should issued certs be valid (in seconds)? Default is 90 days. |
39
- | `DATABASE_URL` | _None_ | **(Required)** A shorthand for telling Bullion how to connect to a database. Acceptable URLs will either begin with `sqlite3:` or [`mysql2://`](https://github.com/brianmario/mysql2#using-active-records-database_url). |
39
+ | `DATABASE_URL` | _None_ | **(Required)** A shorthand for telling Bullion how to connect to a database. Acceptable URLs will either begin with `sqlite3:` or [`trilogy://`](https://github.com/trilogy-libraries/trilogy/tree/main/contrib/ruby). |
40
40
  | `DNS01_NAMESERVERS` | _None_ | A comma-delimited list of nameservers to use for resolving [DNS-01](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) challenges. Usually you'll want this to be set to your _internal_ nameservers so internal names resolve correctly. When not set, it'll use the host's DNS. |
41
41
  | `LOG_LEVEL` | `warn` | Log level for Bullion. Supported levels (starting with the noisiest) are debug, info, warn, error, and fatal. |
42
42
  | `BULLION_PORT` | `9292` | TCP port Bullion will listen on. |
data/Rakefile CHANGED
@@ -62,6 +62,8 @@ end
62
62
 
63
63
  require "openssl"
64
64
  require "sqlite3"
65
+ require "bigdecimal"
66
+ require "trilogy"
65
67
  require "sinatra/activerecord/rake"
66
68
 
67
69
  namespace :db do
data/bullion.gemspec CHANGED
@@ -32,13 +32,13 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency "itsi", "~> 0.2"
33
33
  spec.add_dependency "json", "~> 2.6"
34
34
  spec.add_dependency "jwt", "~> 2.7"
35
- spec.add_dependency "mysql2", "~> 0.5"
36
35
  spec.add_dependency "openssl", "~> 3.0"
37
36
  spec.add_dependency "prometheus-client", "~> 4.2"
38
37
  spec.add_dependency "sinatra", "~> 3.1"
39
38
  spec.add_dependency "sinatra-activerecord", "~> 2.0"
40
39
  spec.add_dependency "sinatra-contrib", "~> 3.1"
41
40
  spec.add_dependency "sqlite3", "~> 2.7"
41
+ spec.add_dependency "trilogy", "~> 2.9"
42
42
 
43
43
  spec.add_development_dependency "acme-client", "~> 2.0"
44
44
  spec.add_development_dependency "bundler", "~> 2.4"
@@ -5,7 +5,7 @@ class CreateAccounts < ActiveRecord::Migration[6.1]
5
5
  def change
6
6
  create_table :accounts do |t|
7
7
  t.boolean :tos_agreed, null: false, default: true, index: true
8
- t.text :public_key, null: false, index: { unique: true }
8
+ t.text :public_key, null: false
9
9
  t.text :contacts, null: false
10
10
 
11
11
  t.timestamps
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bullion/models/account"
4
+
5
+ # Adds a public_key_hash column to the accounts table, ensuring uniqueness
6
+ class AddPublicKeyHashToAccounts < ActiveRecord::Migration[8.0]
7
+ def change
8
+ add_column :accounts, :public_key_hash, :string, null: false, limit: 44
9
+ add_index :accounts, :public_key_hash, unique: true
10
+
11
+ reversible do |dir|
12
+ dir.up do
13
+ say_with_time "Generating public_key_hash for existing accounts" do
14
+ require "digest"
15
+
16
+ Bullion::Models::Account.reset_column_information
17
+ Bullion::Models::Account.find_each do |account|
18
+ digest = Digest::SHA256.base64digest(account.public_key.to_json)
19
+ account.update_column(:public_key_hash, digest)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
data/db/schema.rb CHANGED
@@ -10,22 +10,23 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema[8.0].define(version: 2021_01_06_060335) do
13
+ ActiveRecord::Schema[8.0].define(version: 2025_08_23_073342) do
14
14
  create_table "accounts", force: :cascade do |t|
15
15
  t.boolean "tos_agreed", default: true, null: false
16
16
  t.text "public_key", null: false
17
17
  t.text "contacts", null: false
18
18
  t.datetime "created_at", null: false
19
19
  t.datetime "updated_at", null: false
20
- t.index ["public_key"], name: "index_accounts_on_public_key", unique: true
20
+ t.string "public_key_hash", limit: 44, null: false
21
+ t.index ["public_key_hash"], name: "index_accounts_on_public_key_hash", unique: true
21
22
  t.index ["tos_agreed"], name: "index_accounts_on_tos_agreed"
22
23
  end
23
24
 
24
25
  create_table "authorizations", force: :cascade do |t|
25
26
  t.string "status", default: "pending", null: false
26
- t.datetime "expires", precision: nil, null: false
27
+ t.datetime "expires", null: false
27
28
  t.text "identifier", null: false
28
- t.integer "order_id"
29
+ t.bigint "order_id"
29
30
  t.datetime "created_at", null: false
30
31
  t.datetime "updated_at", null: false
31
32
  t.index ["expires"], name: "index_authorizations_on_expires"
@@ -52,10 +53,10 @@ ActiveRecord::Schema[8.0].define(version: 2021_01_06_060335) do
52
53
  create_table "challenges", force: :cascade do |t|
53
54
  t.string "acme_type", null: false
54
55
  t.string "status", default: "pending", null: false
55
- t.datetime "expires", precision: nil, null: false
56
+ t.datetime "expires", null: false
56
57
  t.string "token", null: false
57
- t.datetime "validated", precision: nil
58
- t.integer "authorization_id"
58
+ t.datetime "validated"
59
+ t.bigint "authorization_id"
59
60
  t.datetime "created_at", null: false
60
61
  t.datetime "updated_at", null: false
61
62
  t.index ["acme_type"], name: "index_challenges_on_acme_type"
@@ -73,12 +74,12 @@ ActiveRecord::Schema[8.0].define(version: 2021_01_06_060335) do
73
74
 
74
75
  create_table "orders", force: :cascade do |t|
75
76
  t.string "status", default: "pending", null: false
76
- t.datetime "expires", precision: nil, null: false
77
+ t.datetime "expires", null: false
77
78
  t.text "identifiers", null: false
78
- t.datetime "not_before", precision: nil, null: false
79
- t.datetime "not_after", precision: nil, null: false
80
- t.integer "certificate_id"
81
- t.integer "account_id"
79
+ t.datetime "not_before", null: false
80
+ t.datetime "not_after", null: false
81
+ t.bigint "certificate_id"
82
+ t.bigint "account_id"
82
83
  t.datetime "created_at", null: false
83
84
  t.datetime "updated_at", null: false
84
85
  t.index ["account_id"], name: "index_orders_on_account_id"
@@ -119,13 +119,13 @@ module Bullion
119
119
  csr_attrs = extract_csr_attrs(csr)
120
120
  csr_sans = extract_csr_sans(csr_attrs)
121
121
  csr_domains = extract_csr_domains(csr_sans)
122
- csr_cn = cn_from_csr(csr)
122
+ csr_cn = cn_from_csr(csr) || csr_domains.first
123
123
 
124
124
  # Make sure the CSR has a valid public key
125
125
  raise Bullion::Acme::Errors::BadCsr unless csr.verify(csr.public_key)
126
126
 
127
127
  return false unless order.ready_status?
128
- raise Bullion::Acme::Errors::BadCsr unless csr_domains.include?(csr_cn)
128
+ raise Bullion::Acme::Errors::BadCsr if csr_cn && !csr_domains.include?(csr_cn)
129
129
  raise Bullion::Acme::Errors::BadCsr unless csr_domains.sort == order.domains.sort
130
130
 
131
131
  true
@@ -127,9 +127,7 @@ module Bullion
127
127
  )
128
128
 
129
129
  # Alternate Names
130
- cn = cn_from_csr(csr)
131
- existing_sans = filter_sans(csr_sans(csr))
132
- valid_alts = (["DNS:#{cn}"] + [*existing_sans]).uniq
130
+ valid_alts = build_valid_alt_names(csr)
133
131
 
134
132
  new_cert.add_extension(ef.create_extension("subjectAltName", valid_alts.join(",")))
135
133
 
@@ -137,21 +135,6 @@ module Bullion
137
135
  [new_cert, valid_alts]
138
136
  end
139
137
 
140
- def csr_sans(csr)
141
- raw_attributes = csr.attributes
142
- return [] unless raw_attributes
143
-
144
- seq = extract_csr_attrs(csr)
145
- return [] unless seq
146
-
147
- values = extract_san_values(seq)
148
- return [] unless values
149
-
150
- values = OpenSSL::ASN1.decode(values).value
151
-
152
- values.select { |v| v.tag == 2 }.map { |v| "DNS:#{v.value}" }
153
- end
154
-
155
138
  def extract_csr_attrs(csr)
156
139
  csr.attributes.select { |a| a.oid == "extReq" }.map { |a| a.value.map(&:value) }
157
140
  end
@@ -161,8 +144,9 @@ module Bullion
161
144
  end
162
145
 
163
146
  def extract_csr_domains(csr_sans)
164
- csr_decoded_sans = OpenSSL::ASN1.decode(csr_sans.first.value[1].value)
165
- csr_decoded_sans.select { |v| v.tag == 2 }.map(&:value)
147
+ subject_alt_names = csr_sans.first.value.find { |v| v.tag == 4 }
148
+ csr_decoded_sans = OpenSSL::ASN1.decode(subject_alt_names.value)
149
+ csr_decoded_sans.value.select { |v| v.tag == 2 }.map(&:value)
166
150
  end
167
151
 
168
152
  def extract_san_values(sequence)
@@ -184,13 +168,33 @@ module Bullion
184
168
  end
185
169
 
186
170
  def cn_from_csr(csr)
187
- if csr.subject.to_s
188
- cns = csr.subject.to_s.split("/").grep(/^CN=/)
171
+ return unless csr.subject.to_s
189
172
 
190
- return cns.first.split("=").last if cns && !cns.empty?
191
- end
173
+ cns = csr.subject.to_s.split("/").grep(/^CN=/)
174
+
175
+ cns.first.split("=").last if cns && !cns.empty?
176
+ end
177
+
178
+ def cn_or_first_san_from_csr(csr)
179
+ cn = cn_from_csr(csr)
180
+ return cn if cn
181
+
182
+ csr_attrs = extract_csr_attrs(csr)
183
+ csr_sans = extract_csr_sans(csr_attrs)
184
+ extract_csr_domains(csr_sans).first
185
+ end
186
+
187
+ def domains_from_csr(csr)
188
+ csr_attrs = extract_csr_attrs(csr)
189
+ csr_sans = extract_csr_sans(csr_attrs)
190
+ extract_csr_domains(csr_sans)
191
+ end
192
192
 
193
- csr_sans(csr).first.split(":").last
193
+ def build_valid_alt_names(csr)
194
+ cn = cn_or_first_san_from_csr(csr)
195
+ csr_domains = domains_from_csr(csr)
196
+ existing_sans = filter_sans(csr_domains).map { |d| "DNS:#{d}" }
197
+ (["DNS:#{cn}"] + [*existing_sans]).uniq
194
198
  end
195
199
 
196
200
  # Signs an ACME CSR
@@ -206,7 +210,7 @@ module Bullion
206
210
  csr_cert.not_after = csr_cert.not_before + (3 * 30 * 24 * 60 * 60)
207
211
 
208
212
  # Force a subject if the cert doesn't have one
209
- cert.subject = simple_subject(cn_from_csr(csr)) unless cert.subject
213
+ cert.subject = simple_subject(cn_or_first_san_from_csr(csr)) unless cert.subject
210
214
 
211
215
  csr_cert.subject = simple_subject(cert.subject.to_s)
212
216
 
@@ -7,10 +7,17 @@ module Bullion
7
7
  serialize :contacts, coder: JSON
8
8
  serialize :public_key, coder: JSON
9
9
 
10
- validates_uniqueness_of :public_key
10
+ validates_uniqueness_of :public_key_hash
11
11
 
12
12
  has_many :orders
13
13
 
14
+ before_save :generate_public_key_hash
15
+
16
+ def generate_public_key_hash
17
+ digest = Digest::SHA256.base64digest(public_key.to_json)
18
+ self.public_key_hash = digest
19
+ end
20
+
14
21
  def kid
15
22
  id
16
23
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bullion
4
- VERSION = "0.10.3"
4
+ VERSION = "0.11.1"
5
5
  end
data/lib/bullion.rb CHANGED
@@ -7,6 +7,7 @@ require "securerandom"
7
7
  require "time"
8
8
  require "logger"
9
9
  require "openssl"
10
+ require "bigdecimal"
10
11
 
11
12
  # External requirements
12
13
  require "benchmark"
@@ -14,7 +15,7 @@ require "dry-configurable"
14
15
  require "sinatra/base"
15
16
  require "sinatra/contrib"
16
17
  require "sinatra/custom_logger"
17
- require "mysql2"
18
+ require "trilogy"
18
19
  require "sinatra/activerecord"
19
20
  require "jwt"
20
21
  require "prometheus/client"
@@ -68,7 +69,11 @@ module Bullion
68
69
  MetricsRegistry = Prometheus::Client.registry
69
70
 
70
71
  def self.ca_key
71
- @ca_key ||= OpenSSL::PKey::RSA.new(File.read(config.ca.key_path), config.ca.secret)
72
+ @ca_key ||= begin
73
+ OpenSSL::PKey::RSA.new(File.read(config.ca.key_path), config.ca.secret)
74
+ rescue OpenSSL::PKey::RSAError
75
+ OpenSSL::PKey::EC.new(File.read(config.ca.key_path), config.ca.secret)
76
+ end
72
77
  end
73
78
 
74
79
  def self.ca_cert_file
@@ -1,5 +1,4 @@
1
1
  #!/bin/sh
2
2
 
3
3
  # Starts the server
4
- rake db:migrate
5
4
  itsi
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Gnagy
@@ -93,20 +93,6 @@ dependencies:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '2.7'
96
- - !ruby/object:Gem::Dependency
97
- name: mysql2
98
- requirement: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '0.5'
103
- type: :runtime
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: '0.5'
110
96
  - !ruby/object:Gem::Dependency
111
97
  name: openssl
112
98
  requirement: !ruby/object:Gem::Requirement
@@ -191,6 +177,20 @@ dependencies:
191
177
  - - "~>"
192
178
  - !ruby/object:Gem::Version
193
179
  version: '2.7'
180
+ - !ruby/object:Gem::Dependency
181
+ name: trilogy
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '2.9'
187
+ type: :runtime
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '2.9'
194
194
  - !ruby/object:Gem::Dependency
195
195
  name: acme-client
196
196
  requirement: !ruby/object:Gem::Requirement
@@ -406,6 +406,7 @@ files:
406
406
  - db/migrate/20210106052306_create_authorizations.rb
407
407
  - db/migrate/20210106055421_create_challenges.rb
408
408
  - db/migrate/20210106060335_create_nonces.rb
409
+ - db/migrate/20250823073342_add_public_key_hash_to_accounts.rb
409
410
  - db/schema.rb
410
411
  - lib/bullion.rb
411
412
  - lib/bullion/acme/error.rb