<filename>tests/test_rfc3279.py
#
# This file is part of pyasn1-modules software.
#
# Created by <NAME>
# Copyright (c) 2019, Vigil Security, LLC
# License: http://snmplabs.com/pyasn1/license.html
#

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.type import univ

from pyasn1_modules import pem, rfc3279, rfc5280


class RSACertificateTestCase(unittest.TestCase):
    rsa_cert_pem_text = """\
<KEY>
"""

    def setUp(self):
        self.asn1Spec = rfc5280.Certificate()

    def testDerCodec(self):
        substrate = pem.readBase64fromText(self.rsa_cert_pem_text)
        asn1Object, rest = der_decoder(substrate, asn1Spec=self.asn1Spec)

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.rsaEncryption, spki_a["algorithm"])

        spki_pk = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"][
            "subjectPublicKey"
        ].asOctets()
        pk, rest = der_decoder(spki_pk, asn1Spec=rfc3279.RSAPublicKey())

        self.assertFalse(rest)
        self.assertTrue(pk.prettyPrint())
        self.assertEqual(spki_pk, der_encoder(pk))
        self.assertEqual(65537, pk["publicExponent"])
        self.assertEqual(
            rfc3279.sha1WithRSAEncryption,
            asn1Object["tbsCertificate"]["signature"]["algorithm"],
        )
        self.assertEqual(
            rfc3279.sha1WithRSAEncryption, asn1Object["signatureAlgorithm"]["algorithm"]
        )

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

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.rsaEncryption, spki_a["algorithm"])
        self.assertEqual(univ.Null(""), spki_a["parameters"])


class ECCertificateTestCase(unittest.TestCase):
    ec_cert_pem_text = """\
<KEY>
"""

    def setUp(self):
        self.asn1Spec = rfc5280.Certificate()

    def testDerCodec(self):
        substrate = pem.readBase64fromText(self.ec_cert_pem_text)
        asn1Object, rest = der_decoder(substrate, asn1Spec=self.asn1Spec)

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.id_ecPublicKey, spki_a["algorithm"])

        spki_a_p, rest = der_decoder(
            spki_a["parameters"], asn1Spec=rfc3279.EcpkParameters()
        )

        self.assertFalse(rest)
        self.assertTrue(spki_a_p.prettyPrint())
        self.assertEqual(spki_a["parameters"], der_encoder(spki_a_p))
        self.assertEqual(univ.ObjectIdentifier("1.3.132.0.34"), spki_a_p["namedCurve"])

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

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.id_ecPublicKey, spki_a["algorithm"])
        self.assertEqual(
            univ.ObjectIdentifier("1.3.132.0.34"), spki_a["parameters"]["namedCurve"]
        )


class DSACertificateTestCase(unittest.TestCase):
    dsa_cert_pem_text = """\
<KEY>
"""

    def setUp(self):
        self.asn1Spec = rfc5280.Certificate()

    def testDerCodec(self):
        substrate = pem.readBase64fromText(self.dsa_cert_pem_text)
        asn1Object, rest = der_decoder(substrate, asn1Spec=self.asn1Spec)

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.id_dsa, spki_a["algorithm"])

        spki_a_p, rest = der_decoder(spki_a["parameters"], asn1Spec=rfc3279.Dss_Parms())
        self.assertFalse(rest)
        self.assertTrue(spki_a_p.prettyPrint())
        self.assertEqual(spki_a["parameters"], der_encoder(spki_a_p))

        q_value = 1260916123897116834511257683105158021801897369967

        self.assertEqual(q_value, spki_a_p["q"])

        sig_value, rest = der_decoder(
            asn1Object["signature"].asOctets(), asn1Spec=rfc3279.Dss_Sig_Value()
        )

        self.assertFalse(rest)
        self.assertTrue(sig_value.prettyPrint())
        self.assertEqual(asn1Object["signature"].asOctets(), der_encoder(sig_value))
        self.assertTrue(sig_value["r"].hasValue())
        self.assertTrue(sig_value["s"].hasValue())

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

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.id_dsa, spki_a["algorithm"])

        q_value = 1260916123897116834511257683105158021801897369967

        self.assertEqual(q_value, spki_a["parameters"]["q"])


