diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 02cf45d..64b4d0a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,9 +18,9 @@ jobs: strategy: fail-fast: false matrix: - ruby-version: ['2.6', '2.7'] + ruby-version: ['2.7', '3.0', '3.1'] container: - image: sorah/ruby:${{ matrix.ruby-version }}-dev + image: public.ecr.aws/sorah/ruby:${{ matrix.ruby-version }}-dev steps: - name: Cache bundled gems @@ -40,7 +40,7 @@ jobs: strategy: fail-fast: false matrix: - ruby-version: ['2.6', '2.7'] + ruby-version: ['2.7', '3.0', '3.1'] # FIXME: once GitHub Actions gains support of adding command line arguments to container # services: @@ -72,7 +72,7 @@ jobs: - run: 'docker run -d --net=host --rm letsencrypt/pebble pebble -config /test/config/pebble-config.json -strict -dnsserver 127.0.0.1:8053' - run: 'docker run -d --net=host --rm letsencrypt/pebble-challtestsrv pebble-challtestsrv -management :8055 -defaultIPv4 127.0.0.1' - - run: 'docker run --net=host -e CI --rm -v $(pwd):/work -v $(realpath ~/bundle):/bundle sorah/ruby:${{ matrix.ruby-version }}-dev sh -c "cd /work && bundle install --path /bundle && bundle exec rspec -fd -t integration_pebble"' + - run: 'docker run --net=host -e CI --rm -v $(pwd):/work -v $(realpath ~/bundle):/bundle public.ecr.aws/sorah/ruby:${{ matrix.ruby-version }}-dev sh -c "cd /work && bundle install --path /bundle && bundle exec rspec -fd -t integration_pebble"' docker-build: name: docker-build diff --git a/lib/acmesmith/certificate_retrieving_service.rb b/lib/acmesmith/certificate_retrieving_service.rb index 5b7e62d..0287ba5 100644 --- a/lib/acmesmith/certificate_retrieving_service.rb +++ b/lib/acmesmith/certificate_retrieving_service.rb @@ -71,11 +71,11 @@ def match?(name: nil, key_id: nil) if key_id top_key_id = if has_root - top.extensions.find { |e| e.oid == 'subjectKeyIdentifier' }.value + value_der(top.extensions.find { |e| e.oid == 'subjectKeyIdentifier' })&.slice(2..-1) else - top.extensions.find { |e| e.oid == 'authorityKeyIdentifier' }.value&.each_line&.grep(/^keyid:/)&.first&.yield_self { |v| v[6..-1] }&.chomp - end - return false unless key_id.downcase == top_key_id.downcase + value_der(top.extensions.find { |e| e.oid == 'authorityKeyIdentifier' })&.slice(4,20) + end&.unpack1('H*')&.downcase + return false unless key_id.downcase.gsub(/:/,'') == top_key_id end true @@ -97,12 +97,25 @@ def top private def find_issuer(cert) return nil if cert.issuer == cert.subject - aki = cert.extensions.find { |e| e.oid == 'authorityKeyIdentifier' }.value&.each_line&.grep(/^keyid:/)&.first&.yield_self { |v| v[6..-1] }&.chomp + # https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.1 + # sequence(\x30\x16) context-specific(\x80\x14) + keyid + aki = value_der(cert.extensions.find { |e| e.oid == 'authorityKeyIdentifier' }) + + # compare using SKI as a AKI DER. this doesn't support AKI using other than keyid but it should be okay certificates.find do |c| - ski = c.extensions.find { |e| e.oid == 'subjectKeyIdentifier' }.value - ski == aki && cert.issuer == c.subject + ski_der = value_der(c.extensions.find { |e| e.oid == 'subjectKeyIdentifier' }) + next unless ski_der + hdr = "\x30\x16\x80\x14".b + keyid = ski_der[2..-1] + + "#{hdr}#{keyid}" == aki && cert.issuer == c.subject end end + + private def value_der(ext) + return nil unless ext + ext.respond_to?(:value_der) ? ext.value_der : ext.to_der[9..-1] + end end private def download(url, format:)