1

in the past we used a (windows) package using CryptLib to handle RSA encryption. Now we want to transfer our clients to a new platform where using CryptLib is not preferred. We created everything, and the only thing left is importing the private keys.

The keys are stored in CryptLib's keyset store (pkcs#15). When googling around, most (ten year old) mails state thing like "you don't want that", and "the author deliberately prevents that" etc. No software seems to handle pkcs#15, and security provider library-writers don't want to create support because nobody uses it.

There seems to be only way out: store the private key in pfx / pkcs#12 format. That format is supported far better.

To use pkcs#12, you have to enable a flag and recompile the cryptlib dll. I did that, and am able to call the pkcs#12 routines.

I use a delphi wrapper to the dll to make things readable: // load keyset (p15) from disk ks := TCryptKeyset.Create(CRYPT_KEYSET_FILE, pansichar(fname), CRYPT_KEYOPT_NONE);

// get private key from keyset ks
ck := TCryptKey.GetPrivateKey(ks, CRYPT_KEYID_NAME, pansichar('Key'), fpasswd);

// test write to a p15 store
ks2 := TCryptKeyset.Create(CRYPT_KEYSET_FILE, 'test.p15', CRYPT_KEYOPT_CREATE );
ks2.AddPrivateKey(ck, 'fiets');

// test write to p12 store
ks3 := TCryptKeyset.Create(CRYPT_KEYSET_FILE, 'test.p12', CRYPT_KEYOPT_CREATE );
ks3.AddPrivateKey(ck, 'fiets'); // <--- fails with error

The first test is with writing a p15 store, and that works well (the store created is almost identical to the original one, except of course the password had been changed). But the second write to the p12 store gets an error. If I trace down the source, it has to do with the private key I provide being seen as a certificate. And because no private key is present yet, it fails with the following error.

I hope someone has ever used the pcs#12 features of cryptlib, or knows another way to handle this situation. It's no problem if the solution is in python, php, c#, delphi...

UPDATE 22 april 2014 I have used the C# wrapper of cryptlib self, and rewrote the code (in case the Delphi wrapper caused trouble), but I got the same result :(

    static void Main(string[] args)
    {
        int ks_ptr = 0;
        int ks_pvk = 0;
        int ks12_ptr = 0;
        try
        {

            Console.WriteLine("Initializing...");
            crypt.Init();
            Console.WriteLine("Loading keystore");
            ks_ptr = crypt.KeysetOpen(crypt.UNUSED, crypt.KEYSET_FILE, "privatekey.key", crypt.KEYOPT_NONE);
            Console.WriteLine("Loading private key");
            ks_pvk = crypt.GetPrivateKey(ks_ptr, crypt.KEYID_NAME, "Key", pwd);

            Console.WriteLine("Creating new keystore");
            ks12_ptr = crypt.KeysetOpen(crypt.UNUSED, crypt.KEYSET_FILE, "privatekey.pfx", crypt.KEYOPT_CREATE);

            Console.WriteLine("Saving private key");
            crypt.AddPrivateKey(ks12_ptr, ks_pvk, "mylittlesecret");
        }
        catch (CryptException ce)
        {
            Console.WriteLine("Exception: "+ce.Message);
            Console.WriteLine("Status writingkeystore: " + GetStatusFor(ks12_ptr));
        }
        Console.WriteLine("Done. Press a key to quit.");
        Console.ReadKey();
    }

UPDATE #2

Looking through the tests, a .p12 IS generated in the tests. With some fiddling also for a brand new .p12 file. But the original key is read from the .p12, so it might contain info that is needed to write the file back... Let check some more...

UPDATE #3 Modified the unittests of cryptlib to get the test private key from my .p15 keystore and then write it to the p12 keystore, but it seems that when setting the private key, an empty pkcs12_info structure is passed to the set item function.

Pfff, I hope somebody has any pointers...

Hugo Logmans
  • 2,202
  • 1
  • 19
  • 14
  • I haven't used a .p15 before. My suggestion might be trivial. Instead of .p12 try .pfx? Were you able to import your .p15 file in to Microsoft key store? If yes, then you can export them back as PFX, provided the private keys are marked exportable. – Raj Apr 18 '14 at 06:59
  • @Raj, thanks for your comment. I did try the pfx option, but that has the same result. For the second part: I have not found ANY software that is able to handle the pkcs#15 file format, except software that use CryptLib. – Hugo Logmans Apr 18 '14 at 13:46
  • use cryptolib and import pkcs#15 in windows key store, then try and export the private key via MMC? – Raj Apr 18 '14 at 13:48
  • If I google cryptolib I get mostly nonmaintained packages, and combining it with p15 or pkcs#15 gives no useful results at all. Which cryptolib package do you refer to? – Hugo Logmans Apr 18 '14 at 14:09
  • I am sorry Hugo, It was a typo in my previous comment, I was referring to your library, Cryptlib. – Raj Apr 21 '14 at 06:46
  • The author of cryptlib has a certain opinion about Microsoft, so that's not supported either (import in windows keystore) – Hugo Logmans Apr 22 '14 at 08:55
  • 1
    In the end I succeeded by implementing a pkcs#15 asn structure reader, getting the certs and private keys and export them to other formats. So I did not use the Cryptlib package anymore. – Hugo Logmans Apr 25 '14 at 14:32
  • Great. please share your comment with some piece of code, so that others who are in your state will benefit. – Raj Apr 28 '14 at 10:12

0 Answers0