void test_a_dbobject_with_an_object::should_store_binary_attributes()
{
    ByteString value1 = "010203040506070809";
    ByteString value2 = "ABABABABABABABABABABABABABABABABAB";
    unsigned long value3 = 0xBDED;
    ByteString value4 = "98A7E5D798A7E5D798A7E5D798A7E5D798A7E5D798A7E5D7";
    ByteString value5 = "ABCDABCDABCDABCDABCDABCDABCDABCD";

    // Create the test object
    {
        DBObject testObject(connection);
        CPPUNIT_ASSERT(testObject.find(1));
        CPPUNIT_ASSERT(testObject.isValid());

        OSAttribute attr1(value1);
        OSAttribute attr2(value2);
        OSAttribute attr3(value3);
        OSAttribute attr4(value4);
        OSAttribute attr5(value5);

        CPPUNIT_ASSERT(testObject.setAttribute(CKA_MODULUS, attr1));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_COEFFICIENT, attr2));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_VALUE_BITS, attr3));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_PUBLIC_EXPONENT, attr4));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBJECT, attr5));
    }

    // Now read back the object
    {
        DBObject testObject(connection);
        CPPUNIT_ASSERT(testObject.find(1));
        CPPUNIT_ASSERT(testObject.isValid());

        CPPUNIT_ASSERT(testObject.attributeExists(CKA_MODULUS));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_COEFFICIENT));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_VALUE_BITS));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_PUBLIC_EXPONENT));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBJECT));
        CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID));

        CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS).isByteStringAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_COEFFICIENT).isByteStringAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_PUBLIC_EXPONENT).isByteStringAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT).isByteStringAttribute());

        CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS).getByteStringValue() == value1);
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_COEFFICIENT).getByteStringValue() == value2);
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3);
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_PUBLIC_EXPONENT).getByteStringValue() == value4);
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT).getByteStringValue() == value5);

        ByteString value6 = "909090908080808080807070707070FF";
        OSAttribute attr6(value6);

        CPPUNIT_ASSERT(testObject.setAttribute(CKA_ISSUER, attr6));
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_ISSUER).isByteStringAttribute());
        CPPUNIT_ASSERT(testObject.getByteStringValue(CKA_ISSUER) == value6);
    }
}
Exemple #2
0
/***********************************************************************//**
 * @brief Test XML attributes
 **************************************************************************/
