예제 #1
0
	Ods::pag* CryptoManager::encrypt(ISC_STATUS* sv, Ods::pag* from, Ods::pag* to)
	{
		// Code calling us is not ready to process exceptions correctly
		// Therefore use old (status vector based) method
		try
		{
			if (crypt && cryptPlugin && Ods::pag_crypt_page[from->pag_type % (pag_max + 1)])
			{
				to[0] = from[0];

				LocalStatus status;
				cryptPlugin->encrypt(&status, dbb.dbb_page_size - sizeof(Ods::pag), &from[1], &to[1]);
				if (!status.isSuccess())
				{
					memcpy(sv, status.get(), sizeof(ISC_STATUS_ARRAY));
					return NULL;
				}

				to->pag_flags |= Ods::crypted_page;
				return to;
			}
			else
			{
				from->pag_flags &= ~Ods::crypted_page;
				return from;
			}
		}
		catch (const Exception& ex)
		{
			ex.stuff_exception(sv);
		}
		return NULL;
	}
예제 #2
0
	bool CryptoManager::decrypt(ISC_STATUS* sv, Ods::pag* page)
	{
		// Code calling us is not ready to process exceptions correctly
		// Therefore use old (status vector based) method
		try
		{
			if (page->pag_flags & Ods::crypted_page)
			{
				if (!cryptPlugin)
				{
					// We are invoked from shared cache manager, i.e. no valid attachment in tdbb
					// Therefore create system temporary attachment like in crypt thread to be able to work with locks
					UserId user;
					user.usr_user_name = "(Crypt plugin loader)";

					Jrd::Attachment* const attachment = Jrd::Attachment::create(&dbb);
					RefPtr<SysAttachment> jAtt(new SysAttachment(attachment));
					attachment->att_interface = jAtt;
					attachment->att_filename = dbb.dbb_filename;
					attachment->att_user = &user;

					BackgroundContextHolder tdbb(&dbb, attachment, sv, FB_FUNCTION);

					// Lock crypt state
					takeStateLock(tdbb);

					Header hdr(tdbb, LCK_read);
					crypt = hdr->hdr_flags & Ods::hdr_encrypted;
					process = hdr->hdr_flags & Ods::hdr_crypt_process;

					if (crypt || process)
					{
						loadPlugin(hdr->hdr_crypt_plugin);
					}

					if (!cryptPlugin)
					{
						(Arg::Gds(isc_decrypt_error)).raise();
						return false;
					}
				}

				LocalStatus status;
				cryptPlugin->decrypt(&status, dbb.dbb_page_size - sizeof(Ods::pag), &page[1], &page[1]);
				if (!status.isSuccess())
				{
					memcpy(sv, status.get(), sizeof(ISC_STATUS_ARRAY));
					return false;
				}
			}

			return true;
		}
		catch (const Exception& ex)
		{
			ex.stuff_exception(sv);
		}
		return false;
	}
예제 #3
0
	void CryptoManager::KeyHolderPlugins::init(IDbCryptPlugin* crypt)
	{
		MutexLockGuard g(holdersMutex, FB_FUNCTION);

		Firebird::HalfStaticArray<Firebird::IKeyHolderPlugin*, 64> holdersVector;
		unsigned int length = knownHolders.getCount();
		IKeyHolderPlugin** vector = holdersVector.getBuffer(length);
		for (unsigned i = 0; i < length; ++i)
		{
			vector[i] = knownHolders[i].getPlugin();
		}

		LocalStatus st;
		crypt->setKey(&st, length, vector);
		if (!st.isSuccess())
		{
			status_exception::raise(st.get());
		}
	}
예제 #4
0
	void CryptoManager::KeyHolderPlugins::attach(Attachment* att, Config* config)
	{
		MutexLockGuard g(holdersMutex, FB_FUNCTION);

		for (GetPlugins<IKeyHolderPlugin> keyControl(PluginType::KeyHolder,
			FB_KEYHOLDER_PLUGIN_VERSION, upInfo, config); keyControl.hasData(); keyControl.next())
		{
			IKeyHolderPlugin* keyPlugin = keyControl.plugin();
			LocalStatus st;
			if (keyPlugin->keyCallback(&st, att->att_crypt_callback) == 1)
			{
				// holder accepted attachment's key
				HolderAttachments* ha = NULL;

				for (unsigned i = 0; i < knownHolders.getCount(); ++i)
				{
					if (knownHolders[i] == keyPlugin)
					{
						ha = &knownHolders[i];
						break;
					}
				}

				if (!ha)
				{
					ha = &(knownHolders.add());
					ha->setPlugin(keyPlugin);
				}

				ha->registerAttachment(att);
				break;		// Do not need >1 key from attachment to single DB
			}
			else if (!st.isSuccess())
			{
				status_exception::raise(st.get());
			}
		}
	}