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 ();
}