Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unknown PGP public key algorithm encountered (EDDSA?) #73

Open
jstedfast opened this issue Apr 1, 2017 · 8 comments
Open

unknown PGP public key algorithm encountered (EDDSA?) #73

jstedfast opened this issue Apr 1, 2017 · 8 comments

Comments

@jstedfast
Copy link
Contributor

I'm working on adding logic to MimeKit to automatically fetch keys from a keyserver and import them when verifying signatures if an unknown key id is encountered (assuming MimeKit is configured to auto-fetch them).

I keep getting an exception about an unknown PGP public key algorithm when trying to read the returned stream. I modified my local copy of BouncyCastle to include the algorithm id in the IOException that gets thrown and the algorithm tag is 22 which doesn't have a mapping in the PublicKeyAlgorithmTag enum.

I took a quick look at rfc4880 and there does not appear to be an algorithm id of 22.

The following test case illustrates the problem.

Test Case:

using System;
using System.IO;
using System.Net.Http;

using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Bcpg.OpenPgp;

namespace KeyserverLookup {
    class Program
    {
        public static void Main (string[] args)
        {
            using (var stream = new MemoryStream ()) {
                using (var client = new HttpClient ()) {
                    var uri = new UriBuilder ();
                    uri.Scheme = "http";
                    uri.Host = "keys.gnupg.net";
                    uri.Port = 11371;
                    uri.Path = "/pks/lookup";
                    uri.Query = "op=get&search=0x24ECFF5AFF68370A";

                    using (var response = client.GetAsync (uri.ToString ()).GetAwaiter ().GetResult ()) {
                        response.Content.CopyToAsync (stream).GetAwaiter ().GetResult ();
                    }
                }

                stream.Position = 0;

                using (var armored = new ArmoredInputStream (stream)) {
                    var bundle = new PgpPublicKeyRingBundle (armored);

                    foreach (PgpPublicKeyRing keyring in bundle.GetKeyRings ()) {
                        foreach (PgpPublicKey key in keyring.GetPublicKeys ()) {
                            var valid = key.GetValidSeconds ();
                            var ctime = key.CreationTime;
                            var exp = ctime.AddSeconds (valid);
                            var now = DateTime.Now;
                            char algorithm = 'D';

                            if (!key.IsMasterKey && valid > 0 && now > exp)
                                continue;

                            switch (key.Algorithm) {
                            case PublicKeyAlgorithmTag.ECDH: algorithm = 'E'; break;
                            case PublicKeyAlgorithmTag.ElGamalEncrypt:
                            case PublicKeyAlgorithmTag.ElGamalGeneral: algorithm = 'g'; break;
                            case PublicKeyAlgorithmTag.RsaEncrypt:
                            case PublicKeyAlgorithmTag.RsaGeneral: algorithm = 'R'; break;
                            }

                            Console.Write ("{0}   {1}{2}/{3:X8} {4}",
                                key.IsMasterKey ? "pub" : "sub",
                                key.BitStrength,
                                algorithm,
                                (int) key.KeyId,
                                ctime.ToString ("yyyy-MM-dd"));
                            if (key.IsRevoked ()) {
                                Console.WriteLine (" [revoked: {0}]", exp.ToString ("yyyy-MM-dd"));
                            } else if (valid > 0) {
                                Console.WriteLine (" [expires: {0}]", exp.ToString ("yyyy-MM-dd"));
                            } else {
                                Console.WriteLine ();
                            }

                            foreach (string uid in key.GetUserIds ()) {
                                Console.WriteLine ("uid       {0}", uid);
                            }
                        }
			
                        Console.WriteLine ();
                    }
                }
            }
        }
    }
}

Error:

./keyserver-lookup.exe 

Unhandled Exception:
System.IO.IOException: unknown PGP public key algorithm encountered: 22
  at Org.BouncyCastle.Bcpg.PublicKeyPacket..ctor (Org.BouncyCastle.Bcpg.BcpgInputStream bcpgIn) [0x000fa] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.PublicSubkeyPacket..ctor (Org.BouncyCastle.Bcpg.BcpgInputStream bcpgIn) [0x00000] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.BcpgInputStream.ReadPacket () [0x002de] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at (wrapper remoting-invoke-with-check) Org.BouncyCastle.Bcpg.BcpgInputStream:ReadPacket ()
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyRing.ReadSubkey (Org.BouncyCastle.Bcpg.BcpgInputStream bcpgInput) [0x00001] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyRing..ctor (System.IO.Stream inputStream) [0x0009c] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpObjectFactory.NextPgpObject () [0x00123] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpObjectFactory.AllPgpObjects () [0x00013] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyRingBundle..ctor (System.IO.Stream inputStream) [0x00007] in <db94dee80fb04a8f9f9551caee933b45>:0 
  at LoadKeyBlockSample.Program.Main (System.String[] args) [0x000b2] in <69e5296966704328a35074713cc14eaa>:0 
@jstedfast
Copy link
Contributor Author

If I use gpg --export 24ECFF5AFF68370A | gpg --list-packets, I get:

:public sub key packet:
	version 4, algo 22, created 1415374702, expires 0
	unknown algorithm 22

So it definitely looks like a broken packet.

It would be nice if there were a graceful way to handle this, though...

@jstedfast
Copy link
Contributor Author

jstedfast commented Apr 1, 2017

Hmmm, I'm getting the same problem for 0x4F0540D577F95F95 which also hits algorithm 22.

@jstedfast
Copy link
Contributor Author

Looks like algorithm 22 is EDDSA. open-keychain/open-keychain#1279

@jstedfast jstedfast changed the title System.IO.IOException: unknown PGP public key algorithm encountered unknown PGP public key algorithm encountered (EDDSA?) Apr 2, 2017
@jstedfast
Copy link
Contributor Author

Latest draft that I can find: https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04

@jstedfast
Copy link
Contributor Author

FWIW, this is an example file downloaded from a pgp keyserver which illustrates this problem:

pubkey.txt

@jstedfast
Copy link
Contributor Author

Latest draft spec for this: https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-07

@stoyandimov
Copy link

I'm am interacting with Passbolt's API and they cloud server key is apparently also EDDSA. This makes it veeery difficult for me to work with BouncyCastle.

Are there plans to include that algorithm?

@jstedfast
Copy link
Contributor Author

Latest draft spec: https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-09

@stoyandimov I have not heard anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants