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

The DIME standard and its tool

After fixing the signet and genrec tools, I had a valid signet for my test domain “” and the DIME management record correctly set up in my dnssec authoritative server (see Part I and Part II of this series). I tried it using dig:

dig +dnssec @localhost txt|grep TXT
; IN TXT 120 IN TXT “ver=1 pok=E7gyvx3E6ksBVkg9CD5XBoXX18txj45iFSqtn9NLqjA tls=c2jM4G+EFZROQYNOyvwVSiQhgL5QW3UJN3CaIipR/Z4hjoSZoO72UlGXdKsAl1T1RQh+/h9rETD1+vaPbkIGCg” 120 IN RRSIG TXT 5 3 120 20170630110908 20170531110908 10287 f8+HE5fw6cSsEwI1CznT2CUoJsIE57Bb/PsoLM4eNlkaIMoWtsLrh8sL EJ2GG2UtoJihLLEXLn+cmEFP7HT9971qd309et48oZCvwBfki0MG0HLy 9rEoG0XgrWODjBU5BKQcSC/dqOogiqTul55TjnCTGBNydYCklolcCQzK Wprsoa2qiBcrW8GFOMDKeXDgx6W7nZiaiYQs5n4aCAHtbXDODz/c89qi FI/5DAFvw/weVwAeRjqNBed4AsCp3UVSu+M4arqItrMagqb53G9OORH/ g4+olkIxNKw0Wqvcez6yHiZyETj0zChiM3zOwk3nrkAw+jrp6Yvztzon Xf/qjQ==

So next step would be to use the dime tool in dev/tools/dime in order to test some addresses. Of course, it would not be that easy!


I built this tool and executed it in order to verify a particular user signet using the Full fingerprint of “” organizational signet. This came out:

../../dime -f ‘UlVB9t7+GcttbVzhDgdHqyZWFWRZQOfFXW8HQIoZX+Rk6JkuuizQzqmyRriQ1pU667FnhSzODVT9tPugwQjvUg’ “”
Querying DIME management record for:
Establishing connection to DX server…
Error: could not connect to DX server.
[0]: src/providers/dime/signet-resolver/dmtp.c:178 [_sgnt_resolv_dmtp_connect()]: 4 (an unspecified error has occurred), errno = 0, aux = “could not establish DMTP connection to host: DIME management record DNSSEC signature was invalid”

So I re-ran the command using the “-v -v -v” flags to add some verbosity:

../../dime -f ‘UlVB9t7+GcttbVzhDgdHqyZWFWRZQOfFXW8HQIoZX+Rk6JkuuizQzqmyRriQ1pU667FnhSzODVT9tPugwQjvUg’ “” -v -v -v -n

— Started parsing DIME management record…
— — VERSION: — [1]
— — PUBLIC KEY: — [E7gyvx3E6ksBVkg9CD5XBoXX18txj45iFSqtn9NLqjA]
— — DX: — []

— DIME management record for: — hashed —
—— version : 1
—— pok : 13b832bf1dc4ea4b0156483d083e570685d7d7cb718f8e62152aad9fd34baa30 [1]
—— tlssig : [not present]
—— policy : experimental
—— syndicates: [not present]
—— dx : [1]
—— expiry : [not present]
—— subdomain : strict
****** This record was retrieved with an INVALID DNSSEC signature.

According to the previous output, the DIME management record was successfully read but its signature (RRSIG) was invalid.

Again, going through the sources I ended up here:

