Using HKP OpenPGP key servers in C# and VB.NET

The first OpenPGP key server based on the HTTP protocol was implemented by Marc Horowitz and a draft version of the protocol HKP (OpenPGP HTTP Keyserver Protocol) can be found at: https://tools.ietf.org/html/draft-shaw-openpgp-hkp-00

This chapter illustrates how to exchange keys with HKP based key servers with the help of DidiSoft OpenPGP Library for .NET. The functionality is available in the class HkpClient located in the namespace DidiSoft.Pgp.Net.

1. HkpClient
2. Searching for a key
3. Uploading a key
4. Timeout
5. Exception handling

HkpClient

The DidiSoft.Pgp.Net.HkpClient class is used for accessing HKP key servers. The class can be instantiated with or without protocol specification before the server name (or IP).

DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("pgp.mit.edu", 80);

this is equal to.

DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("http://pgp.mit.edu");

HTTPS
To access HKP key server with secure connection use

bool secure = true;
DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("hkps.pool.sks-keyservers.net", secure);

this will be equivalent to

DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("https://hkps.pool.sks-keyservers.net");

HKP:// and HKPS:// protocols
As of version 1.7.15.7 you can also specify the HKP protocol like:

DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("hkps://hkps.pool.sks-keyservers.net");

Searching for a key

We can search for a key by referencing it by it’s Key Id, hexadecimal Key Id or part or the whole User Id. The example below illustrates key retrieval with part of the User Id.

C# example

3
4
5
6
7
8
9
10
11
12
13
DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("pgp.mit.edu", 80);
hkp.PartialMatchUserIds = true;
byte[] keyBytes = hkp.GetKeyByUserId("Didisoft");if (keyBytes.Length > 0)
{
   Console.WriteLine("key found");
 
   // example usage of the key
   KeyStore store = new KeyStore();
   store.ImportPublicKey(new MemoryStream(keyBytes));
}

VB.NET example

3
4
5
6
7
8
9
10
11
12
Dim hkp As New DidiSoft.Pgp.Net.HkpClient("pgp.mit.edu", 80)
hkp.PartialMatchUserIds = True
Dim keyBytes As Byte() = hkp.GetKeyByUserId("Didisoft")If (keyBytes.Length > 0) Then
   Console.WriteLine("key found")
 
   ' example usage of the key
   Dim store As New KeyStore()
   store.ImportPublicKey(New MemoryStream(keyBytes))
End If

There may be cases when multiple keys exists on the key server, with the same User ID and the above example will retrieve only the first one. If we need to obtain all keys, we have to use the method GetKeysByUserId and import them in the KeyStore with the method KeyStore.ImportKeyRing.

A key can also be searched by its hexadecimal Key ID with the method HkpClient.GetKeyByKeyIdHex.

Uploading a key

The key upload is simply invoking the method SubmitKey of the HkpClient class. According to RFC 4387 the submitted keys have to be in ASCII armored format.

C# example

DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("pgp.mit.edu", 80);
hkp.SubmitKey(File.ReadAllBytes(@"c:\Test\My_key.asc"));

VB.NET example

Dim hkp As New DidiSoft.Pgp.Net.HkpClient("pgp.mit.edu", 80)
hkp.SubmitKey(File.ReadAllBytes("c:\Test\My_key.asc"))

Timeout

Network communication may experience disruptions and we can control for how long the method calls of the class should wait with the Timeout property. The default value is 20 seconds (20000 milliseconds), and after that time an exception will be thrown.

Here is an example how to set it to 5 seconds:

DidiSoft.Pgp.Net.HkpClient hkp = new DidiSoft.Pgp.Net.HkpClient("pgp.mit.edu");
hkp.Timeout = 5*1000; // 5 seconds = 5000 milliseconds

VB.NET example

Dim hkp As New DidiSoft.Pgp.Net.HkpClient("pgp.mit.edu")
hkp.Timeout = 5*1000 '5 seconds = 5000 milliseconds

Exception handling

All methods for interaction with a HKP key server throw:

System.Net.WebException – in case of a network error

Summary

This chapter was a brief introduction how to exchange keys with HKP OpenPGP keys servers with C# and VB.NET examples.

You may also find useful how to communicate with LDAP OpenPGP key servers.