Latest Tweets

It’s so dark, that it is not even implemented (yet) Part II

The DIME management record

According to the specs document, the DIME standard is based on “the DIME management record”. This record, set as a new sort of TXT record in a DNS domain server, will allow other DMTP-capable servers to communicate securely and privately with no information leakage. Its the cornerstone of the standard, so to speak. This record, of course, has only one mandatory field (POK), and a bunch of optional ones. The Public Organisational Key (POK for short) can be easily obtained by means of using the signet tool, as described in my previous POST. However, and according to the specs document, an additional TLS field must be provided in order to secure the channel. When using dnssec, it is possible to have a self-signed server certificate, but it is mandatory to provide the TLS field in the DIME management record; otherwise there is not going to be any valid TLS communication using the DMTP (DSMTP in this case) protocol.

Inside the dev/tools directory there is a tool called “genrec”. This is the tool you are supposed to use in order to generate this record for your DNS authoritative server. Well, as expected it did not work.


I had my new signet and my MAGMA server set up accordingly; next step I guessed was to generate my DIME management record. So I built the genrec tool and executed it:

../../genrec -k -c tls.localhost.localdomain.pem
Error: could not read ed25519 POK from keyfile.

Of course I should have generated a new TLS file (this file has the certificate and the private key), because my test domain was “”. However, this had nothing to do with the issue at hand. Again, I delve into the source code and I found this:

if (!(pemdata = _read_pem_data(filename, "ED25519 PRIVATE KEY", 1))) {
    RET_ERROR_PTR(ERR_UNSPEC, "unable to read ed25519 private key data from PEM file");

So, genrec was looking for a file with the tags “—–BEGIN ED25519 PRIVATE KEY—–” and “—–END ED25519 PRIVATE KEY—–“. Guess what? The private keys file that was generated using the signet tool had these ones instead: “—–BEGIN ORGANIZATIONAL SIGNET—–” and “—–END ORGANIZATIONAL SIGNET—–“. This is a clear example of forgotten left-overs!

So because I was a bit impatient, I made a copy of my file and then I changed the tags accordingly. Again, genrec complaint about not being able to read the key. So more code-delving! A bit later, I ended up here:

if (!(keys_bin = keys_file_serialize(filename, &keys_len))) {
    RET_ERROR_PTR(ERR_UNSPEC, "could not retrieve keys binary string");
key = keys_signkey_from_binary(keys_bin, keys_len);

The previous code snippet was reading a total of 73 bytes! Obviously, a valid key is 32-byte long (after being base64-decoded, of course). So I had a quick look at the way the signet tool was generating and reading the keys. Loaded with this useful information, I set about to modify the function _load_ed25519_privkey, the one performing the loading of the private keys file for genrec (the commented-out lines are mine):

ED25519_KEY * _load_ed25519_privkey(char const *filename) {
        ED25519_KEY *result;
        //unsigned char *keydata;
        //char *pemdata;
        //size_t klen;
        if (!filename) {
        /*if (!(pemdata = _read_pem_data(filename, "ED25519 PRIVATE KEY", 1))) {
                RET_ERROR_PTR(ERR_UNSPEC, "unable to read ed25519 private key data from PEM file");
        // TCG: proceed as the signet code; first read from the key file:
        if (!(result = dime_keys_signkey_fetch(filename))) {
                RET_ERROR_PTR(ERR_UNSPEC, "unable to read ed25519 private key data from PEM file");
/*      keydata = _b64decode(pemdata, strlen(pemdata), &klen);*/
//      _secure_wipe(pemdata, strlen(pemdata));
//      free(pemdata);
//      printf("Keylength: %zu\n", klen);
        /* Okay, something is really wrong here. The klen is 73 bytes!! */
//      if (!keydata /**/|| (klen != ED25519_KEY_SIZE)/**/) {
        if (!result) {
/*              if (keydata) {
                        _secure_wipe(keydata, klen);
                RET_ERROR_PTR(ERR_UNSPEC, "bad ED25519 key data was read from file");
/*      if (!(result = malloc(sizeof(ED25519_KEY)))) {
                _secure_wipe(keydata, klen);
                RET_ERROR_PTR(ERR_NOMEM, "unable to allocate space for ED25519 key");
        memset(result, 0, sizeof(ED25519_KEY));
        memcpy(result->private_key, keydata, sizeof(result->private_key));
        _secure_wipe(keydata, klen);
        ed25519_publickey_donna(result->private_key, result->public_key);*/
        return result;

After this change, I re-built the genrec tool and tried again:

../../genrec -k -c tls.localhost.localdomain.pem
ver=1 pok=E7gyvx3E6ksBVkg9CD5XBoXX18txj45iFSqtn9NLqjA tls=c2jM4G+EFZROQYNOyvwVSiQhgL5QW3UJN3CaIipR/Z4hjoSZoO72UlGXdKsAl1T1RQh+/h9rETD1+vaPbkIGCg pol=experimental sub=strict

This time it did work; I made sure the POK value was the same by calling signet: they matched up. So I added the DIME management record to my zone file and re-signed the entire zone: 120 IN TXT “ver=1 pok=E7gyvx3E6ksBVkg9CD5XBoXX18txj45iFSqtn9NLqjA tls=c2jM4G+EFZROQYNOyvwVSiQhgL5QW3UJN3CaIipR/Z4hjoSZoO72UlGXdKsAl1T1RQh+/h9rETD1+vaPbkIGCg”

dnssec-signzone -l -o -k

So far so good. But there’s still more to come! See you guys in Part III!