# Certificate installation and post-issuance notification

# at least one of 'certificate' or 'certificate-chain' is required
cat >"/etc/lacme/lacme-certs.conf.d/bad1.conf" <<- EOF
	[bad1]
	certificate-key = /etc/lacme/bad1.key
	subject = /CN=bad1.$DOMAINNAME
EOF
! lacme newOrder bad1 2>"$STDERR" || fail newOrder bad1
grepstderr -Fxq "[bad1] Warning: Missing 'certificate' and 'certificate-chain', skipping"

# 'subject' is required
cat >"/etc/lacme/lacme-certs.conf.d/bad2.conf" <<- EOF
	[bad2]
	certificate-key = /etc/lacme/bad2.key
	certificate = /etc/lacme/bad2.crt
EOF
! lacme newOrder bad2 2>"$STDERR" || fail newOrder bad2
grepstderr -Fxq "[bad2] Warning: Couldn't generate CSR, skipping"

# 'certificate-key' is required
cat >"/etc/lacme/lacme-certs.conf.d/bad3.conf" <<- EOF
	[bad3]
	certificate = /etc/lacme/bad3.crt
	subject = /CN=bad3.$DOMAINNAME
EOF
! lacme newOrder bad3 2>"$STDERR" || fail newOrder bad3
grepstderr -Fxq "[bad3] Warning: Couldn't generate CSR, skipping"


# 'certificate' installs only the leaf certificate
openssl genpkey -algorithm RSA -out /etc/lacme/test1.key
subject="/CN=$(head -c10 /dev/urandom | base32 -w0).$DOMAINNAME"
cat >"/etc/lacme/lacme-certs.conf.d/test1.conf" <<- EOF
	[test1]
	certificate-key = /etc/lacme/test1.key
	certificate = /etc/lacme/test1.crt
	subject = $subject
EOF

lacme newOrder test1 2>"$STDERR" || fail newOrder test1
test /etc/lacme/test1.crt -nt /etc/lacme/test1.key
sed -n "0,/^-----END CERTIFICATE-----$/ p" /etc/lacme/test1.crt >/etc/lacme/test1.pem
diff --unified /etc/lacme/test1.crt /etc/lacme/test1.pem


check_hash() {
    local p1="$1" p2 s1 s2
    s1="$(openssl x509 -noout -hash <"$p1")"
    for p2 in /usr/share/lacme/ca-certificates.pem.*; do
        s2="$(openssl x509 -noout -hash <"$p2")"
        if [ "$s1" = "$s2" ]; then
            return 0
        fi
    done
    return 1
}
csplit -f /usr/share/lacme/ca-certificates.pem. /usr/share/lacme/ca-certificates.crt \
    "/-----BEGIN CERTIFICATE-----/" "{*}"
rm -f /usr/share/lacme/ca-certificates.pem.00

# 'certificate-chain' appends the chain of trust
openssl genpkey -algorithm RSA -out /etc/lacme/test2.key
cat >"/etc/lacme/lacme-certs.conf.d/test2.conf" <<- EOF
	[test2]
	certificate-key = /etc/lacme/test2.key
	certificate-chain = /etc/lacme/test2.crt
	subject = $subject
EOF

lacme newOrder test2 2>"$STDERR" || fail newOrder test2
test /etc/lacme/test2.crt -nt /etc/lacme/test2.key
csplit -f /etc/lacme/test2.chain.pem /etc/lacme/test2.crt \
    "/-----BEGIN CERTIFICATE-----/" "{*}"
test -s /etc/lacme/test2.chain.pem01 # leaf cert (00 is empty)
rm -f /etc/lacme/test2.chain.pem0[01]
test -s /etc/lacme/test2.chain.pem02 # depth 1

# all certificates at depth >=1 must be in our CA bundle
for p in /etc/lacme/test2.chain.pem*; do
    check_hash "$p"
done

# 'certificate' + 'certificate-chain'
openssl genpkey -algorithm RSA -out /etc/lacme/test3.key
cat >"/etc/lacme/lacme-certs.conf.d/test3.conf" <<- EOF
	[test3]
	certificate-key = /etc/lacme/test3.key
	certificate = /etc/lacme/test3.pem
	certificate-chain = /etc/lacme/test3.crt
	subject = $subject
EOF

lacme newOrder test3 2>"$STDERR" || fail newOrder test3
test /etc/lacme/test3.pem -nt /etc/lacme/test3.key
test /etc/lacme/test3.crt -nt /etc/lacme/test3.key
csplit -f /etc/lacme/test3.chain.pem /etc/lacme/test3.crt \
    "/-----BEGIN CERTIFICATE-----/" "{*}"
