ts_102_221: Handle nested security condition data objects

ISO 7816-4 Section 5.4.3.2 "Expanded Format" permits for nesting
of security conditions using boolean operators OR, AND, NOT.

Let's implement decoding and encoding of these.

An example decoded looks like:

pySIM-shell (MF/EF.ARR)> read_record_decoded 1
[
    [
        {
            "access_mode": [
                "activate_file_or_record",
                "deactivate_file_or_record",
                "update_erase"
            ]
        },
        {
            "or": [
                {
                    "control_reference_template": "ADM1"
                },
                {
                    "control_reference_template": "ADM2"
                }
            ]
        }
    ],
    [
        {
            "access_mode": [
                "read_search_compare"
            ]
        },
        {
            "always": null
        }
    ]
]

Prior to this patch, pySim would raise "ValueError: Unknown Tag 0xa0 in bytearray"

Change-Id: Icb09cf3a90303a86fc77406b8b0806b5c926f1be
Closes: OS#5411
diff --git a/pySim/ts_102_221.py b/pySim/ts_102_221.py
index 7cc3025..71d5b82 100644
--- a/pySim/ts_102_221.py
+++ b/pySim/ts_102_221.py
@@ -470,8 +470,35 @@
 
 Always_DO = TL0_DataObject('always', 'Always', 0x90)
 Never_DO = TL0_DataObject('never', 'Never', 0x97)
+
+class Nested_DO(DataObject):
+    """A DO that nests another DO/Choice/Sequence"""
+    def __init__(self, name, tag, choice):
+        super().__init__(name, tag=tag)
+        self.children = choice
+    def from_bytes(self, binary:bytes) -> list:
+        remainder = binary
+        self.decoded = []
+        while remainder:
+            rc, remainder = self.children.decode(remainder)
+            self.decoded.append(rc)
+        return self.decoded
+    def to_bytes(self) -> bytes:
+        encoded = [self.children.encode(d) for d in self.decoded]
+        return b''.join(encoded)
+
+OR_Template = DataObjectChoice('or_template', 'OR-Template',
+                               members=[Always_DO, Never_DO, SecCondByte_DO(), SecCondByte_DO(0x9e), CRT_DO()])
+OR_DO = Nested_DO('or', 0xa0, OR_Template)
+AND_Template = DataObjectChoice('and_template', 'AND-Template',
+                               members=[Always_DO, Never_DO, SecCondByte_DO(), SecCondByte_DO(0x9e), CRT_DO()])
+AND_DO = Nested_DO('and', 0xa7, AND_Template)
+NOT_Template = DataObjectChoice('not_template', 'NOT-Template',
+                               members=[Always_DO, Never_DO, SecCondByte_DO(), SecCondByte_DO(0x9e), CRT_DO()])
+NOT_DO = Nested_DO('not', 0xaf, NOT_Template)
 SC_DO = DataObjectChoice('security_condition', 'Security Condition',
-                         members=[Always_DO, Never_DO, SecCondByte_DO(), SecCondByte_DO(0x9e), CRT_DO()])
+                         members=[Always_DO, Never_DO, SecCondByte_DO(), SecCondByte_DO(0x9e), CRT_DO(),
+                                  OR_DO, AND_DO, NOT_DO])
 
 # TS 102 221 Section 13.1
 class EF_DIR(LinFixedEF):