Issue Your Own NDN Certificates

Junxiao Shi, posted 2016-07-05

To publish contents into a Named Data Networking (NDN) backbone network, you need to connect your NFD end host to the NDN Testbed, run a local producer application, and let the world reach your NFD through Automatic Prefix Propagation. However, a limitation with NDN Forwarding Daemon (NFD)'s Automatic Prefix Propagation is that, the prefix registered toward your end host is always the identity name of your certificate. While this works fine when you only have one or two machines, two problems arise when you want to deploy multiple end hosts:

  • Every certificate request needs an email verification and manual approval process, which is inconvenient. Or, you can copy your certificate and private key onto every machine, but in case any of these machines is compromised, your one and only private key will be exposed.
  • Certificates requested with the same email address have the same "identity name" and hence Automatic Prefix Propagation would register the same prefix. Unless all your machines serve the same contents, registering the same prefix toward all machines hurts network performance because the router has to rely on flooding and probing to figure out which of your machines serves a certain piece of content.

The solution is to issue your own NDN certificates, and let the world trust them.

The Hierarchical Trust Model

In cryptography, two trust models are widely used:

  • In a centralized trust model adopted by public key infrastructure (PKI), a certificate authority (CA) issues a certificate to a named subject that certifies the subject owns a public key. If you trust a CA, you are trusting all the certificates issued by that CA.
  • In a decentralized trust model used by web of trust (WoT), any user can issue a certificate to another user (the subject). If you trust a few of your friends, you can choose to trust the certificates signed by those friends.

Named Data Network (NDN), at architecture level, is designed to support a variety of trust models, include centralized, decentralized, and anything in between. However, the NDN testbed, as of Jun 2016, is operated with a PKI-like, centralized, hierarchical trust model. There is a single root CA, and then all other certificates are either directly or indirectly signed by this root CA.

For example, my certificate is signed by "The University of Arizona", an intermediate CA, which is in turn signed by "NDN Testbed Root".
/ndn/edu/arizona/KEY/cs/shijunxiao/ksk-1457557007329/ID-CERT
/ndn/KEY/edu/arizona/ksk-1413218886898/ID-CERT

You as an Intermediate CA

Unlike in PKI where intermediate CAs are some "big corporations" and they usually charge you money to obtain a certificate, every NDN certificate can act as an intermediate CA and sign other certificates. This means, as soon as you obtain a trusted certificate on ndncert system, you can issue as many certificates as you need. You can issue a certificate for each of your end hosts, and use those certificates for Automatic Prefix Propagation.

Let's put it to work!

I have already requested a trusted certificate from ndncert and installed it on my machine vps3:

vps3 $ ndnsec list -c
* /ndn/edu/arizona/cs/shijunxiao
  +->* /ndn/edu/arizona/cs/shijunxiao/ksk-1457557007329
       +->* /ndn/edu/arizona/KEY/cs/shijunxiao/ksk-1457557007329/ID-CERT/%FD%00%00%01S%5D+%B3B

I want to issue a certificate to my other machine, sunnyq. To do that, I first generate a certificate request on sunnyq:

sunnyq $ ndnsec key-gen -tr /ndn/edu/arizona/cs/shijunxiao/sunnyq > sunnyq.ndncertreq

Then I copy the certificate request file to vps3, and issue the certificate by signing it with my existing trusted certificate:

vps3 $ ndnsec cert-gen -N '' -s /ndn/edu/arizona/cs/shijunxiao - < sunnyq.ndncertreq > sunnyq.ndncert

Finally I copy the signed certificate back to sunnyq, and install the new certificate:

sunnyq $ ndnsec cert-install sunnyq.ndncert
OK: certificate with name [/ndn/edu/arizona/cs/shijunxiao/KEY/sunnyq/ksk-1467762358121/ID-CERT/%FD%00%00%01U%BDv%27%93] has been successfully installed
sunnyq $ ndnsec list -c
* /ndn/edu/arizona/cs/shijunxiao/sunnyq
  +->* /ndn/edu/arizona/cs/shijunxiao/sunnyq/ksk-1467762358121
       +->* /ndn/edu/arizona/cs/shijunxiao/KEY/sunnyq/ksk-1467762358121/ID-CERT/%FD%00%00%01U%BDv%27%93

