On June 11, 2010 5:56 PM, Chad La Joie wrote: > On 6/4/10 9:15 AM, Pellerin, Clement wrote: > > What is the recommended way to implement a KeyResolver for an EncryptedKey > > where the KEK is a PublicKey? > > > > At first I thought I could write a Resolver for the KEK PrivateKey and let > > the EncryptedKeyResolver call it. > > Unfortunately, the KeyResolverSpi API can return a SecretKey but there is > > no provision to return a PrivateKey. > > Can we augment the KeyResolverSpi with a new method > > engineLookupAndResolvePrivateKey()? > > This method would be called by the EncryptedKeyResolver when it detects the > > KeyWrap algorithm rsa-1_5 > > or rsa-oaep-mgf1p. This change looks possible since KeyResolverSpi is a > > class not an interface. > > I think the only way to do what you're asking for would be to add the > additional methods to KeyResolver and KeyResolverSpi. Since the > KeyResolverSpi is an abstract class, adding a no-op > engineLookupAndResolvePrivateKey and engineResolvePrivateKey wouldn't > break API compatibility with. Same with adding the analogous > resolvePrivateKey method on KeyResolver. > > > In the meantime, I tried to replace the EncryptedKeyResolver with my own > > implementation. > > Again, I've hit a problem because I need the symmetric key algorithm. > > Normally this is passed to the constructor of a temporary > > EncryptedKeyResolver in the method > > XMLCipher.decryptToByteArray(): > > ki.registerInternalKeyResolver( > > new EncryptedKeyResolver( > > > > encryptedData.getEncryptionMethod().getAlgorithm(), > > _kek)); > > As you can see, the constructor is called directly. > > If you don't like my idea of a PrivateKey resolver, can we at least move > > that constructor call > > to a new protected method on XMLCipher so we could override it in a > > subclass? > > Whether a private key resolution method was added to the KeyResolver I'd > recommend moving the construction of the KEK resolver to a method > anyways. Given some of the complexities surrounding key resolution > within XML encryption it's certainly not hard to imagine some else down > the road will need a hook like that.
This validates my approach. I would like to point out something about the new factory method to create the EncryptedKeyResolver. XMLCipher already has many similar methods but they are all for interfaces. This would be the first factory method to create a class. Other classes could also make use of a factory method. I can think of KeyInfo for example. XMLCipher.createKeyInfo() would be a great hook to attach thread-specific KeyResolvers. Once the KeyResolver can return a PrivateKey, we have to ask ourselves where does it get it from. My first reaction was to write a KeyStoreKeyResolver that would know how to find a PrivateKey within a KeyStore passed in the constructor. I soon realized this collided with the existing KeyResolvers. It makes more sense to extend the existing KeyResolvers to resolve PrivateKeys than to introduce a super KeyResolver that knows how to return a PrivateKey for any kind of hint. KeyStoreKeyResolver was dead born. Now that we know X509IssuerSerialResolver must resolve PrivateKeys, where does it get it from? I believe the answer is: the same place where it gets the list of certificates. My proposal is to augument the StorageResolver to return an iterator that iterates over the PrivateKeys. For completeness, we would need a third iterator for the SymmetricKeys. When I looked at KeyStoreResolver, I was surprised to find it is not thread-safe. The code expects the user to be single-threaded or else it must create a new StorageResolver and a new KeyStoreResolver each time. I think this is very error prone. It is very tempting for the user to create his StorageResolver once and reuse it all the time. I suggest we make StorageResolver.hasNext() and next() deprecated. I also suggest a new iterator should be returned every time StorageResolver.getIterator() is called. Similarly, a new iterator should be returned every time StoreResolverSpi.getIterator() is called (see KeyStoreResolver for example).