Скрипты для работы с ЭЦП
Подписание файла ЭЦП
- sign.sh
#!/usr/bin/env bash
# Подписание файла ЭЦП
# Вход: файл на STDIN, `SHA1 HASH` и `PIN` как параметры
# Выход: результаты выполнения предназначены для парсинга
# Для удаленного вызова необходимо настроить на сервере авторизацию по ключу
# Для текущего пользователя (sign) необходимо добавить сертификаты,
# а также внести информацию по ним в БД (для работы всей схемы)
SHA_HASH=$1
PIN=$2
SRC_FILE=`mktemp`
DEST_FILE=$SRC_FILE.sig
cat - > $SRC_FILE
echo --------- CRYPTCP BEGIN ---------
timeout 10s /home/sign/interface/expect-sign.sh $SHA_HASH $PIN $SRC_FILE $DEST_FILE
CRYPTCP_CODE=$?
echo --------- CRYPTCP END ---------
if [ "$CRYPTCP_CODE" -eq "0" ]; then
echo --------- CERTIFICATE SECTION BEGIN ---------
CERT_FILE=`mktemp`
cryptcp -nochain -copycert -thumbprint "$SHA_HASH" -f "$DEST_FILE" -df "$CERT_FILE" -der
echo --------- CERTIFICATE BEGIN ---------
echo CERTIFICATE SHA1: "$SHA_HASH"
openssl x509 -in "$CERT_FILE" -inform der -text -noout -nameopt oneline,-esc_msb,-space_eq,sep_comma_plus
echo --------- CERTIFICATE END ---------
rm "$CERT_FILE"
echo --------- CERTIFICATE SECTION END ---------
fi
echo --------- SUMMARY BEGIN ---------
echo CRYPTCP CODE: $CRYPTCP_CODE
echo FILE: $DEST_FILE
echo --------- SUMMARY END ---------
rm $SRC_FILE
Добавление еще одной подписи ЭЦП
- cosign.sh
#!/usr/bin/env bash
# Добавление подписи ЭЦП в файл (в нем должны быть уже другие подписи)
# Вход: файл на STDIN, `SHA1 HASH` и `PIN` как параметры
# Выход: результаты выполнения предназначены для парсинга
# Для удаленного вызова необходимо настроить на сервере авторизацию по ключу
# Для текущего пользователя (sign) необходимо добавить сертификаты,
# а также внести информацию по ним в БД (для работы всей схемы)
SHA_HASH=$1
PIN=$2
SRC_FILE=`mktemp`
cat - > $SRC_FILE
cd "$(dirname "$0")"
source ./lib.sh
# Подписи добавляются без создания нового файла
echo --------- CRYPTCP BEGIN ---------
timeout 10s /home/sign/interface/expect-cosign.sh $SHA_HASH $PIN $SRC_FILE
CRYPTCP_CODE=$?
echo --------- CRYPTCP END ---------
if [ "$CRYPTCP_CODE" -eq "0" ]; then
certmgr_list
if [ "$CERTMGR_CODE" -eq "0" ]; then
certmgr_review
fi
fi
echo --------- SUMMARY BEGIN ---------
echo CRYPTCP CODE: $CRYPTCP_CODE
echo FILE: $SRC_FILE
echo --------- SUMMARY END ---------
Обход проблемы с интерактивным вводом пароля для подписания
При первом подписании документа
- expect-sign.sh
#!/usr/bin/expect
#
# Обход проблемы с интерактивным вводом пароля для подписания
#
set timeout 3
set thumbprint [lindex $argv 0]
set password [lindex $argv 1]
set src_file [lindex $argv 2]
set dest_file [lindex $argv 3]
spawn cryptcp -sign -thumbprint $thumbprint -nochain -der $src_file $dest_file
expect "Password:" { send "$password\r" }
expect {
"Password:" { exit 1 }
"(o) OK, (c) Cancel" {
send "o\r"
exp_continue
}
eof { exit 0 }
}
При добавлении еще одной подписи
- expect-cosign.sh
#!/usr/bin/expect
#
# Обход проблемы с интерактивным вводом пароля для подписания
#
set timeout 3
set thumbprint [lindex $argv 0]
set password [lindex $argv 1]
set src_file [lindex $argv 2]
spawn cryptcp -addsign -thumbprint $thumbprint -nochain $src_file
expect "Password:" { send "$password\r" }
expect {
"Password:" { exit 1 }
"(o) OK, (c) Cancel" {
send "o\r"
exp_continue
}
eof { exit 0 }
}
Проверка документа
- check.sh
#!/usr/bin/env bash
# Проверка подписей файла ЭЦП + Хеш MD5
# Вход: файл на STDIN, ...
# Выход: результаты выполнения предназначены для парсинга
SRC_FILE=`mktemp`
ORIGIN_FILE=`mktemp`
COMMAND=$1
cat - > $SRC_FILE
# Получаем список сертификатов
function certmgr_list()
{
CERTMGR_RESP=`certmgr -list -f "$SRC_FILE"`
CERTMGR_CODE=$?
if [ "$CERTMGR_CODE" -eq "0" ]; then
SHAS=`echo "$CERTMGR_RESP" | grep "SHA1 Hash" | cut -f 2 -d "x"`
fi
}
# Получаем данные сертификатов
function certmgr_review()
{
echo --------- CERTIFICATE SECTION BEGIN ---------
for SHA in $SHAS
do
CERT_FILE=`mktemp`
cryptcp -nochain -copycert -thumbprint "$SHA" -f "$SRC_FILE" -df "$CERT_FILE" -der
echo --------- CERTIFICATE BEGIN ---------
echo CERTIFICATE SHA1: "$SHA"
openssl x509 -in "$CERT_FILE" -inform der -text -noout -nameopt oneline,-esc_msb,-space_eq,sep_comma_plus
echo --------- CERTIFICATE END ---------
rm "$CERT_FILE"
done
echo --------- CERTIFICATE SECTION END ---------
}
# Отчет
function summary()
{
echo --------- SUMMARY BEGIN ---------
echo CERTMGR CODE: $CERTMGR_CODE
echo CRYPTCP CODE: $CRYPTCP_CODE
echo MD5SUM: $MD5
echo --------- SUMMARY END ---------
}
# Хеш файла в контейнере
function md5_check_origin()
{
if [ -f "$ORIGIN_FILE" ]; then
MD5=`md5sum "$ORIGIN_FILE" | cut -f 1 -d " "` # файл есть, вычисляем md5 оригинального файла
else
MD5='0' # ошибка проверки
fi
}
# Хеш переданного файла
function md5_check_src()
{
MD5=`md5sum "$SRC_FILE" | cut -f 1 -d " "`
}
# Проверка подписей
function cryptcp_check()
{
echo --------- CRYPTCP BEGIN ---------
case "$COMMAND" in
"check" ) # Проверка подписи
timeout 5s echo 'NNNNNNNNNNNNNNNNNNNN' | cryptcp -verify -nochain -norev -f "$SRC_FILE" "$SRC_FILE" "$ORIGIN_FILE"
;;
"md5" ) # Только вычисление md5
timeout 5s echo 'NNNNNNNNNNNNNNNNNNNN' | cryptcp -verify -nochain -norev -f "$SRC_FILE" "$SRC_FILE" "$ORIGIN_FILE"
;;
* )
echo 'No such command'
exit 1
;;
esac
CRYPTCP_CODE=$?
echo --------- CRYPTCP END ---------
}
# *************** RUN ****************
certmgr_list
if [ "$CERTMGR_CODE" -eq "0" ]; then
certmgr_review
cryptcp_check
md5_check_origin
else
md5_check_src
fi
summary
rm "$SRC_FILE"
rm "$ORIGIN_FILE"
Получение неподписанного исходного файла
- unsigned.sh
#!/usr/bin/env bash
# Получение неподписанного исходного файла
BASE_FILE=`mktemp`
SRC_FILE=$BASE_FILE.src
ORIGIN_FILE=$BASE_FILE.orig
FINAL_FILE=""
cat - > $SRC_FILE
# Получаем список сертификатов
function certmgr_list()
{
CERTMGR_RESP=`certmgr -list -f "$SRC_FILE"`
CERTMGR_CODE=$?
}
function digest()
{
echo '-------BEGIN UNSIGNED-------'
echo RESULT: $RESULT
echo FILE: $UNSIGNED_FILE
echo '-------END UNSIGNED-------'
}
# *************** RUN ****************
certmgr_list
if [ "$CERTMGR_CODE" -eq "0" ]; then
timeout 5s echo 'NNNNNNNNNNNNNNNNNNNN' | cryptcp -verify -nochain -f "$SRC_FILE" "$SRC_FILE" "$ORIGIN_FILE"
UNSIGNED_FILE=$ORIGIN_FILE
rm "$SRC_FILE" > /dev/null 2>&1
else
UNSIGNED_FILE=$SRC_FILE
rm "$ORIGIN_FILE" > /dev/null 2>&1
fi
digest
rm "$BASE_FILE" > /dev/null 2>&1
Получение PDF-файла для печати
- pdf.sh
#!/usr/bin/env bash
# pdf для печати
BASE_FILE=`mktemp`
SRC_FILE=$BASE_FILE.src
FINAL_FILE=""
cat - > $SRC_FILE
function convertToPdf {
timeout 20s unoconv --connection 'socket,host=127.0.0.1,port=2220,tcpNoDelay=1;urp;StarOffice.ComponentContext' "$SRC_FILE"
RET_CODE=$?
if [ "$RET_CODE" -eq "0" ]; then
FINAL_FILE=$BASE_FILE.pdf
RESULT='0'
else
RESULT='1'
fi
}
function digest()
{
echo '-------BEGIN PDF-------'
echo RESULT: $RESULT
echo FILE: $FINAL_FILE
echo '-------END PDF-------'
}
convertToPdf
digest
rm "$BASE_FILE" > /dev/null 2>&1
rm "$SRC_FILE" > /dev/null 2>&1
Проверка работоспособности
- test.sh
#!/usr/bin/bash
# pdf для печати
cat - > $SRC_FILE
function digest()
{
echo '-------BEGIN PDF-------'
echo RESULT: 1
echo FILE: $SRC_FILE
echo '-------END PDF-------'
}
digest
#rm "$BASE_FILE" > /dev/null 2>&1
#rm "$SRC_FILE" > /dev/null 2>&1
Получение информации об установленных сертификатах
- certdigest.sh
#!/usr/bin/env bash
# Получение информации об установленных сертификатах
function digest()
{
echo '-------BEGIN CERTMGR-------'
certmgr -list
# certmgr -list -store root # test case
echo RESULT: $?
echo '-------END CERTMGR-------'
}
digest
Создание тумбы документа
- thumbnail.sh
#!/usr/bin/env bash
# Получение тумбы файла
BASE_FILE=`mktemp`
SRC_FILE=$BASE_FILE.src
ORIGIN_FILE=$BASE_FILE.orig
FINAL_FILE=""
cat - > $SRC_FILE
# Получаем список сертификатов
function certmgr_list()
{
CERTMGR_RESP=`certmgr -list -f "$SRC_FILE" > /dev/null 2>&1`
CERTMGR_CODE=$?
}
function thumbnail()
{
if [ -f "$STEP_1_FILE" ]; then
timeout 20s unoconv --connection 'socket,host=127.0.0.1,port=2220,tcpNoDelay=1;urp;StarOffice.ComponentContext' "$STEP_1_FILE"
RET_CODE=$?
rm "$STEP_1_FILE"
if [ "$RET_CODE" -eq "0" ]; then
STEP_2_FILE=$BASE_FILE.pdf
if [ -f "$STEP_2_FILE" ]; then
timeout 25s unoconv --connection 'socket,host=127.0.0.1,port=2220,tcpNoDelay=1;urp;StarOffice.ComponentContext' -f gif "$STEP_2_FILE"
RET_CODE=$?
rm "$STEP_2_FILE"
if [ "$RET_CODE" -eq "0" ]; then
FINAL_FILE=$BASE_FILE.gif
if [ -f "$FINAL_FILE" ]; then
RESULT='0'
else
RESULT='1'
fi
else
RESULT='2'
fi
else
RESULT='3'
fi
else
RESULT='4'
fi
else
RESULT='5' # ошибка
fi
}
function digest()
{
echo '-------BEGIN THUMBNAIL-------'
echo RESULT: $RESULT
echo FILE: $FINAL_FILE
echo '-------END THUMBNAIL-------'
}
# *************** RUN ****************
certmgr_list
if [ "$CERTMGR_CODE" -eq "0" ]; then
timeout 5s echo 'NNNNNNNNNNNNNNNNNNNN' | cryptcp -verify -nochain -f "$SRC_FILE" "$SRC_FILE" "$ORIGIN_FILE"
STEP_1_FILE=$ORIGIN_FILE
else
STEP_1_FILE=$SRC_FILE
fi
thumbnail
digest
rm "$BASE_FILE" > /dev/null 2>&1
rm "$SRC_FILE" > /dev/null 2>&1
rm "$ORIGIN_FILE" > /dev/null 2>&1
Watchdog который следит за работоспособностью Офиса в режиме сервера
- office-watchdog.sh
#!/bin/bash
# В режиме "сервера" Офис "подвисает" и перестает делать тумбы
# Поэтому его надо периодически проверять и "поднимать" от имени sign (иначе временные файлы нельзя будет удалить)
# демон работает нестабильно, поэтому пусть запускается каждый раз
exit 1
if [ "`whoami`" != "sign" ]; then
>&2 echo "Run as user: sign"
exit 1
fi
function startService()
{
soffice --nologo --headless --nofirststartwizard --accept='socket,host=127.0.0.1,port=2220,tcpNoDelay=1;urp;StarOffice.Service' &
}
pgrep soffice
if [ "$?" -ne "0" ]; then
startService
exit 0
fi
timeout 20s unoconv --connection 'socket,host=127.0.0.1,port=2220,tcpNoDelay=1;urp;StarOffice.ComponentContext' test.src
if [ "$?" -ne "0" ]; then
pkill soffice
startService
exit 0
fi
Библиотека общих функций
- lib.sh
#!/usr/bin/env bash
# Список общих функций
# Получаем список сертификатов
function certmgr_list()
{
CERTMGR_RESP=`certmgr -list -f "$SRC_FILE"`
CERTMGR_CODE=$?
if [ "$CERTMGR_CODE" -eq "0" ]; then
SHAS=`echo "$CERTMGR_RESP" | grep "SHA1 Hash" | cut -f 2 -d "x"`
fi
}
# Получаем данные сертификатов
function certmgr_review()
{
echo --------- CERTIFICATE SECTION BEGIN ---------
for SHA in $SHAS
do
CERT_FILE=`mktemp`
cryptcp -nochain -copycert -thumbprint "$SHA" -f "$SRC_FILE" -df "$CERT_FILE" -der
echo --------- CERTIFICATE BEGIN ---------
echo CERTIFICATE SHA1: "$SHA"
openssl x509 -in "$CERT_FILE" -inform der -text -noout -nameopt oneline,-esc_msb,-space_eq,sep_comma_plus
echo --------- CERTIFICATE END ---------
rm "$CERT_FILE"
done
echo --------- CERTIFICATE SECTION END ---------
}