#!/bin/bash
# info: register letsencrypt user account
# options: USER
#
# The function creates and register LetsEncript account 


#----------------------------------------------------------#
#                    Variable&Function                     #
#----------------------------------------------------------#

# Argument definition
user=$1

# LE API
API='https://acme-v02.api.letsencrypt.org'

# Includes
source $VESTA/func/main.sh
source $VESTA/conf/vesta.conf

# encode base64
encode_base64() {
    cat |base64 |tr '+/' '-_' |tr -d '\r\n='
}

# Let's Encrypt v2 curl function
query_le_v2() {
    protected='{"nonce": "'$3'",'
    protected=''$protected' "url": "'$1'",'
    protected=''$protected' "alg": "RS256", "jwk": '$jwk'}'
    content="Content-Type: application/jose+json"

    payload_=$(echo -n "$2" |encode_base64)
    protected_=$(echo -n "$protected" |encode_base64)
    signature_=$(printf "%s" "$protected_.$payload_" |\
        openssl dgst -sha256 -binary -sign $USER_DATA/ssl/user.key |\
        encode_base64)

    post_data='{"protected":"'"$protected_"'",'
    post_data=$post_data'"payload":"'"$payload_"'",'
    post_data=$post_data'"signature":"'"$signature_"'"}'

    curl -s -i -d "$post_data" "$1" -H "$content"
}


#----------------------------------------------------------#
#                    Verifications                         #
#----------------------------------------------------------#

check_args '1' "$#" 'USER'
is_format_valid 'user'
is_object_valid 'user' 'USER' "$user"
if [ -e "$USER_DATA/ssl/le.conf" ]; then
    source "$USER_DATA/ssl/le.conf"
fi
if [ ! -z "$KID" ]; then
    exit
fi


#----------------------------------------------------------#
#                       Action                             #
#----------------------------------------------------------#


# Defining user email
if [[ -z "$EMAIL" ]]; then
    EMAIL=$(get_user_value '$CONTACT')
fi

# Defining user agreement
agreement=''

# Generating user key
KEY="$USER_DATA/ssl/user.key"
if [ ! -e "$KEY" ]; then
    openssl genrsa -out $KEY 4096 >/dev/null 2>&1
    chmod 600 $KEY
fi

# Defining key exponent
if [ -z "$EXPONENT" ]; then
    EXPONENT=$(openssl pkey -inform pem -in "$KEY" -noout -text_pub |\
        grep Exponent: |cut -f 2 -d '(' |cut -f 1 -d ')' |sed -e 's/x//' |\
        xxd -r -p |encode_base64)
fi

# Defining key modulus
if [ -z "$MODULUS" ]; then
    MODULUS=$(openssl rsa -in "$KEY" -modulus -noout |\
        sed -e 's/^Modulus=//' |xxd -r -p |encode_base64)
fi

# Defining JWK
jwk='{"e":"'$EXPONENT'","kty":"RSA","n":"'"$MODULUS"'"}'

# Defining key thumbnail
if [ -z "$THUMB" ]; then
    THUMB="$(echo -n "$jwk" |openssl dgst -sha256 -binary |encode_base64)"
fi


# Requesting ACME nonce
nonce=$(curl -s -I "$API/directory" |grep Nonce |cut -f 2 -d \ |tr -d '\r\n')

# Creating ACME account
url="$API/acme/new-acct"
payload='{"termsOfServiceAgreed": true}'
answer=$(query_le_v2 "$url" "$payload" "$nonce")
kid=$(echo "$answer" |grep Location: |cut -f2 -d ' '|tr -d '\r')

# Checking answer status
status=$(echo "$answer" |grep HTTP/1.1 |tail -n1 |cut -f2 -d ' ')
if [[ "${status:0:2}" -ne "20" ]]; then
    check_result $E_CONNECT "Let's Encrypt acc registration failed $status"
fi


#----------------------------------------------------------#
#                       Vesta                              #
#----------------------------------------------------------#

# Adding le.conf
if [ ! -e "$USER_DATA/ssl/le.conf" ]; then
    echo "EXPONENT='$EXPONENT'" > $USER_DATA/ssl/le.conf
    echo "MODULUS='$MODULUS'" >> $USER_DATA/ssl/le.conf
    echo "THUMB='$THUMB'" >> $USER_DATA/ssl/le.conf
    echo "EMAIL='$EMAIL'" >> $USER_DATA/ssl/le.conf
    echo "KID='$kid'" >> $USER_DATA/ssl/le.conf
    chmod 660  $USER_DATA/ssl/le.conf
else
    sed -i '/^KID=/d' $USER_DATA/ssl/le.conf
    echo "KID='$kid'" >> $USER_DATA/ssl/le.conf
fi

# Logging
log_event "$OK" "$ARGUMENTS"

exit
