id:
Гость
вход
регистрация
текущее время 03:20 22/05/2012
главная
проект
новости
форум
faq
библиотека
черновики
разработки
сервисы
софт
поиск
Владелец:
SATtva
(создано 30/04/2008 17:18), редакция от 08/07/2009 12:57 (автор:
Гость
)
Печать
Категории:
криптография
,
софт
,
gnupg
,
эцп
,
исходные тексты
,
расширения
http://www.pgpru.com
/
Черновики
/
Статьи
/
Сервисметоквремени
/tm-verify
>>>
Последние изменения
Последние комментарии
Удаленные документы
Требуется доработка
Досье пользователей
Опросы
Keyserver
Документация Wiki
Правила сайта
Регистрация
==tm-verify: автоматизация проверки нотариального журнала== %%(wacko wrapper=box wrapper_align=right wrapper_width=250) >>**Скачать tm-verify**--- ---[[file:tmverify.py tm-verify 0.2]] ([[file:tmverify.py.asc ЭЦП]])<<%%#| ||{{Tree page="../Сервисметоквремени" depth=0 style="ul" title="((.. <)) Все документы:" nomark=0}}|{{TOC}}|| |# ===Описание=== ++РУС++ Утилита tm-verify предназначена для автоматической проверки записей аудиторского журнала TimeMarker.org в операционной системе Linux. Для работы программы требуется GnuPG и интерпретатор Python. ++ENG++ tm-verify is a utility program that automates verification of TimeMarker.org audit log chains under Linux operating system. Requires installed GnuPG and Python interpreter. ===Функциональность=== * Сверяет подписи с файлов меток. * Проверяет связность цепочки меток по хэшам и другим мета-данным. * Выводит диагностику и результат проверки. ===Как использовать=== * Взять из ((http://timemarker.org/ru/Log.aspx нотариального журнала)) цепочку меток, распаковать в произвольный каталог. * Выполнить: ##./tmverify.py --keyid <ключСервиса> [путь к каталогу]##. Параметр ##--keyid## опционален, но использовать его __крайне__ желательно. Если не указать путь, проверяется текущий каталог. Подробности через ##./tmverify.py --help##. Обратите внимание: все метки, лежащие в конкретном каталоге, должны идти последовательно. Скажем, если в каталоге лежат метки 51, 52, 53, 55, 56, 57, то метка 55 выдаст ошибку связности из-за отсутствия метки 54. Проверка продолжится несмотря на ошибку, но имейте в виду. ===Текущие ограничения=== Нету. ===Планы развития=== ====Ближайшие==== * --Проверка соответствия дополнительных полей меток: Signed-by, Number, Timestamp (последовательность номеров и дат и принадлежность всех меток одному сервису).-- * --Проверка состояния подписей через интерфейс статусов GnuPG.-- * --Проверка связности цепочек по обоим хэш-алгоритмам (RIPEMD160 в дополнение к SHA512).-- * Корректная проверка цепочек, включающих, помимо метаданных, регулярные метки. * Возможность проверки определённого диапазона меток. * Распараллеливание процессов сверки подписей и связности цепочек. * Совместимость с Windows. ====Отдалённые (после выхода API)==== * Автоматическое скачивание цепочек. * Возможность демонизации программы и/или её исполнение по крону. ===Код=== %% #!/usr/bin/env python # -*- coding: utf-8 -*- # @copyright: 2008 Vlad "SATtva" Miller, http://www.vladmiller.info # @license: GNU GPL, http://gnu.org/licenses/gpl.html # @version: 0.2 # # Current limitations: # None? '''TimeMARKER.org chains verifier v.0.2 Usage: %s [OPTIONS] [PATH] Options: -k 0x1234ABCD, --keyid 0x1234ABCD timestamper key ID (8 to 16 digits) -s, --strict warn on every marker signed with an unexpected key -v, --verbose print more information during operation (repeat twice for extra verbose output) -h, --help display this help message --changes display changelog All arguments are optional. If PATH (path to the directory containing marker chain files) is omitted, current directory is searched. All marker files must be in consecutive order, or you will get verification errors. It is strongly recommended to provide program with an optional keyid argument, otherwise it's possible to "correctly" verify markers chain signed with a bogus key. Return values: 0 all checks passed correctly 1 digsig integrity or chaining errors detected 2 program execution error (c) 2008 Vlad "SATtva" Miller <http://www.vladmiller.info> License GNU GPL v3 or later <http://gnu.org/licenses/gpl.html>''' _changelog = '''TimeMARKER.org chains verifier Changelog: 2008-05-04 version 0.2: - Digsig verification process reimplemented with GPG status codes - Timestamper keyID can be provided with --keyid argument - RIPEMD160 hash referrences are checked in addition to SHA512 - Checks for proper metadata formatting - All metadata fields are checked for proper chaining 2008-04-28 version 0.1: - Proof-of-concept, initial release''' import sys, os, getopt, glob, time from subprocess import * from os.path import abspath, expanduser, exists, split from time import mktime, strptime _verbose = 0 _strict = 0 _keyid = '' class tmExceptions(Exception): pass class MetaFormatError(tmExceptions): pass class NoPublicKey(tmExceptions): pass class Marker: 'Marker metadata container' def __init__(self, unpackedMeta): self.dict = {} for k, v in unpackedMeta: self[k] = v def __setitem__(self, k, v): self.dict[k] = v def __getitem__(self, k): return self.dict[k] def __gt__(self, prevMark): 'Assure curMark is consecutive to prevMark' if \ self['fileNum'] > prevMark['fileNum'] and \ self['signer'] == prevMark['signer'] and \ self['date'] > prevMark['date'] and \ self['number'] > prevMark['number'] and \ self['sha_ref'] == prevMark['sha'] and \ self['rmd_ref'] == prevMark['rmd']: return True else: return False def unpackMeta(meta, filename): 'Parse timestamp metadata' if \ meta[2].startswith('Signed-by: ') and \ meta[3].startswith('Timestamp: ') and \ meta[4].startswith('Number: ') and \ meta[5].startswith('Ref-Hash-SHA512: ') and \ meta[6].startswith('Ref-Hash-RIPEMD160: ') and \ meta[7].startswith('Hash-SHA512: ') and \ meta[8].startswith('Hash-RIPEMD160: '): return [('fileNum', int(filename[6:-4])), ('signer', meta[2][20:].strip()), ('date', mktime(strptime(meta[3][20:].strip(), '%a, %d %b %Y %H:%M:%S %Z'))), ('number', int(meta[4][20:].strip())), ('sha_ref', meta[5][20:].strip().upper()), ('rmd_ref', meta[6][20:].strip().upper()), ('sha', hash(''.join(meta).strip('\n\r'), 'SHA512')), ('rmd', hash(''.join(meta).strip('\n\r'), 'RIPEMD160'))] else: raise MetaFormatError, 'in timestamp %s' % filename def gpghome(): 'Get GnuPG home dir. Could be lame and inaccurate in some circumstances.' try: home = os.environ['GNUPGHOME'] except KeyError: home = os.environ['HOME'] + '/.gnupg' return home def checkStatus(status): 'Check digital signature from GnuPG status codes' result = keyID = None for line in status: if line.startswith('[GNUPG:] '): fields = line[9:].strip().split(' ') if fields[0] == 'GOODSIG': result = True keyID = fields[1] if fields[0] == 'BADSIG': result = False keyID = fields[1] if fields[0] == 'ERRSIG': raise NoPublicKey, fields[1] # Expn value is used in the handler return result, keyID def verify(filename): 'Return verification status and original plaintext (lines list) of a signed marker' p = Popen(['gpg', '--status-fd', '2', '-q', '-d', filename], stdout=PIPE, stderr=PIPE, close_fds=True, universal_newlines=False, env={'PATH': '/usr/bin', 'GNUPGHOME': gpghome()}) p.wait() status, keyID = checkStatus(p.stderr.readlines()) return status, keyID, p.stdout.readlines() def hash(str, algo): 'Calculate hash (SHA512 or RIPEMD160) of a marker meta' p = Popen(['gpg', '-q', '--print-md', algo], universal_newlines=False, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True, env={'PATH': '/usr/bin', 'GNUPGHOME': gpghome()}) o = p.communicate(str)[0] return o.replace(' ', '').replace('\n', '') def filelist(path): 'Get file list in a "human sorted" order (e.g. marker312 goes after marker51)' p = abspath(expanduser(path)) if not exists(p): print 'Directory %s not found.' % p print 'Run with --help flag for more information.' sys.exit(2) files = glob.glob(p + '/Marker*.pgp') files.sort(cmp = lambda f1, f2: cmp(int(f1[len(p)+7:-4]), int(f2[len(p)+7:-4]))) if files: return files else: return None def run(path): 'Run checks on markers chain' global _verbose, _strict, _keyid sig_errors = [] key_errors = [] ref_errors = [] try: for file in filelist(path): p, f = split(file) if _verbose: print 'Checking', f # Verifying pgp signature try: status, signKey, lines = verify(file) except NoPublicKey: print 'Signing key 0x%s not found on your GPG keyring.' % sys.exc_value print 'Please download it from a keyserver, from timeMarker.org website,' print 'or get it from some trusted source of your own.' sys.exit(2) if status is not True: sig_errors.append(f) if _verbose: if status is True: print ' Good signature in', f elif status is False: print '!!! BAD signature in', f elif status is None: print '!!! CORRUPT signature in', f # Malformed sig packet try: if not _keyid: _keyid = signKey elif not signKey.endswith(_keyid): key_errors.append(f) print '!!! %s is signed with an unexpected key 0x%s' % (f, signKey[-8:]) if not _strict: print '!!! Switching signing key to 0x%s for subsequent marks' % signKey[-8:] _keyid = signKey except AttributeError: # For CORRUPT sigs pass # Marker objects try: curMark, prevMark = Marker(unpackMeta(lines, f)), curMark except NameError: curMark = Marker(unpackMeta(lines, f)) except MetaFormatError: print '!!! Malformed metadata in', f # Verifying meta chaining try: if not curMark > prevMark: ref_errors.append(f) print '!!! BAD chaining of', f elif _verbose: print ' Good chaining of', f except NameError: pass # More debugging data if _verbose >= 2: print ''.join(lines).strip() if _verbose: print except TypeError: if not path: path = os.getcwd() else: path = abspath(expanduser(path)) print 'No marker files found in directory', path print 'Run with --help flag for more information.' sys.exit(2) # Display summary if len(sig_errors): print '!!! PGP signature verification failed on following markers:' print ', '.join(sig_errors) else: print 'All PGP signatures verified correctly.' if len(key_errors): print '!!! Signing key changes detected on following markers:' print ', '.join(key_errors) else: print 'All timestams signed with correct key.' if len(ref_errors): print '!!! Timestamps chaining failed on following markers:' print ', '.join(ref_errors) else: print 'All timestamps chained correctly.' # Return error code if len(sig_errors) or len(ref_errors) or len(key_errors): sys.exit(1) else: sys.exit(0) def parseComLine(argv): opts, args = getopt.getopt(argv, 'hvk:s', ['help', 'verbose', 'keyid=', 'strict', 'changes']) for o, a in opts: if o == '--changes': print _changelog sys.exit() elif o in ('-h', '--help'): print __doc__ % sys.argv[0] sys.exit() elif o in ('-v', '--verbose'): global _verbose _verbose = _verbose + 1 elif o in ('-s', '--strict'): global _strict _strict = 1 elif o in ('-k', '--keyid'): if a.startswith('0x'): a = a[2:] if len(a) < 8 or len(a) > 16: print 'Timestamping service key ID should be 8 to 16 digits long' print 'plus an optional "0x" prefix.' print 'Run with --help flag for more information.' sys.exit(2) else: global _keyid _keyid = a.upper() run(''.join(args)) if __name__ == "__main__": parseComLine(sys.argv[1:]) %%
Ваше имя:
Запомнить псевдоним (сохранить в cookie)
OpenPGP-подписанный текст в кодировке
CP1251 (Windows)
UTF-8
KOI8-R
CP866 (DOS)
KOI8-U
Помощь
Сохранить параметры OpenPGP в cookie
Пожалуйста, напишите, кого/что вы видите
на изображенной слева картинке. Если
там несколько персонажей/предметов,
перечислите их в именительном падеже
через пробел (одинаковых приводите во
множественном числе).
(осталось попыток на решение теста: 3)
Поддержка
BBCode
включена
Нормы пользования
. Некоторые права на материалы сайта защищены по условиям лицензии CreativeCommons. Движок
openSpace 0.8.25a
и дизайн сайта © 2006-2007
Vlad "SATtva" Miller
.