#!/bin/bash
# https://github.com/ctt-gob-es/clienteafirma/issues/20
# Script para firmar documentos usando AutoFirma
#
# Joaquín Ferrero. 2022.11.08
# Joaquín Ferrero. 2021.03.06
#
# Ejecutar:
#   Pasar el documento PDF a firmar como parámetro.
#   El resultado es otro documento con una coletilla en el nombre.
#
#    ~/bin/firma_generica.sh Factura_EMPRESA_2022_0534117.pdf
#
# Personalización básica:
# * NIF
# * Nombre del archivo .p12 con la firma digital.
# * Contraseña para acceder a ese archivo.
# * Posición de la firma en la página.
#       Se usa el truco de hacerlo primero con AutoFirma y luego
#       ver qué valores utiliza mirando el final del archivo AUTOFIRMA.afirma.log.xml.
# * Imagen de una firma digitalizada. Opcional.
#       El mismo truco que el anterior.
# * ERROR: No funciona la plantilla $$LOCATION$$, así que está puesto de forma directa.
# * Como no me gustaba el texto por defecto de $$ISSUERCN$$, también lo he puesto directamente.
#

[[ -z "${4}" ]] && \
echo "#> Debes pasar al menos los siguientes parámetros:
    1) Tu DNI
    2) La ruta del certificado p12
    3) Su contraseña
    4) El archivo a firmar
    5) Imagen para la firma
# Ej: vx-autofirma 111222333A '/home/docente/Documentos/certificado.p12' 'p@ssw0rd' './doc.pdf' '~/Imágenes/firma.jpg'
" && exit 1

# Leemos el nombre del archivo pdf pasado por línea de comandos
ARCHIVO="${4}"
# Creamos el nombre del archivo resultado
##ARCHIVOFIRMADO="${ARCHIVO/%.pdf/_firmado.pdf}"
ARCHIVOFIRMADO="${ARCHIVO%.pdf}_firmado.pdf"    # método alternativo por si falla el anterior

### Personalización #######################################################################################
NIF="${1}"                                 # NIF
# DIR='/home/usuario/Documentos/Empresa'          # Ruta al dir. de trabajo
STORE="pkcs12:${2}"           # Ruta al almacén del certificado digital P12
PASSWORD="${3}"                           # Contraseña del archivo de la firma digital
LOCATION="Zaragoza"                           # Lugar donde se firma
ISSUERCN="FNMT-RCM"                             # Emisor del certificado
IMAGEN_FIRMA="${5}"


JAVADIR="/usr/lib/java/jdk-11.0.2/bin"          # Ruta al motor Java, si fuera necesario
AUTOFIRMA="/usr/lib/AutoFirma/AutoFirma.jar"    # Ruta al AutoFirma.jar

# Personalizacion de la salida
FORMAT="pades"                                  # Formato para firma de pdf

# Posición de la firma visible
PositionOnPageLowerLeftX='350'                  # Coordenada X Abajo Izquierda
PositionOnPageLowerLeftY='85'                   # Coordenada Y Abajo Izquierda
PositionOnPageUpperRightX='550'                 # Coordenada X Arriba Derecha
PositionOnPageUpperRightY='195'                 # Coordenada Y Arriba Derecha

# Fuente de letras
l2FontColor='black'                             # Color de letra
l2FontSize='7'                                  # Tamaño de letra
l2FontFamily='1'                                # Familia de fuente
l2FontStyle='0'                                 # Estilo de Fuente

# Página
signaturaPage='1'                               # Página donde firmaremos -1=última

# Rúbrica o imagen a añadir, opcional
# Se crea con el comando: base64 -w 0 <archivo> y se copian los datos en base64 en la siguiente variable
#signatureRubricImage='... datos en base64 ...'
# Otra forma: llamar al comando base64 directamente, en todas las ocasiones
### signatureRubricImage=$(base64 -w 0 ~/Documentos/Empresa/Firmas/FIRMA_DEL_TESORERO.jpg)
signatureRubricImage=$(base64 -w 0 "${IMAGEN_FIRMA}")

