We’ve already had a few posts describing the DRT and what it does, but now we can actually show it off! This post is designed to provide a brief but useful look at the DRT SDK Sample.
The DRT SDK Sample demonstrates how to:
· Initialize the DRT_SETTINGS structure
· Use and attach a variety security and bootstrap providers
· Add an exception for the DRT to the Windows Firewall
· Register and unregister keys in the DRT
· Perform various types of DRT Searches
Each time the sample is executed, it creates one DRT node. In order to create a useful DRT, multiple nodes are required. These can be run either locally with multiple nodes on the same machine, or across a network with nodes on different machines.
Upon startup, the DRT SDK Sample prompts for which security provider to use. The security provider is used both for identity verification, to ensure that a node has the right to participate in the DRT, and for confidentiality of the DRT payload. The sample has three security provider options:
· Null Security Provider – A bare-bones security provider that allows any node to publish any key. It does not perform any encryption on the DRT payload, and is useful for debugging and prototyping.
· Derived Key Security Provider – This provider secures keys using X.509 certificates, and chains them to a common root. Nodes can only publish a key if they have a valid X.509 certificate derived from the common root. Also, the key that they publish is derived from the SHA-2 hash of the public key embedded in their certificate. The payload is encrypted using the public/private key pairs. Since this provider requires the generation of certificates, the setup is slightly more complicated. Checkout the section on the derived key security provider below.
· Custom Security Provider – This provider is based on the null security provider. It is also a bare bones security provider that only performs serialization of the data, without encryption. The difference is that the code for this provider is available in CustomSecurityProvider.cpp and provides a useful base for the creation of a customized security provider.
Derived Key Security Provider
The DRT SDK Sample contains code to automatically generate certificates when using the Derived Key Security Provider (DKSP). The certificates will be generated and saved in the current directory. Therefore, when using the DKSP, each DRT Instance should be started in its own folder.
As mentioned above, the DKSP requires the certificates of all instances to be derived from a common root certificate. The easiest way to accomplish this is to start one DRT Instance using the DKSP. Both a root and client cert will be generated. Then simply copy the root certificate into the folder of each of the other DRT Instances before starting them. If a root cert already exists, the DRT SDK Sample will generate client certs based on that root cert.
In order to join an existing DRT, a new DRT node must be able to “discover” peers that are already joined to the DRT. This is the role of the bootstrap provider. A new DRT node can bootstrap from any already joined DRT node that is currently publishing a key.
· DNS Bootstrap Provider – The DNS bootstrap provider bootstraps using DNS. It accepts the computer name, either a FQDN or the hostname of a computer on a local network as well as the port that the remote DRT instance is listening on.
· PNRP Bootstrap Provider – The Peer Name Resolution Protocol (PNRP) bootstrap provider uses PNRP to bootstrap the DRT. It accepts the peer name (for example 0.somename), performs a PNRP resolve for that name, and then bootstraps from one of the endpoints that it finds. *To use the PNRP bootstrap provider the PNRP port, 3540, must be opened in the Windows Firewall. The sample will open the firewall as necessary provided it has sufficient privileges.
· Custom Bootstrap Provider – The custom bootstrap provider is based on the DNS bootstrap provider. The difference is that the code is available in CustomBootstrapper.cpp, and is a useful example of how to write an application-specific bootstrap provider.
After selection of a security provider and bootstrap provider, the DRT will attempt to bootstrap. If other peers cannot be found, the DRT will transition to the ALONE state. This is expected for the first DRT instance that is started since no other nodes exist in the mesh.
The first DRT instance should publish a key so that subsequent instances can bootstrap from it. This can be accomplished by choosing menu option 1. In the case of the Null Security Provider or Custom Security provider, choosing option 1 will produce a prompt for a DRT Key to register. If the Derived Key Security Provider is used, a new certificate will be generated based on the root cert, and a DRT Key based on a hash of the newly generated cert will be published.
Subsequent DRT Instances should transition to the active state as they join the mesh.
The DRT key space is circular and each key is 256 bits. A wide variety of searches can be performed by specifying various options in the DRT_SEARCH_INFO structure. The DRT SDK Sample highlights the most commonly used scenarios:
· Simple DRT Search – This search uses the default options for the DRT_SEARCH_INFO structure. It is an exact match search throughout the entire number space except that it will exclude keys published by the current DRT Instance.
· Nearest Match Search – This search also searches throughout the entire number space for a key, but rather than failing if the exact key is not found, it will return the closest key that exists to the one that was specified. This search can be modified to return more than one nearest match by changing SearchInfo.cMaxEndpoints.
· Iterative Search – This search is the same as the Simple DRT Search except that it will fire the SearchEvent, and provide an intermediate match, for each hop during the search.
· Range Search – This search prompts for a target key, and a min key and max key for the range. This search will return the first match it finds that falls within the specified range. Since the number space is circular, min and max have no real meaning. Thus, the target key is used to determine which “side” of the range to search. This search also can be modified to return the closest key to the target within the specified range by setting SearchInfo.fAnyMatchInRange to FALSE.
Hopefully, this post gives a good overview of how to use the DRT SDK Sample, and helps to highlight some of the basic uses of the DRT. Although the SDK Sample covers many different security providers, bootstrap providers, and search types, we tried to keep the code easy to read and straightforward. I look forward to your questions and comments.