Subject: krb5.conf "clockskew" does not accept MIT-compatible
duration-string format
Hello,
We ran into a discrepancy between MIT krb5 and the JDK's Kerberos
implementation while debugging a Kerberos-related incident, and would
like to report it here before filing a JBS issue, in case this is
already known or there's context we're missing.
Summary
-------
MIT krb5 documents "clockskew" in krb5.conf as a "(duration string.)"
value - i.e. it accepts the same grammar as other duration-formatted
keys: a bare integer (seconds), "h:m[:s]", or a composite "NdNhNmNs"
form (e.g. "5m", "1h30m", "36:00").
The JDK's Kerberos implementation documents/treats "clockskew" the
same way by virtue of reading it from the same krb5.conf file, but its
actual parser only accepts a bare integer. Any MIT-valid duration
string with a unit suffix silently fails to parse and falls back to
the hardcoded default (Krb5.DEFAULT_ALLOWABLE_CLOCKSKEW) - with no
exception, no log output (unless Kerberos debug logging is enabled),
and no indication to the administrator that their configured value was
ignored.
This is inconsistent with the JDK's own handling of other duration
keys in the same file: "ticket_lifetime" and "renew_lifetime" are
parsed via the shared Config.duration(String) utility, which already
implements the full MIT grammar correctly. "clockskew" simply never
got wired up to it - it goes through Config.getIntValue() instead,
which is a plain Integer.parseInt() wrapper.
Where this lives (pinned to commit
569b05addf69698fc93026b4dca69bc6ca0920b6):
- Faulty: KerberosTime.getDefaultSkew(), reads "clockskew" via
getIntValue():
https://github.com/openjdk/jdk/blob/569b05addf69698fc93026b4dca69bc6ca0920b6/src/java.security.jgss/share/classes/sun/security/krb5/internal/KerberosTime.java#L288-L297
- Correct precedent: KrbAsReq, reads "ticket_lifetime" (line 130/132)
and "renew_lifetime" (line 139/141) via Config.duration():
https://github.com/openjdk/jdk/blob/569b05addf69698fc93026b4dca69bc6ca0920b6/src/java.security.jgss/share/classes/sun/security/krb5/KrbAsReq.java
Reproduction
------------
krb5.conf:
[libdefaults]
default_realm = EXAMPLE.COM
clockskew = 5m
ClockskewRepro.java:
import sun.security.krb5.Config;
public class ClockskewRepro {
public static void main(String[] args) throws Exception {
Config cfg = Config.getInstance();
String raw = cfg.get("libdefaults", "clockskew");
System.out.println("Raw value from krb5.conf: " + raw);
int viaDuration = Config.duration(raw);
System.out.println("Config.duration(\"" + raw + "\") = "
+ viaDuration + " seconds (MIT-compatible)");
int viaIntValue = cfg.getIntValue("libdefaults", "clockskew");
System.out.println("getIntValue(\"clockskew\") = " +
viaIntValue
+ " (Integer.MIN_VALUE = parse failed / unusable)");
}
}
Build/run (JDK 9+, module access needed for the internal API):
javac --add-exports
java.security.jgss/sun.security.krb5=ALL-UNNAMED ClockskewRepro.java
java --add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED \
-Djava.security.krb5.conf=krb5.conf ClockskewRepro
Observed output, reproduced independently on two systems:
OpenJDK 21.0.12 (mainline, Linux):
Raw value from krb5.conf: 10m
Config.duration("10m") = 600 seconds (MIT-compatible)
getIntValue("clockskew") = -2147483648
Zulu 8.96.0.205-CA (1.8.0_504, Windows):
Raw value from krb5.conf: 5m
Config.duration("5m") = 300 seconds (MIT-compatible)
getIntValue("clockskew") = -2147483648
In both cases the administrator's configured clock-skew tolerance is
silently discarded in favor of the built-in default, with no error or
warning surfaced anywhere by default.
We don't have a JBS account / can't file issues ourselves, so we're
reporting here first. If this looks like a genuine bug to someone with
filing access, could you file a JBS issue (or let us know if one
already exists that we missed) and loop us in? Happy to provide
anything else needed - full repro archive, additional JDK
versions/vendors tested, etc.
Thanks,
Michael Osipov