Hi all, I'm currently writing an openPGP client in .NET, and trying to use the BouncyCastle C# v1.7 implementation for the crypto. For reasons of requiring that I target a specific .NET version, I had to recompile the library from source (a few, mostly trivial, changes were made to get it to compile).[1]
I've gotten it to open and parse key data correctly, but it's throwing an exception when trying to parse encrypted or signed data. Note that I'm not trying to actually decrypt/verify the data, just read the packets of the input stream. This happens both with my own files (generated using gpg) and with the signed test files that come with the source. The exception is IOException:"unknown PGP public key algorithm encountered". The stack trace is as follows (namespaces and paths excluded due to me needing to transcribe this all): PublicKeyPacket.PublicKeyPacket(BcpgInputStream) @ line 50 BcpgInputStream.ReadPacket() @ line 220 PgpPublicKeyRing.PgpPublicKeyRing(inputStream) @ line 48 PgpObjectFactory.NextPgpObject() @ line 76 PgpObjectFactory.AllPgpObjects() @ line 136 The reason for the exception is a switch statement on a variable called "algorithm" falling through the bottom. The variable is typed as a PublicKeyAlgorithmTag (enum), but it has (depending on the file I test with) values such as 129, 221, or 120, which don't map to any value of the enum. The actual key algorithms used are ELG-E, RSA, and DSA, respectively (according to GPG). The value is the same for different files signed with the same key, at least in my testing so far, but different for files signed by other keys of the same type (but different bit length on the asymmetric key). I'm not very familiar at all with the binary structure of openpgp data, so I'm hoping somebody out there can help me figure out what is going on here. Is the value not being masked and/or bit-shifted in a way that it should be? Is the wrong value being read from the stream? I suspect that the latter possibility is correct, as the code accurately identifies the key types when parsing a file that's just a bunch of exported keys. If anybody could help me out with this, I'd be greatly appreciative. Thank you, Chris [1]: The target platform is Windows Runtime, the API family for Windows Store apps. When using it with C#, the API is basically a subset of .NET 4.5. The preprocessor define for this platform is NETFX_CORE. My changes mostly consisted of things like replacing deprecated functions with their new forms, and generally only concerned manipulating strings (I had to add Platform.ToUpperInvariant(String) because it's now done differently, for example) and finishing working with streams (Close() is now deprecated; just destruct or explicitly call Dispose()). I also had to remove (#if exclude) a bit of code that tried to do things which Store apps aren't permitted to do generally, such as talk to the system PKI stores. I did have to make one change to actual crypto code; the entire System.Threading.Thread class is now deprecated, so the core of the ThreadedSeedGenerator RNG, which operates on the timing differences between threads, had to be re-written. I'm moderately familiar with the approach, but cannot promise that my implementation (using the new Tasks API for asynchronous code) is correct. None of this should have any impact on processing a binary stream while it is still open, however. With that said, if anybody would like (now, or when I get it working...) I'm happy to return my changes to the community. I can't easily generate a diff or patch at this time, but I could do so later. I imagine there will be others attempting to use this API (which is, I believe, also the target API for Windows Phone 8 apps, unlike the Silverlight API used for WP7) in the future, and would like to help them out.
