public void _08_AttributeArrayAttributeTest() { if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0) Assert.Inconclusive("Test cannot be executed on this platform"); ObjectAttribute nestedAttribute1 = new ObjectAttribute(CKA.CKA_TOKEN, true); ObjectAttribute nestedAttribute2 = new ObjectAttribute(CKA.CKA_PRIVATE, true); List<ObjectAttribute> originalValue = new List<ObjectAttribute>(); originalValue.Add(nestedAttribute1); originalValue.Add(nestedAttribute2); // Create attribute with attribute array value using (ObjectAttribute attr = new ObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue)) { Assert.IsTrue(attr.Type == (ulong)CKA.CKA_WRAP_TEMPLATE); List<ObjectAttribute> recoveredValue = attr.GetValueAsObjectAttributeList(); Assert.IsTrue(recoveredValue.Count == 2); Assert.IsTrue(recoveredValue[0].Type == (ulong)CKA.CKA_TOKEN); Assert.IsTrue(recoveredValue[0].GetValueAsBool() == true); Assert.IsTrue(recoveredValue[1].Type == (ulong)CKA.CKA_PRIVATE); Assert.IsTrue(recoveredValue[1].GetValueAsBool() == true); } // There is the same pointer to unmanaged memory in both nestedAttribute1 and recoveredValue[0] instances // therefore private low level attribute structure needs to be modified to prevent double free. // This special handling is needed only in this synthetic test and should be avoided in real world application. LLA80.CK_ATTRIBUTE ckAttribute1 = (LLA80.CK_ATTRIBUTE)typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(nestedAttribute1); ckAttribute1.value = IntPtr.Zero; ckAttribute1.valueLen = 0; typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(nestedAttribute1, ckAttribute1); // There is the same pointer to unmanaged memory in both nestedAttribute2 and recoveredValue[1] instances // therefore private low level attribute structure needs to be modified to prevent double free. // This special handling is needed only in this synthetic test and should be avoided in real world application. LLA80.CK_ATTRIBUTE ckAttribute2 = (LLA80.CK_ATTRIBUTE)typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(nestedAttribute2); ckAttribute2.value = IntPtr.Zero; ckAttribute2.valueLen = 0; typeof(ObjectAttribute).GetField("_ckAttribute", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(nestedAttribute2, ckAttribute2); originalValue = null; // Create attribute with null attribute array value using (ObjectAttribute attr = new ObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue)) { Assert.IsTrue(attr.Type == (ulong)CKA.CKA_WRAP_TEMPLATE); Assert.IsTrue(attr.GetValueAsObjectAttributeList() == originalValue); } originalValue = new List<ObjectAttribute>(); // Create attribute with empty attribute array value using (ObjectAttribute attr = new ObjectAttribute(CKA.CKA_WRAP_TEMPLATE, originalValue)) { Assert.IsTrue(attr.Type == (ulong)CKA.CKA_WRAP_TEMPLATE); Assert.IsTrue(attr.GetValueAsObjectAttributeList() == null); } }