ietf-mailsig
[Top] [All Lists]

Re: The cost of choices

2005-07-29 15:04:23
Earl Hood wrote:

On July 29, 2005 at 13:45, Michael Thomas wrote:

I'm not seeing how this prevents a malicious domain from spoofing
the OP identity if the OP has third-party signatures enabled?
If you can provide a more detailed example, I would appreciate it.
Note that this mainly a question of what the receiver does once it's validated a signature (eg, the RSA check succeeds). At that point, the receiver can try to see if the signature binds to an outside address -- like say the From address.

The problem is that DKIM does not define any robust binding capabilities
of the signer.  Since the i= tag does not have to equal From, how
does the verifier know exactly what the signature is bound to?
As I've mentioned, this is what was dropped in our rush to get the documents
out. It will be back in ssp-01. Here's some psuedo code that I've written up as being what the words ought to be in the next draft. (note that this also includes
much of what is in the current draft).

Feel free to help me debug this :)

      Mike
$i = contents of identity tag in signature
$d = contents of the domain tag in signature
$g = contents of granularity tag in DKIM RR
$i_localpart   // variable for local part of $i
$i_domainpart  // variable for domain part of $i

domainpart ($a) {
    return right hand side of address $a;
}

localpart ($a) {
    return left hand side of address $a;
}

subdomainof ($test, $domain) {
    if ($test is improper subdomain of $domain)
        return TRUE;
    else
        return FALSE;
}

regexmatch ($string, $pattern) {
    return TRUE if match, FALSE otherwise;
}

verifysignature () {
    return TRUE if public key verify succeeds, FALSE otherwise;
}


dkim_verify () {
  if ($i == NULL) {
     // i is missing, default to $d and null
     $i_localpart = "";
     $i_domainpart = $d;
  } else {
     // split into constituent parts
     $i_localpart = localpart ($i);
     $i_domainpart = domainpart ($i)
  }
  // make certain that the domain in $i is a subdomain of $d
  if (! subdomainof ($i_domainpart, $d))
      return NOVERIFY;
  // enforce the granularity requirement
  if (! regexmatch ($i_localpart, $g))
      return NOVERIFY;
  if (verify_signature ())
      return VERIFY;
  else
      return NOVERIFY;  
}

dkim_signerPolicy ($domain) {
    return o= part of DNS(_policy._domainkey.$domain);
}

// check to see if a successfully verified dkim
// signature binds to the outside header, normally
// the From address.

dkim_bindToHdr ($headerval) {
  if ($i == NULL) {
     // i is missing, default to $d and $g
     $i = "$g(_at_)$d";
  }
  if (! regexmatch ($headerval, $i))
      return NOBIND;
  else
      return BIND;
}

// in the preference order of the receiver. From is
// the only one mandatory

$outsideheaders = "From, Sender";       
$from = ; // 2822 From: address in msg

dkim_bindToOutsideHdrs () {
   foreach ($hdr in $outsideheaders) {
      if (dkim_bindToHdr ($hdr) == BIND) {
         if ($hdr != "From") {
             $policy = dkim_signerPolicy (domainpart ($from));
             if ($policy == strict || $policy == nomail)
                 return FAIL;
             else
                 return PASS;
         } else
             return PASS;
      }     
   }
   return NEUTRAL;
}

dkim_receiver () {
  // first do the verification operation
  dkim_verify ();
  // now see if they bind
  return dkim_bindToOutsideHdrs ();
}
<Prev in Thread] Current Thread [Next in Thread>