#
# This file is part of pyasn1-alt-modules software.
#
# Copyright (c) 2019-2025, Vigil Security, LLC
# License: http://vigilsec.com/pyasn1-alt-modules-license.txt
#
import sys
import unittest

from pyasn1.codec.der.decoder import decode as der_decoder
from pyasn1.codec.der.encoder import encode as der_encoder

from pyasn1_alt_modules import pem
from pyasn1_alt_modules import rfc5275
from pyasn1_alt_modules import rfc5652
from pyasn1_alt_modules import rfc6402


class GLUseKEKTestCase(unittest.TestCase):
    pem_text = """\

KS1zJZvX/ury+ySGvKDLkfnqwZARR9W7TkTdx0L9W9oVjyEgOeGkvA==
"""

    def testDerCodec(self):
        substrate = pem.readBase64fromText(self.pem_text)

        layers = { }
        layers.update(rfc5652.cmsContentTypesMap)

        getNextLayer = {
            rfc5652.id_ct_contentInfo: lambda x: x['contentType'],
            rfc5652.id_signedData: lambda x: x['encapContentInfo']['eContentType'],
            rfc6402.id_cct_PKIData: lambda x: None
        }

        getNextSubstrate = {
            rfc5652.id_ct_contentInfo: lambda x: x['content'],
            rfc5652.id_signedData: lambda x: x['encapContentInfo']['eContent'],
            rfc6402.id_cct_PKIData: lambda x: None
        }

        next_layer = rfc5652.id_ct_contentInfo
        while next_layer:
            asn1Object, rest = der_decoder(
                substrate, asn1Spec=layers[next_layer])

            self.assertFalse(rest)
            self.assertTrue(asn1Object.prettyPrint())
            self.assertEqual(substrate, der_encoder(asn1Object))

            substrate = getNextSubstrate[next_layer](asn1Object)
            next_layer = getNextLayer[next_layer](asn1Object)

        found_gl_use_kek = False
        for ctrl in asn1Object['controlSequence']:
            if ctrl['attrType'] == rfc5275.id_skd_glUseKEK:
                cv, rest = der_decoder(
                    ctrl['attrValues'][0],
                    asn1Spec=rfc5652.cmsAttributesMap[ctrl['attrType']])

                self.assertFalse(rest)
                self.assertTrue(cv.prettyPrint())
                self.assertEqual(ctrl['attrValues'][0], der_encoder(cv))

                self.assertIn(
                    'example.com',
                    cv['glInfo']['glAddress']['rfc822Name'])

                self.assertIn(
                    'example.com',
                    cv['glOwnerInfo'][0]['glOwnerAddress']['rfc822Name'])

                self.assertEqual(31, cv['glKeyAttributes']['duration'])
                found_gl_use_kek = True

        self.assertTrue(found_gl_use_kek)

    def testOpenTypes(self):
        substrate = pem.readBase64fromText(self.pem_text)
        asn1Object, rest = der_decoder(
            substrate, asn1Spec=rfc5652.ContentInfo(), decodeOpenTypes=True)

        self.assertFalse(rest)
        self.assertTrue(asn1Object.prettyPrint())
        self.assertEqual(substrate, der_encoder(asn1Object))

        sd = asn1Object['content']
        self.assertEqual(
            rfc6402.id_cct_PKIData, sd['encapContentInfo']['eContentType'])

        pkid, rest = der_decoder(
            sd['encapContentInfo']['eContent'],
            asn1Spec=rfc6402.PKIData(),
            decodeOpenTypes=True)

        self.assertFalse(rest)
        self.assertTrue(pkid.prettyPrint())
        self.assertEqual(sd['encapContentInfo']['eContent'], der_encoder(pkid))

        found_gl_use_kek = False
        for ctrl in pkid['controlSequence']:
            if ctrl['attrType'] == rfc5275.id_skd_glUseKEK:
                cv = ctrl['attrValues'][0]

                self.assertIn(
                    'example.com',
                    cv['glInfo']['glAddress']['rfc822Name'])

                self.assertIn(
                    'example.com',
                    cv['glOwnerInfo'][0]['glOwnerAddress']['rfc822Name'])

                self.assertEqual(31, cv['glKeyAttributes']['duration'])
                found_gl_use_kek = True

        self.assertTrue(found_gl_use_kek)


suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])

if __name__ == '__main__':
    import sys

    result = unittest.TextTestRunner(verbosity=2).run(suite)
    sys.exit(not result.wasSuccessful())
