This commit was manufactured by cvs2svn to create tag
[krb5.git] / src / lib / krb5 / krb / mk_req_ext.c
index f146d14832c949c30a3743a0bf79e4bde7f0996d..88daab56704bd2d734af8da6004204e412a30260 100644 (file)
  * this permission notice appear in supporting documentation, and that
  * the name of M.I.T. not be used in advertising or publicity pertaining
  * to distribution of the software without specific, written prior
- * permission.  M.I.T. makes no representations about the suitability of
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
  * this software for any purpose.  It is provided "as is" without express
  * or implied warranty.
  * 
@@ -67,93 +70,96 @@ krb5_generate_authenticator PROTOTYPE((krb5_context,
                                       const krb5_checksum *, krb5_keyblock *,
                                       krb5_int32, krb5_authdata ** ));
 
-krb5_error_code INTERFACE
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
 krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
                     outbuf)
     krb5_context         context;
-    krb5_auth_context  **auth_context;
+    krb5_auth_context  FAR * auth_context;
     const krb5_flags     ap_req_options;
-    krb5_data          * in_data;
-    krb5_creds                 * in_creds;
-    krb5_data          * outbuf;
+    krb5_data          FAR * in_data;
+    krb5_creds                 FAR * in_creds;
+    krb5_data          FAR * outbuf;
 {
     krb5_error_code      retval;
     krb5_checksum        checksum;
     krb5_checksum        *checksump = 0;
-    krb5_auth_context  * new_auth_context;
+    krb5_auth_context    new_auth_context;
 
     krb5_ap_req request;
     krb5_data *scratch = 0;
-    krb5_encrypt_block eblock;
     krb5_data *toutbuf;
 
+    request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK;
     request.authenticator.ciphertext.data = 0;
-    request.ap_options = ap_req_options;
     request.ticket = 0;
     
     if (!in_creds->ticket.length) 
        return(KRB5_NO_TKT_SUPPLIED);
 
     /* we need a native ticket */
-    if (retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket))
+    if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket)))
        return(retval);
     
-    /* verify a valid etype is available */
-    if (!valid_etype(request.ticket->enc_part.etype)) {
-       retval = KRB5_PROG_ETYPE_NOSUPP;
+    /* verify that the ticket is not expired */
+    if ((retval = krb5_validate_times(context, &in_creds->times)) != 0)
        goto cleanup;
-    }
 
     /* generate auth_context if needed */
     if (*auth_context == NULL) {
-       if (retval = krb5_auth_con_init(context, &new_auth_context))
+       if ((retval = krb5_auth_con_init(context, &new_auth_context)))
            goto cleanup;
        *auth_context = new_auth_context;
     }
 
     /* set auth context keyblock */
-    if (retval = krb5_copy_keyblock(context, &in_creds->keyblock, 
-                                   &((*auth_context)->keyblock))) 
+    if ((retval = krb5_copy_keyblock(context, &in_creds->keyblock, 
+                                    &((*auth_context)->keyblock))))
        goto cleanup;
 
     /* generate seq number if needed */
     if ((((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
      || ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
       && ((*auth_context)->local_seq_number == 0)) 
-       if (retval = krb5_generate_seq_number(context, &in_creds->keyblock,
-                                    &(*auth_context)->local_seq_number))
+       if ((retval = krb5_generate_seq_number(context, &in_creds->keyblock,
+                                    &(*auth_context)->local_seq_number)))
            goto cleanup;
        
 
     /* generate subkey if needed */
-    if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey))
-       if (retval = krb5_generate_subkey(context, &(in_creds)->keyblock, 
-                                         &(*auth_context)->local_subkey))
+    if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey)) {
+       /* Provide some more fodder for random number code.
+          This isn't strong cryptographically; the point here is not
+          to guarantee randomness, but to make it less likely that multiple
+          sessions could pick the same subkey.  */
+       struct {
+           krb5_int32 sec, usec;
+       } rnd_data;
+       krb5_data d;
+       krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec);
+       d.length = sizeof (rnd_data);
+       d.data = (char *) &rnd_data;
+       (void) krb5_c_random_seed (context, &d);
+
+       if ((retval = krb5_generate_subkey(context, &(in_creds)->keyblock, 
+                                          &(*auth_context)->local_subkey)))
            goto cleanup;
