2012-11-05 135 views
1

我正在編寫一個使用CryptoAPI和Schannel建立到客戶端的安全SSL連接的服務器應用程序。服務器要求客戶提交證書以進行驗證(通過在AcceptSecurityContext中設置ASC_REQ_MUTUAL_AUTH標誌)。爲客戶端證書添加CA證書

我遇到的問題是一些客戶端(即使用javax.net.ssl的客戶端)不會傳遞客戶端證書(即使它已被配置爲這樣做)。我懷疑這是因爲用於簽署客戶端證書的CA證書不在握手過程中傳遞給客戶端的CA列表中。

我試着做以下CA證書添加到這個列表的變化:

PCERT_CONTEXT caCertContext = ...; /* Imported from a DER formatted file */ 

HCERTSTORE systemStore = CertOpenStore(
       CERT_STORE_PROV_SYSTEM, 
       0, 
       0, 
       CERT_STORE_OPEN_EXISTING_FLAG | 
        CERT_SYSTEM_STORE_LOCAL_MACHINE, 
       L"ROOT"); 

bool ok = CertAddCertificateContextToStore(
       systemStore, 
       caCertContext, 
       CERT_STORE_ADD_USE_EXISTING, 
       NULL); 

if (!ok) 
{ 
    std::cerr << "Could not add certificate to system store!" << std::endl; 
} 

在上面的例子CertAddCertificateContextToStore總是失敗。如果我將CERT_SYSTEM_STORE_LOCAL_MACHINE更改爲CERT_SYSTEM_STORE_CURRENT_USER,我會彈出一個要求我確認證書的彈出窗口,但即使我接受CA證書也不會出現在發送給客戶端的列表中。

我也嘗試用臨時內存存儲(我從here中選擇的東西)擴展系統存儲集合,但無濟於事。

任何人都知道一種方法來解決這個問題?理想的編程方式不使用任何GUI或外部工具?

+0

調用CertAddCertificateContextToStore()後,從GetLastError()返回的值是什麼?我做了一些非常相似的事情,但使用CertAddEncodedCertificateToStore()成功。 – NuSkooler

+0

GetLastError()返回「5」,無論這應該是什麼意思......編輯:看起來像錯誤5是ERROR_ACCESS_DENIED –

回答

1

您正在收到該錯誤,因爲您沒有權限訪問商店作爲讀取和寫入,您只能以讀取的方式訪問它。所以,你必須做的就是添加CERT_STORE_READONLY_FLAG所以這將是:

HCERTSTORE systemStore = CertOpenStore(
      CERT_STORE_PROV_SYSTEM, 
      0, 
      0, 
      CERT_STORE_OPEN_EXISTING_FLAG | 
       CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG , 
      L"ROOT"); 

如果您要更改您的商店,並沒有它只是意味着你將需要管理提升,當你運行你的C閱讀++應用程序。

+0

但是,如果它是隻讀的,我怎樣才能以編程方式擴展CA證書的集合?請注意,我不希望它添加到系統存儲中,因爲這會使該機器上的所有應用程序都成爲全局的。 –

+0

我編輯我的答案。您需要將應用程序升級到管理員權限才能對商店進行更改。我知道我用這種方式解決了我的一個問題,所以你可以試試。您可以通過將這個添加到清單文件中來實現。 –