# Personalización de la firma visible en el documento
# Estos son campos que AutoFirma rellenerá
# $$SUBJECTCN$$ Nombre común (CN, Common Name) del titular del certificado de firma
# $$ISSUERCN$$ Nombre común (CN, Common Name) del emisor del certificado de firma
# $$CERTSERIAL$$ Número de serie del certificado de firma
# $$SIGNDATE=PATRÓN$$ Fecha de la firma
# $$GIVENNAME$$ Nombre del titular (G, Given Name) (podría estar vacío)
# $$SURNAME$$ Apellidos del titular (SN, Surname) (podría estar vacío)
# $$ORGANIZATION$$ Organización (O, Organization) (podría estar vacío)
# $$REASON$$ Razón por la que se firma el PDF. (podría estar vacío)
# $$LOCATION$$ Ciudad en la que se firma el PDF. (podría estar vacío)
# $$CONTACT$$ Información de contacto del firmante del PDF. (podría estar vacío)

# Formato del campo de la fecha:
# https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
#FECHA="EEEE d 'de' MMMM 'de' yyyy, HH:mm:ss"
FECHA="d 'de' MMMM 'de' yyyy, HH:mm:ss"

# Texto que queremos que aparezca en la firma
# Este es un texto libre, pero debe entrecomillarse con comillas simples, ya que contiene caracteres '$'
LAYER2TEXT='











Firma digital de $$SUBJECTCN$$, en '$LOCATION', el $$SIGNDATE='$FECHA'$$
Certificado emitido por '$ISSUERCN
# Firmado digitalmente por $$SUBJECTCN$$ el día $$SIGNDATE=dd/MM/yyyy$$ con un certificado emitido por $$ISSUERCN$$
# Para que salga nombre y apellidos: Firma digital de $$GIVENNAME$$ $$SURNAME$$

# Configuración que espera AutoFirma
CONFIG="layer2Text=$LAYER2TEXT\n\
signaturePositionOnPageLowerLeftX=$PositionOnPageLowerLeftX\n\
signaturePositionOnPageLowerLeftY=$PositionOnPageLowerLeftY\n\
signaturePositionOnPageUpperRightX=$PositionOnPageUpperRightX\n\
signaturePositionOnPageUpperRightY=$PositionOnPageUpperRightY\n\
layer2FontColor=$l2FontColor\n\
layer2FontSize=$l2FontSize\n\
layer2FontFamily=$l2FontFamily\n\
layer2FontStyle=$l2FontStyle\n\
signatureRubricImage=$signatureRubricImage\n\
signaturePage=$signaturaPage"

### Fin de la personalización #############################################################################

# Aquí se hace la firma
# Se puede hacer de varias maneras. Aquí hay dos que he encontrado.
# Escoger aquella que mejor se ajuste al contenido del almacén, y comentar las líneas de la otra solución.

# 1º, con -filter, poner algo que esté dentro del certificado, por ejemplo, el NIF

### $JAVADIR/java -jar $AUTOFIRMA sign      \
java -jar $AUTOFIRMA sign      \
-i "$ARCHIVO"                       \
-o "$ARCHIVOFIRMADO"                \
-store $STORE                       \
-format $FORMAT                     \
-password $PASSWORD                 \
-filter subject.contains:$NIF       \
-config "$CONFIG"

echo ""
exit

# 2º, con -alias, para encontrar el certificado dentro del almacén .p12
# primero llamamos a AutoFirma para pedir los alias de un determinado almacén
### ALIASES=$($JAVADIR/java -jar $AUTOFIRMA listaliases -store $STORE -password $PASSWORD)
ALIASES=$(java -jar $AUTOFIRMA listaliases -store $STORE -password $PASSWORD)

### $JAVADIR/java -jar $AUTOFIRMA sign      \
java -jar $AUTOFIRMA sign      \
-i "$ARCHIVO"                       \
-o "$ARCHIVOFIRMADO"                \
-store $STORE                       \
-format $FORMAT                     \
-password $PASSWORD                 \
-alias "$ALIASES"                   \
-config "$CONFIG"

echo ""
exit

# FIN de firma.sh