CK_OBJECT_HANDLE SoftDatabase::importPublicKey(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { // Begin the transaction if(sqlite3_exec(db, "BEGIN IMMEDIATE;", NULL, NULL, NULL) != SQLITE_OK) { return CK_INVALID_HANDLE; } CHECK_DB_RESPONSE(sqlite3_step(insert_object_sql) != SQLITE_DONE); CK_OBJECT_HANDLE objectID = sqlite3_last_insert_rowid(db); sqlite3_reset(insert_object_sql); CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE; CK_DATE emptyDate; CK_MECHANISM_TYPE mechType = CK_UNAVAILABLE_INFORMATION; // Created by db handle and application. So we can remove the correct session objects in the future. CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VENDOR_DEFINED, &db, sizeof(db)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VENDOR_DEFINED+1, appID, strlen(appID)) != CKR_OK); // General information CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_LOCAL, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_KEY_GEN_MECHANISM, &mechType, sizeof(mechType)) != CKR_OK); // Default values, may be changed by the template. CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_LABEL, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_ID, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_SUBJECT, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_PRIVATE, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_MODIFIABLE, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_TOKEN, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_DERIVE, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_ENCRYPT, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VERIFY, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VERIFY_RECOVER, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_WRAP, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_TRUSTED, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_START_DATE, &emptyDate, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_END_DATE, &emptyDate, 0) != CKR_OK); // Extract the attributes for(CK_ULONG i = 0; i < ulCount; i++) { if(pTemplate[i].type == CKA_MODULUS) { Botan::BigInt bigModulus = Botan::BigInt(0); bigModulus.binary_decode((Botan::byte*)pTemplate[i].pValue, pTemplate[i].ulValueLen); CK_ULONG bits = bigModulus.bits(); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_MODULUS_BITS, &bits, sizeof(bits)) != CKR_OK); } CHECK_DB_RESPONSE(this->saveAttribute(objectID, pTemplate[i].type, pTemplate[i].pValue, pTemplate[i].ulValueLen) != CKR_OK); } sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); return objectID; }