Данная статья предназначена в первую очередь для разработчиков, чьи программные продукты должны работать на компьютерах под управлением ОС СН в условиях применения Замкнутой Программной Среды (ЗПС). Для того, чтобы ЗПС позволила запуск добавляемых разработчиками файлов (исполняемых файлов и файлов библиотек), эти файлы должны быть подписаны. Предлагаемый сценарий позволяет автоматизировать задачу подписания файлов.
Данная статья применима к:
ОС СН Смоленск 1.6
ОС СН Ленинград 8.1
В данной статье предполагается, что комплект ключей для подписи ПО уже получен. В ином случае требуется запросить такой комплект (см. Как получить ключи для подписи СПО). Также в данной статье:
Название организации принято за org;
Текст сценария, приведённый в настоящей статье, скопирован в файл signdll;
Подписываемый файл test.dll находится в том же каталоге, что и сценарий подписывания;
ЗПС выключена, так как библиотека Python xattr получается из стороннего репозитория и не подписана;
Для установки библиотеки xattr требуется настроенный доступ в Интернет.
Установка пакетов и настройка ключей
Файл с текстом сценария нужно сделать исполняемым:
chmod +x signdll
Для нормальной работы сценария необходимо установить набор пакетов и библиотек. Команды для установки:
-p, --pgoptions передать следующие параметры программе bsign;
-R --replace - заменить оригинальный DLL не изменяя его имя;
-h - вывод краткой подсказки.
Текст сценария:
#!/usr/bin/python3
import sys
import shutil
import subprocess
import argparse
import xattr
DIGSIG_ELF_SIG_SIZE = 512
parser = argparse.ArgumentParser()
parser.add_argument('dll', metavar='filename.dll', help='path to dll to sign')
parser.add_argument('-p', '--pgoptions', help='pass options to the privacy guard program')
parser.add_argument('-R', '--replace', help='replace original dll', action='store_true')
args = parser.parse_args()
if not args.dll.endswith('.dll'):
print("[Error] Must have filename.dll as an argument")
sys.exit(1)
name = args.dll
try:
if args.replace:
new_name = name
else:
new_name = name[:-4] + '_signed.dll'
shutil.copyfile(name, new_name)
with open(new_name, mode='ab') as f:
f.write(b'\x00' * DIGSIG_ELF_SIG_SIZE)
bsign_args = ['bsign', '--sign', '--xattr', new_name]
if args.pgoptions is not None:
if '--batch' in args.pgoptions:
bsign_args.append('--nopass')
bsign_args.extend(['-p', args.pgoptions])
if subprocess.call(bsign_args):
print("[Error] Calling bsign failure")
sys.exit(1)
sig = xattr.getxattr(new_name, 'user.sig')
xattr.removexattr(new_name, 'user.sig')
with open(new_name, mode='r+b') as f:
f.seek(-DIGSIG_ELF_SIG_SIZE, 2)
f.write(sig)
except Exception as e:
print(str(e))
sys.exit(1)
Пример вызова сценария
Для подписания одного файла
Пример вызова для подписания файла test.dll (предполагается, что сценарий и подписываемый файл находятся в одном каталоге):
./signdll test.dll
После вызова сценария ввести пароль из файла org_password.txt.
При успешном подписывании в текущем каталоге будет создан файл test_signed.dll.
Для подписания пакета файлов
Получить шестнадцатеричный идентификатор ключа командой:
где default-key - шестнадцатеричный идентификатор ключа. В данном примере использован ключ -R, который позволяет встроить подпись в подписываемый файл не создавая его копию.