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

📄 pkinit.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
	krb5_timestamp sec;	int32_t usec;	memset(&ap, 0, sizeof(ap));	/* fill in PKAuthenticator */	ret = copy_PrincipalName(req_body->sname, &ap.pkAuthenticator.kdcName);	if (ret) {	    free_AuthPack_Win2k(&ap);	    krb5_clear_error_string(context);	    goto out;	}	ret = copy_Realm(&req_body->realm, &ap.pkAuthenticator.kdcRealm);	if (ret) {	    free_AuthPack_Win2k(&ap);	    krb5_clear_error_string(context);	    goto out;	}	krb5_us_timeofday(context, &sec, &usec);	ap.pkAuthenticator.ctime = sec;	ap.pkAuthenticator.cusec = usec;	ap.pkAuthenticator.nonce = nonce;	ASN1_MALLOC_ENCODE(AuthPack_Win2k, buf.data, buf.length,			   &ap, &size, ret);	free_AuthPack_Win2k(&ap);	if (ret) {	    krb5_set_error_string(context, "AuthPack_Win2k: %d", ret);	    goto out;	}	if (buf.length != size)	    krb5_abortx(context, "internal ASN1 encoder error");	oid = oid_id_pkcs7_data();    } else if (ctx->type == COMPAT_IETF) {	AuthPack ap;		memset(&ap, 0, sizeof(ap));	ret = build_auth_pack(context, nonce, ctx, ctx->dh, req_body, &ap);	if (ret) {	    free_AuthPack(&ap);	    goto out;	}	ASN1_MALLOC_ENCODE(AuthPack, buf.data, buf.length, &ap, &size, ret);	free_AuthPack(&ap);	if (ret) {	    krb5_set_error_string(context, "AuthPack: %d", ret);	    goto out;	}	if (buf.length != size)	    krb5_abortx(context, "internal ASN1 encoder error");	oid = oid_id_pkauthdata();    } else	krb5_abortx(context, "internal pkinit error");    ret = create_signature(context, oid, &buf, ctx->id,			   ctx->peer, &sd_buf);    krb5_data_free(&buf);    if (ret)	goto out;    ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &sd_buf, &buf);    krb5_data_free(&sd_buf);    if (ret) {	krb5_set_error_string(context,			      "ContentInfo wrapping of signedData failed");	goto out;    }    if (ctx->type == COMPAT_WIN2K) {	PA_PK_AS_REQ_Win2k winreq;	pa_type = KRB5_PADATA_PK_AS_REQ_WIN;	memset(&winreq, 0, sizeof(winreq));	winreq.signed_auth_pack = buf;	ASN1_MALLOC_ENCODE(PA_PK_AS_REQ_Win2k, buf.data, buf.length,			   &winreq, &size, ret);	free_PA_PK_AS_REQ_Win2k(&winreq);    } else if (ctx->type == COMPAT_IETF) {	PA_PK_AS_REQ req;	pa_type = KRB5_PADATA_PK_AS_REQ;	memset(&req, 0, sizeof(req));	req.signedAuthPack = buf;		if (ctx->trustedCertifiers) {	    req.trustedCertifiers = calloc(1, sizeof(*req.trustedCertifiers));	    if (req.trustedCertifiers == NULL) {		krb5_set_error_string(context, "malloc: out of memory");		free_PA_PK_AS_REQ(&req);		goto out;	    }	    ret = build_edi(context, ctx->id->hx509ctx, 			    ctx->id->anchors, req.trustedCertifiers);	    if (ret) {		krb5_set_error_string(context, "pk-init: failed to build trustedCertifiers");		free_PA_PK_AS_REQ(&req);		goto out;	    }	}	req.kdcPkId = NULL;	ASN1_MALLOC_ENCODE(PA_PK_AS_REQ, buf.data, buf.length,			   &req, &size, ret);	free_PA_PK_AS_REQ(&req);    } else	krb5_abortx(context, "internal pkinit error");    if (ret) {	krb5_set_error_string(context, "PA-PK-AS-REQ %d", ret);	goto out;    }    if (buf.length != size)	krb5_abortx(context, "Internal ASN1 encoder error");    ret = krb5_padata_add(context, md, pa_type, buf.data, buf.length);    if (ret)	free(buf.data);    if (ret == 0 && ctx->type == COMPAT_WIN2K)	krb5_padata_add(context, md, KRB5_PADATA_PK_AS_09_BINDING, NULL, 0);out:    free_ContentInfo(&content_info);    return ret;}krb5_error_code KRB5_LIB_FUNCTION _krb5_pk_mk_padata(krb5_context context,		   void *c,		   const KDC_REQ_BODY *req_body,		   unsigned nonce,		   METHOD_DATA *md){    krb5_pk_init_ctx ctx = c;    int win2k_compat;    win2k_compat = krb5_config_get_bool_default(context, NULL,						FALSE,						"realms",						req_body->realm,						"pkinit_win2k",						NULL);    if (win2k_compat) {	ctx->require_binding = 	    krb5_config_get_bool_default(context, NULL,					 FALSE,					 "realms",					 req_body->realm,					 "pkinit_win2k_require_binding",					 NULL);	ctx->type = COMPAT_WIN2K;    } else	ctx->type = COMPAT_IETF;    ctx->require_eku = 	krb5_config_get_bool_default(context, NULL,				     TRUE,				     "realms",				     req_body->realm,				     "pkinit_require_eku",				     NULL);    ctx->require_krbtgt_otherName = 	krb5_config_get_bool_default(context, NULL,				     TRUE,				     "realms",				     req_body->realm,				     "pkinit_require_krbtgt_otherName",				     NULL);    ctx->require_hostname_match = 	krb5_config_get_bool_default(context, NULL,				     FALSE,				     "realms",				     req_body->realm,				     "pkinit_require_hostname_match",				     NULL);    ctx->trustedCertifiers = 	krb5_config_get_bool_default(context, NULL,				     TRUE,				     "realms",				     req_body->realm,				     "pkinit_trustedCertifiers",				     NULL);    return pk_mk_padata(context, ctx, req_body, nonce, md);}krb5_error_code KRB5_LIB_FUNCTION_krb5_pk_verify_sign(krb5_context context,		     const void *data,		     size_t length,		     struct krb5_pk_identity *id,		     heim_oid *contentType,		     krb5_data *content,		     struct krb5_pk_cert **signer){    hx509_certs signer_certs;    int ret;    *signer = NULL;    ret = hx509_cms_verify_signed(id->hx509ctx,				  id->verify_ctx,				  data,				  length,				  NULL,				  id->certpool,				  contentType,				  content,				  &signer_certs);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret,			    "CMS verify signed failed");	return ret;    }    *signer = calloc(1, sizeof(**signer));    if (*signer == NULL) {	krb5_clear_error_string(context);	ret = ENOMEM;	goto out;    }	    ret = hx509_get_one_cert(id->hx509ctx, signer_certs, &(*signer)->cert);    if (ret) {	_krb5_pk_copy_error(context, id->hx509ctx, ret,			    "Failed to get on of the signer certs");	goto out;    }out:    hx509_certs_free(&signer_certs);    if (ret) {	if (*signer) {	    hx509_cert_free((*signer)->cert);	    free(*signer);	    *signer = NULL;	}    }    return ret;}static krb5_error_codeget_reply_key_win(krb5_context context,		  const krb5_data *content,		  unsigned nonce,		  krb5_keyblock **key){    ReplyKeyPack_Win2k key_pack;    krb5_error_code ret;    size_t size;    ret = decode_ReplyKeyPack_Win2k(content->data,				    content->length,				    &key_pack,				    &size);    if (ret) {	krb5_set_error_string(context, "PKINIT decoding reply key failed");	free_ReplyKeyPack_Win2k(&key_pack);	return ret;    }         if (key_pack.nonce != nonce) {	krb5_set_error_string(context, "PKINIT enckey nonce is wrong");	free_ReplyKeyPack_Win2k(&key_pack);	return KRB5KRB_AP_ERR_MODIFIED;    }    *key = malloc (sizeof (**key));    if (*key == NULL) {	krb5_set_error_string(context, "PKINIT failed allocating reply key");	free_ReplyKeyPack_Win2k(&key_pack);	krb5_set_error_string(context, "malloc: out of memory");	return ENOMEM;    }    ret = copy_EncryptionKey(&key_pack.replyKey, *key);    free_ReplyKeyPack_Win2k(&key_pack);    if (ret) {	krb5_set_error_string(context, "PKINIT failed copying reply key");	free(*key);	*key = NULL;    }    return ret;}static krb5_error_codeget_reply_key(krb5_context context,	      const krb5_data *content,	      const krb5_data *req_buffer,	      krb5_keyblock **key){    ReplyKeyPack key_pack;    krb5_error_code ret;    size_t size;    ret = decode_ReplyKeyPack(content->data,			      content->length,			      &key_pack,			      &size);    if (ret) {	krb5_set_error_string(context, "PKINIT decoding reply key failed");	free_ReplyKeyPack(&key_pack);	return ret;    }        {	krb5_crypto crypto;	/* 	 * XXX Verify kp.replyKey is a allowed enctype in the	 * configuration file	 */	ret = krb5_crypto_init(context, &key_pack.replyKey, 0, &crypto);	if (ret) {	    free_ReplyKeyPack(&key_pack);	    return ret;	}	ret = krb5_verify_checksum(context, crypto, 6,				   req_buffer->data, req_buffer->length,				   &key_pack.asChecksum);	krb5_crypto_destroy(context, crypto);	if (ret) {	    free_ReplyKeyPack(&key_pack);	    return ret;	}    }    *key = malloc (sizeof (**key));    if (*key == NULL) {	krb5_set_error_string(context, "PKINIT failed allocating reply key");	free_ReplyKeyPack(&key_pack);	krb5_set_error_string(context, "malloc: out of memory");	return ENOMEM;    }    ret = copy_EncryptionKey(&key_pack.replyKey, *key);    free_ReplyKeyPack(&key_pack);    if (ret) {	krb5_set_error_string(context, "PKINIT failed copying reply key");	free(*key);	*key = NULL;    }    return ret;}static krb5_error_codepk_verify_host(krb5_context context,	       const char *realm,	       const krb5_krbhst_info *hi,	       struct krb5_pk_init_ctx_data *ctx,	       struct krb5_pk_cert *host){    krb5_error_code ret = 0;    if (ctx->require_eku) {	ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert,				   oid_id_pkkdcekuoid(), 0);	if (ret) {	    krb5_set_error_string(context, "No PK-INIT KDC EKU in kdc certificate");	    return ret;	}    }    if (ctx->require_krbtgt_otherName) {	hx509_octet_string_list list;	int i;	ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx,						       host->cert,						       oid_id_pkinit_san(),						       &list);	if (ret) {	    krb5_set_error_string(context, "Failed to find the PK-INIT "				  "subjectAltName in the KDC certificate");	    return ret;	}	for (i = 0; i < list.len; i++) {	    KRB5PrincipalName r;	    ret = decode_KRB5PrincipalName(list.val[i].data,					   list.val[i].length,					   &r,					   NULL);	    if (ret) {		krb5_set_error_string(context, "Failed to decode the PK-INIT "				      "subjectAltName in the KDC certificate");		break;	    }	    if (r.principalName.name_string.len != 2 ||		strcmp(r.principalName.name_string.val[0], KRB5_TGS_NAME) != 0 ||		strcmp(r.principalName.name_string.val[1], realm) != 0 ||		strcmp(r.realm, realm) != 0)	    {		krb5_set_error_string(context, "KDC have wrong realm name in "				      "the certificate");		ret = KRB5_KDC_ERR_INVALID_CERTIFICATE;	    }	    free_KRB5PrincipalName(&r);	    if (ret)		break;	}	hx509_free_octet_string_list(&list);    }    if (ret)	return ret;        if (hi) {	ret = hx509_verify_hostname(ctx->id->hx509ctx, host->cert, 				    ctx->require_hostname_match,				    HX509_HN_HOSTNAME,				    hi->hostname,				    hi->ai->ai_addr, hi->ai->ai_addrlen);	if (ret)	    krb5_set_error_string(context, "Address mismatch in "				  "the KDC certificate");    }    return ret;}static krb5_error_codepk_rd_pa_reply_enckey(krb5_context context,		      int type,		      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,	       	      unsigned nonce,		      const krb5_data *req_buffer,	       	      PA_DATA *pa,	       	      krb5_keyblock **key) {    krb5_error_code ret;    struct krb5_pk_cert *host = NULL;    krb5_data content;    heim_oid contentType = { 0, NULL };    if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), dataType)) {	krb5_set_error_string(context, "PKINIT: Invalid content type");	return EINVAL;    }    ret = hx509_cms_unenvelope(ctx->id->hx509ctx,			       ctx->id->certs,			       HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT,			       indata->data,			       indata->length,			       NULL,			       &contentType,			       &content);    if (ret) {	_krb5_pk_copy_error(context, ctx->id->hx509ctx, ret,			    "Failed to unenvelope CMS data in PK-INIT reply");	return ret;    }    der_free_oid(&contentType);#if 0 /* windows LH with interesting CMS packets, leaks memory */    {	size_t ph = 1 + der_length_len (length);	unsigned char *ptr = malloc(length + ph);	size_t l;	memcpy(ptr + ph, p, length);	ret = der_put_length_and_tag (ptr + ph - 1, ph, length,				      ASN1_C_UNIV, CONS, UT_Sequence, &l);	if (ret)	    return ret;	ptr += ph - l;	length += l;	p = ptr;    }#endif    /* win2k uses ContentInfo */    if (type == COMPAT_WIN2K) {	heim_oid type;	heim_octet_string out;	ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL);	if (der_heim_oid_cmp(&type, oid_id_pkcs7_signedData())) {	    ret = EINVAL; /* XXX */	    krb5_set_error_string(context, "PKINIT: Invalid content type");	    der_free_oid(&type);	    der_free_octet_string(&out);	    goto out;	}	der_free_oid(&type);	krb5_data_free(&content);	ret = krb5_data_copy(&content, out.data, out.length);	der_free_octet_string(&out);	if (ret) {	    krb5_set_error_string(context, "PKINIT: out of memory");	    goto out;	}    }    ret = _krb5_pk_verify_sign(context, 

⌨️ 快捷键说明

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