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

📄 pkinit.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (pa->padata_type == KRB5_PADATA_PK_AS_REQ_WIN) {	AuthPack_Win2k ap;	ret = decode_AuthPack_Win2k(eContent.data,				    eContent.length,				    &ap,				    NULL);	if (ret) {	    krb5_set_error_string(context, "can't decode AuthPack: %d", ret);	    goto out;	}  	ret = pk_check_pkauthenticator_win2k(context, 					     &ap.pkAuthenticator,					     req);	if (ret) {	    free_AuthPack_Win2k(&ap);	    goto out;	}	client_params->type = PKINIT_COMPAT_WIN2K;	client_params->nonce = ap.pkAuthenticator.nonce;	if (ap.clientPublicValue) {	    krb5_set_error_string(context, "DH not supported for windows");	    ret = KRB5KRB_ERR_GENERIC;	    goto out;	}	free_AuthPack_Win2k(&ap);    } else if (pa->padata_type == KRB5_PADATA_PK_AS_REQ) {	AuthPack ap;	ret = decode_AuthPack(eContent.data,			      eContent.length,			      &ap,			      NULL);	if (ret) {	    krb5_set_error_string(context, "can't decode AuthPack: %d", ret);	    free_AuthPack(&ap);	    goto out;	}  	ret = pk_check_pkauthenticator(context, 				       &ap.pkAuthenticator,				       req);	if (ret) {	    free_AuthPack(&ap);	    goto out;	}	client_params->type = PKINIT_COMPAT_27;	client_params->nonce = ap.pkAuthenticator.nonce;	if (ap.clientPublicValue) {	    ret = get_dh_param(context, config, 			       ap.clientPublicValue, client_params);	    if (ret) {		free_AuthPack(&ap);		goto out;	    }	}	if (ap.supportedCMSTypes) {	    ret = hx509_peer_info_alloc(kdc_identity->hx509ctx,					&client_params->peer);	    if (ret) {		free_AuthPack(&ap);		goto out;	    }	    ret = hx509_peer_info_set_cms_algs(kdc_identity->hx509ctx,					       client_params->peer,					       ap.supportedCMSTypes->val,					       ap.supportedCMSTypes->len);	    if (ret) {		free_AuthPack(&ap);		goto out;	    }	}	free_AuthPack(&ap);    } else	krb5_abortx(context, "internal pkinit error");    kdc_log(context, config, 0, "PK-INIT request of type %s", type);out:    if (ret)	krb5_warn(context, ret, "PKINIT");    if (signed_content.data)	free(signed_content.data);    krb5_data_free(&eContent);    der_free_oid(&eContentType);    der_free_oid(&contentInfoOid);    if (ret)	_kdc_pk_free_client_param(context, client_params);    else	*ret_params = client_params;    return ret;}/* * */static krb5_error_codeBN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer){    integer->length = BN_num_bytes(bn);    integer->data = malloc(integer->length);    if (integer->data == NULL) {	krb5_clear_error_string(context);	return ENOMEM;    }    BN_bn2bin(bn, integer->data);    integer->negative = BN_is_negative(bn);    return 0;}static krb5_error_codepk_mk_pa_reply_enckey(krb5_context context,		      krb5_kdc_configuration *config,		      pk_client_params *client_params,		      const KDC_REQ *req,		      const krb5_data *req_buffer,		      krb5_keyblock *reply_key,		      ContentInfo *content_info){    const heim_oid *envelopedAlg = NULL, *sdAlg = NULL;    krb5_error_code ret;    krb5_data buf, signed_data;    size_t size;    int do_win2k = 0;    krb5_data_zero(&buf);    krb5_data_zero(&signed_data);    /*     * If the message client is a win2k-type but it send pa data     * 09-binding it expects a IETF (checksum) reply so there can be     * no replay attacks.     */    switch (client_params->type) {    case PKINIT_COMPAT_WIN2K: {	int i = 0;	if (_kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_09_BINDING) == NULL	    && config->pkinit_require_binding == 0)	{	    do_win2k = 1;	}	break;    }    case PKINIT_COMPAT_27:	break;    default:	krb5_abortx(context, "internal pkinit error");    }	        if (do_win2k) {	ReplyKeyPack_Win2k kp;	memset(&kp, 0, sizeof(kp));	envelopedAlg = oid_id_rsadsi_des_ede3_cbc();	sdAlg = oid_id_pkcs7_data();	ret = copy_EncryptionKey(reply_key, &kp.replyKey);	if (ret) {	    krb5_clear_error_string(context);	    goto out;	}	kp.nonce = client_params->nonce;		ASN1_MALLOC_ENCODE(ReplyKeyPack_Win2k, 			   buf.data, buf.length,			   &kp, &size,ret);	free_ReplyKeyPack_Win2k(&kp);    } else {	krb5_crypto ascrypto;	ReplyKeyPack kp;	memset(&kp, 0, sizeof(kp));	sdAlg = oid_id_pkrkeydata();	ret = copy_EncryptionKey(reply_key, &kp.replyKey);	if (ret) {	    krb5_clear_error_string(context);	    goto out;	}	ret = krb5_crypto_init(context, reply_key, 0, &ascrypto);	if (ret) {	    krb5_clear_error_string(context);	    goto out;	}	ret = krb5_create_checksum(context, ascrypto, 6, 0,				   req_buffer->data, req_buffer->length,				   &kp.asChecksum);	if (ret) {	    krb5_clear_error_string(context);	    goto out;	}			     	ret = krb5_crypto_destroy(context, ascrypto);	if (ret) {	    krb5_clear_error_string(context);	    goto out;	}	ASN1_MALLOC_ENCODE(ReplyKeyPack, buf.data, buf.length, &kp, &size,ret);	free_ReplyKeyPack(&kp);    }    if (ret) {	krb5_set_error_string(context, "ASN.1 encoding of ReplyKeyPack "			      "failed (%d)", ret);	goto out;    }    if (buf.length != size)	krb5_abortx(context, "Internal ASN.1 encoder error");    {	hx509_query *q;	hx509_cert cert;		ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);	if (ret)	    goto out;		hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);	hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);		ret = hx509_certs_find(kdc_identity->hx509ctx, 			       kdc_identity->certs, 			       q, 			       &cert);	hx509_query_free(kdc_identity->hx509ctx, q);	if (ret)	    goto out;		ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,					0,					sdAlg,					buf.data,					buf.length,					NULL,					cert,					client_params->peer,					client_params->client_anchors,					kdc_identity->certpool,					&signed_data);	hx509_cert_free(cert);    }    krb5_data_free(&buf);    if (ret) 	goto out;    if (client_params->type == PKINIT_COMPAT_WIN2K) {	ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(),					 &signed_data,					 &buf);	if (ret)	    goto out;	krb5_data_free(&signed_data);	signed_data = buf;    }    ret = hx509_cms_envelope_1(kdc_identity->hx509ctx,			       0,			       client_params->cert,			       signed_data.data, signed_data.length, 			       envelopedAlg,			       oid_id_pkcs7_signedData(), &buf);    if (ret)	goto out;        ret = _krb5_pk_mk_ContentInfo(context,				  &buf,				  oid_id_pkcs7_envelopedData(),				  content_info);out:    krb5_data_free(&buf);    krb5_data_free(&signed_data);    return ret;}/* * */static krb5_error_codepk_mk_pa_reply_dh(krb5_context context,                  DH *kdc_dh,      		  pk_client_params *client_params,                  krb5_keyblock *reply_key,		  ContentInfo *content_info,		  hx509_cert *kdc_cert){    KDCDHKeyInfo dh_info;    krb5_data signed_data, buf;    ContentInfo contentinfo;    krb5_error_code ret;    size_t size;    heim_integer i;    memset(&contentinfo, 0, sizeof(contentinfo));    memset(&dh_info, 0, sizeof(dh_info));    krb5_data_zero(&buf);    krb5_data_zero(&signed_data);    *kdc_cert = NULL;    ret = BN_to_integer(context, kdc_dh->pub_key, &i);    if (ret)	return ret;    ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret);    if (ret) {	krb5_set_error_string(context, "ASN.1 encoding of "			      "DHPublicKey failed (%d)", ret);	krb5_clear_error_string(context);	return ret;    }    if (buf.length != size)	krb5_abortx(context, "Internal ASN.1 encoder error");    dh_info.subjectPublicKey.length = buf.length * 8;    dh_info.subjectPublicKey.data = buf.data;        dh_info.nonce = client_params->nonce;    ASN1_MALLOC_ENCODE(KDCDHKeyInfo, buf.data, buf.length, &dh_info, &size, 		       ret);    if (ret) {	krb5_set_error_string(context, "ASN.1 encoding of "			      "KdcDHKeyInfo failed (%d)", ret);	goto out;    }    if (buf.length != size)	krb5_abortx(context, "Internal ASN.1 encoder error");    /*      * Create the SignedData structure and sign the KdcDHKeyInfo     * filled in above     */    {	hx509_query *q;	hx509_cert cert;		ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);	if (ret)	    goto out;		hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);	hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);		ret = hx509_certs_find(kdc_identity->hx509ctx, 			       kdc_identity->certs, 			       q, 			       &cert);	hx509_query_free(kdc_identity->hx509ctx, q);	if (ret)	    goto out;		ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,					0,					oid_id_pkdhkeydata(),					buf.data,					buf.length,					NULL,					cert,					client_params->peer,					client_params->client_anchors,					kdc_identity->certpool,					&signed_data);	*kdc_cert = cert;    }    if (ret)	goto out;    ret = _krb5_pk_mk_ContentInfo(context,				  &signed_data,				  oid_id_pkcs7_signedData(),				  content_info);    if (ret)	goto out; out:    if (ret && *kdc_cert) {	hx509_cert_free(*kdc_cert);	*kdc_cert = NULL;    }    krb5_data_free(&buf);    krb5_data_free(&signed_data);    free_KDCDHKeyInfo(&dh_info);    return ret;}/* * */krb5_error_code_kdc_pk_mk_pa_reply(krb5_context context,		    krb5_kdc_configuration *config,		    pk_client_params *client_params,		    const hdb_entry_ex *client,		    const KDC_REQ *req,		    const krb5_data *req_buffer,		    krb5_keyblock **reply_key,		    METHOD_DATA *md){    krb5_error_code ret;    void *buf;    size_t len, size;    krb5_enctype enctype;    int pa_type;    hx509_cert kdc_cert = NULL;    int i;    if (!config->enable_pkinit) {	krb5_clear_error_string(context);	return 0;    }    if (req->req_body.etype.len > 0) {	for (i = 0; i < req->req_body.etype.len; i++)	    if (krb5_enctype_valid(context, req->req_body.etype.val[i]) == 0)		break;	if (req->req_body.etype.len <= i) {	    ret = KRB5KRB_ERR_GENERIC;	    krb5_set_error_string(context,				  "No valid enctype available from client");	    goto out;	}		enctype = req->req_body.etype.val[i];    } else	enctype = ETYPE_DES3_CBC_SHA1;    if (client_params->type == PKINIT_COMPAT_27) {	PA_PK_AS_REP rep;	const char *type, *other = "";	memset(&rep, 0, sizeof(rep));	pa_type = KRB5_PADATA_PK_AS_REP;	if (client_params->dh == NULL) {	    ContentInfo info;	    type = "enckey";	    rep.element = choice_PA_PK_AS_REP_encKeyPack;	    ret = krb5_generate_random_keyblock(context, enctype, 						&client_params->reply_key);	    if (ret) {		free_PA_PK_AS_REP(&rep);		goto out;	    }	    ret = pk_mk_pa_reply_enckey(context,					config,					client_params,					req,					req_buffer,					&client_params->reply_key,					&info);	    if (ret) {		free_PA_PK_AS_REP(&rep);		goto out;	    }	    ASN1_MALLOC_ENCODE(ContentInfo, rep.u.encKeyPack.data, 			       rep.u.encKeyPack.length, &info, &size, 			       ret);	    free_ContentInfo(&info);	    if (ret) {		krb5_set_error_string(context, "encoding of Key ContentInfo "				      "failed %d", ret);		free_PA_PK_AS_REP(&rep);		goto out;	    }	    if (rep.u.encKeyPack.length != size)		krb5_abortx(context, "Internal ASN.1 encoder error");	} else {	    ContentInfo info;	    type = "dh";	    if (client_params->dh_group_name)		other = client_params->dh_group_name;	    rep.element = choice_PA_PK_AS_REP_dhInfo;	    ret = generate_dh_keyblock(context, client_params, enctype,				       &client_params->reply_key);	    if (ret)		return ret;	    ret = pk_mk_pa_reply_dh(context, client_params->dh,				    client_params, 				    &client_params->reply_key,				    &info,				    &kdc_cert);	    ASN1_MALLOC_ENCODE(ContentInfo, rep.u.dhInfo.dhSignedData.data,			       rep.u.dhInfo.dhSignedData.length, &info, &size,			       ret);	    free_ContentInfo(&info);	    if (ret) {		krb5_set_error_string(context, "encoding of Key ContentInfo "				      "failed %d", ret);		free_PA_PK_AS_REP(&rep);		goto out;	    }	    if (rep.u.encKeyPack.length != size)		krb5_abortx(context, "Internal ASN.1 encoder error");	}	if (ret) {	    free_PA_PK_AS_REP(&rep);	    goto out;	}	ASN1_MALLOC_ENCODE(PA_PK_AS_REP, buf, len, &rep, &size, ret);	free_PA_PK_AS_REP(&rep);	if (ret) {	    krb5_set_error_string(context, "encode PA-PK-AS-REP failed %d",				  ret);	    goto out;	}	if (len != size)	    krb5_abortx(context, "Internal ASN.1 encoder error");	kdc_log(context, config, 0, "PK-INIT using %s %s", type, other);    } else if (client_params->type == PKINIT_COMPAT_WIN2K) {	PA_PK_AS_REP_Win2k rep;	ContentInfo info;	if (client_params->dh) {	    krb5_set_error_string(context, "Windows PK-INIT doesn't support DH");	    ret = KRB5KRB_ERR_GENERIC;	    goto out;	}	memset(&rep, 0, sizeof(rep));	pa_type = KRB5_PADATA_PK_AS_REP_19;	rep.element = choice_PA_PK_AS_REP_encKeyPack;	ret = krb5_generate_random_keyblock(context, enctype, 					    &client_params->reply_key);	if (ret) {	    free_PA_PK_AS_REP_Win2k(&rep);	    goto out;

⌨️ 快捷键说明

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