[OpenAFS-devel] Problem with des3-cbc-sha1 keys and OpenAFS 1.8.X

John P Janosik jpjanosi@us.ibm.com
Wed, 29 Apr 2020 13:53:06 -0500


--0__=8FBB0FCADFF69A498f9e8a93df938690918c8FBB0FCADFF69A49
Content-Transfer-Encoding: quoted-printable
Content-type: text/plain; charset=US-ASCII



Hello

I hit a problem with "ticket contained unknown key version number" errors
while trying to stand up a new OpenAFS 1.8.X server in a cell using non
single-DES keys for the afs service principal.  Any tokens created from a
des3-cbc-sha1 service ticket fail against the OpenAFS 1.8.X server, but
work against the IBM AFS servers which use rxkad.keytab to hold the keys.
The KeyFileExt on the OpenAFS 1.8.x server was generated by running
akeycovert after copying the rxkad.keytab from one of the
production/working servers.  I believe this is a bug in this section of
code from rxkad/ticket5.c:tkt=5FDecodeTicket5 because it passes the wrong k=
ey
size to get=5Fkey=5Fenctype for des3-cbc-sha1 keys:

 266         code =3D krb5=5Fenctype=5Fkeybits(context,  t5.enc=5Fpart.etyp=
e,
&keysize);
 267         if (code !=3D 0) {
 268             krb5=5Ffree=5Fcontext(context);
 269             goto unknown=5Fkey;
 270         }
 271         keysize =3D keysize / 8;
 272         allocsiz =3D keysize;
 273         keybuf =3D rxi=5FAlloc(allocsiz);
 274         /* this is not quite a hole for afsconf=5FGetKeyByTypes. A
wrapper
 275            that calls afsconf=5FGetKeyByTypes and
afsconf=5FtypedKey=5Fvalues
 276            is needed */
 277         code =3D get=5Fkey=5Fenctype(get=5Fkey=5Frock, v5=5Fserv=5Fkvn=
o,
t5.enc=5Fpart.etype,
 278                                keybuf, &keysize);
 279         if (code) {
 280             rxi=5FFree(keybuf, allocsiz);
 281             krb5=5Ffree=5Fcontext(context);
 282             goto unknown=5Fkey;
 283         }

The key bits for des3-cbc-sha1 is 168, but key size is 24.  Dividing 168 by
8 at line 271 results in 21 instead of 24.  When in
auth/authcon.c:auth=5Fafsconf=5FGetRxkadKrb5Key AFSCONF=5FBADKEY is returne=
d due
to the size mismatch:

  45 static int =5Fafsconf=5FGetRxkadKrb5Key(void *arock, int kvno, int
enctype, void *outkey,
  46                                     size=5Ft *keylen)
  47 {
  48     struct afsconf=5Fdir *adir =3D arock;
  49     struct afsconf=5FtypedKey *kobj;
  50     struct rx=5Fopaque *keymat;
  51     afsconf=5FkeyType tktype;
  52     int tkvno, tenctype;
  53     int code;
  54
  55     code =3D afsconf=5FGetKeyByTypes(adir, afsconf=5Frxkad=5Fkrb5, kvn=
o,
enctype, &kobj);
  56     if (code !=3D 0)
  57         return code;
  58     afsconf=5FtypedKey=5Fvalues(kobj, &tktype, &tkvno, &tenctype,
&keymat);
  59     if (*keylen < keymat->len) {
  60         afsconf=5FtypedKey=5Fput(&kobj);
  61         return AFSCONF=5FBADKEY;
  62     }
  63     memcpy(outkey, keymat->val, keymat->len);
  64     *keylen =3D keymat->len;
  65     afsconf=5FtypedKey=5Fput(&kobj);
  66     return 0;
  67 }

I created the following patch which is working with tokens generated from
all the key types I tested(des3-cbc-sha1, aes128-cts-hmac-sha1-96,
aes256-cts-hmac-sha1-96, and arcfour-hmac):

