A key provider plugin can offer one or more keys. In the screenshot on the
right, the plugin has added the options 'Certificate', 'Smart Card'
and 'User Credentials' to the key files combo box. It is possible for
your plugin to show additional file selection dialog boxes, etc., however
it is recommended that you provide keys directly, so that a user has just
to pick it from the combo box (like KeePass offers multiple file locations already).

Each time the master key dialog opens, KeePass first queries information
from all plugins using the KPM_KEYPROV_QUERY_INFO_FIRST and
KPM_KEYPROV_QUERY_INFO_NEXT messages. The information you supply in
response to these messages is shown in the key files combo box.
When the user selects one of the options you provide and clicks [OK], KeePass will
send a KPM_KEYPROV_QUERY_KEY message to your plugin to actually get
the key. For details, see the sections below. When the dialog is closed, you
get a KPM_KEYPROV_FINALIZE message, in which you can clean up
any cached keys.

Sample
Source Code

Here's the source code of a very simple key provider plugin for KeePass.
Note that this source code cannot be compiled as is, because a few code blocks
have been left out. The complete version is part of the downloadable
sample key provider
Visual C++ 2005 project.

KPM_KEYPROV_QUERY_INFO_FIRST
and KPM_KEYPROV_QUERY_INFO_NEXT Messages

These two messages are used to query information about the
keys you provide. The KPM_KEYPROV_QUERY_INFO_FIRST message
is sent once, afterwards the KPM_KEYPROV_QUERY_INFO_NEXT message
is sent repeatedly until you don't provide a new key any more.
The parameters are the same for both messages:

lParamW [in]: NULL. Reserved for future use.

lParamL [out]: Pointer to a KP_KEYPROV_INFO structure.

You need to fill out the KP_KEYPROV_INFO structure in
lParamL. If you don't want to return a provider, simply leave this structure untouched.

KPM_KEYPROV_QUERY_KEY
Message

This message is sent to your plugin when the user has selected one of
the keys you provide and has clicked [OK]. Parameters:

lParamW [in]: Pointer to a string: displayed name in the combo box that has been selected.

lParamL [out]: Pointer to a KP_KEYPROV_KEY structure.

You should fill out the KP_KEYPROV_KEY structure
in lParamL in order to return a key.

KPM_KEYPROV_QUERY_KEY_EX
Message

This message is sent to your plugin when the user has selected one of
the keys you provide and has clicked [OK]. Parameters:

lParamW [in]: Pointer to a KP_KEYPROV_CONTEXT structure.

lParamL [out]: Pointer to a KP_KEYPROV_KEY structure.

You should fill out the KP_KEYPROV_KEY structure
in lParamL in order to return a key.

This message is an extended version of the KPM_KEYPROV_QUERY_KEY
message. Its lParamW is a pointer to a KP_KEYPROV_CONTEXT,
which contains more information about the requested key and context.

Your plugin should either reply to KPM_KEYPROV_QUERY_KEY
or to KPM_KEYPROV_QUERY_KEY_EX.

KP_KEYPROV_INFO
Structure

Each key that you provide (certificate, smart card, ...) must be registered by responding
to KPM_KEYPROV_QUERY_INFO_FIRST and KPM_KEYPROV_QUERY_INFO_NEXT
messages by filling out the structure in lParamL. This structure looks like the following:

DWORD dwFlags: Reserved for future use, must be 0.

LPCTSTR lpName: Unique display name of the key.

DWORD dwImageIndex: Index of the icon shown in the combo box.

DWORD dwReserved: Reserved for future use, must be 0.

Make sure that the lpName pointer you return is still valid when KeePass
tries to read from it. The message processing function will already be finished when
KeePass reads the pointer, therefore you should store the name in some global/static
place.

Icon IDs specify the
index of the icon in the built-in icons list of KeePass that is used in the combo box.
Custom icons are not supported.

Returning
a Key In KP_KEYPROV_KEY

In the KPM_KEYPROV_QUERY_KEY message, you need to return the actual key
by filling out the KP_KEYPROV_KEY structure in
lParamL.

DWORD dwType: Reserved for future use, must be 0.

DWORD dwFormat: Reserved for future use, must be 0.

LPVOID lpData: Key data pointer.

DWORD dwDataSize: Size of the key (lpData) in bytes.

DWORD dwReserved: Reserved for future use, must be 0.

Make sure that the lpData pointer you return is still valid when KeePass
tries to read from it. The message processing function will already be finished when
KeePass reads the pointer, therefore you should store the key data in some global/static
place.

You can clean up the global/static memory when you get the
KPM_KEYPROV_FINALIZE message (it is sent when the dialog is closed
and KeePass has successfully copied the key you provided). It is highly recommended
that you zeroize out key memory before releasing it.