class KEACertificateTestCase(unittest.TestCase):
    kea_cert_pem_text = """\
<KEY>
"""

    def setUp(self):
        self.asn1Spec = rfc5280.Certificate()

    def testDerCodec(self):
        substrate = pem.readBase64fromText(self.kea_cert_pem_text)
        asn1Object, rest = der_decoder(substrate, asn1Spec=self.asn1Spec)

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.id_keyExchangeAlgorithm, spki_a["algorithm"])

        spki_a_p, rest = der_decoder(
            spki_a["parameters"], asn1Spec=rfc3279.KEA_Parms_Id()
        )
        self.assertFalse(rest)
        self.assertTrue(spki_a_p.prettyPrint())

        self.assertEqual(spki_a["parameters"], der_encoder(spki_a_p))
        self.assertEqual(univ.OctetString(hexValue="5cf8f127e6569d6d88b3"), spki_a_p)
        self.assertEqual(
            rfc3279.id_dsa_with_sha1,
            asn1Object["tbsCertificate"]["signature"]["algorithm"],
        )
        self.assertEqual(
            rfc3279.id_dsa_with_sha1, asn1Object["signatureAlgorithm"]["algorithm"]
        )

        sig_value, rest = der_decoder(
            asn1Object["signature"].asOctets(), asn1Spec=rfc3279.Dss_Sig_Value()
        )
        self.assertFalse(rest)
        self.assertTrue(sig_value.prettyPrint())
        self.assertEqual(asn1Object["signature"].asOctets(), der_encoder(sig_value))
        self.assertTrue(sig_value["r"].hasValue())
        self.assertTrue(sig_value["s"].hasValue())

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

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.id_keyExchangeAlgorithm, spki_a["algorithm"])
        self.assertEqual(
            univ.OctetString(hexValue="5cf8f127e6569d6d88b3"), spki_a["parameters"]
        )

        self.assertEqual(
            rfc3279.id_dsa_with_sha1,
            asn1Object["tbsCertificate"]["signature"]["algorithm"],
        )
        self.assertEqual(
            rfc3279.id_dsa_with_sha1, asn1Object["signatureAlgorithm"]["algorithm"]
        )


class DHCertificateTestCase(unittest.TestCase):
    dh_cert_pem_text = """\
<KEY>
"""

    def setUp(self):
        self.asn1Spec = rfc5280.Certificate()

    def testDerCodec(self):
        substrate = pem.readBase64fromText(self.dh_cert_pem_text)
        asn1Object, rest = der_decoder(substrate, asn1Spec=self.asn1Spec)

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.dhpublicnumber, spki_a["algorithm"])

        spki_a_p, rest = der_decoder(
            spki_a["parameters"], asn1Spec=rfc3279.DomainParameters()
        )

        self.assertFalse(rest)
        self.assertTrue(spki_a_p.prettyPrint())
        self.assertEqual(spki_a["parameters"], der_encoder(spki_a_p))

        q_value = 65838278260281264030127352144753816831178774189428428256716126077244217603537

        self.assertEqual(q_value, spki_a_p["q"])

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

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

        spki_a = asn1Object["tbsCertificate"]["subjectPublicKeyInfo"]["algorithm"]

        self.assertEqual(rfc3279.dhpublicnumber, spki_a["algorithm"])

        q_value = 65838278260281264030127352144753816831178774189428428256716126077244217603537

        self.assertEqual(q_value, spki_a["parameters"]["q"])


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

if __name__ == "__main__":
    unittest.TextTestRunner(verbosity=2).run(suite)
