derive_key_lucid() uses krb5int_derive_key() to
construct the requested key. However, in the
end it copies the key from kout keyblock, whereas
the derive function puts it into key_out. The
original code contains the invalid assumption
that krb5_k_create_key() binds the newly created
key to the keyblock which was used to create it.
Xyratex-bug-id: SNT-15
Signed-off-by: Andrew Perepechko <andrew.perepechko@seagate.com>
Change-Id: Id2f28b4a9ca3909861a703f2ce07ed860087e809
Reviewed-on: http://review.whamcloud.com/13076
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout)
{
memset(lout, 0, sizeof(*lout));
key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout)
{
memset(lout, 0, sizeof(*lout));
+ lout->data = malloc(kin->length);
+ if (lout->data == NULL)
+ return KRB5_CC_NOMEM;
+
lout->type = kin->enctype;
lout->length = kin->length;
lout->type = kin->enctype;
lout->length = kin->length;
- lout->data = kin->contents;
+ memcpy(lout->data, kin->contents, kin->length);
+ lout->data = malloc(kin->keyvalue.length);
+ if (lout->data == NULL)
+ return KRB5_CC_NOMEM;
+
lout->type = kin->keytype;
lout->length = kin->keyvalue.length;
memcpy(lout->data, kin->keyvalue.data, kin->keyvalue.length);
#endif
lout->type = kin->keytype;
lout->length = kin->keyvalue.length;
memcpy(lout->data, kin->keyvalue.data, kin->keyvalue.length);
#endif
}
/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
}
/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
unsigned char constant_data[K5CLENGTH];
krb5_data datain;
int keylength;
unsigned char constant_data[K5CLENGTH];
krb5_data datain;
int keylength;
- krb5_keyblock kin, kout; /* must send krb5_keyblock, not lucid! */
+#endif
+ krb5_keyblock kin; /* must send krb5_keyblock, not lucid! */
#if defined(HAVE_HEIMDAL) || HAVE_KRB5INT_DERIVE_KEY
krb5_context kcontext;
#if defined(HAVE_HEIMDAL) || HAVE_KRB5INT_DERIVE_KEY
krb5_context kcontext;
+ krb5_keyblock *outkey;
+#else
+ krb5_keyblock kout;
#endif
#if HAVE_KRB5INT_DERIVE_KEY
krb5_key key_in, key_out;
#endif
#endif
#if HAVE_KRB5INT_DERIVE_KEY
krb5_key key_in, key_out;
#endif
-#ifdef HAVE_HEIMDAL
- krb5_keyblock *outkey;
-#endif
/*
* XXX Hack alert. We don't have "legal" access to these
/*
* XXX Hack alert. We don't have "legal" access to these
- /* allocate memory for output key */
- if ((out->data = malloc(keylength)) == NULL) {
- code = ENOMEM;
- goto out;
- }
- out->length = keylength;
- out->type = in->type;
-
/* Convert to correct format for call to krb5_derive_key */
key_lucid_to_krb5(in, &kin);
/* Convert to correct format for call to krb5_derive_key */
key_lucid_to_krb5(in, &kin);
- key_lucid_to_krb5(out, &kout);
datain.data = (char *) constant_data;
datain.length = K5CLENGTH;
datain.data = (char *) constant_data;
datain.length = K5CLENGTH;
((char *)(datain.data))[4] = (char) extra;
((char *)(datain.data))[4] = (char) extra;
-#ifdef HAVE_KRB5
-#if HAVE_KRB5INT_DERIVE_KEY
+ /* Step 1: Init context */
+ /* Heimdal and newer MIT Kerberos require kcontext */
+#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL)
code = krb5_init_context(&kcontext);
code = krb5_init_context(&kcontext);
- if (code) {
- free(out->data);
- out->data = NULL;
+#endif
+
+ /* Step 2: Get the derived key */
+#ifdef HAVE_KRB5
+#if HAVE_KRB5INT_DERIVE_KEY
code = krb5_k_create_key(kcontext, &kin, &key_in);
code = krb5_k_create_key(kcontext, &kin, &key_in);
- if (code) {
- free(out->data);
- out->data = NULL;
- goto out;
- }
- code = krb5_k_create_key(kcontext, &kout, &key_out);
- if (code) {
- free(out->data);
- out->data = NULL;
code = krb5int_derive_key(enc, key_in, &key_out, &datain,
DERIVE_RFC3961);
code = krb5int_derive_key(enc, key_in, &key_out, &datain,
DERIVE_RFC3961);
+
+ krb5_k_free_key(kcontext, key_in);
+ if (code == 0) {
+ krb5_k_key_keyblock(kcontext, key_out, &outkey);
+ krb5_k_free_key(kcontext, key_out);
+ }
#else /* !HAVE_KRB5INT_DERIVE_KEY */
#else /* !HAVE_KRB5INT_DERIVE_KEY */
+ out->length = keylength;
+ out->type = in->type;
+
+ key_lucid_to_krb5(out, &kout);
+
code = krb5_derive_key(enc, &kin, &kout, &datain);
#endif /* HAVE_KRB5INT_DERIVE_KEY */
#else /* !defined(HAVE_KRB5) */
code = krb5_derive_key(enc, &kin, &kout, &datain);
#endif /* HAVE_KRB5INT_DERIVE_KEY */
#else /* !defined(HAVE_KRB5) */
- if ((code = krb5_init_context(&kcontext))) {
- }
code = krb5_derive_key(kcontext, &kin, in->type, constant_data, K5CLENGTH, &outkey);
#endif /* defined(HAVE_KRB5) */
code = krb5_derive_key(kcontext, &kin, in->type, constant_data, K5CLENGTH, &outkey);
#endif /* defined(HAVE_KRB5) */
- if (code) {
- free(out->data);
- out->data = NULL;
- }
-#ifdef HAVE_KRB5
- key_krb5_to_lucid(&kout, out);
-#if HAVE_KRB5INT_DERIVE_KEY
- krb5_free_context(kcontext);
-#endif /* HAVE_KRB5INT_DERIVE_KEY */
-#else /* !defined(HAVE_KRB5) */
- key_krb5_to_lucid(outkey, out);
+
+ /* Step 3: Copy the key to out */
+#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL)
+ code = key_krb5_to_lucid(outkey, out);
krb5_free_keyblock(kcontext, outkey);
krb5_free_keyblock(kcontext, outkey);
- krb5_free_context(kcontext);
+#else /* !defined(HAVE_KRB5) */
+ code = key_krb5_to_lucid(&kout, out);
#endif /* defined(HAVE_KRB5) */
#endif /* defined(HAVE_KRB5) */
+ /* Step 4: Free the context */
+#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL)
+ krb5_free_context(kcontext);
+#endif
+
out:
if (code)
printerr(0, "ERROR: %s: returning error %d (%s)\n",
out:
if (code)
printerr(0, "ERROR: %s: returning error %d (%s)\n",