Subject: [xmpp] DNS-based DNA

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 29 Jun 2010 22:26:33 -0400

I would like to re-open the debate on AC-based DNA vs. DNS-based DNA.   
I thought about it a little more, and it seems like DNS-based DNA is  
actually the lighter-weight solution, given current libraries, and  
actually the more forward-compatible approach.

I've included pseudo-code for completeness below, but the gist is that  
the client should:
1. Check for a DNSSEC-secure delegation; if it exists, use it
2. Connect to server and get name
3. If name doesn't match, server can offer a cert as a new DNSSEC TA
4. If name in cert matches intended domain, client installs TA and re- 
queries for delegation
5. If delegation validates this time and the name matches the server,  
go ahead

Three things in favor of this approach over ACDNA:

1. You can check for delegation before connecting, and thus accept/ 
reject faster

2. It's doable with existing libraries (see libunbound's ub_ctx_add_ta  
command)

3. It's forward-compatible with DNSSEC deployment; as more of the DNS  
is secure, more delegations will be handled by line (1) and fewer by  
lines (3-5).

--Richard

-----BEGIN pseudo-code-----
// Goal: Connect to destination_name

// See if the domain is delegated
// If so, remember the delegated name
// Also remember DNSSEC validation status with current TAs
delegate_record = QUERY_FOR_SRV("_xmpp-delegate." + destination_name);
delegate_name = NULL;
delegated_flag = false;
if (delegate_record != NULL) {
     delegated_flag = true;
     delegate_name = delegate_record.name;
}
dnssec_flag = delegate_record.dnssec_secured

// Establish TLS connection to the server
xmpp_server = QUERY_FOR_SRV(destination_name).name;
tls_connection = TLS_CONNECT(xmpp_server);
remote_name = tls_connection.authenticated_name;

// Check the name of the server
// Deal with easy cases first
if (!delegated_flag && remote_name == destination_name) {
     goto SUCCESS;
}
if (!delegated_flag && remote_name != destination_name) {
     goto FAIL;
}
else if (delegated_flag && dnssec_flag && remote_name ==  
delegate_name) {
     goto SUCCESS;
}
else if (delegated_flag && dnssec_flag && remote_name !=  
delegate_name) {
     goto FAIL;
}
else {// if (delegated_flag && !dnssec_flag)
     // Get "External TA" cert using XMPP
     // <challenge><proof type="urn:ietf:params:dna:proof:dnssec-ta"></ 
challenge>
     // <proof>http://hosting-provider.com/customers/destination_name.cert 
</proof>
     eta_url = XMPP_CHALLENGE("urn:ietf:params:dna:proof:dnssec-eta");
     eta_cert = HTTP_GET(ta_url);
     if (!eta_url || !eta_cert) {
         goto FAIL;
     }

     // Check name in ETA cert
     if (eta_cert.name != destination_name) {
         goto FAIL;
     }

     // Extract key material and install as a DNSSEC TA
     DNS_RESOLVER_INSTALL_TA(eta_cert.pub_key);
     delegate_record = QUERY_FOR_SRV("_xmpp-delegate." +  
destination_name);
     DNS_RESOLVER_REMOVE_TA(eta_cert.pub_key);
     if (!delegate_record) {
         goto FAIL;
     } else if (!delegate_record.dnssec_secured) {
         goto FAIL;
     } else if (delegate_record.name != remote_name) {
         goto FAIL;
     } else { // if delegate_record && dnssec_secured && name ==  
remote_name
         goto SUCCESS;
     }
}

-----END pseudo-code-----