diff -Nrup openafs-1.8.5-orig/src/rxkad/ticket5.c
openafs-1.8.5-changed/src/rxkad/ticket5.c
--- openafs-1.8.5-orig/src/rxkad/ticket5.c	2020-04-28
15:52:40.455888457 -0500
+++ openafs-1.8.5-changed/src/rxkad/ticket5.c	2020-04-28
15:37:46.788413717 -0500
@@ -263,12 +263,11 @@ tkt=5FDecodeTicket5(char *ticket, afs=5Fint3
 	    krb5=5Ffree=5Fcontext(context);
 	    goto unknown=5Fkey;
 	}
-	code =3D krb5=5Fenctype=5Fkeybits(context,  t5.enc=5Fpart.etype, &keysize=
);
+	code =3D krb5=5Fenctype=5Fkeysize(context,  t5.enc=5Fpart.etype, &keysize=
);
 	if (code !=3D 0) {
 	    krb5=5Ffree=5Fcontext(context);
 	    goto unknown=5Fkey;
 	}
-	keysize =3D keysize / 8;
 	allocsiz =3D keysize;
 	keybuf =3D rxi=5FAlloc(allocsiz);
 	/* this is not quite a hole for afsconf=5FGetKeyByTypes. A wrapper


Thanks,

John Janosik
jpjanosi@us.ibm.com

--0__=8FBB0FCADFF69A498f9e8a93df938690918c8FBB0FCADFF69A49
Content-Transfer-Encoding: quoted-printable
Content-type: text/html; charset=US-ASCII
Content-Disposition: inline

<html><body><p><tt><font size=3D"2">Hello</font></tt><br><br><tt><font size=
=3D"2">I hit a problem with &quot;ticket contained unknown key version numb=
er&quot; errors while trying to stand up a new OpenAFS 1.8.X server in a ce=
ll using non single-DES keys for the afs service principal. &nbsp;Any token=
s created from a des3-cbc-sha1 service ticket fail against the OpenAFS 1.8.=
X server, but work against the IBM AFS servers which use rxkad.keytab to ho=
ld the keys. &nbsp;The KeyFileExt on the OpenAFS 1.8.x server was generated=
 by running akeycovert after copying the rxkad.keytab from one of the produ=
ction/working servers. &nbsp;I believe this is a bug in this section of cod=
e from rxkad/ticket5.c:tkt=5FDecodeTicket5 because it passes the wrong key =
size to get=5Fkey=5Fenctype for des3-cbc-sha1 keys:</font></tt><br><br><tt>=
<font size=3D"2">&nbsp;266 &nbsp; &nbsp; &nbsp; &nbsp; code =3D krb5=5Fenct=
ype=5Fkeybits(context, &nbsp;t5.enc=5Fpart.etype, &amp;keysize);</font></tt=
><br><tt><font size=3D"2">&nbsp;267 &nbsp; &nbsp; &nbsp; &nbsp; if (code !=
=3D 0) {</font></tt><br><tt><font size=3D"2">&nbsp;268 &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; krb5=5Ffree=5Fcontext(context);</font></tt><br><tt><f=
ont size=3D"2">&nbsp;269 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unk=
nown=5Fkey;</font></tt><br><tt><font size=3D"2">&nbsp;270 &nbsp; &nbsp; &nb=
sp; &nbsp; }</font></tt><br><tt><font size=3D"2">&nbsp;271 &nbsp; &nbsp; &n=
bsp; &nbsp; keysize =3D keysize / 8;</font></tt><br><tt><font size=3D"2">&n=
bsp;272 &nbsp; &nbsp; &nbsp; &nbsp; allocsiz =3D keysize;</font></tt><br><t=
t><font size=3D"2">&nbsp;273 &nbsp; &nbsp; &nbsp; &nbsp; keybuf =3D rxi=5FA=
lloc(allocsiz);</font></tt><br><tt><font size=3D"2">&nbsp;274 &nbsp; &nbsp;=
 &nbsp; &nbsp; /* this is not quite a hole for afsconf=5FGetKeyByTypes. A w=
rapper</font></tt><br><tt><font size=3D"2">&nbsp;275 &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp;that calls afsconf=5FGetKeyByTypes and afsconf=5FtypedKe=
y=5Fvalues</font></tt><br><tt><font size=3D"2">&nbsp;276 &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp;is needed */</font></tt><br><tt><font size=3D"2">&nb=
sp;277 &nbsp; &nbsp; &nbsp; &nbsp; code =3D get=5Fkey=5Fenctype(get=5Fkey=
=5Frock, v5=5Fserv=5Fkvno, t5.enc=5Fpart.etype,</font></tt><br><tt><font si=
ze=3D"2">&nbsp;278 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;keybuf, &amp;keysize=
);</font></tt><br><tt><font size=3D"2">&nbsp;279 &nbsp; &nbsp; &nbsp; &nbsp=
; if (code) {</font></tt><br><tt><font size=3D"2">&nbsp;280 &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; rxi=5FFree(keybuf, allocsiz);</font></tt><br><tt=
><font size=3D"2">&nbsp;281 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; krb5=
=5Ffree=5Fcontext(context);</font></tt><br><tt><font size=3D"2">&nbsp;282 &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown=5Fkey;</font></tt><br=
><tt><font size=3D"2">&nbsp;283 &nbsp; &nbsp; &nbsp; &nbsp; }</font></tt><u=
l></ul><font size=3D"2">The key bits for </font><tt><font size=3D"2">des3-c=
bc-sha1</font></tt><font size=3D"2"> </font><font size=3D"2">is 168, but ke=
y size is 24.  Dividing 168 by 8 at line 271 results in 21 instead of 24.  =
When in auth/authcon.c:auth=5Fafsconf=5FGetRxkadKrb5Key AFSCONF=5FBADKEY is=
 returned due to the size mismatch:</font><br><br><tt><font size=3D"2">&nbs=
p; 45 static int =5Fafsconf=5FGetRxkadKrb5Key(void *arock, int kvno, int en=
ctype, void *outkey,</font></tt><br><tt><font size=3D"2">&nbsp; 46 &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size=5Ft *keylen)</font></tt><br=
><tt><font size=3D"2">&nbsp; 47 {</font></tt><br><tt><font size=3D"2">&nbsp=
; 48 &nbsp; &nbsp; struct afsconf=5Fdir *adir =3D arock;</font></tt><br><tt=
><font size=3D"2">&nbsp; 49 &nbsp; &nbsp; struct afsconf=5FtypedKey *kobj;<=
/font></tt><br><tt><font size=3D"2">&nbsp; 50 &nbsp; &nbsp; struct rx=5Fopa=
que *keymat;</font></tt><br><tt><font size=3D"2">&nbsp; 51 &nbsp; &nbsp; af=
sconf=5FkeyType tktype;</font></tt><br><tt><font size=3D"2">&nbsp; 52 &nbsp=
; &nbsp; int tkvno, tenctype;</font></tt><br><tt><font size=3D"2">&nbsp; 53=
 &nbsp; &nbsp; int code;</font></tt><br><tt><font size=3D"2">&nbsp; 54 </fo=
nt></tt><br><tt><font size=3D"2">&nbsp; 55 &nbsp; &nbsp; code =3D afsconf=
=5FGetKeyByTypes(adir, afsconf=5Frxkad=5Fkrb5, kvno, enctype, &amp;kobj);</=
font></tt><br><tt><font size=3D"2">&nbsp; 56 &nbsp; &nbsp; if (code !=3D 0)=
</font></tt><br><tt><font size=3D"2">&nbsp; 57 &nbsp; &nbsp; &nbsp; &nbsp; =
return code;</font></tt><br><tt><font size=3D"2">&nbsp; 58 &nbsp; &nbsp; af=
sconf=5FtypedKey=5Fvalues(kobj, &amp;tktype, &amp;tkvno, &amp;tenctype, &am=
p;keymat);</font></tt><br><tt><font size=3D"2">&nbsp; 5</font></tt><tt><fon=
t size=3D"2">9 &nbsp; &nbsp; if (*keylen &lt; keymat-&gt;len) {</font></tt>=
<br><tt><font size=3D"2">&nbsp; 60 &nbsp; &nbsp; &nbsp; &nbsp; afsconf=5Fty=
pedKey=5Fput(&amp;kobj);</font></tt><br><tt><font size=3D"2">&nbsp; 61 &nbs=
p; &nbsp; &nbsp; &nbsp; return AFSCONF=5FBADKEY;</font></tt><br><tt><font s=
ize=3D"2">&nbsp; 62 &nbsp; &nbsp; }</font></tt><br><tt><font size=3D"2">&nb=
sp; 63 &nbsp; &nbsp; memcpy(outkey, keymat-&gt;val, keymat-&gt;len);</font>=
</tt><br><tt><font size=3D"2">&nbsp; 64 &nbsp; &nbsp; *keylen =3D keymat-&g=
t;len;</font></tt><br><tt><font size=3D"2">&nbsp; 65 &nbsp; &nbsp; afsconf=
=5FtypedKey=5Fput(&amp;kobj);</font></tt><br><tt><font size=3D"2">&nbsp; 66=
 &nbsp; &nbsp; return 0;</font></tt><br><tt><font size=3D"2">&nbsp; 67 }</f=
ont></tt><ul></ul><tt><font size=3D"2">I created the following patch which =
is working with tokens generated from all the key types I tested(</font></t=
t><tt><font size=3D"2">des3-cbc-sha1, </font></tt><tt><font size=3D"2">aes1=
28-cts-hmac-sha1-96, </font></tt><tt><font size=3D"2">aes256-cts-hmac-sha1-=
96</font></tt><tt><font size=3D"2">, and </font></tt><tt><font size=3D"2">a=
rcfour-hmac)</font></tt><tt><font size=3D"2">:</font></tt><br><br><tt><font=
 size=3D"2">diff -Nrup openafs-1.8.5-orig/src/rxkad/ticket5.c openafs-1.8.5=
-changed/src/rxkad/ticket5.c</font></tt><br><tt><font size=3D"2">--- openaf=
s-1.8.5-orig/src/rxkad/ticket5.c        2020-04-28 15:52:40.455888457 -0500=
</font></tt><br><tt><font size=3D"2">+++ openafs-1.8.5-changed/src/rxkad/ti=
cket5.c        2020-04-28 15:37:46.788413717 -0500</font></tt><br><tt><font=
 size=3D"2">@@ -263,12 +263,11 @@ tkt=5FDecodeTicket5(char *ticket, afs=5Fi=
nt3</font></tt><br><tt><font size=3D"2">&nbsp;         &nbsp; &nbsp;krb5=5F=
free=5Fcontext(context);</font></tt><br><tt><font size=3D"2">&nbsp;        =
 &nbsp; &nbsp;goto unknown=5Fkey;</font></tt><br><tt><font size=3D"2">&nbsp=
;        }</font></tt><br><tt><font size=3D"2">-        code =3D krb5=5Fenc=
type=5Fkeybits(context, &nbsp;t5.enc=5Fpart.etype, &amp;keysize);</font></t=
t><br><tt><font size=3D"2">+        code =3D krb5=5Fenctype=5Fkeysize(conte=
xt, &nbsp;t5.enc=5Fpart.etype, &amp;keysize);</font></tt><br><tt><font size=
=3D"2">&nbsp;        if (code !=3D 0) {</font></tt><br><tt><font size=3D"2"=
>&nbsp;         &nbsp; &nbsp;krb5=5Ffree=5Fcontext(context);</font></tt><br=
><tt><font size=3D"2">&nbsp;         &nbsp; &nbsp;goto unknown=5Fkey;</font=
></tt><br><tt><font size=3D"2">&nbsp;        }</font></tt><br><tt><font siz=
e=3D"2">-        keysize =3D keysize / 8;</font></tt><br><tt><font size=3D"=
2">&nbsp;        allocsiz =3D keysize;</font></tt><br><tt><font size=3D"2">=
&nbsp;        keybuf =3D rxi=5FAlloc(allocsiz);</font></tt><br><tt><font si=
ze=3D"2">&nbsp;        /* this is not quite a hole for afsconf=5FGetKeyByTy=
pes. A wrapper</font></tt><br><br><br><tt><font size=3D"2">Thanks,</font></=
tt><br><tt><font size=3D"2"><br>John Janosik<br>jpjanosi@us.ibm.com</font><=
/tt><BR>
</body></html>

--0__=8FBB0FCADFF69A498f9e8a93df938690918c8FBB0FCADFF69A49--