-
+    }
 
     if (in_data) {
-      if ((*auth_context)->cksumtype == 0x8003) {
-       /* XXX Special hack for GSSAPI */
-       checksum.checksum_type = 0x8003;
-       checksum.length = in_data->length;
-       checksum.contents = (krb5_octet *) in_data->data;
-      } else  {
-       /* Generate checksum, XXX What should the seed be? */
-       if ((checksum.contents = (krb5_octet *)malloc(krb5_checksum_size(context,
-                                (*auth_context)->cksumtype))) == NULL) {
-         retval = ENOMEM;
-         goto cleanup;
+       if ((*auth_context)->req_cksumtype == 0x8003) {
+           /* XXX Special hack for GSSAPI */
+           checksum.checksum_type = 0x8003;
+           checksum.length = in_data->length;
+           checksum.contents = (krb5_octet *) in_data->data;
+       } else {
+           if ((retval = krb5_c_make_checksum(context, 
+                                              (*auth_context)->req_cksumtype,
+                                              (*auth_context)->keyblock,
+                                              KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
+                                              in_data, &checksum)))
+               goto cleanup_cksum;
        }
-       if (retval = krb5_calculate_checksum(context, 
-                                            (*auth_context)->cksumtype, 
-                                            in_data->data, in_data->length,
-                                            (*auth_context)->keyblock->contents,
-                                            (*auth_context)->keyblock->length,
-                                            &checksum))
-         goto cleanup_cksum;
-      }
-      checksump = &checksum;
+       checksump = &checksum;
     }
 
     /* Generate authenticator */
@@ -163,15 +169,17 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
        goto cleanup_cksum;
     }
 
-    if (retval = krb5_generate_authenticator(context, (*auth_context)->authentp,
-                                            (in_creds)->client, checksump,
-                                            (*auth_context)->local_subkey,
-                                            (*auth_context)->local_seq_number,
-                                            (in_creds)->authdata))
+    if ((retval = krb5_generate_authenticator(context,
+                                             (*auth_context)->authentp,
+                                             (in_creds)->client, checksump,
+                                             (*auth_context)->local_subkey,
+                                             (*auth_context)->local_seq_number,
+                                             (in_creds)->authdata)))
        goto cleanup_cksum;
        
     /* encode the authenticator */
-    if (retval = encode_krb5_authenticator((*auth_context)->authentp, &scratch))
+    if ((retval = encode_krb5_authenticator((*auth_context)->authentp,
+                                           &scratch)))
        goto cleanup_cksum;
     
     /* Null out these fields, to prevent pointer sharing problems;
@@ -181,47 +189,20 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
     (*auth_context)->authentp->checksum = NULL;
     (*auth_context)->authentp->authorization_data = NULL;
 
-    /* put together an eblock for this encryption */
-
-    krb5_use_cstype(context, &eblock, request.ticket->enc_part.etype);
-    request.authenticator.etype = request.ticket->enc_part.etype;
-    request.authenticator.kvno = 0;
-    request.authenticator.ciphertext.length =
-       krb5_encrypt_size(scratch->length, eblock.crypto_entry);
-    /* add padding area, and zero it */
-    if (!(scratch->data = realloc(scratch->data,
-                                 request.authenticator.ciphertext.length))) {
-       /* may destroy scratch->data */
-       retval = ENOMEM;
-       goto cleanup_cksum;
-    }
-    memset(scratch->data + scratch->length, 0,
-         request.authenticator.ciphertext.length - scratch->length);
-    if (!(request.authenticator.ciphertext.data =
-         malloc(request.authenticator.ciphertext.length))) {
-       retval = ENOMEM;
-       goto cleanup_cksum;
-    }
-
-    /* do any necessary key pre-processing */
-    if (retval = krb5_process_key(context, &eblock, &(in_creds)->keyblock))
-       goto cleanup;
-
     /* call the encryption routine */
-    if (retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
-                             (krb5_pointer) request.authenticator.ciphertext.data,
-                             scratch->length, &eblock, 0)) {
-        krb5_finish_key(context, &eblock);
+    if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock,
+                                     KRB5_KEYUSAGE_AP_REQ_AUTH,
+                                     scratch, &request.authenticator)))
        goto cleanup_cksum;
-    }
 
-    if (retval = krb5_finish_key(context, &eblock))
+    if ((retval = encode_krb5_ap_req(&request, &toutbuf)))
        goto cleanup_cksum;
-    
-    if (retval = encode_krb5_ap_req(&request, &toutbuf))
-       goto cleanup_cksum;
-    
+#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
     *outbuf = *toutbuf;
+#else
+    memcpy(outbuf, toutbuf, sizeof(krb5_data));
+#endif
+
     krb5_xfree(toutbuf);
 
 cleanup_cksum:
@@ -264,7 +245,6 @@ krb5_generate_authenticator(context, authent, client, cksum, key, seq_number, au
            return retval;
     } else
        authent->subkey = 0;
-    authent->subkey = key;
     authent->seq_number = seq_number;
     authent->authorization_data = authorization;