At this moment, my machine sunnyq has a certificate that is trusted by the testbed.

Publish the Certificate

With a "trusted" certificate installed on sunnyq, I import the certificate and private key into NFD's KeyChain, and trigger an Automatic Prefix Propagation. However, it isn't working:

1467762966.909510 INFO: [RibManager] Adding route /ndn/edu/arizona/cs/shijunxiao/sunnyq/ping nexthop=266 origin=0 cost=0
1467762966.967302 TRACE: [AutoPrefixPropagator] start propagate /ndn/edu/arizona/cs/shijunxiao/sunnyq
1467762971.064292 TRACE: [AutoPrefixPropagator] fail to propagate /ndn/edu/arizona/cs/shijunxiao/sunnyq
     reason:Cannot fetch cert: /ndn/edu/arizona/cs/shijunxiao/KEY/sunnyq/ksk-1467762358121/ID-CERT
     retry wait time: 50 seconds

The error message says, the Arizona router cannot fetch my sunnyq certificate.

This highlights a difference in how the certificates are collected:

  • When you visit an HTTPS website, the TLS implementation on the web server sends the web server's certificate and the certificates of all intermediate CAs to your browser. Your browser can then verify the signature using those certificates plus the root CA certificate which should already be on your machine.
  • In NDN libraries (as of ndn-cxx 0.4.1), the packet only carries the Name of the signer's certificate. When the prefix registration command is sent to the Arizona router, the signature validation code on the router expresses Interests to retrieve the signer's certificate and intermediate CA certificates as Data packets. If a certificate cannot be retrieved, the router would not be able to verify the signature.

In order to allow the Arizona router to verify the signature on my prefix registration command, I must publish the sunnyq certificate. Two things are needed to publish the certificate: (1) a producer application; (2) a prefix registration toward the producer.

The NDN repository, repo-ng, is a producer application that can run as a daemon, and publish arbitrary pre-signed Data packets. It can be installed from Ubuntu PPA, and is suitable for this purpose.

Before I can use repo-ng to publish my certificates, I need to tell repo-ng to act as a producer of the name prefix of my certificate. This can be done be modifying repo-ng configuration file, which is located at /etc/ndn/repo-ng.conf if installed from Ubuntu PPA. I change repo.data.prefix configuration key to /ndn/edu/arizona/cs/shijunxiao/KEY. Other settings can be kept as default.

Then I restart repo-ng service. With repo-ng daemon running, I can insert the sunnyq certificate into the repository:

vps3 $ base64 -d sunnyq.ndncert | nc localhost 7376

And I can check that the certificate can be fetched on the local machine:

vps3 $ ndnpeek /ndn/edu/arizona/cs/shijunxiao/KEY/sunnyq/ksk-1467762358121/ID-CERT | ndn-dissect | head -14
6 (Data) (size: 784)
  7 (Name) (size: 87)
    8 (NameComponent) (size: 3) [[ndn]]
    8 (NameComponent) (size: 3) [[edu]]
    8 (NameComponent) (size: 7) [[arizona]]
    8 (NameComponent) (size: 2) [[cs]]
    8 (NameComponent) (size: 10) [[shijunxiao]]
    8 (NameComponent) (size: 3) [[KEY]]
    8 (NameComponent) (size: 6) [[sunnyq]]
    8 (NameComponent) (size: 17) [[ksk-1467762358121]]
    8 (NameComponent) (size: 7) [[ID-CERT]]
    8 (NameComponent) (size: 9) [[%FD%00%00%01U%BDv%27%93]]
  20 (MetaInfo) (size: 9)
    24 (ContentType) (size: 1) [[%02]]

repo-ng fulfills the first condition of publishing the certificate. To meet the second condition of having a prefix registration toward the producer, I can use Automatic Prefix Propagation with the existing certificate obtained from ndncert system. If you haven't noticed, this repo-ng setup is on vps3, the machine that has my existing certificate, rather than on sunnyq.

As soon as I connect vps3 to the testbed (including /localhop/nfd prefix registration), repo-ng's /ndn/edu/arizona/cs/shijunxiao/KEY prefix would trigger Automatic Prefix Propagation and cause Arizona router to register /ndn/edu/arizona/cs/shijunxiao, the identity name of my existing certificate, toward vps3. This allows the certificate to be retrieve from everywhere, including the signature validation code on Arizona router.

