Ejemplo n.º 1
0
def test_export_import_pubkey():
    '''
    Функция `Crypt.get_key(keytype=csp.AT_SIGNATURE)` возвращает одну из двух пар открытый/закрытый
    ключ, связанных с контекстом. Необязательный параметр `keytype` по
    умолчанию обеспечивает извлечение ключей подписи. Может также принимать
    значение `csp.AT_KEYEXCHANGE`, для извлечения ключей обмена. Результатом
    функции является либо экземпляр класса `Key()` либо `None`, если хранилище
    не содержит ключей.

    Функция `Key.encode(cryptkey=None)` экспортирует ключ во внутренний
    бинарный формат для передачи по каналам данных. Необязательный параметр
    `cryptkey` задает открытый ключ получателя. При его использовании
    экспортируется закрытая половина ключа в зашифрованном для получателя виде.
    Без этого параметра экспортируется незашифрованный открытый ключ.

    Функция `Crypt.import_key(k, decrypt)` связывает ключ `k` с контекстом
    криптопровайдера. Параметр `k` содержит блоб для передачи ключа во
    внутреннем формате. Необязательный второй параметр `decrypt` задает объект
    `Key` для расшифровки закрытого ключа.

    '''
    context = csp.Crypt(test_container, PROV_GOST, 0, test_provider)

    recipient = csp.Crypt(b'', PROV_GOST, csp.CRYPT_VERIFYCONTEXT, test_provider)

    sk = context.get_key()
    assert sk

    pk = recipient.import_key(sk.encode())
    assert pk
Ejemplo n.º 2
0
def test_sign_data():
    '''
    При создании нового пустого сообщения, конструктору передается либо
    контекст, либо конструктор вызывается без параметров.

    Метод `CryptMsg.add_signer_cert(c)` сохраняет в сообщении сертификат `c`,
    которым будет подписано сообщение. Таким образом можно добавлять несколько
    подписантов и их сертификатов.

    Метод `CryptMsg.sign_data(s)` создает сообщение, закодированное в PKCS7,
    подписанное всеми сертификатами из списка. Подписи и сертификаты входят в
    байтовую строку, которая возвращается функцией.
    '''
    ctx = csp.Crypt(
        test_container,
        PROV_GOST,
        0, test_provider
    )
    cs = csp.CertStore(ctx, b"MY")
    cert = list(cs.find_by_name(test_cn))[0]
    mess = csp.CryptMsg()
    print(csp.CertInfo(cert).name())
    data = mess.sign_data(b'hurblewurble', cert, False)
    assert len(data)
    return data
Ejemplo n.º 3
0
def test_store_key():
    context = csp.Crypt(test_container, PROV_GOST, 0, test_provider)
    key = context.get_key()
    certdata = test_extract_cert()
    newc = csp.Cert(certdata)
    key.store_cert(newc)
    assert key.extract_cert() == certdata
Ejemplo n.º 4
0
def main():
    global ctxname
    try:
        ctx = csp.Crypt(b'{0}'.format(ctxname), csp.PROV_GOST_2001_DH, 0 | silent, provider)
    except:
        ctx = None
    if ctx is None:
        ctx = csp.Crypt(
            b'{0}'.format(ctxname), csp.PROV_GOST_2001_DH, csp.CRYPT_NEWKEYSET | silent, provider)
    msg = csp.CryptMsg(ctx)
    cs = csp.CertStore(ctx, b"My")

    rec_c = list(cs.find_by_name(b'123456789abcdef'))[0]
    ci = csp.CertInfo(rec_c)
    print(ci.name(), ci.issuer(), hexlify(ci.serial()))
    print(ci.not_before(), ci.not_after())

    msg.add_recipient(rec_c)
    data = msg.encrypt_data(b'Test byte string')
    print(len(data))

    #rec_c = list(cs.find_by_name(b'test'))[0]
    cs2 = csp.CertStore()
    cs2.add_cert(rec_c)
    encrypted = csp.CryptMsg(data)
    print('type:', encrypted.get_type())
    print('data:', encrypted.get_data())
    return_data = encrypted.decrypt(cs2)
    print(return_data)

    signed = msg.sign_data(b'Test signed data', rec_c)
    print(len(signed))

    msg2 = csp.CryptMsg(signed, ctx)
    info = csp.CertInfo(msg2, 0)
    print('version:', info.version())
    print('type:', msg2.get_type())
    print(msg2.verify(0))
    detached = msg.sign_data(b'Test signed data', rec_c, True)
    print(len(detached))
    sig = csp.Signature(detached, ctx)
    print(sig.verify_data(b'Test signed data', 0))
    print(sig.verify_data(b'Test zigned Data', 0))
    sig2 = csp.CryptMsg(open('tests/data1.p7s', 'rb').read())
    print('sig type:', sig2.get_type())
    print('sig data:', sig2.get_data())
Ejemplo n.º 5
0
def test_context_not_found():
    ctx = csp.Crypt(
        b"some_wrong_ctx",
        PROV_GOST,
        csp.CRYPT_SILENT,
        test_provider,
    )
    assert not ctx
