Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement C_CopyObject for DB backend #540

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lib/SoftHSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,7 @@ CK_RV SoftHSM::C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject
{
if (!object->attributeExists(attrType))
{
WARNING_MSG("Attribute 0x%lx does not exist even though it was reported as next.");
rv = CKR_FUNCTION_FAILED;
break;
}
Expand Down
60 changes: 57 additions & 3 deletions src/lib/object_store/DBObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,37 @@ bool DBObject::createTables()
return true;
}

// update schema to support new features with dbs from previous versions.
bool DBObject::migrateTables()
{
MutexLocker lock(_mutex);

if (_connection == NULL)
{
ERROR_MSG("Object is not connected to the database.");
return false;
}

// attributes
DB::Statement cr_attrs = _connection->prepare(
"create view if not exists attributes as "
"select object_id, type from attribute_array "
"union all select object_id, type from attribute_binary "
"union all select object_id, type from attribute_boolean "
"union all select object_id, type from attribute_datetime "
"union all select object_id, type from attribute_integer "
"union all select object_id, type from attribute_real "
"union all select object_id, type from attribute_text"
);
if (!_connection->execute(cr_attrs))
{
ERROR_MSG("Failed to create \"attributes\" view");
return false;
}

return true;
}

bool DBObject::dropTables()
{
MutexLocker lock(_mutex);
Expand All @@ -212,6 +243,14 @@ bool DBObject::dropTables()
return false;
}

// attributes
DB::Statement dr_attrs = _connection->prepare("drop view attributes");
if (!_connection->execute(dr_attrs))
{
ERROR_MSG("Failed to drop \"attributes\" view");
return false;
}

// Create the tables inside the database
DB::Statement dr_object = _connection->prepare("drop table object");
if (!_connection->execute(dr_object))
Expand Down Expand Up @@ -450,6 +489,7 @@ static AttributeKind attributeKind(CK_ATTRIBUTE_TYPE type)
case CKA_EXPONENT_1: return akBinary;
case CKA_EXPONENT_2: return akBinary;
case CKA_COEFFICIENT: return akBinary;
case CKA_PUBLIC_KEY_INFO: return akBinary;
case CKA_PRIME: return akBinary;
case CKA_SUBPRIME: return akBinary;
case CKA_BASE: return akBinary;
Expand All @@ -464,6 +504,7 @@ static AttributeKind attributeKind(CK_ATTRIBUTE_TYPE type)
case CKA_KEY_GEN_MECHANISM: return akInteger;
case CKA_MODIFIABLE: return akBoolean;
case CKA_COPYABLE: return akBoolean;
case CKA_DESTROYABLE: return akBoolean;
case CKA_ECDSA_PARAMS: return akBinary;
case CKA_EC_POINT: return akBinary;
case CKA_SECONDARY_AUTH: return akBoolean;
Expand Down Expand Up @@ -1082,7 +1123,7 @@ ByteString DBObject::getByteStringValue(CK_ATTRIBUTE_TYPE type)
}
}

CK_ATTRIBUTE_TYPE DBObject::nextAttributeType(CK_ATTRIBUTE_TYPE)
CK_ATTRIBUTE_TYPE DBObject::nextAttributeType(CK_ATTRIBUTE_TYPE last)
{
MutexLocker lock(_mutex);

Expand All @@ -1097,8 +1138,21 @@ CK_ATTRIBUTE_TYPE DBObject::nextAttributeType(CK_ATTRIBUTE_TYPE)
return false;
}

// FIXME: implement for C_CopyObject
return CKA_CLASS;
DB::Statement stmt = _connection->prepare("select MIN(type) from attributes where object_id=%lld and type>%ld", _objectId, last);

if (!stmt.isValid())
{
WARNING_MSG("Failed to prepare next attribute query");
return CKA_CLASS;
}

DB::Result result = _connection->perform(stmt);
if (!result.isValid())
{
return CKA_CLASS;
}

return result.getULongLong(1);
}

// Set the specified attribute
Expand Down
3 changes: 3 additions & 0 deletions src/lib/object_store/DBObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class DBObject : public OSObject
// create tables to support storage of attributes for the object.
bool createTables();

// update schema to support new features with dbs from previous versions.
bool migrateTables();

// drop tables that support storage of attributes for the object.
bool dropTables();

Expand Down
4 changes: 2 additions & 2 deletions src/lib/object_store/DBToken.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ DBToken::DBToken(const std::string &baseDir, const std::string &tokenName, int u

// First create the tables that support storage of object attributes and then insert the object containing
// the token info into the database.
if (!tokenObject.createTables() || !tokenObject.insert() || tokenObject.objectId()!=DBTOKEN_OBJECT_TOKENINFO)
if (!tokenObject.createTables() || !tokenObject.migrateTables() || !tokenObject.insert() || tokenObject.objectId()!=DBTOKEN_OBJECT_TOKENINFO)
{
tokenObject.dropConnection();

Expand Down Expand Up @@ -211,7 +211,7 @@ DBToken::DBToken(const std::string &baseDir, const std::string &tokenName, int u
DBObject tokenObject(_connection);

// First find the token obect that indicates the token is properly initialized.
if (!tokenObject.find(DBTOKEN_OBJECT_TOKENINFO))
if (!tokenObject.find(DBTOKEN_OBJECT_TOKENINFO) || !tokenObject.migrateTables())
{
tokenObject.dropConnection();

Expand Down
Loading