int _load_dnskey_file(const char *filename) {
// The ttl is unlimited and we don't want to save this entry to the cache.
if (!(dk = _add_dnskey_entry_rsa(dname, flags, algorithm, pubkey, keytag, rdata, rdlen, 0, 0, 1))) 
    RET_ERROR_INT(ERR_UNSPEC, "unable to import DNS root key entry");
// Any key from a local file is automatically validated.
dk-->validated = 1;

In my case, the “root-anchor.key” file located in /root/.dime/ already had the “.” and “” DNSKEYS. According to the previous code, any DNSKEY in that file would be automatically validated. Clearly, this was not the case. The memcached daemon was working fine, so I though that maybe the issue should reside in the way the object was constructed and then added to the cache. So I modified the  _add_dnskey_entry_rsa function so that, inside it, the key was already validated before adding the object to the cache:

dnskey->pubkey = pubkey;
dnskey->keytag = keytag;
dnskey->do_cache = do_cache;
dnskey->validated = 1;

Once this change was made, I re-built the dime tool and tried again:

++++++ This record WAS retrieved with a valid DNSSEC signature.
Establishing connection to DX server…
— Returning cached DIME record.
– Attempting DMTP connection to DIME record-supplied DX server #1 at …
—- Initialized openssl library.
—- Initialized SSL context with cipher list: ECDHE-RSA-AES256-GCM-SHA384
— Established TCP connection (IPV4) to
– Attempting validation in x509 certificate chain: localhost.localdomain (level 0); verified = no / 18
– Attempting validation in x509 certificate chain: localhost.localdomain (level 0); verified = yes / 18
— Successfully established TLS connection to

So far so good; but after passing the signature validation of the RRSIG field, the tool blocked right after establishing a valid TLS connection to the DMTP Magma server. Again, reading the sources I discovered where the new issue resided:

if (!(banner = _sgnt_resolv_read_dmtp_line(session, NULL, &bcode, 0))) {
        RET_ERROR_INT(ERR_UNSPEC, "unable to read DMTP banner");
while (nleft && (!(lbreak = strstr((char *)session->_inbuf, "\r\n")))) {

Dime was expecting the server’s banner; inside _sgnt_resolv_read_dmtp_line the freezing happened because the tool was expecting “\r\n” as the end-of-line, but the server was returning only “\n” (this would be clearly demonstrated by looking inside the commands.c file in the srv/servers/dmtp directory later on; keep reading) So the loop never ended, and the whole dime tool blocked. I altered the line like this:

while (nleft && (!(lbreak = strstr((char *)session->_inbuf, "\n")))) {

This time it worked:

– Continuing verification of self-signed DX TLS certificate …
– DX TLS certificate matched DIME record signature.
– DX TLS certificate verification succeeded automatically (TLS cert match + dnssec).
– DX certificate successfully verified.
– Attempting to verify fingerprint (UlVB9t7+GcttbVzhDgdHqyZWFWRZQOfFXW8HQIoZX+Rk6JkuuizQzqmyRriQ1pU667FnhSzODVT9tPugwQjvUg) for signet:
Error: signet verification failed.

The connection to the DMTP server was fine this time, but the signet could not be verified. That was odd, because I made sure to have that user signet already installed in the database. So I tried the connection to the DMTP server myself using the openssl connect command:

openssl s_client -crlf -connect

220 DSMTP Magma

Then, I tried the EHLO command and the VRFY command to no avail:


I tried some other commands, according to the specs document reference to no avail either. The only ones working were: RST, NOOP, and QUIT. So I went, once again, through the sources and I found simple function placeholders for the DMTP commands:

 * @brief       Specify the destination domain for a message in response to an DMTP RCPT command.
 * @param       con             the DMTP client connection issuing the command.
 * @return      This function returns no value.
void dmtp_rcpt(connection_t *con) {
        con_write_bl(con, "250 RCPT COMMAND COMPLETE\n", 26);
 * @brief       Specify the origin domain for a message in response to an DMTP MAIL command.
 * @param       con             the DMTP client connection issuing the command.
 * @return      This function returns no value.
void dmtp_mail(connection_t *con) {
        // Spit back the all clear.
        con_write_bl(con, "250 MAIL COMMAND COMPLETE\n", 26);
 * @brief       Process an DMTP MAIL command.
 * @param       con             the DMTP client connection issuing the command.
 * @return      This function returns no value.
void dmtp_data(connection_t *con) {
        con_write_bl(con, "451 DATA FAILED - INTERNAL SERVER ERROR - PLEASE TRY AGAIN LATER\n", 65);

So, basically, the DMTP server is not functional at all yet. This surprised me a lot, because there’s a talk at Defcon in 2014 where Ladar shown his MAGMA server capabilities (there’s even a video showing the direct communication and sending of DMTP commands via Telnet). If you are as mystified as I am, go watch it: (minute 40:00).

So maybe they have been tuning things a bit, or they have decided to start afresh, or whatever. I opened a new issue on @github but they have deleted it. So, well, as far as I’m concerned, DIME and MAGMA are far from being something to test and deploy. Hopefully, this great idea would come to fruition, eventually. In the meantime, I suggest to keep an eye on this project.