Ejemplo n.º 6
0
def test_import_public_key_info():
    context = csp.Crypt(test_container, PROV_GOST, 0, test_provider)
    cs = csp.CertStore(None, b"MY")
    cert = list(c for c in cs.find_by_name(bytes(test_cn)) if csp.CertInfo(c).name() == b'CN=' + test_cn)[0]
    pkey = context.import_public_key_info(cert)
    assert pkey
    keyBlob = pkey.encode(None)
    print(len(keyBlob))
    assert len(keyBlob) >= 100
Ejemplo n.º 7
0
def main():
    global ctxname
    ctx = csp.Crypt(ctxname, csp.PROV_GOST_2012_256, 0 | csp.CRYPT_SILENT, provider)
    if not ctx:
        print('Container', ctxname, 'not found!')
        return
    print(ctx.name())
    print(ctx.prov_name())
    print(ctx.uniq_name())
    print(ctx.prov_type())
Ejemplo n.º 8
0
def test_derive_key():
    ctx = csp.Crypt(
        b'',
        PROV_GOST,
        csp.CRYPT_VERIFYCONTEXT,
        test_provider
    )
    data = b'1234'
    hash1 = csp.Hash(ctx, data)
    key1 = hash1.derive_key()
    return key1
Ejemplo n.º 9
0
def test_cert_acquire_key():
    '''
    Контекст криптопровайдера может быть создан путем вызова конструктора на
    объект `Cert`. При этом вернется контекст, связанный с контейнером ключа
    данного сертификата. Если получить ключ не удастся, будет брошено
    исключение `ValueError`.
    '''
    cs = csp.CertStore(None, b"MY")
    cert = list(c for c in cs.find_by_name(bytes(test_cn)) if csp.CertInfo(c).name() == b'CN=' + test_cn)[0]
    ctx = csp.Crypt(cert)
    return ctx
Ejemplo n.º 10
0
def test_hash_hmac():
    key = test_derive_key()
    ctx = csp.Crypt(
        b'',
        PROV_GOST,
        csp.CRYPT_VERIFYCONTEXT,
        test_provider
    )
    data = b'The quick brown fox jumps over the lazy dog'
    hash1 = csp.Hash(ctx, data, key, 0)
    digest_str = hexlify(hash1.digest())
    print(digest_str)
    assert digest_str == b'3e7dea7f2384b6c5a3d0e24aaa29c05e89ddd762145030ec22c71a6db8b2c1f4'
Ejemplo n.º 11
0
def test_context_named_keystore():
    '''
    Подключение к именованному контейнеру. Если контейнер с данным именем не
    найден, будет возвращено `None`.
    '''
    context = csp.Crypt(
        test_container,
        PROV_GOST,
        0,
        test_provider,
    )
    assert context
    return context
Ejemplo n.º 12
0
def test_hash_digest_string():
    ctx = csp.Crypt(
        b'',
        PROV_GOST,
        csp.CRYPT_VERIFYCONTEXT,
        test_provider
    )
    data = b'The quick brown fox jumps over the lazy dog'
    length = 0 if test_cn.endswith(b'2012') else 2001
    hash1 = csp.Hash(ctx, data, length)
    digest_str = hexlify(hash1.digest())
    print(digest_str, length)
    if length == 2001:
        assert digest_str == b'9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76'
        return
    assert digest_str == b'3e7dea7f2384b6c5a3d0e24aaa29c05e89ddd762145030ec22c71a6db8b2c1f4'
Ejemplo n.º 13
0
def test_hash_digest_empty():
    ctx = csp.Crypt(
        b'',
        PROV_GOST,
        csp.CRYPT_VERIFYCONTEXT,
        test_provider
    )
    data = b''
    length = 0 if test_cn.endswith(b'2012') else 2001
    hash1 = csp.Hash(ctx, data, length)
    digest_str = hexlify(hash1.digest())
    print(digest_str, length)
    if length == 2001:
        assert digest_str == b'981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0'
        return
    assert digest_str == b'3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb'
Ejemplo n.º 14
0
def test_context_simple():
    '''
    Контест создается функцией `Crypt()`. Первым параметром передается
    строка-имя контейнера ключей. Второй параметр -- тип провайдера, третий --
    флаги. Контейнер без имени является контейнером пользователя по умолчанию.
    Результатом функции является экземпляр класса `Crypt()`. Если именованный
    контейнер не найден, бросается исключение `ValueError`.

    '''
    context = csp.Crypt(
        b'',
        PROV_GOST,
        csp.CRYPT_VERIFYCONTEXT,
        test_provider
    )
    assert context
    return context
Ejemplo n.º 15
0
def tease(s):
    for f in range(10):
        cs = csp.CertStore(None, "MY")
        lst = list(cs)
        print(len(lst))
        del lst
        del cs
    for n in range(10):
        cc = csp.Cert(s)
        print(list(cc.eku()))
        del cc
    for n in range(100):
        cont = b'123456789abcdefj'
        ctx = csp.Crypt(cont, 75, 0)
        del ctx
        req = cryptoapi.create_request(cont, req_params)
        del req
        del cont
Ejemplo n.º 16
0
def test_detached_sign():
    '''
    Второй необязательный параметр `detach` функции CryptMsg.sign_data()`
    управляет режимом подписывания. При вызове со значение `True` функция
    подписи вернет не полное подписанное сообщение, а только подпись, которую
    можно хранить отдельно от подписанных ей данных.
    '''
    ctx = csp.Crypt(
        test_container,
        PROV_GOST,
        0,
        test_provider
    )
    assert ctx
    cs = csp.CertStore(None, b"MY")
    cert = list(cs.find_by_name(test_cn))[0]
    mess = csp.CryptMsg()
    data = mess.sign_data(b'hurblewurble', cert, True)
    assert len(data)
    return data
Ejemplo n.º 17
0
def test_hash_digest_random():
    '''
    Test Hash()

    Объект Hash может инициализироваться данными из байтовой строки или быть
    пустым. Метод `Hash.update()` добавляет данные из байтовой строки `s` к
    хэшу. Метод `Hash.digest()` возвращает хэш в виде байтовой строки.
    После вызова digest() добавлять данные больше нельзя.
    '''
    ctx = csp.Crypt(
        b'',
        PROV_GOST,
        csp.CRYPT_VERIFYCONTEXT,
        test_provider
    )
    data = os.urandom(1024)
    length = 0 if test_cn.endswith(b'2012') else 2001
    hash1 = csp.Hash(ctx, data, length)
    hash2 = csp.Hash(ctx, length)
    hash2.update(data)
    digest1 = hash1.digest()
    digest2 = hash2.digest()
    print(hexlify(digest1), hexlify(digest2))
    assert digest1 == digest2
Ejemplo n.º 18
0
def test_detached_sign2():
    '''
    Класс `Signature` наследует всю функциональность `CryptMsg`, но
    ориентирован на работу с отсоединенными подписями. Поэтому метод
    `Signature.sign_data()` по умолчанию возвращает отсоединенную подпись.
    '''
    ctx = csp.Crypt(
        test_container,
        PROV_GOST,
        0,
        test_provider
    )
    assert ctx
    cs = csp.CertStore(ctx, b"MY")
    cert = list(cs.find_by_name(test_cn))[0]

    # создание новой (пустой) отсоединенной подписи
    sgn = csp.Signature(ctx)

    # подписывание данных экземпляром `Signature` по умолчанию дает
    # отсоединенную подпись.
    data = sgn.sign_data(b'hurblewurble', cert)
    assert len(data)
    return data
Ejemplo n.º 19
0
def test_csp_info():
    context = csp.Crypt(test_container, PROV_GOST, 0, test_provider)
    info = csp.CSPInfo(context)
    assert info
    assert info.version()
    assert len(info.bytes())
Ejemplo n.º 20
0
def test_msg_signatures():
    '''

    Поле `CryptMsg.num_signers` содержит количество подписантов сообщения.

    Функция `CryptMsg.get_nth_signer_info(n)` возвращает структуру, уникально
    идентифицирующую сертификат `n`-го подписанта. По ней можно получить
    сертификат подписанта, либо из хранилища в сообщении, либо из системного
    хранилища.  Для этого служит функция `CertStore.get_cert_by_info()`. Если
    сертификата нет в хранилище, функция возвращает `None`.

    Полученный таким образом сертификат `c` можно использовать для проверки
    подписи под сообщением с помощью функции `CryptMsg.verify_cert(c)`. Функция
    возвращает `True`, если для данного сертификата соответствующая ему подпись
    верна.

    Для упрощения обработки сертификатов, функция `CryptMsg.signer_certs()`
    перечисляет сертификаты всех подписантов сообщения.

    '''
    ctx = csp.Crypt(
        b'',
        PROV_GOST,
        csp.CRYPT_VERIFYCONTEXT,
        test_provider
    )
    testdata = test_sign_data()
    # testdata = open('tests/logical.cms', 'rb').read()

    # загрузка сообщения из блоба данных
    msg = csp.CryptMsg(testdata, ctx)
    del testdata
    # сведения о раскодированном сообщении
    print(msg.num_signers())
    print(len(msg.get_data()))
    # TODO переделать тесты ниже
    return

    # Идентификационная информация для 1-го подписанта.
    psi = msg.get_nth_signer_info(0)
    assert psi
    my = csp.CertStore(msg)
    sys_my = csp.CertStore(None, "MY")

    # Из сообщения можно извлечь сертификат по этой информации
    verify_cert = my.get_cert_by_info(psi)
    t1 = verify_cert.thumbprint()
    verify_cert = my.get_cert_by_info(psi)

    # Сертификат можно извлечь так же из системного хранилища, если он там
    # есть.
    same_cert = sys_my.get_cert_by_info(psi)
    t2 = same_cert.thumbprint()
    assert t1 == t2

    # разнообразные проверки подписей через сертификаты
    print(verify_cert.name())
    assert msg.verify_cert(verify_cert)
    ns = list(c.name() for c in msg.signer_certs())
    assert len(ns)
    cs = list(csp.CertStore(msg))
    print([(msg.verify_cert(x), x.name()) for x in cs])
    assert all(msg.verify_cert(c) for c in cs)