sed -i "/^$/d" /etc/lacme/test3.chain.pem*
diff -q /etc/lacme/test3.chain.pem01 /etc/lacme/test3.pem
st="$(stat -c "%U:%G %#a" /etc/lacme/test3.pem)"
[ "$st" = "root:root 0644" ]
st="$(stat -c "%U:%G %#a" /etc/lacme/test3.crt)"
[ "$st" = "root:root 0644" ]

# owner user
openssl genpkey -algorithm RSA -out /etc/lacme/test4.key
cat >"/etc/lacme/lacme-certs.conf.d/test4.conf" <<- EOF
	[test4]
	certificate-key = /etc/lacme/test4.key
	certificate = /etc/lacme/test4.pem
	certificate-chain = /etc/lacme/test4.crt
	owner = nonexistent-user
	subject = $subject
EOF

! lacme newOrder test4 2>"$STDERR" || fail newOrder test4
grepstderr -Fxq "getpwnam(nonexistent-user)"
! test -e /etc/lacme/test4.pem
! test -e /etc/lacme/test4.crt

sed -ri "s/^owner\\s*=.*/owner = nobody/" /etc/lacme/lacme-certs.conf.d/test4.conf
lacme newOrder test4 2>"$STDERR" || fail newOrder test4
st="$(stat -c "%U:%G %#a" /etc/lacme/test4.pem)"
[ "$st" = "nobody:root 0644" ]
st="$(stat -c "%U:%G %#a" /etc/lacme/test4.crt)"
[ "$st" = "nobody:root 0644" ]

# owner user:group
openssl genpkey -algorithm RSA -out /etc/lacme/test5.key
cat >"/etc/lacme/lacme-certs.conf.d/test5.conf" <<- EOF
	[test5]
	certificate-key = /etc/lacme/test5.key
	certificate = /etc/lacme/test5.pem
	certificate-chain = /etc/lacme/test5.crt
	owner = nobody:nonexistent-group
	subject = $subject
EOF

! lacme newOrder test5 2>"$STDERR" || fail newOrder test5
grepstderr -Fxq "getgrnam(nonexistent-group)"
! test -e /etc/lacme/test5.pem
! test -e /etc/lacme/test5.crt

sed -ri "s/^owner\\s*=.*/owner = nobody:nogroup/" /etc/lacme/lacme-certs.conf.d/test5.conf
lacme newOrder test5 2>"$STDERR" || fail newOrder test5
st="$(stat -c "%U:%G %#a" /etc/lacme/test5.pem)"
[ "$st" = "nobody:nogroup 0644" ]
st="$(stat -c "%U:%G %#a" /etc/lacme/test5.crt)"
[ "$st" = "nobody:nogroup 0644" ]

# umask restrictions (also test empty values)
openssl genpkey -algorithm RSA -out /etc/lacme/test6.key
cat >"/etc/lacme/lacme-certs.conf.d/test6.conf" <<- EOF
	[test6]
	certificate-key = /etc/lacme/test6.key
	certificate-chain = /etc/lacme/test6.crt
	certificate =
	mode =
	owner =
	subject = $subject
EOF

( umask 0077 && lacme newOrder test6 2>"$STDERR" || fail newOrder test6 )
! test -e /etc/lacme/test6.pem
st="$(stat -c "%U:%G %#a" /etc/lacme/test6.crt)"
[ "$st" = "root:root 0600" ]

# mode
openssl genpkey -algorithm RSA -out /etc/lacme/test7.key
cat >"/etc/lacme/lacme-certs.conf.d/test7.conf" <<- EOF
	[test7]
	certificate-key = /etc/lacme/test7.key
	certificate = /etc/lacme/test7.pem
	certificate-chain = /etc/lacme/test7.crt
	mode = 0400
	subject = $subject
EOF

lacme newOrder test7 2>"$STDERR" || fail newOrder test7
st="$(stat -c "%U:%G %#a" /etc/lacme/test7.pem)"
[ "$st" = "root:root 0400" ]
st="$(stat -c "%U:%G %#a" /etc/lacme/test7.crt)"
[ "$st" = "root:root 0400" ]

# post-issuance notification
openssl genpkey -algorithm RSA -out /etc/lacme/test8.key
cat >"/etc/lacme/lacme-certs.conf.d/test8.conf" <<- EOF
	[test8]
	certificate-key = /etc/lacme/test8.key
	certificate-chain = /etc/lacme/test8.crt
	subject = $subject
	notify = touch /tmp/test8.notify
EOF

lacme newOrder test8 2>"$STDERR" || fail newOrder test8
grepstderr -Fxq "Running notification command \`touch /tmp/test8.notify\`"
test -e /tmp/test8.notify

rm -f /tmp/test8.notify
lacme newOrder test8 2>"$STDERR" || fail newOrder test8
ngrepstderr -Fq "Running notification command"
! test -e /tmp/test8.notify

# vim: set filetype=sh :