Certificate-based key provider plugin

Mark B
  • Mark B

    Mark B - 2009-07-07

    Finally got around to doing this.  Dominik, the code changes worked great -- thanks.

    The binary, which can be used with KeePass 2.0.8 (21738), is at

    The DLL should be dropped into wherever KeePass is intalled (whereever KeePass.exe lives).

    When you create a database and select the certificates for which to encrypt the key, the code will attempt to check the validity of the certificate, including revocation list checks.  This is usually very quick, unless you're offline.

    I put up the source at

    The source is meant to be extracted into the ext folder.

    Dominik, one small bug report ... in RememberKeyFilePath (MainForm_Functions.cs), we invoke AceKeyFilePath.SetKeyFilePath with the name of the key provider plugin.  It then incorrectly gets expanded to a filename, and when I go to open database, it complains about the key file not being found.  Should be an easy fix ... we just need to check whether the name is a key provider.

    One other thought while working on this is that it may be a good idea to restructure the existing "key file" mechanism as a plugin.  Even if it's a built-in plugin that's always added to the plugin manager.  The benefit is that the main code would be simplified and the "Create" button would work equally for all plugins.  If you think this is a good idea, I can help with the code.

    Give it a try and let me know what you think!  If you think others may be interested, you can put it up KeePass plugins page.

    Of course, you are using it at your own risk, etc. etc.


    • Dominik Reichl

      Dominik Reichl - 2009-07-09

      Impressive plugin, thanks a lot!

      I've added it to the KeePass plugins page:

      I've also added the bug to my to-do list. The key file mechanism in my opinion is fine as it is.

      Best regards

    • Dominik Reichl

      Dominik Reichl - 2009-07-28

      On the bug: I've fixed it now. KeePass 2.09 will remember key files and providers in separate nodes in the configuration file. This is necessary, because KeePass can't decide at configuration loading time whether the remembered item is a key file or a provider (because plugins aren't loaded at this time yet, and must not, as the configuration file specifies whether plugins should be loaded or not).

      Here's the latest development snapshot for testing:

      Thanks and best regards

    • Kirby

      Kirby - 2009-08-04

      I've downloaded the snapshot but it tells me that the Plugin is not compatible :(
      I think this means that the plugin must be recompiled?

      Kind regards,

      • Mark B

        Mark B - 2009-08-09

        I recompiled the plugin to work with the 090728 development snapshot:


        Dominik -- your fix seems to work well except for one issue -- when I lock and then unlock the database, there's often a delay before the "Open Database" dialog selects the plugin (or even before it adds it to the drop down list).  Not quite sure why, the time it takes for the plugin to appear seems random.

    • Paul

      Paul - 2009-08-04

      Are you using KeePass 2.08?

      cheers, Paul

    • Piotr

      Piotr - 2009-08-11

      Is there a way to compile a pluging so that it could be loaded in more then one keepass version?

      In the plugin reference to keepass there is an option:
      Specific Version = false

      but when the pluging is loaded into a different keepass ver. then the one compiled for
      ObjectHandle oh = Activator.CreateInstanceFrom(strFilePath, strType); //PluginMenager.cs
      throughs an exeption.

      Any suggestion?

      Piotr J.

    • Dominik Reichl

      Dominik Reichl - 2009-08-16

      Mark, KeePass by default searches all drives/disks for key files. This might cause the delay. You could try disabling the option "Automatically search key files on removable media" in Options -> Advanced.

      Piotr, there's unfortunately no way to do this. As you've already seen (Activator), .NET assemblies are always referenced by exact version (which you can't specify manually -- think of a hash of the file as version number). In order to avoid this, plugins would need to be made independent of the KeePass assembly -- not only you'd then had to use a very limited set of APIs (which need to be defined independently of KeePass), but also you'd soon run into a mess of plugin interface DLLs (each time the API is changed, a new DLL file would be required). No solution in my opinion.

      Best regards

      • Mark B

        Mark B - 2009-08-17

        Thanks Dominik, that makes sense.

        One other request ... I had a person contact me who uses the 'Open URL' to open the password database.  For that, it would be handy if the encrypted key file could be stored in the same place (and accessed through a URL instead of through a local disk file).   That's easy enough ... the only catch is that the username/pwd is probably the same for the key file as for the database but it's not available in the plugin.  I can see options -- pass IOConnectionInfo to the plugin through the KeyProviderQueryContext, or throw up a form in the plugin to ask the user again.  My preference would be to pass the IOConnectionInfo through the context.

        Btw, interesting conversation on compiling plugins dynamically.  I did this project out of personal need as well as to learn C# and .NET and I spent a fair bit of time investigating how to compile my plugin to be version independent.  I came to much the same conclusion as you did.  The only viable alternative I could find is policy files to override the version at runtime.

        One aspect to consider when discussing compiling plugins on the fly is the fact that assemblies can be signed (e.g., using signtool.exe) and so (potentially) users could have some assurance that the code hasn't been tampered with and comes from a source they trust (I realize I don't do this with my plugin right now).   It would be good if there was some ability to sign the source code as well if that's how plugins are distributed.  Of course, users could always inspect the code they download to ensure it doesn't do anything bad, but that's not practical for most.

    • Piotr

      Piotr - 2009-08-16

      Dominik, I was tring to thing of a solution. I was looking at binding redirectes and other stuff. So far no luck.

      Just now I found this:

      I will have to play around with it some more but an idea would be as following:
      to be able to load the pluging either as a dll or as a cs file that would be compiled at the be keepass at the start. I will see if it would work and it's speed.  Any thoughts?

      Piotr J.

    • Dominik Reichl

      Dominik Reichl - 2009-08-16

      This is a really interesting idea! I already used this stuff in KPScript for compiling KPS script files, and am pretty sure that it would work for plugins, too. Disadvantages are that the plugin then has to be open source (but I guess this is a requirement for most people anyway), that only plugins written in C# and VB would be able to benefit from this new feature, and that it probably won't work with Mono (?). Also, I'm not sure whether the compiler is available in all .NET frameworks (especially in the client profile?).

      Anyway, as optional file format the advantages would be huge. I don't think performance is a problem -- on the one hand the C# compiler is extremely fast, and on the other hand the plugin DLL needs to be generated once only anyway (so we could save it to some cache directory). Ideally a plugin developer would just pack the whole plugin source code into a ZIP and rename the file to PLGX or something. KeePass could then compile the assembly based on the CSPROJ file... I'll try implementing something like that in the next days.

      Thanks and best regards

    • Piotr

      Piotr - 2009-08-16

      Sounds realy nice.
      I was thinghing about compliling olny into memory but caching it on the disk would be nice. But checking if the original plgx content hadn't change would also be good.

      Also a thought about integrity check like a special file inside a zip with hashes of the rest of file. Or some form of signing the plgx file. And mayby having the ability to limit plgx to some kp versions. Just some random thoughts.

      By the way - with the csproj file that could be a lot of work to implement.

      Looking forward to this new feature.
      Piotr J.

    • Piotr

      Piotr - 2009-08-16

      Seems like there are ways for Mono >2.2:


    • Dominik Reichl

      Dominik Reichl - 2009-08-17

      The current forum is confusing... Now my previous reply got moved below later replies, mixing up their order... :-(

      I've now added a DatabaseIOInfo to the key provider query context object, which allows you to access the IOConnectionInfo of the database. Thanks for the suggestion!

      Here's the latest 2.x development snapshot for testing:

      Best regards

    • Dominik Reichl

      Dominik Reichl - 2009-08-20

      I've finished the first version of PLGX. See detailed post:

      Best regards

  • PuhL

    PuhL - 2009-10-25

    Mark, can you recompile your plugin to be compatible with KP v.2.09 or make it in plgx format?
    Seems that your plugin is the only correct way to use a fingerprint sensor.
    Thanks in advance.

    With best regards

  • RoninMC

    RoninMC - 2012-08-20

    Hi Mark,

    great plugin. Lovin' it! I was hoping you could answer me a question though…

    I'm trying to encrypt a DB for several certificates choosing "certificate-protected key". After clicking "OK" it will generate the .p7mkey File and open a dialog where I can select the certificates for encryption. But no matter how many certificates I keep moving around in my MS certificate stores with certmgr.msc they won't show up in the dialog.
    I can only select my personal certificate and a general certificate of my company.

    Am I doing something wrong? Wasn't able to find a clue on the web…

    Thanks for your help. Greatly appreciated,


Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks