Created
February 7, 2019 16:25
-
-
Save Cryolite/0a0ca9f671e102bbfa0a7c19a1f71b74 to your computer and use it in GitHub Desktop.
https://qiita.com/nwtgck/items/78309fc529da7776cba0 のプロトコル上に証明書による安全な鍵交換を実装する PoC コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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