⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkinit.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
			       content.data,			       content.length,			       ctx->id,			       &contentType,			       &content,			       &host);    if (ret)	goto out;    /* make sure that it is the kdc's certificate */    ret = pk_verify_host(context, realm, hi, ctx, host);    if (ret) {	goto out;    }#if 0    if (type == COMPAT_WIN2K) {	if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {	    krb5_set_error_string(context, "PKINIT: reply key, wrong oid");	    ret = KRB5KRB_AP_ERR_MSG_TYPE;	    goto out;	}    } else {	if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) {	    krb5_set_error_string(context, "PKINIT: reply key, wrong oid");	    ret = KRB5KRB_AP_ERR_MSG_TYPE;	    goto out;	}    }#endif    switch(type) {    case COMPAT_WIN2K:	ret = get_reply_key(context, &content, req_buffer, key);	if (ret != 0 && ctx->require_binding == 0)	    ret = get_reply_key_win(context, &content, nonce, key);	break;    case COMPAT_IETF:	ret = get_reply_key(context, &content, req_buffer, key);	break;    }    if (ret)	goto out;    /* XXX compare given etype with key->etype */ out:    if (host)	_krb5_pk_cert_free(host);    der_free_oid(&contentType);    krb5_data_free(&content);    return ret;}static krb5_error_codepk_rd_pa_reply_dh(krb5_context context,		  const heim_octet_string *indata,		  const heim_oid *dataType,		  const char *realm,		  krb5_pk_init_ctx ctx,		  krb5_enctype etype,		  const krb5_krbhst_info *hi,		  const DHNonce *c_n,		  const DHNonce *k_n,                  unsigned nonce,                  PA_DATA *pa,                  krb5_keyblock **key){    unsigned char *p, *dh_gen_key = NULL;    struct krb5_pk_cert *host = NULL;    BIGNUM *kdc_dh_pubkey = NULL;    KDCDHKeyInfo kdc_dh_info;    heim_oid contentType = { 0, NULL };    krb5_data content;    krb5_error_code ret;    int dh_gen_keylen;    size_t size;    krb5_data_zero(&content);    memset(&kdc_dh_info, 0, sizeof(kdc_dh_info));    if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), dataType)) {	krb5_set_error_string(context, "PKINIT: Invalid content type");	return EINVAL;    }    ret = _krb5_pk_verify_sign(context, 			       indata->data,			       indata->length,			       ctx->id,			       &contentType,			       &content,			       &host);    if (ret)	goto out;    /* make sure that it is the kdc's certificate */    ret = pk_verify_host(context, realm, hi, ctx, host);    if (ret)	goto out;    if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) {	krb5_set_error_string(context, "pkinit - dh reply contains wrong oid");	ret = KRB5KRB_AP_ERR_MSG_TYPE;	goto out;    }    ret = decode_KDCDHKeyInfo(content.data,			      content.length,			      &kdc_dh_info,			      &size);    if (ret) {	krb5_set_error_string(context, "pkinit - "			      "failed to decode KDC DH Key Info");	goto out;    }    if (kdc_dh_info.nonce != nonce) {	krb5_set_error_string(context, "PKINIT: DH nonce is wrong");	ret = KRB5KRB_AP_ERR_MODIFIED;	goto out;    }    if (kdc_dh_info.dhKeyExpiration) {	if (k_n == NULL) {	    krb5_set_error_string(context, "pkinit; got key expiration "				  "without server nonce");	    ret = KRB5KRB_ERR_GENERIC;	    goto out;	}	if (c_n == NULL) {	    krb5_set_error_string(context, "pkinit; got DH reuse but no "				  "client nonce");	    ret = KRB5KRB_ERR_GENERIC;	    goto out;	}    } else {	if (k_n) {	    krb5_set_error_string(context, "pkinit: got server nonce "				  "without key expiration");	    ret = KRB5KRB_ERR_GENERIC;	    goto out;	}	c_n = NULL;    }    p = kdc_dh_info.subjectPublicKey.data;    size = (kdc_dh_info.subjectPublicKey.length + 7) / 8;    {	DHPublicKey k;	ret = decode_DHPublicKey(p, size, &k, NULL);	if (ret) {	    krb5_set_error_string(context, "pkinit: can't decode "				  "without key expiration");	    goto out;	}	kdc_dh_pubkey = integer_to_BN(context, "DHPublicKey", &k);	free_DHPublicKey(&k);	if (kdc_dh_pubkey == NULL) {	    ret = KRB5KRB_ERR_GENERIC;	    goto out;	}    }        dh_gen_keylen = DH_size(ctx->dh);    size = BN_num_bytes(ctx->dh->p);    if (size < dh_gen_keylen)	size = dh_gen_keylen;    dh_gen_key = malloc(size);    if (dh_gen_key == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	ret = ENOMEM;	goto out;    }    memset(dh_gen_key, 0, size - dh_gen_keylen);    dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),				   kdc_dh_pubkey, ctx->dh);    if (dh_gen_keylen == -1) {	krb5_set_error_string(context, 			      "PKINIT: Can't compute Diffie-Hellman key");	ret = KRB5KRB_ERR_GENERIC;	goto out;    }    *key = malloc (sizeof (**key));    if (*key == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	ret = ENOMEM;	goto out;    }    ret = _krb5_pk_octetstring2key(context,				   etype,				   dh_gen_key, dh_gen_keylen,				   c_n, k_n,				   *key);    if (ret) {	krb5_set_error_string(context,			      "PKINIT: can't create key from DH key");	free(*key);	*key = NULL;	goto out;    } out:    if (kdc_dh_pubkey)	BN_free(kdc_dh_pubkey);    if (dh_gen_key) {	memset(dh_gen_key, 0, DH_size(ctx->dh));	free(dh_gen_key);    }    if (host)	_krb5_pk_cert_free(host);    if (content.data)	krb5_data_free(&content);    der_free_oid(&contentType);    free_KDCDHKeyInfo(&kdc_dh_info);    return ret;}krb5_error_code KRB5_LIB_FUNCTION_krb5_pk_rd_pa_reply(krb5_context context,		     const char *realm,		     void *c,		     krb5_enctype etype,		     const krb5_krbhst_info *hi,		     unsigned nonce,		     const krb5_data *req_buffer,		     PA_DATA *pa,		     krb5_keyblock **key){    krb5_pk_init_ctx ctx = c;    krb5_error_code ret;    size_t size;    /* Check for IETF PK-INIT first */    if (ctx->type == COMPAT_IETF) {	PA_PK_AS_REP rep;	heim_octet_string os, data;	heim_oid oid;		if (pa->padata_type != KRB5_PADATA_PK_AS_REP) {	    krb5_set_error_string(context, "PKINIT: wrong padata recv");	    return EINVAL;	}	ret = decode_PA_PK_AS_REP(pa->padata_value.data,				  pa->padata_value.length,				  &rep,				  &size);	if (ret) {	    krb5_set_error_string(context, "Failed to decode pkinit AS rep");	    return ret;	}	switch (rep.element) {	case choice_PA_PK_AS_REP_dhInfo:	    os = rep.u.dhInfo.dhSignedData;	    break;	case choice_PA_PK_AS_REP_encKeyPack:	    os = rep.u.encKeyPack;	    break;	default:	    free_PA_PK_AS_REP(&rep);	    krb5_set_error_string(context, "PKINIT: -27 reply "				  "invalid content type");	    return EINVAL;	}	ret = hx509_cms_unwrap_ContentInfo(&os, &oid, &data, NULL);	if (ret) {	    free_PA_PK_AS_REP(&rep);	    krb5_set_error_string(context, "PKINIT: failed to unwrap CI");	    return ret;	}	switch (rep.element) {	case choice_PA_PK_AS_REP_dhInfo:	    ret = pk_rd_pa_reply_dh(context, &data, &oid, realm, ctx, etype, hi,				    ctx->clientDHNonce,				    rep.u.dhInfo.serverDHNonce,				    nonce, pa, key);	    break;	case choice_PA_PK_AS_REP_encKeyPack:	    ret = pk_rd_pa_reply_enckey(context, COMPAT_IETF, &data, &oid, realm, 					ctx, etype, hi, nonce, req_buffer, pa, key);	    break;	default:	    krb5_abortx(context, "pk-init as-rep case not possible to happen");	}	der_free_octet_string(&data);	der_free_oid(&oid);	free_PA_PK_AS_REP(&rep);    } else if (ctx->type == COMPAT_WIN2K) {	PA_PK_AS_REP_Win2k w2krep;	/* Check for Windows encoding of the AS-REP pa data */ #if 0 /* should this be ? */	if (pa->padata_type != KRB5_PADATA_PK_AS_REP) {	    krb5_set_error_string(context, "PKINIT: wrong padata recv");	    return EINVAL;	}#endif	memset(&w2krep, 0, sizeof(w2krep));		ret = decode_PA_PK_AS_REP_Win2k(pa->padata_value.data,					pa->padata_value.length,					&w2krep,					&size);	if (ret) {	    krb5_set_error_string(context, "PKINIT: Failed decoding windows "				  "pkinit reply %d", ret);	    return ret;	}	krb5_clear_error_string(context);		switch (w2krep.element) {	case choice_PA_PK_AS_REP_Win2k_encKeyPack: {	    heim_octet_string data;	    heim_oid oid;	    	    ret = hx509_cms_unwrap_ContentInfo(&w2krep.u.encKeyPack, 					       &oid, &data, NULL);	    free_PA_PK_AS_REP_Win2k(&w2krep);	    if (ret) {		krb5_set_error_string(context, "PKINIT: failed to unwrap CI");		return ret;	    }	    ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &data, &oid, realm,					ctx, etype, hi, nonce, req_buffer, pa, key);	    der_free_octet_string(&data);	    der_free_oid(&oid);	    break;	}	default:	    free_PA_PK_AS_REP_Win2k(&w2krep);	    krb5_set_error_string(context, "PKINIT: win2k reply invalid "				  "content type");	    ret = EINVAL;	    break;	}        } else {	krb5_set_error_string(context, "PKINIT: unknown reply type");	ret = EINVAL;    }    return ret;}struct prompter {    krb5_context context;    krb5_prompter_fct prompter;    void *prompter_data;};static int hx_pass_prompter(void *data, const hx509_prompt *prompter){    krb5_error_code ret;    krb5_prompt prompt;    krb5_data password_data;    struct prompter *p = data;       password_data.data   = prompter->reply.data;    password_data.length = prompter->reply.length;    prompt.prompt = prompter->prompt;    prompt.hidden = hx509_prompt_hidden(prompter->type);    prompt.reply  = &password_data;    switch (prompter->type) {    case HX509_PROMPT_TYPE_INFO:	prompt.type   = KRB5_PROMPT_TYPE_INFO;	break;    case HX509_PROMPT_TYPE_PASSWORD:    case HX509_PROMPT_TYPE_QUESTION:    default:	prompt.type   = KRB5_PROMPT_TYPE_PASSWORD;	break;    }	       ret = (*p->prompter)(p->context, p->prompter_data, NULL, NULL, 1, &prompt);    if (ret) {	memset (prompter->reply.data, 0, prompter->reply.length);	return 1;    }    return 0;}void KRB5_LIB_FUNCTION_krb5_pk_allow_proxy_certificate(struct krb5_pk_identity *id,				 int boolean){    hx509_verify_set_proxy_certificate(id->verify_ctx, boolean);}krb5_error_code KRB5_LIB_FUNCTION_krb5_pk_load_id(krb5_context context,		 struct krb5_pk_identity **ret_id,		 const char *user_id,		 const char *anchor_id,		 char * const *chain_list,		 char * const *revoke_list,		 krb5_prompter_fct prompter,		 void *prompter_data,		 char *password){    struct krb5_pk_identity *id = NULL;    hx509_lock lock = NULL;    struct prompter p;    int ret;    *ret_id = NULL;    if (anchor_id == NULL) {	krb5_set_error_string(context, "PKINIT: No anchor given");	return HEIM_PKINIT_NO_VALID_CA;    }    if (user_id == NULL) {	krb5_set_error_string(context,			      "PKINIT: No user certificate given");	return HEIM_PKINIT_NO_PRIVATE_KEY;    }    /* load cert */    id = calloc(1, sizeof(*id));    if (id == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	return ENOMEM;    }	    ret = hx509_context_init(&id->hx509ctx);    if (ret)	goto out;    ret = hx509_lock_init(id->hx509ctx, &lock);    if (password && password[0])	hx509_lock_add_password(lock, password);    if (prompter) {	p.context = context;	p.prompter = prompter;	p.prompter_data = prompter_data;	ret = hx509_lock_set_prompter(lock, hx_pass_prompter, &p);	if (ret)	    goto out;    }    ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret,			    "Failed to init cert certs");	goto out;    }    ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret,			    "Failed to init anchors");	goto out;    }    ret = hx509_certs_init(id->hx509ctx, "MEMORY:pkinit-cert-chain", 			   0, NULL, &id->certpool);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret,			    "Failed to init chain");	goto out;    }    while (chain_list && *chain_list) {	ret = hx509_certs_append(id->hx509ctx, id->certpool,				 NULL, *chain_list);	if (ret) {	    _krb5_pk_copy_error(context, id->hx509ctx, ret,				"Failed to laod chain %s",				*chain_list);	    goto out;	}	chain_list++;    }    if (revoke_list) {	ret = hx509_revoke_init(id->hx509ctx, &id->revokectx);	if (ret) {	    _krb5_pk_copy_error(context, id->hx509ctx, ret,				"Failed init revoke list");	    goto out;	}	while (*revoke_list) {	    ret = hx509_revoke_add_crl(id->hx509ctx, 				       id->revokectx,				       *revoke_list);	    if (ret) {		_krb5_pk_copy_error(context, id->hx509ctx, ret, 				    "Failed load revoke list");		goto out;	    }	    revoke_list++;	}    } else	hx509_context_set_missing_revoke(id->hx509ctx, 1);    ret = hx509_verify_init_ctx(id->hx509ctx, &id->verify_ctx);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret, 			    "Failed init verify context");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -