Esempio n. 1
0
krb5_error_code
securid_make_sam_challenge_2_and_cksum(krb5_context context,
                                       krb5_sam_challenge_2 *sc2,
                                       krb5_sam_challenge_2_body *sc2b,
                                       krb5_keyblock *cksum_key)
{
    krb5_error_code retval;
    krb5_checksum **cksum_array = NULL;
    krb5_checksum *cksum = NULL;
    krb5_cksumtype cksumtype;
    krb5_data *encoded_challenge_body = NULL;

    if (!cksum_key)
        return KRB5_PREAUTH_NO_KEY;
    if (!sc2 || !sc2b)
        return KRB5KDC_ERR_PREAUTH_FAILED;

    retval = encode_krb5_sam_challenge_2_body(sc2b, &encoded_challenge_body);
    if (retval || !encoded_challenge_body) {
        encoded_challenge_body = NULL;
        goto cksum_cleanup;
    }

    cksum_array = calloc(2, sizeof(krb5_checksum *));
    if (!cksum_array) {
        retval = ENOMEM;
        goto cksum_cleanup;
    }

    cksum = (krb5_checksum *)k5alloc(sizeof(krb5_checksum), &retval);
    if (retval)
        goto cksum_cleanup;
    cksum_array[0] = cksum;
    cksum_array[1] = NULL;

    retval = krb5int_c_mandatory_cksumtype(context, cksum_key->enctype,
                                           &cksumtype);
    if (retval)
        goto cksum_cleanup;

    retval = krb5_c_make_checksum(context, cksumtype, cksum_key,
                                  KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM,
                                  encoded_challenge_body, cksum);
    if (retval)
        goto cksum_cleanup;

    sc2->sam_cksum = cksum_array;
    sc2->sam_challenge_2_body = *encoded_challenge_body;
    return 0;

cksum_cleanup:
    krb5_free_data(context, encoded_challenge_body);
    free(cksum_array);
    free(cksum);
    return retval;
}
Esempio n. 2
0
static krb5_error_code
make_ad_signedpath_checksum(krb5_context context,
                            krb5_const_principal for_user_princ,
                            const krb5_db_entry *krbtgt,
                            krb5_keyblock *krbtgt_key,
                            krb5_enc_tkt_part *enc_tkt_part,
                            krb5_principal *deleg_path,
                            krb5_pa_data **method_data,
                            krb5_checksum *cksum)
{
    krb5_error_code                 code;
    krb5_data                      *data;
    krb5_cksumtype                  cksumtype;
    krb5_const_principal            client;

    if (for_user_princ != NULL)
        client = for_user_princ;
    else
        client = enc_tkt_part->client;

    code = make_ad_signedpath_data(context,
                                   client,
                                   enc_tkt_part->times.authtime,
                                   deleg_path,
                                   method_data,
                                   enc_tkt_part->authorization_data,
                                   &data);
    if (code != 0)
        return code;

    code = krb5int_c_mandatory_cksumtype(context,
                                         krbtgt_key->enctype,
                                         &cksumtype);
    if (code != 0) {
        krb5_free_data(context, data);
        return code;
    }

    if (!krb5_c_is_keyed_cksum(cksumtype)) {
        krb5_free_data(context, data);
        return KRB5KRB_AP_ERR_INAPP_CKSUM;
    }

    code = krb5_c_make_checksum(context, cksumtype, krbtgt_key,
                                KRB5_KEYUSAGE_AD_SIGNEDPATH, data,
                                cksum);

    krb5_free_data(context, data);

    return code;
}
Esempio n. 3
0
krb5_error_code KRB5_CALLCONV
krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype,
                     krb5_key key, krb5_keyusage usage,
                     const krb5_data *input, krb5_checksum *cksum)
{
    const struct krb5_cksumtypes *ctp;
    krb5_crypto_iov iov;
    krb5_data cksum_data;
    krb5_octet *trunc;
    krb5_error_code ret;

    if (cksumtype == 0) {
        ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype,
                                            &cksumtype);
        if (ret != 0)
            return ret;
    }
    ctp = find_cksumtype(cksumtype);
    if (ctp == NULL)
        return KRB5_BAD_ENCTYPE;

    ret = verify_key(ctp, key);
    if (ret != 0)
        return ret;

    ret = alloc_data(&cksum_data, ctp->compute_size);
    if (ret != 0)
        return ret;

    iov.flags = KRB5_CRYPTO_TYPE_DATA;
    iov.data = *input;
    ret = ctp->checksum(ctp, key, usage, &iov, 1, &cksum_data);
    if (ret != 0)
        goto cleanup;

    cksum->magic = KV5M_CHECKSUM;
    cksum->checksum_type = cksumtype;
    cksum->length = ctp->output_size;
    cksum->contents = (krb5_octet *) cksum_data.data;
    cksum_data.data = NULL;
    if (ctp->output_size < ctp->compute_size) {
        trunc = realloc(cksum->contents, ctp->output_size);
        if (trunc != NULL)
            cksum->contents = trunc;
    }

cleanup:
    zapfree(cksum_data.data, ctp->compute_size);
    return ret;
}
Esempio n. 4
0
static krb5_error_code
k5_insert_checksum(krb5_context context,
                   krb5_pac pac,
                   krb5_ui_4 type,
                   const krb5_keyblock *key,
                   krb5_cksumtype *cksumtype)
{
    krb5_error_code ret;
    size_t len;
    krb5_data cksumdata;

    ret = krb5int_c_mandatory_cksumtype(context, key->enctype, cksumtype);
    if (ret != 0)
        return ret;

    ret = krb5_c_checksum_length(context, *cksumtype, &len);
    if (ret != 0)
        return ret;

    ret = k5_pac_locate_buffer(context, pac, type, &cksumdata);
    if (ret == 0) {
        /*
         * If we're resigning PAC, make sure we can fit checksum
         * into existing buffer
         */
        if (cksumdata.length != PAC_SIGNATURE_DATA_LENGTH + len)
            return ERANGE;

        memset(cksumdata.data, 0, cksumdata.length);
    } else {
        /* Add a zero filled buffer */
        cksumdata.length = PAC_SIGNATURE_DATA_LENGTH + len;
        cksumdata.data = NULL;

        ret = k5_pac_add_buffer(context, pac,
                                type, &cksumdata,
                                TRUE, &cksumdata);
        if (ret != 0)
            return ret;
    }

    /* Encode checksum type into buffer */
    store_32_le((krb5_ui_4)*cksumtype, cksumdata.data);

    return 0;
}
Esempio n. 5
0
/* Construct an AP-REQ message for a TGS request. */
static krb5_error_code
tgs_construct_ap_req(krb5_context context, krb5_data *checksum_data,
                     krb5_creds *tgt, krb5_keyblock *subkey,
                     krb5_data **ap_req_asn1_out)
{
    krb5_cksumtype cksumtype;
    krb5_error_code ret;
    krb5_checksum checksum;
    krb5_authenticator authent;
    krb5_ap_req ap_req;
    krb5_data *authent_asn1 = NULL;
    krb5_ticket *ticket = NULL;
    krb5_enc_data authent_enc;

    *ap_req_asn1_out = NULL;
    memset(&checksum, 0, sizeof(checksum));
    memset(&ap_req, 0, sizeof(ap_req));
    memset(&authent_enc, 0, sizeof(authent_enc));

    /* Determine the authenticator checksum type. */
    switch (tgt->keyblock.enctype) {
    case ENCTYPE_DES_CBC_CRC:
    case ENCTYPE_DES_CBC_MD4:
    case ENCTYPE_DES_CBC_MD5:
    case ENCTYPE_ARCFOUR_HMAC:
    case ENCTYPE_ARCFOUR_HMAC_EXP:
        cksumtype = context->kdc_req_sumtype;
        break;
    default:
        ret = krb5int_c_mandatory_cksumtype(context, tgt->keyblock.enctype,
                                            &cksumtype);
        if (ret)
            goto cleanup;
    }

    /* Generate checksum. */
    ret = krb5_c_make_checksum(context, cksumtype, &tgt->keyblock,
                               KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM, checksum_data,
                               &checksum);
    if (ret)
        goto cleanup;

    /* Construct, encode, and encrypt an authenticator. */
    authent.subkey = subkey;
    authent.seq_number = 0;
    authent.checksum = &checksum;
    authent.client = tgt->client;
    authent.authorization_data = tgt->authdata;
    ret = krb5_us_timeofday(context, &authent.ctime, &authent.cusec);
    if (ret)
        goto cleanup;
    ret = encode_krb5_authenticator(&authent, &authent_asn1);
    if (ret)
        goto cleanup;
    ret = krb5_encrypt_helper(context, &tgt->keyblock,
                              KRB5_KEYUSAGE_TGS_REQ_AUTH, authent_asn1,
                              &authent_enc);
    if (ret)
        goto cleanup;

    ret = decode_krb5_ticket(&tgt->ticket, &ticket);
    if (ret)
        goto cleanup;

    /* Encode the AP-REQ. */
    ap_req.authenticator = authent_enc;
    ap_req.ticket = ticket;
    ret = encode_krb5_ap_req(&ap_req, ap_req_asn1_out);

cleanup:
    free(checksum.contents);
    krb5_free_ticket(context, ticket);
    krb5_free_data_contents(context, &authent_enc.ciphertext);
    if (authent_asn1 != NULL)
        zapfree(authent_asn1->data, authent_asn1->length);
    free(authent_asn1);
    return ret;
}
Esempio n. 6
0
krb5_error_code KRB5_CALLCONV
krb5_mk_safe(krb5_context context, krb5_auth_context auth_context,
             const krb5_data *userdata, krb5_data *outbuf,
             krb5_replay_data *outdata)
{
    krb5_error_code       retval;
    krb5_key              key;
    krb5_replay_data      replaydata;

    /* Clear replaydata block */
    memset(&replaydata, 0, sizeof(krb5_replay_data));

    /* Get key */
    if ((key = auth_context->send_subkey) == NULL)
        key = auth_context->key;

    /* Get replay info */
    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
        (auth_context->rcache == NULL))
        return KRB5_RC_REQUIRED;

    if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) ||
         (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
        (outdata == NULL))
        /* Need a better error */
        return KRB5_RC_REQUIRED;

    if (!auth_context->local_addr)
        return KRB5_LOCAL_ADDR_REQUIRED;

    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) ||
        (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME)) {
        if ((retval = krb5_us_timeofday(context, &replaydata.timestamp,
                                        &replaydata.usec)))
            return retval;
        if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) {
            outdata->timestamp = replaydata.timestamp;
            outdata->usec = replaydata.usec;
        }
    }
    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
        (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) {
        replaydata.seq = auth_context->local_seq_number++;
        if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)
            outdata->seq = replaydata.seq;
    }

    {
        krb5_address * premote_fulladdr = NULL;
        krb5_address * plocal_fulladdr;
        krb5_address remote_fulladdr;
        krb5_address local_fulladdr;
        krb5_cksumtype sumtype;

        CLEANUP_INIT(2);

        if (auth_context->local_port) {
            if (!(retval = krb5_make_fulladdr(context, auth_context->local_addr,
                                              auth_context->local_port,
                                              &local_fulladdr))){
                CLEANUP_PUSH(local_fulladdr.contents, free);
                plocal_fulladdr = &local_fulladdr;
            } else {
                goto error;
            }
        } else {
            plocal_fulladdr = auth_context->local_addr;
        }

        if (auth_context->remote_addr) {
            if (auth_context->remote_port) {
                if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr,
                                                  auth_context->remote_port,
                                                  &remote_fulladdr))){
                    CLEANUP_PUSH(remote_fulladdr.contents, free);
                    premote_fulladdr = &remote_fulladdr;
                } else {
                    CLEANUP_DONE();
                    goto error;
                }
            } else {
                premote_fulladdr = auth_context->remote_addr;
            }
        }

        {
            krb5_enctype enctype = krb5_k_key_enctype(context, key);
            unsigned int nsumtypes;
            unsigned int i;
            krb5_cksumtype *sumtypes;
            retval = krb5_c_keyed_checksum_types (context, enctype,
                                                  &nsumtypes, &sumtypes);
            if (retval) {
                CLEANUP_DONE ();
                goto error;
            }
            if (nsumtypes == 0) {
                retval = KRB5_BAD_ENCTYPE;
                krb5_free_cksumtypes (context, sumtypes);
                CLEANUP_DONE ();
                goto error;
            }
            for (i = 0; i < nsumtypes; i++)
                if (auth_context->safe_cksumtype == sumtypes[i])
                    break;
            krb5_free_cksumtypes (context, sumtypes);
            if (i < nsumtypes)
                sumtype = auth_context->safe_cksumtype;
            else {
                switch (enctype) {
                case ENCTYPE_DES_CBC_MD4:
                    sumtype = CKSUMTYPE_RSA_MD4_DES;
                    break;
                case ENCTYPE_DES_CBC_MD5:
                case ENCTYPE_DES_CBC_CRC:
                    sumtype = CKSUMTYPE_RSA_MD5_DES;
                    break;
                default:
                    retval = krb5int_c_mandatory_cksumtype(context, enctype,
                                                           &sumtype);
                    if (retval) {
                        CLEANUP_DONE();
                        goto error;
                    }
                    break;
                }
            }
        }
        if ((retval = krb5_mk_safe_basic(context, userdata, key, &replaydata,
                                         plocal_fulladdr, premote_fulladdr,
                                         sumtype, outbuf))) {
            CLEANUP_DONE();
            goto error;
        }

        CLEANUP_DONE();
    }

    if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
        krb5_donot_replay replay;

        if ((retval = krb5_gen_replay_name(context, auth_context->local_addr,
                                           "_safe", &replay.client))) {
            free(outbuf);
            goto error;
        }

        replay.server = "";             /* XXX */
        replay.msghash = NULL;
        replay.cusec = replaydata.usec;
        replay.ctime = replaydata.timestamp;
        if ((retval = krb5_rc_store(context, auth_context->rcache, &replay))) {
            /* should we really error out here? XXX */
            free(outbuf);
            goto error;
        }
        free(replay.client);
    }

    return 0;

error:
    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--;

    return retval;
}
Esempio n. 7
0
krb5_error_code
kdc_fast_response_handle_padata(struct kdc_request_state *state,
                                krb5_kdc_req *request,
                                krb5_kdc_rep *rep, krb5_enctype enctype)
{
    krb5_error_code retval = 0;
    krb5_fast_finished finish;
    krb5_fast_response fast_response;
    krb5_data *encoded_ticket = NULL;
    krb5_data *encrypted_reply = NULL;
    krb5_pa_data *pa = NULL, **pa_array = NULL;
    krb5_cksumtype cksumtype = CKSUMTYPE_RSA_MD5;
    krb5_pa_data *empty_padata[] = {NULL};
    krb5_keyblock *strengthen_key = NULL;
    kdc_realm_t *kdc_active_realm = state->realm_data;

    if (!state->armor_key)
        return 0;
    memset(&finish, 0, sizeof(finish));
    retval = krb5_init_keyblock(kdc_context, enctype, 0, &strengthen_key);
    if (retval == 0)
        retval = krb5_c_make_random_key(kdc_context, enctype, strengthen_key);
    if (retval == 0) {
        state->strengthen_key = strengthen_key;
        strengthen_key = NULL;
    }

    fast_response.padata = rep->padata;
    if (fast_response.padata == NULL)
        fast_response.padata = &empty_padata[0];
    fast_response.strengthen_key = state->strengthen_key;
    fast_response.nonce = request->nonce;
    fast_response.finished = &finish;
    finish.client = rep->client;
    pa_array = calloc(3, sizeof(*pa_array));
    if (pa_array == NULL)
        retval = ENOMEM;
    pa = calloc(1, sizeof(krb5_pa_data));
    if (retval == 0 && pa == NULL)
        retval = ENOMEM;
    if (retval == 0)
        retval = krb5_us_timeofday(kdc_context, &finish.timestamp, &finish.usec);
    if (retval == 0)
        retval = encode_krb5_ticket(rep->ticket, &encoded_ticket);
    if (retval == 0)
        retval = krb5int_c_mandatory_cksumtype(kdc_context,
                                               state->armor_key->enctype,
                                               &cksumtype);
    if (retval == 0)
        retval = krb5_c_make_checksum(kdc_context, cksumtype,
                                      state->armor_key,
                                      KRB5_KEYUSAGE_FAST_FINISHED,
                                      encoded_ticket, &finish.ticket_checksum);
    if (retval == 0)
        retval = encrypt_fast_reply(state, &fast_response, &encrypted_reply);
    if (retval == 0) {
        pa[0].pa_type = KRB5_PADATA_FX_FAST;
        pa[0].length = encrypted_reply->length;
        pa[0].contents = (unsigned char *)  encrypted_reply->data;
        pa_array[0] = &pa[0];
        krb5_free_pa_data(kdc_context, rep->padata);
        rep->padata = pa_array;
        pa_array = NULL;
        free(encrypted_reply);
        encrypted_reply = NULL;
        pa = NULL;
    }
    if (pa)
        free(pa);
    if (pa_array)
        free(pa_array);
    if (encrypted_reply)
        krb5_free_data(kdc_context, encrypted_reply);
    if (encoded_ticket)
        krb5_free_data(kdc_context, encoded_ticket);
    if (strengthen_key != NULL)
        krb5_free_keyblock(kdc_context, strengthen_key);
    if (finish.ticket_checksum.contents)
        krb5_free_checksum_contents(kdc_context, &finish.ticket_checksum);
    return retval;
}
Esempio n. 8
0
/* Get the RFC3961 mandator cksumtype for key. */
static inline krb5_error_code
get_cksumtype(krb5_key key, krb5_cksumtype *out)
{
    return krb5int_c_mandatory_cksumtype(NULL, key->keyblock.enctype, out);
}
Esempio n. 9
0
krb5_error_code KRB5_CALLCONV
krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context,
		     krb5_flags ap_req_options, krb5_data *in_data,
		     krb5_creds *in_creds, krb5_data *outbuf)
{
    krb5_error_code 	  retval;
    krb5_checksum	  checksum;
    krb5_checksum	  *checksump = 0;
    krb5_auth_context	  new_auth_context;
    krb5_enctype	  *desired_etypes = NULL;

    krb5_ap_req request;
    krb5_data *scratch = 0;
    krb5_data *toutbuf;

    request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK;
    request.authenticator.ciphertext.data = NULL;
    request.ticket = 0;
    
    if (!in_creds->ticket.length) 
	return(KRB5_NO_TKT_SUPPLIED);

    if ((ap_req_options & AP_OPTS_ETYPE_NEGOTIATION) &&
	!(ap_req_options & AP_OPTS_MUTUAL_REQUIRED))
	return(EINVAL);

    /* we need a native ticket */
    if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket)))
	return(retval);
    
    /* 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)))
	    goto cleanup;
	*auth_context = new_auth_context;
    }

    if ((*auth_context)->keyblock != NULL) {
	krb5_free_keyblock(context, (*auth_context)->keyblock);
	(*auth_context)->keyblock = NULL;
    }

    /* set 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)))
	    goto cleanup;
	

    /* generate subkey if needed */
    if (!in_data &&(*auth_context)->checksum_func) {
	retval = (*auth_context)->checksum_func( context,
						 *auth_context,
						 (*auth_context)->checksum_func_data,
						 &in_data);
	if (retval)
	    goto cleanup;
    }

    if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->send_subkey)) {
	retval = krb5int_generate_and_save_subkey (context, *auth_context,
						   &in_creds->keyblock,
						   in_creds->keyblock.enctype);
	if (retval)
	    goto cleanup;
    }


    if (in_data) {

      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 {
	    krb5_cksumtype cksumtype;
	    retval = krb5int_c_mandatory_cksumtype(context, (*auth_context)->keyblock->enctype,
						   &cksumtype);
	    if (retval)
		goto cleanup_cksum;
	    if ((*auth_context)->req_cksumtype)
		cksumtype = (*auth_context)->req_cksumtype;
	    if ((retval = krb5_c_make_checksum(context, 
					       cksumtype,
					       (*auth_context)->keyblock,
					       KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
					       in_data, &checksum)))
		goto cleanup_cksum;
	}
	checksump = &checksum;
    }

    /* Generate authenticator */
    if (((*auth_context)->authentp = (krb5_authenticator *)malloc(sizeof(
					krb5_authenticator))) == NULL) {
	retval = ENOMEM;
	goto cleanup_cksum;
    }

    if (ap_req_options & AP_OPTS_ETYPE_NEGOTIATION) {
	if ((*auth_context)->permitted_etypes == NULL) {
	    retval = krb5_get_tgs_ktypes(context, in_creds->server, &desired_etypes);
	    if (retval)
		goto cleanup_cksum;
	} else
	    desired_etypes = (*auth_context)->permitted_etypes;
    }

    if ((retval = krb5_generate_authenticator(context,
					      (*auth_context)->authentp,
					      in_creds->client, checksump,
					      (*auth_context)->send_subkey,
					      (*auth_context)->local_seq_number,
					      in_creds->authdata,
					      (*auth_context)->ad_context,
					      desired_etypes,
					      in_creds->keyblock.enctype)))
	goto cleanup_cksum;
	
    /* encode the authenticator */
    if ((retval = encode_krb5_authenticator((*auth_context)->authentp,
					    &scratch)))
	goto cleanup_cksum;
    
    /* call the encryption routine */
    if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock,
				      KRB5_KEYUSAGE_AP_REQ_AUTH,
				      scratch, &request.authenticator)))
	goto cleanup_cksum;

    if ((retval = encode_krb5_ap_req(&request, &toutbuf)))
	goto cleanup_cksum;
    *outbuf = *toutbuf;

    free(toutbuf);

cleanup_cksum:
    /* Null out these fields, to prevent pointer sharing problems;
     * they were supplied by the caller
     */
    if ((*auth_context)->authentp != NULL) {
	(*auth_context)->authentp->client = NULL;
	(*auth_context)->authentp->checksum = NULL;
    }
    if (checksump && checksump->checksum_type != 0x8003)
      free(checksump->contents);

cleanup:
    if (desired_etypes &&
	desired_etypes != (*auth_context)->permitted_etypes)
	free(desired_etypes);
    if (request.ticket)
	krb5_free_ticket(context, request.ticket);
    if (request.authenticator.ciphertext.data) {
    	(void) memset(request.authenticator.ciphertext.data, 0,
		      request.authenticator.ciphertext.length);
	free(request.authenticator.ciphertext.data);
    }
    if (scratch) {
	memset(scratch->data, 0, scratch->length);
        free(scratch->data);
	free(scratch);
    }
    return retval;
}
Esempio n. 10
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context = NULL;
    size_t i;
    struct test *test;
    krb5_keyblock kb, *kbp;
    krb5_checksum cksum;
    krb5_cksumtype mtype;
    krb5_boolean valid, verbose = FALSE;
    int status = 0;

    if (argc >= 2 && strcmp(argv[1], "-v") == 0)
        verbose = TRUE;
    for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) {
        test = &test_cases[i];
        if (test->enctype != 0) {
            kb.magic = KV5M_KEYBLOCK;
            kb.enctype = test->enctype;
            kb.length = test->keybits.length;
            kb.contents = (unsigned char *)test->keybits.data;
            kbp = &kb;
        } else
            kbp = NULL;
        ret = krb5_c_make_checksum(context, test->sumtype, kbp, test->usage,
                                   &test->plaintext, &cksum);
        assert(!ret);
        if (verbose) {
            char buf[64];
            krb5_cksumtype_to_string(test->sumtype, buf, sizeof(buf));
            printf("\nTest %d:\n", (int)i);
            printf("Plaintext: %.*s\n", (int)test->plaintext.length,
                   test->plaintext.data);
            printf("Checksum type: %s\n", buf);
            if (test->enctype != 0) {
                krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf));
                printf("Enctype: %s\n", buf);
                printhex("Key: ", test->keybits.data, test->keybits.length);
                printf("Key usage: %d\n", (int)test->usage);
            }
            printhex("Checksum: ", cksum.contents, cksum.length);
        }
        if (test->cksum.length != cksum.length ||
            memcmp(test->cksum.data, cksum.contents, cksum.length) != 0) {
            printf("derive test %d failed\n", (int)i);
            status = 1;
            if (!verbose)
                break;
        }

        /* Test that the checksum verifies successfully. */
        ret = krb5_c_verify_checksum(context, kbp, test->usage,
                                     &test->plaintext, &cksum, &valid);
        assert(!ret);
        if (!valid) {
            printf("test %d verify failed\n", (int)i);
            status = 1;
            if (!verbose)
                break;
        }

        if (kbp != NULL) {
            ret = krb5int_c_mandatory_cksumtype(context, kbp->enctype, &mtype);
            assert(!ret);
            if (test->sumtype == mtype) {
                /* Test that a checksum type of 0 uses the mandatory checksum
                 * type for the key. */
                cksum.checksum_type = 0;
                ret = krb5_c_verify_checksum(context, kbp, test->usage,
                                             &test->plaintext, &cksum, &valid);
                assert(!ret && valid);
            }
        }

        krb5_free_checksum_contents(context, &cksum);
    }
    return status;
}
Esempio n. 11
0
krb5_error_code 
krb5int_fast_prep_req (krb5_context context, struct krb5int_fast_request_state *state,
		        krb5_kdc_req *request,
		       const krb5_data *to_be_checksummed, kdc_req_encoder_proc encoder,
		       krb5_data **encoded_request)
{
    krb5_error_code retval = 0;
    krb5_pa_data *pa_array[2];
    krb5_pa_data pa[2];
    krb5_fast_req fast_req;
    krb5_fast_armored_req *armored_req = NULL;
    krb5_data *encoded_fast_req = NULL;
    krb5_data *encoded_armored_req = NULL;
    krb5_data *local_encoded_result = NULL;
    krb5_cksumtype cksumtype;
    krb5_data random_data;
    char random_buf[4];


    assert(state != NULL);
    assert(state->fast_outer_request.padata == NULL);
    memset(pa_array, 0, sizeof pa_array);
    if (state->armor_key == NULL) {
	return encoder(request, encoded_request);
    }
/* Fill in a fresh random nonce for each inner request*/
    	random_data.length = 4;
	random_data.data = (char *)random_buf;
	retval = krb5_c_random_make_octets(context, &random_data);
	if (retval == 0) {
	    	    request->nonce = 0x7fffffff & load_32_n(random_buf);
		    state->nonce = request->nonce;
	}
    fast_req.req_body =  request;
    if (fast_req.req_body->padata == NULL) {
	fast_req.req_body->padata = calloc(1, sizeof(krb5_pa_data *));
	if (fast_req.req_body->padata == NULL)
	    retval = ENOMEM;
    }
    fast_req.fast_options = state->fast_options;
    if (retval == 0)
	retval = encode_krb5_fast_req(&fast_req, &encoded_fast_req);
    if (retval == 0) {
	armored_req = calloc(1, sizeof(krb5_fast_armored_req));
	if (armored_req == NULL)
	    retval = ENOMEM;
    }
    if (retval == 0)
	armored_req->armor = state->armor;
    if (retval == 0)
	retval = krb5int_c_mandatory_cksumtype(context, state->armor_key->enctype,
					       &cksumtype);
    if (retval ==0)
	retval = krb5_c_make_checksum(context, cksumtype, state->armor_key,
				      KRB5_KEYUSAGE_FAST_REQ_CHKSUM, to_be_checksummed,
				      &armored_req->req_checksum);
    if (retval == 0)
	retval = krb5_encrypt_helper(context, state->armor_key,
				     KRB5_KEYUSAGE_FAST_ENC, encoded_fast_req,
				     &armored_req->enc_part);
    if (retval == 0)
	retval = encode_krb5_pa_fx_fast_request(armored_req, &encoded_armored_req);
    if (retval==0) {
	pa[0].pa_type = KRB5_PADATA_FX_FAST;
	pa[0].contents = (unsigned char *) encoded_armored_req->data;
	pa[0].length = encoded_armored_req->length;
	pa_array[0] = &pa[0];
    }
    state->fast_outer_request.padata = pa_array;
    if(retval == 0)
	retval = encoder(&state->fast_outer_request, &local_encoded_result);
    if (retval == 0) {
	*encoded_request = local_encoded_result;
	local_encoded_result = NULL;
    }
    if (encoded_armored_req)
	krb5_free_data(context, encoded_armored_req);
    if (armored_req) {
	armored_req->armor = NULL; /*owned by state*/
	krb5_free_fast_armored_req(context, armored_req);
    }
    if (encoded_fast_req)
	krb5_free_data(context, encoded_fast_req);
    if (local_encoded_result)
	krb5_free_data(context, local_encoded_result);
    state->fast_outer_request.padata = NULL;
    return retval;
}