void TestGXml::test_GXml_attributes(void)
{
    // Test attribute name-value constructors
    GXmlAttribute attr1("test", "1.0");
    test_assert(attr1.value() == "1.0", "Test if value()= 1.0",
                "Unexpected attribute "+attr1.value());
    GXmlAttribute attr2("test", "\"1.0\"");
    test_assert(attr2.value() == "1.0", "Test if value()= 1.0",
                "Unexpected attribute "+attr2.value());
    GXmlAttribute attr3("test", "'1.0'");
    test_assert(attr3.value() == "1.0", "Test if value()= 1.0",
                "Unexpected attribute "+attr3.value());
    GXmlAttribute attr4("test", "''1.0'");
    test_assert(attr4.value() == "'1.0", "Test if value()= '1.0",
                "Unexpected attribute "+attr4.value());
    GXmlAttribute attr5("test", "'1.0");
    test_assert(attr5.value() == "'1.0", "Test if value()= '1.0",
                "Unexpected attribute "+attr5.value());
    GXmlAttribute attr6("test", "1.0'");
    test_assert(attr6.value() == "1.0'", "Test if value()= 1.0'",
                "Unexpected attribute "+attr6.value());
    GXmlAttribute attr7("test", "\"1.0");
    test_assert(attr7.value() == "\"1.0", "Test if value()= \"1.0",
                "Unexpected attribute "+attr7.value());
    GXmlAttribute attr8("test", "1.0\"");
    test_assert(attr8.value() == "1.0\"", "Test if value()= 1.0\"",
                "Unexpected attribute "+attr8.value());
    GXmlAttribute attr9("test", "\"\"1.0\"");
    test_assert(attr9.value() == "\"1.0", "Test if value()= \"1.0",
                "Unexpected attribute "+attr9.value());

    // Return
    return;
}
void test_a_dbobject_with_an_object::should_store_unsigned_long_attributes()
{
	// Add unsigned long attributes to the object
	{
		DBObject testObject(connection);
		CPPUNIT_ASSERT(testObject.find(1));
		CPPUNIT_ASSERT(testObject.isValid());

		unsigned long value1 = 0x12345678;
		unsigned long value2 = 0x87654321;
		unsigned long value3 = 0x01010101;
		unsigned long value4 = 0x10101010;
		unsigned long value5 = 0xABCDEF;

		OSAttribute attr1(value1);
		OSAttribute attr2(value2);
		OSAttribute attr3(value3);
		OSAttribute attr4(value4);
		OSAttribute attr5(value5);

		CPPUNIT_ASSERT(testObject.setAttribute(CKA_MODULUS_BITS, attr1));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_AUTH_PIN_FLAGS, attr3));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBPRIME_BITS, attr4));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_KEY_TYPE, attr5));
	}

	// Now read back the object
	{
		DBObject testObject(connection);
		CPPUNIT_ASSERT(testObject.find(1));
		CPPUNIT_ASSERT(testObject.isValid());

		CPPUNIT_ASSERT(testObject.attributeExists(CKA_MODULUS_BITS));
		CPPUNIT_ASSERT(testObject.attributeExists(CKA_PRIME_BITS));
		CPPUNIT_ASSERT(testObject.attributeExists(CKA_AUTH_PIN_FLAGS));
		CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBPRIME_BITS));
		CPPUNIT_ASSERT(testObject.attributeExists(CKA_KEY_TYPE));
		CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID));

		CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE)->isUnsignedLongAttribute());

		CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_MODULUS_BITS)->getUnsignedLongValue(), (unsigned long)0x12345678);
		CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_PRIME_BITS)->getUnsignedLongValue(), (unsigned long)0x87654321);
		CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_AUTH_PIN_FLAGS)->getUnsignedLongValue(), (unsigned long)0x01010101);
		CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_SUBPRIME_BITS)->getUnsignedLongValue(), (unsigned long)0x10101010);
		CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_KEY_TYPE)->getUnsignedLongValue(), (unsigned long)0xABCDEF);

		unsigned long value6 = 0x90909090;
		OSAttribute attr6(value6);

		CPPUNIT_ASSERT(testObject.setAttribute(CKA_CLASS, attr6));
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_CLASS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_CLASS)->getUnsignedLongValue(), value6);
	}
}
void test_a_dbobject_with_an_object::should_store_boolean_attributes()
{
    {
        DBObject testObject(connection);
        CPPUNIT_ASSERT(testObject.find(1));
        CPPUNIT_ASSERT(testObject.isValid());

        bool value1 = true;
        bool value2 = false;
        bool value3 = true;
        bool value4 = true;
        bool value5 = false;

        OSAttribute attr1(value1);
        OSAttribute attr2(value2);
        OSAttribute attr3(value3);
        OSAttribute attr4(value4);
        OSAttribute attr5(value5);

        CPPUNIT_ASSERT(testObject.setAttribute(CKA_TOKEN, attr1));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_SENSITIVE, attr2));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_EXTRACTABLE, attr3));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_NEVER_EXTRACTABLE, attr4));
        CPPUNIT_ASSERT(testObject.setAttribute(CKA_SIGN, attr5));
    }

    {
        DBObject testObject(connection);
        CPPUNIT_ASSERT(testObject.find(1));
        CPPUNIT_ASSERT(testObject.isValid());

        CPPUNIT_ASSERT(testObject.attributeExists(CKA_TOKEN));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_SENSITIVE));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_EXTRACTABLE));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_NEVER_EXTRACTABLE));
        CPPUNIT_ASSERT(testObject.attributeExists(CKA_SIGN));
        CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID));

        CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).isBooleanAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_SENSITIVE).isBooleanAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_EXTRACTABLE).isBooleanAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_NEVER_EXTRACTABLE).isBooleanAttribute());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_SIGN).isBooleanAttribute());

        CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).getBooleanValue());
        CPPUNIT_ASSERT(!testObject.getAttribute(CKA_SENSITIVE).getBooleanValue());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_EXTRACTABLE).getBooleanValue());
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_NEVER_EXTRACTABLE).getBooleanValue());
        CPPUNIT_ASSERT(!testObject.getAttribute(CKA_SIGN).getBooleanValue());

        bool value6 = true;
        OSAttribute attr6(value6);

        CPPUNIT_ASSERT(testObject.setAttribute(CKA_VERIFY, attr6));
        CPPUNIT_ASSERT(testObject.getAttribute(CKA_VERIFY).isBooleanAttribute());
        CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_VERIFY).getBooleanValue(), value6);
        CPPUNIT_ASSERT_EQUAL(testObject.getBooleanValue(CKA_VERIFY, false), value6);
    }
}
void SessionObjectTests::testBoolAttr()
{
    SessionObject testObject(NULL, 1, 1);

	CPPUNIT_ASSERT(testObject.isValid());

	bool value1 = true;
	bool value2 = false;
	bool value3 = true;
	bool value4 = true;
	bool value5 = false;

	OSAttribute attr1(value1);
	OSAttribute attr2(value2);
	OSAttribute attr3(value3);
	OSAttribute attr4(value4);
	OSAttribute attr5(value5);

	CPPUNIT_ASSERT(testObject.setAttribute(CKA_TOKEN, attr1));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_SENSITIVE, attr2));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_EXTRACTABLE, attr3));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_NEVER_EXTRACTABLE, attr4));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_SIGN, attr5));

	CPPUNIT_ASSERT(testObject.isValid());

	CPPUNIT_ASSERT(testObject.attributeExists(CKA_TOKEN));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_SENSITIVE));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_EXTRACTABLE));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_NEVER_EXTRACTABLE));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_SIGN));
	CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID));

	CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN)->isBooleanAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SENSITIVE)->isBooleanAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_EXTRACTABLE)->isBooleanAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_NEVER_EXTRACTABLE)->isBooleanAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SIGN)->isBooleanAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID) == NULL);

	CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN)->getBooleanValue() == true);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SENSITIVE)->getBooleanValue() == false);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_EXTRACTABLE)->getBooleanValue() == true);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_NEVER_EXTRACTABLE)->getBooleanValue() == true);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SIGN)->getBooleanValue() == false);

	bool value6 = true;
	OSAttribute attr6(value6);

	CPPUNIT_ASSERT(testObject.setAttribute(CKA_VERIFY, attr6));
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_VERIFY)->isBooleanAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_VERIFY)->getBooleanValue() == value6);
}
void SessionObjectTests::testByteStrAttr()
{
	ByteString value1 = "010203040506070809";
	ByteString value2 = "ABABABABABABABABABABABABABABABABAB";
	ByteString value3 = "BDEBDBEDBBDBEBDEBE792759537328";
	ByteString value4 = "98A7E5D798A7E5D798A7E5D798A7E5D798A7E5D798A7E5D7";
	ByteString value5 = "ABCDABCDABCDABCDABCDABCDABCDABCD";

    SessionObject testObject(NULL, 1, 1);

	CPPUNIT_ASSERT(testObject.isValid());

	OSAttribute attr1(value1);
	OSAttribute attr2(value2);
	OSAttribute attr3(value3);
	OSAttribute attr4(value4);
	OSAttribute attr5(value5);

	CPPUNIT_ASSERT(testObject.setAttribute(CKA_MODULUS, attr1));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_COEFFICIENT, attr2));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_VALUE_BITS, attr3));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_PUBLIC_EXPONENT, attr4));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBJECT, attr5));

	CPPUNIT_ASSERT(testObject.isValid());

	CPPUNIT_ASSERT(testObject.attributeExists(CKA_MODULUS));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_COEFFICIENT));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_VALUE_BITS));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_PUBLIC_EXPONENT));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBJECT));
	CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID));

	CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS)->isByteStringAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_COEFFICIENT)->isByteStringAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS)->isByteStringAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_PUBLIC_EXPONENT)->isByteStringAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT)->isByteStringAttribute());

	CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS)->getByteStringValue() == value1);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_COEFFICIENT)->getByteStringValue() == value2);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS)->getByteStringValue() == value3);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_PUBLIC_EXPONENT)->getByteStringValue() == value4);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT)->getByteStringValue() == value5);

	ByteString value6 = "909090908080808080807070707070FF";
	OSAttribute attr6(value6);

	CPPUNIT_ASSERT(testObject.setAttribute(CKA_ISSUER, attr6));
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_ISSUER)->isByteStringAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_ISSUER)->getByteStringValue() == value6);
}
void SessionObjectTests::testULongAttr()
{
    SessionObject testObject(NULL, 1, 1);

	CPPUNIT_ASSERT(testObject.isValid());

	unsigned long value1 = 0x12345678;
	unsigned long value2 = 0x87654321;
	unsigned long value3 = 0x01010101;
	unsigned long value4 = 0x10101010;
	unsigned long value5 = 0xABCDEF;

	OSAttribute attr1(value1);
	OSAttribute attr2(value2);
	OSAttribute attr3(value3);
	OSAttribute attr4(value4);
	OSAttribute attr5(value5);

	CPPUNIT_ASSERT(testObject.setAttribute(CKA_MODULUS_BITS, attr1));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_AUTH_PIN_FLAGS, attr3));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBPRIME_BITS, attr4));
	CPPUNIT_ASSERT(testObject.setAttribute(CKA_KEY_TYPE, attr5));
		
	CPPUNIT_ASSERT(testObject.isValid());

	CPPUNIT_ASSERT(testObject.attributeExists(CKA_MODULUS_BITS));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_PRIME_BITS));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_AUTH_PIN_FLAGS));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBPRIME_BITS));
	CPPUNIT_ASSERT(testObject.attributeExists(CKA_KEY_TYPE));
	CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID));

	CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS)->isUnsignedLongAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->isUnsignedLongAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS)->isUnsignedLongAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS)->isUnsignedLongAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE)->isUnsignedLongAttribute());

	CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS)->getUnsignedLongValue() == 0x12345678);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->getUnsignedLongValue() == 0x87654321);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS)->getUnsignedLongValue() == 0x01010101);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS)->getUnsignedLongValue() == 0x10101010);
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE)->getUnsignedLongValue() == 0xABCDEF);

	unsigned long value6 = 0x90909090;
	OSAttribute attr6(value6);

	CPPUNIT_ASSERT(testObject.setAttribute(CKA_CLASS, attr6));
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_CLASS)->isUnsignedLongAttribute());
	CPPUNIT_ASSERT(testObject.getAttribute(CKA_CLASS)->getUnsignedLongValue() == value6);
}
void test_a_dbobject_with_an_object::should_use_transactions()
{
    DBObject testObject(connection);
    CPPUNIT_ASSERT(testObject.find(1));
    CPPUNIT_ASSERT(testObject.isValid());

    bool value1 = true;
    unsigned long value2 = 0x87654321;
    unsigned long value3 = 0xBDEBDBED;
    ByteString value4 = "AAAAAAAAAAAAAAAFFFFFFFFFFFFFFF";

    OSAttribute attr1(value1);
    OSAttribute attr2(value2);
    OSAttribute attr3(value3);
    OSAttribute attr4(value4);

    CPPUNIT_ASSERT(testObject.setAttribute(CKA_TOKEN, attr1));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_VALUE_BITS, attr3));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_ID, attr4));

    // Create secondary instance for the same object.
    // This needs to have a different connection to the database to simulate
    // another process accessing the data.
    DBObject testObject2(connection2);
    CPPUNIT_ASSERT(testObject2.find(1));
    CPPUNIT_ASSERT(testObject2.isValid());

    // Check that it has the same attributes
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID).isByteStringAttribute());

    // Check that the attributes have the same values as set on testObject.
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN).getBooleanValue() == value1);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == value2);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID).getByteStringValue() == value4);

    // New values
    bool value1a = false;
    unsigned long value2a = 0x12345678;
    unsigned long value3a = 0xABABABAB;
    ByteString value4a = "EDEDEDEDEDEDEDEDEDEDEDEDEDEDED";

    OSAttribute attr1a(value1a);
    OSAttribute attr2a(value2a);
    OSAttribute attr3a(value3a);
    OSAttribute attr4a(value4a);

    // Start transaction on object
    CPPUNIT_ASSERT(testObject.startTransaction(DBObject::ReadWrite));

    // Change the attributes
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_TOKEN, attr1a));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2a));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_VALUE_BITS, attr3a));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_ID, attr4a));

    // Verify that the attributes were set
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID).isByteStringAttribute());

    CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).getBooleanValue() == value1a);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == value2a);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3a);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID).getByteStringValue() == value4a);

    // Verify that they are unchanged on the other instance
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID).isByteStringAttribute());

    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN).getBooleanValue() == value1);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == value2);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID).getByteStringValue() == value4);

    // Commit the transaction
    CPPUNIT_ASSERT(testObject.commitTransaction());

    // Verify that non-modifiable attributes did not propagate but modifiable attributes
    // have now changed on the other instance
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID).isByteStringAttribute());

    // NOTE: 3 attributes below cannot be modified after creation and therefore are not required to propagate.
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN).getBooleanValue() != value1a);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() != value2a);
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() != value3a);

    // CKA_ID attribute can be modified after creation and therefore should have propagated.
    CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID).getByteStringValue() == value4a);

    // Start transaction on object
    CPPUNIT_ASSERT(testObject.startTransaction(DBObject::ReadWrite));

    // Change the attributes
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_TOKEN, attr1));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_VALUE_BITS, attr3));
    CPPUNIT_ASSERT(testObject.setAttribute(CKA_ID, attr4));

    // Verify that the attributes were set
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID).isByteStringAttribute());

    CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).getBooleanValue() == value1);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == value2);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID).getByteStringValue() == value4);

    // Create a fresh third instance for the same object to force the data to be retrieved from the database.
    DBObject testObject3(connection2);
    CPPUNIT_ASSERT(testObject3.find(1));
    CPPUNIT_ASSERT(testObject3.isValid());

    // Verify that they are unchanged on the other instance, while the transaction is still in progress.
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_ID).isByteStringAttribute());

    // Verify that the attributes from the database are still hodling the same value as when the transaction started.
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_TOKEN).getBooleanValue() == value1a);
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == value2a);
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3a);
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_ID).getByteStringValue() == value4a);

    // Abort the transaction
    CPPUNIT_ASSERT(testObject.abortTransaction());

    // Verify that after aborting the transaction the values in testObject have reverted back to their
    // original state.
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID).isByteStringAttribute());

    // After aborting a transaction the testObject should be back to pre transaction state.
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN).getBooleanValue() == value1a);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == value2a);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3a);
    CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID).getByteStringValue() == value4a);

    // Verify that testObject3 still has the original values.
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_TOKEN).isBooleanAttribute());
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_VALUE_BITS).isUnsignedLongAttribute());
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_ID).isByteStringAttribute());

    // Verify that testObject3 still has the original values.
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_TOKEN).getBooleanValue() == value1a);
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == value2a);
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_VALUE_BITS).getUnsignedLongValue() == value3a);
    CPPUNIT_ASSERT(testObject3.getAttribute(CKA_ID).getByteStringValue() == value4a);
}
void test_a_dbobject_with_an_object::can_refresh_attributes()
{
	bool value1 = true;
	bool value1a = false;
	unsigned long value2 = 0x87654321;
	unsigned long value2a = 0x76767676;
	unsigned long value2b = 0x89898989;
	ByteString value3 = "BDEBDBEDBBDBEBDEBE792759537328";
	ByteString value3a = "466487346943785684957634";
	ByteString value4 = "0102010201020102010201020102010201020102";	

	// Create the test object
	{
		DBObject testObject(connection);
		CPPUNIT_ASSERT(testObject.find(1));
		CPPUNIT_ASSERT(testObject.isValid());

		OSAttribute attr1(value1);
		OSAttribute attr2(value2);
		OSAttribute attr3(value3);

		CPPUNIT_ASSERT(testObject.setAttribute(CKA_TOKEN, attr1));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBJECT, attr3));
	}

	// Now read back the object
	{
		DBObject testObject(connection);
		CPPUNIT_ASSERT(testObject.find(1));
		CPPUNIT_ASSERT(testObject.isValid());

		CPPUNIT_ASSERT(testObject.attributeExists(CKA_TOKEN));
		CPPUNIT_ASSERT(testObject.attributeExists(CKA_PRIME_BITS));
		CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBJECT));
		CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID));

		CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN)->isBooleanAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT)->isByteStringAttribute());

		CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN)->getBooleanValue());
		CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_PRIME_BITS)->getUnsignedLongValue(), value2);
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT)->getByteStringValue() == value3);

		OSAttribute attr1(value1a);
		OSAttribute attr2(value2a);
		OSAttribute attr3(value3a);

		// Change the attributes
		CPPUNIT_ASSERT(testObject.isValid());

		CPPUNIT_ASSERT(testObject.setAttribute(CKA_TOKEN, attr1));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2));
		CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBJECT, attr3));

		// Check the attributes
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN)->isBooleanAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT)->isByteStringAttribute());

		CPPUNIT_ASSERT(testObject.getAttribute(CKA_TOKEN)->getBooleanValue() == value1a);
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->getUnsignedLongValue() == value2a);
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBJECT)->getByteStringValue() == value3a);

		// Open the object a second time
		DBObject testObject2(connection);
		CPPUNIT_ASSERT(testObject2.find(1));
		CPPUNIT_ASSERT(testObject2.isValid());

		// Check the attributes on the second instance
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN)->isBooleanAttribute());
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_SUBJECT)->isByteStringAttribute());

		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_TOKEN)->getBooleanValue() == value1a);
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS)->getUnsignedLongValue() == value2a);
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_SUBJECT)->getByteStringValue() == value3a);

		// Add an attribute on the second object
		OSAttribute attr4(value4);

		CPPUNIT_ASSERT(testObject.setAttribute(CKA_ID, attr4));

		// Check the attribute
		CPPUNIT_ASSERT(testObject2.attributeExists(CKA_ID));
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID)->isByteStringAttribute());
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_ID)->getByteStringValue() == value4);

		// Now check that the first instance also knows about it
		CPPUNIT_ASSERT(testObject.attributeExists(CKA_ID));
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID)->isByteStringAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_ID)->getByteStringValue() == value4);

		// Now change another attribute
		OSAttribute attr2b(value2b);

		CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2b));

		// Check the attribute
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->isUnsignedLongAttribute());
		CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS)->getUnsignedLongValue() == value2b);

		// Now check that the second instance also knows about the change
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS)->isUnsignedLongAttribute());
		
		// Note that the CKA_PRIME_BITS attribute cannot officially be modified.
		// We optimize inside DBObject to only propagate to the database modifiable attributes.
		// Therefore we don't expect changes to CKA_PRIME_BITS to propagate to testObject2.
		CPPUNIT_ASSERT(testObject2.getAttribute(CKA_PRIME_BITS)->getUnsignedLongValue() != value2b);
	}
}