Now I can try Automatic Prefix Propagation on sunnyq again, and it works:

1467765117.288321 INFO: [RibManager] Adding route /ndn/edu/arizona/cs/shijunxiao/sunnyq/ping nexthop=271 origin=0 cost=0
1467765117.338249 TRACE: [AutoPrefixPropagator] start propagate /ndn/edu/arizona/cs/shijunxiao/sunnyq
1467765117.407855 TRACE: [AutoPrefixPropagator] success to propagate /ndn/edu/arizona/cs/shijunxiao/sunnyq

Can I Impersonate as Google with my Intermediate CA?

You may have heard about ANSSI, whose intermediate CA issued unauthorized certificates for Google, which is a weakness of traditional PKI architecture: your browser automatically trusts all the certificates issued by any root or intermediate CA trusted by your machine. To reduce such risks, PKI has tight control on who can become an intermediate CA, through a "key usage" attribute in certificate.

But why NDN does not have a "key usage" restriction and allow every certificate to act as an intermediate CA? What if you issue a certificate for Google from your intermediate CA?

Yes, you can issue such a certificate. However, it will not be trusted.

As an educational example, I issued a fake certificate for Google:

sunnyq $ ndnsec key-gen -tr /google > google.ndncertreq
vps3 $ ndnsec cert-gen -N '' -s /ndn/edu/arizona/cs/shijunxiao - < google.ndncertreq > google.ndncert
vps3 $ base64 -d google.ndncert | nc localhost 7376
sunnyq $ ndnsec cert-install google.ndncert
OK: certificate with name [/google/KEY/ksk-1467766216023/ID-CERT/%FD%00%00%01U%BD%AF%15%21] has been successfully installed

The first hurdle is how to publish this certificate: the certificate name starts with /google/KEY but Automatic Prefix Propagation won't register this prefix for you. But let's say you managed to have this certificate published so that the router can retrieve it (I have insider access to the router so I just registered /google/KEY prefix from the router console during this experiment). And then you'll find the certificate is still not trusted:

1467766942.479390 INFO: [RibManager] Adding route /google/ping nexthop=274 origin=0 cost=0
1467766942.526838 TRACE: [AutoPrefixPropagator] start propagate /google
1467766942.592013 TRACE: [AutoPrefixPropagator] fail to propagate /google
     reason:KeyLocatorChecker failed!
     retry wait time: 50 seconds

This highlights a difference between PKI and NDN certificates:

  • In PKI, an intermediate CA carry the full authority of the root CA, and any certificate issued by an intermediate CA is trusted to the same level as a certificate issued by the root CA itself.
  • In NDN, your intermediate CA only has the authority to issue certificates under your identity name.

For example, the identity name of my certificate is /ndn/edu/arizona/cs/shijunxiao. From my intermediate CA, I can issue a sub-certificate for a longer name such as /ndn/edu/arizona/cs/shijunxiao/temperature-sensor, I can also issue another certificate for the same namespace /ndn/edu/arizona/cs/shijunxiao, but I don't have the authority for shorter prefixes so that any certificate issued out of my identity name will not be trusted. And this is why the trust model is called hierarchical trust model: the authority of an intermediate CA follows the name hierarchy of the issuer certificate's identity name.

Some Notes

The machine that publishes the certificates should be up and running at all times. If it's offline, the packets signed by the certificates you issued (including but not limited to prefix registration commands) cannot be verified, because the certificates cannot be retrieved. That's why I install the repo-ng on vps3, which is a virtual machine in the cloud.

It's technically possible to issue certificates to someone else under your namespace. In 2014, I asked NDN testbed operations about issuing certificates to others. I'm told that it's not against any existing policy, but you will be held responsible if they abuse the testbed. Thus, it's recommended to only use this mechanism on your own devices. However, you can certainly create a separate root CA, and use the commands to issue certificates to anyone.

Summary

In the previous article, you let the world reach the NDN Forwarding Daemon (NFD) on one of your machines through Automatic Prefix Propagation. This article introduces NDN's hierarchical trust model, and explains how to issue certificates for your other machines and publish them so that they can use Automatic Prefix Propagation with a distinct prefix for each machine. This article also explains the difference between PKI and NDN's hierarchical trust model, and demonstrates that the authority of your certificate is restricted by your identity name.