diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8569f914d2e1bca0b4b56f2bdf9f10db924171bf..505e74e47252e6bf5cc305b800acc313876b65af 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ - repo: git://github.com/pre-commit/pre-commit-hooks - sha: v0.7.1 + sha: v0.9.1 hooks: - id: check-added-large-files - id: check-merge-conflict @@ -10,10 +10,3 @@ files: bundle_certs - id: shellcheck files: bundle_certs -- repo: local - hooks: - - id: test - name: make test - language: system - entry: make test test_source - files: bundle_certs|Makefile diff --git a/.travis.yml b/.travis.yml index 7b519b7a2b23178c54e102245a34d0281bc7d5ce..7c84a26b938ab3930a565c03ac9659d133736e45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,6 @@ addons: - mawk - openssl - curl - - build-essential - cabal-install - ghc @@ -29,7 +28,8 @@ install: - pip install pre_commit | cat script: - - pre-commit run --all-files + - pre-commit run --all-files + - bats --tap tests/ notifications: on_failure: never diff --git a/README.rst b/README.rst index 2e1a21ea9af48f01b0bec88c853df20400a66612..da4ec74bbe368214c1a145b6a341ea026b75fa37 100644 --- a/README.rst +++ b/README.rst @@ -28,8 +28,9 @@ For regular use: For testing/ development purposes, all of the above, plus: -- Make. - Curl. +- `Bats <https://github.com/sstephenson/bats>`_. +- `Pre-commit <http://pre-commit.com/>`_. Usage ----- @@ -58,12 +59,12 @@ Shell functions subject hash). - bundle_certs: See Usage section above. -Development ------------ +Development and testing +----------------------- -For testing run :code:`make test`. For cleaning temporary files run :code:`git -clean -fdx`. You can use `pre-commit <http://pre-commit.com/>`_ to have the test -(which is quite quick) run on every commit to ensure quality code. +Testing is done using Bats <https://github.com/sstephenson/bats>`_. To test run +:code:`bats --tap tests/`. `Pre-commit <http://pre-commit.com/>`_ is also +configured for this repo. License ------- diff --git a/bundle_certs b/bundle_certs index 19d64805d984b5b62c76f2a719aa3ac0e08b5d27..206642bba96fb8724c64b9fb397314cca2065420 100755 --- a/bundle_certs +++ b/bundle_certs @@ -3,7 +3,7 @@ # Check if the script is being sourced or not. # shellcheck disable=SC2142 -alias is_sourced='[ "$_" != "$0" ] && expr "$-" : ".*i.*" > /dev/null' +alias is_sourced='[ "$_" != "$0" ] && [ "${-#*i}" != "$-" ]' # Returns the subject hash of the certificate path provided. alias subject_hash='openssl x509 -noout -subject_hash -in' @@ -61,38 +61,41 @@ unbundle_cert () { } bundle_certs () { - local issuer issued ordered_certs filename + local filename issuer issued bundle + if [ $# -eq 0 ] + then + echo "Usage: bundle_certs filename [filename2 [filename3 ...]]" >> /dev/stderr + return 1 + fi for filename in "$@" do [ -f "$filename" ] && unbundle_cert "$filename" done - cd certs - issuer="$(find_root_cert "*")" + issuer="$(find_root_cert certs/*)" if [ -z "$issuer" ] then - echo "Failed to find root certificate." > /dev/stderr - exit 1 + echo "Failed to find root certificate." >> /dev/stderr + return 1 fi - issued="$(find_cert_by_issuer_hash "$issuer" "*")" + issued="$(find_cert_by_issuer_hash "$(basename "$issuer")" certs/*)" + bundle="$(cat "$issued")" while [ -n "$issued" ] do - ordered_certs="$issued $ordered_certs" issuer="$issued" - issued="$(find_cert_by_issuer_hash "$issuer" "*")" + issued="$(find_cert_by_issuer_hash "$(basename "$issuer")" certs/*)" + [ -n "$issued" ] && bundle="$(echo "${bundle:-}"; cat "$issued")" done - cat "$ordered_certs" - cd .. + echo "$bundle" rm -r certs } - -if ! is_sourced +if ! (is_sourced) then set -eu if [ $# -eq 0 ] then - echo "Usage: $0 filename [filename2 [filename3 ...]]" > /dev/stderr - exit 1 + echo "Usage: $(basename "$0") filename [filename2 [filename3 ...]]" >> /dev/stderr + return 1 else bundle_certs "$@" fi diff --git a/Makefile b/tests/bundle-certs.bats similarity index 51% rename from Makefile rename to tests/bundle-certs.bats index 8015254f5e03851cf259885d306402e3dbfbd330..9401ebbe011433b70e1f41da0d95dc9b6aef3893 100644 --- a/Makefile +++ b/tests/bundle-certs.bats @@ -1,59 +1,42 @@ -.PHONY: test clean +#!/usr/bin/env bats -.testcerts: - mkdir -p .testcerts - -.testcerts/serial: .testcerts +setup () { + teardown + mkdir -p .testcerts echo 1000 > .testcerts/serial - -.testcerts/root.key: .testcerts openssl genrsa -out .testcerts/root.key 4096 - -.testcerts/root.crt: .testcerts/root.key openssl req -new -x509 -days 7 -key .testcerts/root.key -nodes -out .testcerts/root.crt -subj /C=US/ST=State/L=City/O=RootCA/OU=Unit/CN=localhost/emailAddress=none@nowhere.com - -.testcerts/intermediate1.key: .testcerts openssl genrsa -out .testcerts/intermediate1.key 4096 - -.testcerts/intermediate1.csr: .testcerts/intermediate1.key openssl req -new -key .testcerts/intermediate1.key -out .testcerts/intermediate1.csr -subj /C=US/ST=State/L=City/O=FirstIntermediate/OU=Unit/CN=localhost/emailAddress=none@nowhere.com - -.testcerts/intermediate1.crt: .testcerts/intermediate1.csr .testcerts/root.key .testcerts/root.crt .testcerts/serial openssl x509 -req -days 7 -in .testcerts/intermediate1.csr -out .testcerts/intermediate1.crt -CAkey .testcerts/root.key -CA .testcerts/root.crt -CAserial .testcerts/serial - -.testcerts/intermediate2.key: .testcerts openssl genrsa -out .testcerts/intermediate2.key 4096 - -.testcerts/intermediate2.csr: .testcerts/intermediate2.key openssl req -new -key .testcerts/intermediate2.key -out .testcerts/intermediate2.csr -subj /C=US/ST=State/L=City/O=SecondIntermediate/OU=Unit/CN=localhost/emailAddress=none@nowhere.com - -.testcerts/intermediate2.crt: .testcerts/intermediate2.csr .testcerts/intermediate1.key .testcerts/serial .testcerts/intermediate1.crt openssl x509 -req -days 7 -in .testcerts/intermediate2.csr -out .testcerts/intermediate2.crt -CAkey .testcerts/intermediate1.key -CA .testcerts/intermediate1.crt -CAserial .testcerts/serial - -.testcerts/server.key: .testcerts openssl genrsa -out .testcerts/server.key 4096 - -.testcerts/server.csr: .testcerts/server.key openssl req -new -key .testcerts/server.key -out .testcerts/server.csr -subj /C=US/ST=State/L=City/O=Server/OU=Unit/CN=localhost/emailAddress=none@nowhere.com - -.testcerts/server.crt: .testcerts/intermediate2.key .testcerts/server.csr .testcerts/serial .testcerts/intermediate2.crt openssl x509 -req -days 7 -in .testcerts/server.csr -out .testcerts/server.crt -CAkey .testcerts/intermediate2.key -CA .testcerts/intermediate2.crt -CAserial .testcerts/serial - -.testcerts/intermediates.crt: .testcerts/intermediate1.crt .testcerts/intermediate2.crt cat .testcerts/intermediate1.crt .testcerts/intermediate2.crt > .testcerts/intermediates.crt - -.testcerts/bundle.crt: .testcerts/intermediates.crt .testcerts/server.crt - ./bundle_certs .testcerts/* > .testcerts/bundle.crt - -test: .testcerts/bundle.crt .testcerts/root.crt .testcerts/server.key - openssl s_server -cert .testcerts/bundle.crt -key .testcerts/server.key -quiet -www -no_dhe & echo "$$!" > .server.pid - test "$$(curl --fail --cacert .testcerts/root.crt --write-out '%{ssl_verify_result}' --silent --output /dev/null https://localhost:4433)" = "0" - if [ -f .server.pid ] && [ -d "/proc/$$(cat .server.pid)" ]; then kill "$$(cat .server.pid)"; fi - rm -f .server.pid - -clean: - - kill "$$(cat .server.pid)" - git clean -fdx - -test_source: - /bin/sh -c '. ./bundle_certs' +} + +teardown () { + [ -f .server.pid ] && [ -d "/proc/$$(cat .server.pid)" ] && kill "$(cat .server.pid)" || true + #git clean -fdX +} + +server_test () { + openssl s_server -cert .testcerts/bundle.crt -key .testcerts/server.key -quiet -www -no_dhe & + echo "$!" > .server.pid + run curl --fail --cacert .testcerts/root.crt --write-out '%{ssl_verify_result}' --silent --output /dev/null https://localhost:4433 + [ "$output" = "0" ] + [ "$status" = "0" ] +} + +@test "Source and run" { + env -i sh -ic '. ./bundle_certs && bundle_certs .testcerts/* > .testcerts/bundle.crt' + server_test +} + +@test "Run" { + ./bundle_certs .testcerts/* > .testcerts/bundle.crt + server_test +}