Skip to content

Instantly share code, notes, and snippets.

@stbuehler
Created August 4, 2017 10:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stbuehler/0f4d6d8910077bf6caabb95469c3d454 to your computer and use it in GitHub Desktop.
Save stbuehler/0f4d6d8910077bf6caabb95469c3d454 to your computer and use it in GitHub Desktop.
S/MIME test mails send scripts
#!/bin/bash
set -e
tmpdir=$(mktemp --tmpdir -d smime-build-msg-XXXXXXX)
trap 'rm -rf "${tmpdir}"' EXIT
cd "${tmpdir}"
debug_show() {
local name="$1"
printf "File: %s\n---\n" "${name}"
cat -- "${name}"
printf "%s\n" "---"
}
mode="$1"
if [ ${#mode} -ne 3 ]; then
echo >&2 "Invalid mode length, pick [xn][xn][dn]"
exit 1
fi
shift
case "${mode:0:1}" in
x)
enc_ct="x-pkcs7-mime"
;;
n)
enc_ct="pkcs7-mime"
;;
*)
echo >&2 "Invalid enc_ct mode, pick [xn][xn][dn]"
exit 1
;;
esac
case "${mode:1:1}" in
x)
sign_ct="x-"
;;
n)
sign_ct=""
;;
*)
echo >&2 "Invalid sign_ct mode, pick [xn][xn][dn]"
exit 1
;;
esac
case "${mode:2:1}" in
d)
sign_type="detached"
sign_command="--detach-sign"
sign_ct="${sign_ct}pkcs7-signature"
;;
n)
sign_type="non-detached"
sign_command="--sign"
sign_ct="${sign_ct}pkcs7-mime"
;;
*)
echo >&2 "Invalid sign_type mode, pick [xn][xn][dn]"
exit 1
;;
esac
unset known_addresses
declare -A known_addresses
# known_addresses[alice@example.com]='Alice'
recipient_lines=()
recipient_args=()
for recipient in "$@"; do
case "${recipient}" in
to:*)
r=${recipient#to:}
m=To
;;
cc:*)
r=${recipient#cc:}
m=Cc:
;;
bcc:*)
r=${recipient#bcc:}
m=Bcc:
;;
*)
r=${recipient}
m=To
;;
esac
name=${known_addresses[$r]}
if [ -z "${name}" ]; then
recipient_lines+=("${m}: ${r}")
else
recipient_lines+=("${m}: ${name} <${r}>")
fi
recipient_args+=(-r "${r}")
done
pass="$(openssl rand -base64 9)"
code="$(openssl rand 6 | base32 -w0 | tr A-Z a-z | tr -d =)"
(
printf "%s\r\n" "Content-Type: text/plain; charset=utf-8"
printf "%s\r\n" "Content-Transfer-Encoding: quoted-printable"
printf "\r\n"
(
cat <<EOF
Hallo,
kannst du diese Mail lesen?
Dann antworte bitte auf diese Mail :)
${pass}
Viele Grüße,
Stefan
EOF
if [ -f ~/.signature ]; then
echo
echo "-- "
cat ~/.signature
fi
echo
) | perl -MMIME::QuotedPrint -ne 'print encode_qp($_, "\r\n");'
) > msg
echo "Signing message"
gpgsm --quiet "${sign_command}" -o signed.p7m msg 2> /dev/null
if [ "${sign_type}" = "non-detached" ]; then
(
printf "%s\r\n" "MIME-Version: 1.0"
printf "%s\r\n" "Content-Type: application/${sign_ct}; name=\"smime.p7m\"; smime-type=\"signed-data\""
printf "%s\r\n" "Content-Description: S/MIME Signed Message"
printf "%s\r\n" "Content-Transfer-Encoding: base64"
printf "\r\n"
base64 signed.p7m
) > signed.part
else
micalg="$(openssl pkcs7 -inform DER -in signed.p7m -noout -print | grep algorithm | head -n1 | awk '{print $2}')"
if [ "${micalg}" != "sha256" ]; then
echo >&2 "Unexpected signature algorithm: '${micalg}'"
exit 1
fi
# micalg=sha-256 ?
boundary="$(openssl rand 20 | base32 -w0 | tr A-Z a-z | tr -d =)"
(
printf "%s\r\n" "MIME-Version: 1.0"
printf "%s\r\n" "Content-Type: multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=${micalg}; boundary=\"${boundary}\""
printf "\r\n"
printf "This is a cryptographically signed message in MIME format.\r\n"
printf "\r\n%s\r\n" "--${boundary}"
# message has its own header?
cat msg
printf "\r\n%s\r\n" "--${boundary}"
printf "%s\r\n" "Content-Type: application/${sign_ct}; name=\"smime.p7s\""
printf "%s\r\n" "Content-Transfer-Encoding: base64"
printf "%s\r\n" "Content-Disposition: attachment; filename=\"smime.p7s\""
printf "%s\r\n" "Content-Description: S/MIME Cryptographic Signature"
printf "\r\n"
base64 signed.p7m
printf "\r\n%s\r\n" "--${boundary}--"
) > signed.part
fi
# debug_show signed.part
echo "Encrypting message"
gpgsm --batch --quiet -e "${recipient_args[@]}" -o encrypted.p7m signed.part 2> /dev/null
(
printf "%s\r\n" "MIME-Version: 1.0"
printf "%s\r\n" "Content-Disposition: attachment; filename=\"smime.p7m\""
printf "%s\r\n" "Content-Type: application/${enc_ct}; smime-type=enveloped-data; name=\"smime.p7m\""
printf "%s\r\n" "Content-Transfer-Encoding: base64"
printf "%s\r\n" "Content-Description: S/MIME Signed Message"
for l in "${recipient_lines[@]}"; do
printf "%s\r\n" "$l"
done
printf "%s\r\n" "Subject: ${enc_ct} and ${sign_ct} (${sign_type}) signature test (${code})"
printf "\r\n"
base64 encrypted.p7m
) > mail.eml
echo "Sending message: ${enc_ct} and ${sign_ct} (${sign_type}) signature test (${code})"
# send mail according to To, Cc, Bcc headers
exim -bm -t < mail.eml
# only send mail to some test address
# exim -bm alice@example.com < mail.eml
#!/bin/bash
set -e
mode_mask="$1"
if [ ${#mode_mask} -ne 3 ]; then
echo >&2 "Invalid mode length, pick [.xn][.xn][.dn]"
exit 1
fi
shift
mask1=${mode_mask:0:1}
mask2=${mode_mask:1:1}
mask3=${mode_mask:2:1}
for enc_ct in x n; do
[ "${mask1}" != "." -a "${mask1}" != "${enc_ct}" ] && continue
for sign_ct in x n; do
[ "${mask2}" != "." -a "${mask2}" != "${sign_ct}" ] && continue
for sign_type in d n; do
[ "${mask3}" != "." -a "${mask3}" != "${sign_type}" ] && continue
./send.sh "${enc_ct}${sign_ct}${sign_type}" "$@"
done
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment