Скрипты для работы с ЭЦП

Подписание файла ЭЦП

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 ---------
}
Печать/экспорт