Microsoft RPC SChannel не зашифрован
Я изо всех сил пытался получить безопасный клиент / сервер RPC, используя Microsoft RPC. Я не использую COM, просто прям C.
Я создал сертификат корневого CA и создал сертификат, подписанный этим сертификатом для сервера. Сертификаты установлены в сертификационных магазинах.
RPC прекрасно работает в незашифрованном виде и даже будет работать с настройкой SCHANNEL, только не зашифрованной.
ServerCode:
RpcServerUseProtseqEpW(
L"ncacn_ip_tcp",
RPC_C_LISTEN_MAX_CALLS_DEFAULT,
port,
NULL);
CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
(HCRYPTPROV)NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG,
L"MY")
CertFindCertificateInStore(
hStore,
X509_ASN_ENCODING|PKCS_7_ASAN_ENCODING,
CERT_FIND_SUBJEECT_STR,
subject,
NULL);
RpcCertGeneratePrincipalNameW(
ccert_ctx_server,
RPC_C_FULL_CERT_CHAIN,
serverPrincName);
schannel.dwVersion = SCHANNEL_CRED_VERSION;
schannel.cCreds = 1;
schannel.paCred = &ccert_ctx_server;
RpcServerRegisterAuthInfoW(
serverPrincName,
RPC_C_AUTHN_GSS_SCHANNEL,
NULL,
&schannel);
RpcServerRegisterIf2(
h_v1_ifspec,
NULL,
NULL,
RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH // seems to be required by SCHANNEL
RPC_C_LISTEN_MAX_CALLS_DEFAULT,
(unsigned)-1,
SecurityCallback); SecurityCallback returns RPC_S_OK
Код клиента:
RpcStringBindingComposeW(
NULL,
L"ncacn_ip_tcp",
address,
port,
NULL,
&stringBinding);
RpcBindingFronStringBindingW(
stringBinding,
hBind);
CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
(HCRYPTPROV)NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG,
L"MY")
CertFindCertificateInStore(
hStore,
X509_ASN_ENCODING|PKCS_7_ASAN_ENCODING,
CERT_FIND_SUBJEECT_STR,
subject,
NULL);
RpcCertGeneratePrincipalNameW(
ccert_ctx_server,
RPC_C_FULL_CERT_CHAIN,
serverPrincName);
schannel.dwVersion = SCHANNEL_CRED_VERSION;
schannel.cCreds = 1;
schannel.paCred = &ccert_ctx_client;
RpcServerRegisterAuthInfoW(
serverPrincName,
RPC_C_AUTHN_GSS_SCHANNEL,
NULL,
&schannel);
RpcBindingSetAuthInfo(
hBind,
serverPrincName,
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY,
RPC_C_AUTHN_GSS_SCHANNEL,
&schannelCred,
RPC_C_AUTHZ_NONE)
Учитывая все это, RPC будет работать, но он не будет зашифрован, как проверено с помощью Wireshark. Я работал с очень минимальным определением структуры SCHANNEL и не использовал структуру qos. Ничто не имеет большого значения. единственное, что действительно имеет значение, это если я изменю RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH на RPC_IF_ALLOW_SECURE_ONLY. Затем я получаю отказ в доступе при вызове RPC. Из того, что я понимаю, это нормальная функциональность SCHANNEL, и вы должны предоставить свою собственную аутентификацию в Security Callback.
Когда я вызываю RpcBindingInqAuthClient в моем обратном вызове безопасности, я получаю сообщение об ошибке 1746: привязка не содержит никакой информации аутентификации.
Я просмотрел MSDN, несколько различных ссылок, разбросанных по сети, но мало что можно узнать о том, как заставить SCHANNEL работать.
Мой выбор для SCHANNEL - я не могу положиться на kerberos или ntlm. Я использую tcp через Интернет, поэтому сертификаты - это то, что мне подходит. Я не могу использовать http, потому что я не могу настроить IIS на своем сервере, DCE, кажется, даже менее документирован, чем schannel.
Спасибо!