X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pygost%2Ftest_cms.py;h=9359875800a7a3ab756234384e0361b2ffa94c9a;hb=5ecaafbe1a87f9a311a18574653e6dbc75a776b9;hp=8eeea91f3edabe6a93eacdfd9d1e0e41c6e31d0e;hpb=5013b980d53a9969649a59535b7566f73f11521e;p=pygost.git diff --git a/pygost/test_cms.py b/pygost/test_cms.py index 8eeea91..9359875 100644 --- a/pygost/test_cms.py +++ b/pygost/test_cms.py @@ -1,11 +1,10 @@ # coding: utf-8 # PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2018 Sergey Matveev +# Copyright (C) 2015-2019 Sergey Matveev # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# the Free Software Foundation, version 3 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,8 +19,7 @@ from unittest import skipIf from unittest import TestCase from pygost.gost28147 import cfb_decrypt -from pygost.gost3410 import CURVE_PARAMS -from pygost.gost3410 import GOST3410Curve +from pygost.gost3410 import CURVES from pygost.gost3410 import prv_unmarshal from pygost.gost3410 import pub_unmarshal from pygost.gost3410 import public_key @@ -35,15 +33,13 @@ from pygost.wrap import unwrap_cryptopro from pygost.wrap import unwrap_gost try: + from pyderasn import DecodePathDefBy from pyderasn import OctetString from pygost.asn1schemas.cms import ContentInfo - from pygost.asn1schemas.cms import DigestedData - from pygost.asn1schemas.cms import EnvelopedData - from pygost.asn1schemas.cms import Gost2814789EncryptedKey - from pygost.asn1schemas.cms import Gost2814789Parameters - from pygost.asn1schemas.cms import GostR3410KeyTransport - from pygost.asn1schemas.cms import SignedData + from pygost.asn1schemas.oids import id_envelopedData + from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256 + from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512 except ImportError: pyderasn_exists = False else: @@ -67,10 +63,10 @@ class TestSigned(TestCase): ): content_info, tail = ContentInfo().decode(content_info_raw) self.assertSequenceEqual(tail, b"") - signed_data, tail = SignedData().decode(bytes(content_info["content"])) - self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(content_info["content"].defined) + _, signed_data = content_info["content"].defined self.assertEqual(len(signed_data["signerInfos"]), 1) - curve = GOST3410Curve(*CURVE_PARAMS[curve_name]) + curve = CURVES[curve_name] self.assertTrue(verify( curve, public_key(curve, prv_unmarshal(prv_key_raw)), @@ -92,7 +88,7 @@ VNwDQ8enFItJZ8DEX4blZ8QtziNCMl5HbA== self.process_cms( content_info_raw, prv_key_raw, - "GostR3410_2001_CryptoPro_XchA_ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", GOST34112012256, 2001, ) @@ -111,7 +107,7 @@ PS+KRYxT8vhcsBLWWxDkc1McI7aF09hqtED36mQOfACzeJjEoUjALpmJob1V self.process_cms( content_info_raw, prv_key_raw, - "GostR3410_2012_TC26_ParamSetB", + "id-tc26-gost-3410-12-512-paramSetB", GOST34112012512, 2012, ) @@ -127,8 +123,8 @@ class TestDigested(TestCase): def process_cms(self, content_info_raw, hasher): content_info, tail = ContentInfo().decode(content_info_raw) self.assertSequenceEqual(tail, b"") - digested_data, tail = DigestedData().decode(bytes(content_info["content"])) - self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(content_info["content"].defined) + _, digested_data = content_info["content"].defined self.assertSequenceEqual( hasher(bytes(digested_data["encapContentInfo"]["eContent"])).digest(), bytes(digested_data["digest"]), @@ -168,31 +164,57 @@ class TestEnvelopedKTRI(TestCase): keker, plaintext_expected, ): - sbox = "Gost28147_tc26_ParamZ" - content_info, tail = ContentInfo().decode(content_info_raw) - self.assertSequenceEqual(tail, b"") - enveloped_data, tail = EnvelopedData().decode(bytes(content_info["content"])) + sbox = "id-tc26-gost-28147-param-Z" + content_info, tail = ContentInfo().decode(content_info_raw, ctx={ + "defines_by_path": [ + ( + ( + "content", + DecodePathDefBy(id_envelopedData), + "recipientInfos", + any, + "ktri", + "encryptedKey", + DecodePathDefBy(spki_algorithm), + "transportParameters", + "ephemeralPublicKey", + "algorithm", + "algorithm", + ), + ( + ( + ("..", "subjectPublicKey"), + { + id_tc26_gost3410_2012_256: OctetString(), + id_tc26_gost3410_2012_512: OctetString(), + }, + ), + ), + ) for spki_algorithm in ( + id_tc26_gost3410_2012_256, + id_tc26_gost3410_2012_512, + ) + ], + }) self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(content_info["content"].defined) + _, enveloped_data = content_info["content"].defined eci = enveloped_data["encryptedContentInfo"] ri = enveloped_data["recipientInfos"][0] - encrypted_key, tail = GostR3410KeyTransport().decode( - bytes(ri["ktri"]["encryptedKey"]) - ) - self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(ri["ktri"]["encryptedKey"].defined) + _, encrypted_key = ri["ktri"]["encryptedKey"].defined ukm = bytes(encrypted_key["transportParameters"]["ukm"]) - spk = bytes(encrypted_key["transportParameters"]["ephemeralPublicKey"]["subjectPublicKey"]) - pub_key_their, tail = OctetString().decode(spk) - self.assertSequenceEqual(tail, b"") - curve = GOST3410Curve(*CURVE_PARAMS[curve_name]) + spk = encrypted_key["transportParameters"]["ephemeralPublicKey"]["subjectPublicKey"] + self.assertIsNotNone(spk.defined) + _, pub_key_their = spk.defined + curve = CURVES[curve_name] kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) key_wrapped = bytes(encrypted_key["sessionEncryptedKey"]["encryptedKey"]) mac = bytes(encrypted_key["sessionEncryptedKey"]["macKey"]) cek = unwrap_cryptopro(kek, ukm + key_wrapped + mac, sbox=sbox) ciphertext = bytes(eci["encryptedContent"]) - encryption_params, tail = Gost2814789Parameters().decode( - bytes(eci["contentEncryptionAlgorithm"]["parameters"]) - ) - self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(eci["contentEncryptionAlgorithm"]["parameters"].defined) + _, encryption_params = eci["contentEncryptionAlgorithm"]["parameters"].defined iv = bytes(encryption_params["iv"]) self.assertSequenceEqual( cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), @@ -270,7 +292,7 @@ pRmMVN+YtRsrEHwH3ToQ/i4vrtgA+eONuKT2uKZFikxA+VNmeeGdhkgqETMihQ== self.process_cms( content_info_raw, prv_key_our, - "GostR3410_2001_CryptoPro_XchA_ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", keker, b"Test data to encrypt.\n" * 100, ) @@ -301,7 +323,7 @@ FTAVBAj+1QzaXaN9FwYJKoUDBwECBQEBgAyK54euw0sHhEVEkA0= self.process_cms( content_info_raw, prv_key_our, - "GostR3410_2012_TC26_ParamSetB", + "id-tc26-gost-3410-12-512-paramSetB", keker, b"Test message", ) @@ -322,33 +344,55 @@ class TestEnvelopedKARI(TestCase): keker, plaintext_expected, ): - sbox = "Gost28147_tc26_ParamZ" - content_info, tail = ContentInfo().decode(content_info_raw) - self.assertSequenceEqual(tail, b"") - enveloped_data, tail = EnvelopedData().decode(bytes(content_info["content"])) + sbox = "id-tc26-gost-28147-param-Z" + content_info, tail = ContentInfo().decode(content_info_raw, ctx={ + "defines_by_path": [ + ( + ( + "content", + DecodePathDefBy(id_envelopedData), + "recipientInfos", + any, + "kari", + "originator", + "originatorKey", + "algorithm", + "algorithm", + ), + ( + ( + ("..", "publicKey"), + { + id_tc26_gost3410_2012_256: OctetString(), + id_tc26_gost3410_2012_512: OctetString(), + }, + ), + ), + ) for _ in ( + id_tc26_gost3410_2012_256, + id_tc26_gost3410_2012_512, + ) + ], + }) self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(content_info["content"].defined) + _, enveloped_data = content_info["content"].defined eci = enveloped_data["encryptedContentInfo"] kari = enveloped_data["recipientInfos"][0]["kari"] - pub_key_their, tail = OctetString().decode( - bytes(kari["originator"]["originatorKey"]["publicKey"]), - ) - self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(kari["originator"]["originatorKey"]["publicKey"].defined) + _, pub_key_their = kari["originator"]["originatorKey"]["publicKey"].defined ukm = bytes(kari["ukm"]) rek = kari["recipientEncryptedKeys"][0] - curve = GOST3410Curve(*CURVE_PARAMS[curve_name]) + curve = CURVES[curve_name] kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) - encrypted_key, tail = Gost2814789EncryptedKey().decode( - bytes(rek["encryptedKey"]), - ) - self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(rek["encryptedKey"].defined) + _, encrypted_key = rek["encryptedKey"].defined key_wrapped = bytes(encrypted_key["encryptedKey"]) mac = bytes(encrypted_key["macKey"]) cek = unwrap_gost(kek, ukm + key_wrapped + mac, sbox=sbox) ciphertext = bytes(eci["encryptedContent"]) - encryption_params, tail = Gost2814789Parameters().decode( - bytes(eci["contentEncryptionAlgorithm"]["parameters"]) - ) - self.assertSequenceEqual(tail, b"") + self.assertIsNotNone(eci["contentEncryptionAlgorithm"]["parameters"].defined) + _, encryption_params = eci["contentEncryptionAlgorithm"]["parameters"].defined iv = bytes(encryption_params["iv"]) self.assertSequenceEqual( cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), @@ -381,7 +425,7 @@ UNjyuY+54uVcHw== self.process_cms( content_info_raw, prv_key_our, - "GostR3410_2001_CryptoPro_XchA_ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", keker, b"Test message", ) @@ -412,7 +456,7 @@ WFUZEnEuAKcuG6dTOawEBLhi9hIwOgYJKoZIhvcNAQcBMB8GBiqFAwICFTAVBAiD self.process_cms( content_info_raw, prv_key_our, - "GostR3410_2012_TC26_ParamSetB", + "id-tc26-gost-3410-12-512-paramSetB", keker, b"Test message", )