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.

Спасибо!

0 ответов

Другие вопросы по тегам