Skip to content

Instantly share code, notes, and snippets.

@Cryolite
Created February 7, 2019 16:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cryolite/0a0ca9f671e102bbfa0a7c19a1f71b74 to your computer and use it in GitHub Desktop.
Save Cryolite/0a0ca9f671e102bbfa0a7c19a1f71b74 to your computer and use it in GitHub Desktop.
https://qiita.com/nwtgck/items/78309fc529da7776cba0 のプロトコル上に証明書による安全な鍵交換を実装する PoC コード
#!/usr/bin/env bash
set -euo pipefail
if [[ -v VERBOSE ]]; then
set -x
PS4='+$LINENO: '
fi
function print-error-message ()
{
if [[ -t 2 ]] && type -t tput >/dev/null; then
if (( "$(tput colors)" == 256 )); then
echo "$(tput setaf 9)$1$(tput sgr0)" >&2
else
echo "$(tput setaf 1)$1$(tput sgr0)" >&2
fi
else
echo "$1" >&2
fi
}
function print-usage ()
{
cat <<'EOF'
Usage: client [--hostname HOSTNAME] URL
Secure netcat over a Piping Server.
URL A URL on a Piping Server. This URL must be shared
with the server.
--hostname HOSTNAME A hostname that is expected to appear in the
Common Name (CN) or Subject Alternative Names
(SANs) of the certificate the server presents. If
HOSTNAME does not appear in either CN nor SANs,
the certificate will be rejected.
-h, --help Display this help and exit.
EOF
}
if getopt -T; (( $? != 4 )); then
print-error-message "\`getopt' is not an enhanced version."
exit 1
fi
opts="$(getopt -n "client" -l hostname:,help -- h "$@")"
eval set -- "$opts"
while (( $# > 0 )); do
arg="$1"
shift
case "$arg" in
--hostname)
hostname="$1"
shift
;;
-h|--help)
set +x
print-usage
exit 0
;;
--)
if (( $# == 0 )); then
print-error-message "\`URL' is not specified."
exit 1
fi
url="$1"
shift
;;
*)
print-error-message "An unknown argument \`$arg'."
exit 1
esac
done
base_url="$(dirname "$url")"
while true; do
recv_basename="$(head -c 64 /dev/urandom | tr -dc '[:alnum:]' | head -c 16)"
if (( "$(wc -c <<<$recv_basename)" == 16 )); then
break
fi
done
recv_url="$base_url/$recv_basename"
curl -T - "$url" <<<$recv_url
tmpdir="$(mktemp -d)"
trap "rm -rf '$tmpdir'" EXIT
curl "$recv_url" >"$tmpdir/cert.pem"
openssl x509 -in "$tmpdir/cert.pem" -out "$tmpdir/leaf_cert.pem"
openssl verify -CAfile "$tmpdir/cert.pem" -verify_hostname "$hostname" -x509_strict "$tmpdir/leaf_cert.pem" || {
print-error-message "Failed to verify the certificate."
exit 1
}
while true; do
shared_key="$(head -c 64 /dev/urandom | tr -dc '[:alnum:]' | head -c 16)"
if (( "$(wc -c <<<$shared_key)" == 16 )); then
break
fi
done
cat <<<$shared_key >"$tmpdir/shared_key"
openssl pkeyutl -encrypt -in "$tmpdir/shared_key" -certin -inkey "$tmpdir/leaf_cert.pem" -out "$tmpdir/shared_key.bin"
curl -T "$tmpdir/shared_key.bin" "$url"
openssl enc -aes-256-cbc -pass "file:$tmpdir/shared_key" | curl -T - "$url"
#!/usr/bin/env bash
set -euo pipefail
if [[ -v VERBOSE ]]; then
set -x
PS4='+$LINENO: '
fi
function print-error-message ()
{
if [[ -t 2 ]] && type -t tput >/dev/null; then
if (( "$(tput colors)" == 256 )); then
echo "$(tput setaf 9)$1$(tput sgr0)" >&2
else
echo "$(tput setaf 1)$1$(tput sgr0)" >&2
fi
else
echo "$1" >&2
fi
}
function print-usage ()
{
cat <<'EOF'
Usage: server [--cert CERTIFICATE] [--key PRIVATE_KEY] URL
Secure netcat over a Piping Server.
URL A URL on a Piping Server. This URL must be shared
with the client.
--cert CERTIFICATE A path to a file containing certificates including
ones for intermediate Certificate Authorities
(CAs). The first certificate in the file must be
the leaf certificate, which is followed by ones
for CAs. Only PEM format is supported.
--key PRIVATE_KEY The private key file corresponding to CERTIFICATE.
Only PEM format is supported.
-h, --help Display this help and exit.
EOF
}
if getopt -T; (( $? != 4 )); then
print-error-message "\`getopt' is not an enhanced version."
exit 1
fi
opts="$(getopt -n "server" -l cert:,key:,help -- h "$@")"
eval set -- "$opts"
while (( $# > 0 )); do
arg="$1"
shift
case "$arg" in
--cert)
cert_path="$1"
shift
;;
--key)
key_path="$1"
shift
;;
-h|--help)
set +x
print-usage
exit 0
;;
--)
if (( $# == 0 )); then
print-error-message "\`URL' is not specified."
exit 1
fi
url="$1"
shift
;;
*)
print-error-message "An unknown argument \`$arg'."
exit 1
esac
done
base_url="$(dirname "$url")"
send_url="$(curl "$url")"
curl -T "$cert_path" "$send_url"
tmpdir="$(mktemp -d)"
trap "rm -rf '$tmpdir'" EXIT
curl "$url" >"$tmpdir/shared_key.bin"
openssl pkeyutl -decrypt -in "$tmpdir/shared_key.bin" -inkey "$key_path" -out "$tmpdir/shared_key"
curl "$url" | openssl enc -aes-256-cbc -d -pass "file:$tmpdir/shared_key"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment