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

John P Janosik jpjanosi@us.ibm.com
Tue, 5 May 2020 10:17:21 -0500


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

Benjamin Kaduk <kaduk@mit.edu> wrote on 05/04/2020 11:06:34 PM:

>
> Hi John,
>
> That sounds like an accurate diagnosis and plausible patch.
> "But what's really impressive is that triple-DES is used at all!"
>

Yep, luckily we found while debugging this that the old AIX machines using
triple-DES just need a config update.

> Please let me know if you're in a position to submit the patch to gerrit
or
> I should do so on your behalf.  (In review I'll have to check that it
works
> for builds against both Heimdal and MIT APIs.)
>

I checked with Yadav on the steps to submit the patch to gerrit.  Since it
is unlikely I will often be submitting patches, Yadav agreed to do the work
to submit to gerrit.  Thanks for the offer.

John

> Thanks again,
>
> Ben
>
> On Wed, Apr 29, 2020 at 01:53:06PM -0500, John P Janosik wrote:
> >
> >
> > 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 wro=
ng
key
> > size to get=5Fkey=5Fenctype for des3-cbc-sha1 keys:
> >
> >  266         code =3D krb5=5Fenctype=5Fkeybits(context,  t5.enc=5Fpart.=
etype,
> > &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=
=5Fkvno,
> > 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 ret=
urned
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,=
 kvno,
> > 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, &k=
eysize);
> > +   code =3D krb5=5Fenctype=5Fkeysize(context,  t5.enc=5Fpart.etype, &k=
eysize);
> >     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__=8FBB0FCCDFC0D8CF8f9e8a93df938690918c8FBB0FCCDFC0D8CF
Content-Transfer-Encoding: quoted-printable
Content-type: text/html; charset=US-ASCII
Content-Disposition: inline

<html><body><p><tt><font size=3D"2">Benjamin Kaduk &lt;kaduk@mit.edu&gt; wr=
ote on 05/04/2020 11:06:34 PM:<br><br>&gt; <br>&gt; Hi John,<br>&gt; <br>&g=
t; That sounds like an accurate diagnosis and plausible patch.<br>&gt; &quo=
t;But what's really impressive is that triple-DES is used at all!&quot;<br>=
&gt; </font></tt><br><br><tt><font size=3D"2">Yep, luckily we found while d=
ebugging this that the old AIX machines using triple-DES just need a config=
 update.</font></tt><br><tt><font size=3D"2"><br>&gt; Please let me know if=
 you're in a position to submit the patch to gerrit or<br>&gt; I should do =
so on your behalf. &nbsp;(In review I'll have to check that it works<br>&gt=
; for builds against both Heimdal and MIT APIs.)<br>&gt; </font></tt><br><b=
r><tt><font size=3D"2">I checked with Yadav on the steps to submit the patc=
h to gerrit. &nbsp;Since it is unlikely I will often be submitting patches,=
 Yadav agreed to do the work to submit to gerrit. &nbsp;Thanks for the offe=
r.</font></tt><br><br><tt><font size=3D"2">John</font></tt><br><tt><font si=
ze=3D"2"><br>&gt; Thanks again,<br>&gt; <br>&gt; Ben<br>&gt; <br>&gt; On We=
d, Apr 29, 2020 at 01:53:06PM -0500, John P Janosik wrote:<br>&gt; &gt; <br=
>&gt; &gt; <br>&gt; &gt; Hello<br>&gt; &gt; <br>&gt; &gt; I hit a problem w=
ith &quot;ticket contained unknown key version number&quot; errors<br>&gt; =
&gt; while trying to stand up a new OpenAFS 1.8.X server in a cell using no=
n<br>&gt; &gt; single-DES keys for the afs service principal. &nbsp;Any tok=
ens created from a<br>&gt; &gt; des3-cbc-sha1 service ticket fail against t=
he OpenAFS 1.8.X server, but<br>&gt; &gt; work against the IBM AFS servers =
which use rxkad.keytab to hold the keys.<br>&gt; &gt; The KeyFileExt on the=
 OpenAFS 1.8.x server was generated by running<br>&gt; &gt; akeycovert afte=
r copying the rxkad.keytab from one of the<br>&gt; &gt; production/working =
servers. &nbsp;I believe this is a bug in this section of<br>&gt; &gt; code=
 from rxkad/ticket5.c:tkt=5FDecodeTicket5 because it passes the wrong key<b=
r>&gt; &gt; size to get=5Fkey=5Fenctype for des3-cbc-sha1 keys:<br>&gt; &gt=
; <br>&gt; &gt; &nbsp;266 &nbsp; &nbsp; &nbsp; &nbsp; code =3D krb5=5Fencty=
pe=5Fkeybits(context, &nbsp;t5.enc=5Fpart.etype,<br>&gt; &gt; &amp;keysize)=
;<br>&gt; &gt; &nbsp;267 &nbsp; &nbsp; &nbsp; &nbsp; if (code !=3D 0) {<br>=
&gt; &gt; &nbsp;268 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; krb5=5Ffree=
=5Fcontext(context);<br>&gt; &gt; &nbsp;269 &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; goto unknown=5Fkey;<br>&gt; &gt; &nbsp;270 &nbsp; &nbsp; &nbsp; =
&nbsp; }<br>&gt; &gt; &nbsp;271 &nbsp; &nbsp; &nbsp; &nbsp; keysize =3D key=
size / 8;<br>&gt; &gt; &nbsp;272 &nbsp; &nbsp; &nbsp; &nbsp; allocsiz =3D k=
eysize;<br>&gt; &gt; &nbsp;273 &nbsp; &nbsp; &nbsp; &nbsp; keybuf =3D rxi=
=5FAlloc(allocsiz);<br>&gt; &gt; &nbsp;274 &nbsp; &nbsp; &nbsp; &nbsp; /* t=
his is not quite a hole for afsconf=5FGetKeyByTypes. A<br>&gt; &gt; wrapper=
<br>&gt; &gt; &nbsp;275 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;that calls=
 afsconf=5FGetKeyByTypes and<br>&gt; &gt; afsconf=5FtypedKey=5Fvalues<br>&g=
t; &gt; &nbsp;276 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;is needed */<br>=
&gt; &gt; &nbsp;277 &nbsp; &nbsp; &nbsp; &nbsp; code =3D get=5Fkey=5Fenctyp=
e(get=5Fkey=5Frock, v5=5Fserv=5Fkvno,<br>&gt; &gt; t5.enc=5Fpart.etype,<br>=
&gt; &gt; &nbsp;278 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;keybuf, &amp;keysiz=
e);<br>&gt; &gt; &nbsp;279 &nbsp; &nbsp; &nbsp; &nbsp; if (code) {<br>&gt; =
&gt; &nbsp;280 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rxi=5FFree(keybuf,=
 allocsiz);<br>&gt; &gt; &nbsp;281 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; krb5=5Ffree=5Fcontext(context);<br>&gt; &gt; &nbsp;282 &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; goto unknown=5Fkey;<br>&gt; &gt; &nbsp;283 &nbsp; &=
nbsp; &nbsp; &nbsp; }<br>&gt; &gt; <br>&gt; &gt; The key bits for des3-cbc-=
sha1 is 168, but key size is 24. &nbsp;Dividing 168 by<br>&gt; &gt; 8 at li=
ne 271 results in 21 instead of 24. &nbsp;When in<br>&gt; &gt; auth/authcon=
.c:auth=5Fafsconf=5FGetRxkadKrb5Key AFSCONF=5FBADKEY is returned due<br>&gt=
; &gt; to the size mismatch:<br>&gt; &gt; <br>&gt; &gt; &nbsp; 45 static in=
t =5Fafsconf=5FGetRxkadKrb5Key(void *arock, int kvno, int<br>&gt; &gt; enct=
ype, void *outkey,<br>&gt; &gt; &nbsp; 46 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; size=5Ft *keylen)<br>&gt; &gt; &nbsp; 47 {<br>&gt; &gt; &=
nbsp; 48 &nbsp; &nbsp; struct afsconf=5Fdir *adir =3D arock;<br>&gt; &gt; &=
nbsp; 49 &nbsp; &nbsp; struct afsconf=5FtypedKey *kobj;<br>&gt; &gt; &nbsp;=
 50 &nbsp; &nbsp; struct rx=5Fopaque *keymat;<br>&gt; &gt; &nbsp; 51 &nbsp;=
 &nbsp; afsconf=5FkeyType tktype;<br>&gt; &gt; &nbsp; 52 &nbsp; &nbsp; int =
tkvno, tenctype;<br>&gt; &gt; &nbsp; 53 &nbsp; &nbsp; int code;<br>&gt; &gt=
; &nbsp; 54<br>&gt; &gt; &nbsp; 55 &nbsp; &nbsp; code =3D afsconf=5FGetKeyB=
yTypes(adir, afsconf=5Frxkad=5Fkrb5, kvno,<br>&gt; &gt; enctype, &amp;kobj)=
;<br>&gt; &gt; &nbsp; 56 &nbsp; &nbsp; if (code !=3D 0)<br>&gt; &gt; &nbsp;=
 57 &nbsp; &nbsp; &nbsp; &nbsp; return code;<br>&gt; &gt; &nbsp; 58 &nbsp; =
&nbsp; afsconf=5FtypedKey=5Fvalues(kobj, &amp;tktype, &amp;tkvno, &amp;tenc=
type,<br>&gt; &gt; &amp;keymat);<br>&gt; &gt; &nbsp; 59 &nbsp; &nbsp; if (*=
keylen &lt; keymat-&gt;len) {<br>&gt; &gt; &nbsp; 60 &nbsp; &nbsp; &nbsp; &=
nbsp; afsconf=5FtypedKey=5Fput(&amp;kobj);<br>&gt; &gt; &nbsp; 61 &nbsp; &n=
bsp; &nbsp; &nbsp; return AFSCONF=5FBADKEY;<br>&gt; &gt; &nbsp; 62 &nbsp; &=
nbsp; }<br>&gt; &gt; &nbsp; 63 &nbsp; &nbsp; memcpy(outkey, keymat-&gt;val,=
 keymat-&gt;len);<br>&gt; &gt; &nbsp; 64 &nbsp; &nbsp; *keylen =3D keymat-&=
gt;len;<br>&gt; &gt; &nbsp; 65 &nbsp; &nbsp; afsconf=5FtypedKey=5Fput(&amp;=
kobj);<br>&gt; &gt; &nbsp; 66 &nbsp; &nbsp; return 0;<br>&gt; &gt; &nbsp; 6=
7 }<br>&gt; &gt; <br>&gt; &gt; I created the following patch which is worki=
ng with tokens generated from<br>&gt; &gt; all the key types I tested(des3-=
cbc-sha1, aes128-cts-hmac-sha1-96,<br>&gt; &gt; aes256-cts-hmac-sha1-96, an=
d arcfour-hmac):<br>&gt; &gt; <br>&gt; &gt; diff -Nrup openafs-1.8.5-orig/s=
rc/rxkad/ticket5.c<br>&gt; &gt; openafs-1.8.5-changed/src/rxkad/ticket5.c<b=
r>&gt; &gt; --- openafs-1.8.5-orig/src/rxkad/ticket5.c &nbsp; 2020-04-28<br=
>&gt; &gt; 15:52:40.455888457 -0500<br>&gt; &gt; +++ openafs-1.8.5-changed/=
src/rxkad/ticket5.c &nbsp; 2020-04-28<br>&gt; &gt; 15:37:46.788413717 -0500=
<br>&gt; &gt; @@ -263,12 +263,11 @@ tkt=5FDecodeTicket5(char *ticket, afs=
=5Fint3<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; krb5=5Ffree=5Fcontext(cont=
ext);<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown=5Fkey;<br>&gt; =
&gt; &nbsp; &nbsp; }<br>&gt; &gt; - &nbsp; code =3D krb5=5Fenctype=5Fkeybit=
s(context, &nbsp;t5.enc=5Fpart.etype, &amp;keysize);<br>&gt; &gt; + &nbsp; =
code =3D krb5=5Fenctype=5Fkeysize(context, &nbsp;t5.enc=5Fpart.etype, &amp;=
keysize);<br>&gt; &gt; &nbsp; &nbsp; if (code !=3D 0) {<br>&gt; &gt; &nbsp;=
 &nbsp; &nbsp; &nbsp; krb5=5Ffree=5Fcontext(context);<br>&gt; &gt; &nbsp; &=
nbsp; &nbsp; &nbsp; goto unknown=5Fkey;<br>&gt; &gt; &nbsp; &nbsp; }<br>&gt=
; &gt; - &nbsp; keysize =3D keysize / 8;<br>&gt; &gt; &nbsp; &nbsp; allocsi=
z =3D keysize;<br>&gt; &gt; &nbsp; &nbsp; keybuf =3D rxi=5FAlloc(allocsiz);=
<br>&gt; &gt; &nbsp; &nbsp; /* this is not quite a hole for afsconf=5FGetKe=
yByTypes. A wrapper<br>&gt; &gt; <br>&gt; &gt; <br>&gt; &gt; Thanks,<br>&gt=
; &gt; <br>&gt; &gt; John Janosik<br>&gt; &gt; jpjanosi@us.ibm.com<br>&gt; =
<br></font></tt><BR>
</body></html>

--0__=8FBB0FCCDFC0D8CF8f9e8a93df938690918c8FBB0FCCDFC0D8CF--