2014-03-07 38 views
1

的證書的序列號我正在嘗試編寫一個應用程序來申請證書並使用代碼將其吊銷。 通過引用msdn,我實現了使用ICertRequest3接口的應用認證部分,以及使用ICertAdmin2 :: RevokeCertificate接口的Revoking部分。獲取代碼爲

這是問題所在,它需要ICertAdmin2 :: RevokeCertificate的證書序列號才能起作用,而且我不知道如何獲取由CA頒發的證書的序列號屬性 。

具體而言,我需要的是找到一種方法來提取由CA發出的證書的序列號屬性後,我提交請求與ICertRequest3。

爲了您的信息,以下是申請和撤銷證書的代碼片段。

HRESULT enrollWithICertRequest3(
    X509CertificateEnrollmentContext context, 
    LPCWSTR template_name, 
    X509EnrollmentAuthFlags policy_server_authtype, 
    LPCWSTR policy_server_url, 
    LPCWSTR policy_server_username, 
    LPCWSTR policy_server_password, 
    X509EnrollmentAuthFlags enrollment_server_authtype, 
    LPCWSTR enrollment_server_url, 
    LPCWSTR enrollment_server_username, 
    LPCWSTR enrollment_server_password, 
    BSTR *cert_base64) 
{ 
    HRESULT hr = S_OK; 

    BSTR bstr_template_name = NULL; 
    BSTR bstr_policyserver_url = NULL; 
    BSTR bstr_policyserver_id = NULL; 
    BSTR bstr_policyserver_username = NULL; 
    BSTR bstr_policyserver_password = NULL; 

    IX509EnrollmentPolicyServer *policyserver_interface = NULL; 
    IX509CertificateTemplates *templates_interface = NULL; 
    IX509CertificateTemplate *template_interface = NULL; 

    IX509Enrollment2 *enroll2_interface = NULL; 
    BSTR bstrRequest = NULL; 

    BSTR bstrEnrollmentServerUrl = NULL; 
    BSTR bstrEnrollmentServerUsername = NULL; 
    BSTR bstrEnrollmentServerPassword = NULL; 

    ICertRequest3 *request3_interface = NULL; 
    LONG disposition = 0; 
    BSTR bstr_disposition = NULL; 
    VARIANT var_fullresponse; 

    VariantInit(&var_fullresponse); 
    var_fullresponse.vt = VT_BSTR; 
    var_fullresponse.bstrVal = NULL; 

    bstr_template_name = SysAllocString(template_name); 
    bstr_policyserver_url = SysAllocString(policy_server_url); 
    if(!bstr_template_name && template_name || 
     !bstr_policyserver_url && policy_server_url) 
    { 
     hr = E_OUTOFMEMORY; 
     goto error; 
    } 

    if(policy_server_authtype == X509AuthUsername) 
    { 
     bstr_policyserver_username = SysAllocString(policy_server_username); 
     bstr_policyserver_password = SysAllocString(policy_server_password); 

     if(!bstr_policyserver_username && policy_server_username || 
      !bstr_policyserver_password && policy_server_password) 
     { 
      hr = E_OUTOFMEMORY; 
      goto error; 
     } 
    } 
    else if(policy_server_authtype == X509AuthCertificate) 
    { 
     //This call is preparation of the call to pPolicyServer->SetCredential. 
     //For certificate authentication, bstrPolicyServerUsername should be a 
     //pointer to a memory blob in which certificate hash value is stored. 
     hr = hex2BstrByte(policy_server_username, &bstr_policyserver_username); 
     if(FAILED(hr)) 
      goto error; 
    } 

    hr = CoCreateInstance(
     __uuidof(CX509EnrollmentPolicyWebService), 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     __uuidof(IX509EnrollmentPolicyServer), 
     (void **)&policyserver_interface); 
    if(FAILED(hr)) 
     goto error; 

    //The bstrPolicyServerId is optional 
    hr = policyserver_interface->Initialize(
     bstr_policyserver_url, //[in] BSTR bstrPolicyServerUrl 
     NULL,     //[in] BSTR bstrPolicyServerId 
     policy_server_authtype, //[in] X509EnrollmentAuthFlags authFlags 
     false,     //[in] VARIANT_BOOL fIsUnTrusted 
     context);    //[in] X509CertificateEnrollmentContext context 
    if(FAILED(hr)) 
     goto error; 

    //This call sets authentication type and authentication credential 
    //to policy server to the object pointed by pPolicyServer. 
    //This call is necessary even for Kerberos authentication type. 
    hr = policyserver_interface->SetCredential(
     NULL,      //[in] LONG hWndParent 
     policy_server_authtype,  //[in] X509EnrollmentAuthFlags flag 
     bstr_policyserver_username, //[in] BSTR strCredential 
     bstr_policyserver_password); //[in] BSTR strPassword 
    if(FAILED(hr)) 
     goto error; 

    //The flag LoadOptionDefault means enrollment process reads 
    //policies (templates) from local cache in file system if it exists. 
    //Otherwise, it queries policies (templates) from policy server through 
    //http protocol, then caches them in local file system. 
    //The flag LoadOptionReload queries policies (templates) directly from 
    //policy server regardless of if cached policies (templates) exist. 
    hr = policyserver_interface->LoadPolicy(LoadOptionDefault); //[in] X509EnrollmentPolicyLoadOption option 
    if(FAILED(hr)) 
     goto error; 

    //pTemplates points to collection of policies (templates) 
    hr = policyserver_interface->GetTemplates(&templates_interface); 
    if(FAILED(hr)) 
     goto error; 

    //pTemplate points to the policy (template) specified by a template name 
    hr = templates_interface->get_ItemByName(bstr_template_name, &template_interface); 
    if(FAILED(hr)) 
     goto error; 

    //This call is preparation of the call IX509Enrollment2::InstallResponse2 
    hr = policyserver_interface->GetPolicyServerId(&bstr_policyserver_id); 
    if(FAILED(hr)) 
     goto error; 

    hr = CoCreateInstance(
     __uuidof(CX509Enrollment), 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     __uuidof(IX509Enrollment2), 
     (void **) &enroll2_interface); 
    if(FAILED(hr)) 
     goto error; 

    //This is a new API in Windows 7 to support http protocol 
    hr = enroll2_interface->InitializeFromTemplate(
     context,  //[in] X509CertificateEnrollmentContext context 
     policyserver_interface, //[in] IX509EnrollmentPolicyServer *pPolicyServer 
     template_interface);  //[in] IX509CertificateTemplate *pTemplate 
    if(FAILED(hr)) 
     goto error; 

    //Get request blob for the call ICertRequest3::Submit 
    hr = enroll2_interface->CreateRequest(
     XCN_CRYPT_STRING_BASE64, 
     &bstrRequest); 
    if(FAILED(hr)) 
     goto error; 

    hr = CoCreateInstance(
     __uuidof(CCertRequest), 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     __uuidof(ICertRequest3), 
     (void **) &request3_interface); 
    if(FAILED(hr)) 
     goto error; 

    bstrEnrollmentServerUrl = SysAllocString(enrollment_server_url); 
    if(!bstrEnrollmentServerUrl && enrollment_server_url) 
    { 
     hr = E_OUTOFMEMORY; 
     goto error; 
    } 

    if(enrollment_server_authtype == X509AuthUsername) 
    { 
     bstrEnrollmentServerUsername = SysAllocString(enrollment_server_username); 
     bstrEnrollmentServerPassword = SysAllocString(enrollment_server_password); 

     if(!bstrEnrollmentServerUsername && enrollment_server_username || 
      !bstrEnrollmentServerPassword && enrollment_server_password) 
     { 
      hr = E_OUTOFMEMORY; 
      goto error; 
     } 
    } 
    else if(enrollment_server_authtype == X509AuthCertificate) 
    { 
     //This call is preparation of the call to pCertRequest3->SetCredential. 
     //For certificate authentication, bstrPolicyServerUsername should be a 
     //pointer to a memory blob in which certificate hash value is stored. 
     hr = hex2BstrByte(enrollment_server_username, &bstrEnrollmentServerUsername); 
     if(FAILED(hr)) 
      goto error; 
    } 

    //This call sets authentication type and authentication credential 
    //to enrollment server to the object pointed by pCertRequest3. 
    //This call is necessary even for Kerberos authentication type. 
    hr = request3_interface->SetCredential(
     NULL,       //[in] LONG hWnd 
     enrollment_server_authtype,  //[in] X509EnrollmentAuthFlags AuthType 
     bstrEnrollmentServerUsername, //[in] BSTR strCredential 
     bstrEnrollmentServerPassword); //[in] BSTR strPassword 
    if(FAILED(hr)) 
     goto error; 

    //Submit request and get response 
    //For ICertRequest3::Submit, bstrConfig can be 
    //enrollment server URL 
    hr = request3_interface->Submit(
     CR_IN_BASE64 | CR_IN_FORMATANY, //[in] LONG Flags 
     bstrRequest,     //[in] BSTR const strRequest 
     NULL,       //[in] BSTR const strAttributes 
     bstrEnrollmentServerUrl,  //[in] BSTR const strConfig 
     &disposition);     //[out, retval] LONG *pDisposition 
    if(FAILED(hr)) 
     goto error; 

    //Check the submission status 
    if(disposition != CR_DISP_ISSUED) //Not enrolled 
    { 
     hr = request3_interface->GetDispositionMessage(&bstr_disposition); 
     if(FAILED(hr)) 
      goto error; 

     request3_interface->GetLastStatus(&hr); 

     if(disposition == CR_DISP_UNDER_SUBMISSION) //Pending 
     { 
      wprintf(L"The submission is in pending status: %s \n", bstr_disposition); 
      goto error; 
     } 
     else //Failed 
     { 
      wprintf(L"The submission failed: %s \n", bstr_disposition); 
      goto error; 
     } 
    } 

    // Get the issued certificate 
    hr = request3_interface->GetCertificate(CR_OUT_BASE64, cert_base64); 
    if(FAILED(hr)) 
     goto error; 

    ////Get full response for installation 
    //hr = request3_interface->GetFullResponseProperty(
    // FR_PROP_FULLRESPONSENOPKCS7, //[in] LONG PropId (FR_PROP_*) 
    // 0,        //[in] LONG PropIndex 
    // PROPTYPE_BINARY,    //[in] LONG PropType (PROPTYPE_* 
    // CR_OUT_BASE64,     //[in] LONG Flags (CR_OUT_*) 
    // &var_fullresponse);    //[out, retval] VARIANT *pvarPropertyValue 
    //if(FAILED(hr)) 
    // goto error; 

    ////Install the response 
    //hr = enroll2_interface->InstallResponse2(
    // AllowNone,     //[in] InstallResponseRestrictionFlags Restrictions 
    // var_fullresponse.bstrVal, //[in] BSTR strResponse 
    // XCN_CRYPT_STRING_BASE64, //[in] EnrodingType Encoding 
    // bstr_policyserver_password, //[in] BSTR strPassword 
    // bstr_policyserver_url,  //[in] BSTR strEnrollmentPolicyServerUrl 
    // bstr_policyserver_id,   //[in] BSTR strEnrollmentPolicyServerID 
    // PsfNone,     //[in] PolicyServerUrlFlags EnrollmentPolicyServerFlags 
    // policy_server_authtype);  //[in] X509EnrollmentAuthFlags authFlags 
    //if(FAILED(hr)) 
    // goto error 

    /*BSTR pwd = SysAllocString(L"tOngbupan"); 
    hr = enroll2_interface->CreatePFX(pwd, PFXExportEEOnly, XCN_CRYPT_STRING_BASE64, cert_base64); 
    SysFreeString(pwd);*/ 


    error: 
    SysFreeString(bstr_template_name); 
    SysFreeString(bstr_policyserver_url); 
    SysFreeString(bstr_policyserver_id); 
    SysFreeString(bstr_policyserver_username); 
    SysFreeString(bstr_policyserver_password); 

    SysFreeString(bstr_disposition); 
    SysFreeString(bstrEnrollmentServerUrl); 
    SysFreeString(bstrEnrollmentServerPassword); 
    SysFreeString(bstrEnrollmentServerUsername); 
    SysFreeString(bstrRequest); 

    if(!var_fullresponse.bstrVal) 
     VariantClear(&var_fullresponse); 

    if(policyserver_interface) 
     policyserver_interface->Release(); 

    if(templates_interface) 
     templates_interface->Release(); 

    if(request3_interface) 
     request3_interface->Release(); 

    if(template_interface) 
     template_interface->Release(); 

    if(enroll2_interface) 
     enroll2_interface->Release(); 

    return hr; 
} 







    bool revokeUserCert(const wstring& cert_serial_num) 
{ 
    BSTR bstrSerial = NULL; // certificate serial number 
    HRESULT hr; 
    LONG nDisp; 

    ICertAdmin2* pCertAdmin = NULL; 

    bstrSerial = SysAllocString(cert_serial_num.c_str()); 

    hr = CoCreateInstance(
     CLSID_CCertAdmin, 
     NULL,  // pUnkOuter 
     CLSCTX_INPROC_SERVER, 
     IID_ICertAdmin2, 
     (void **) &pCertAdmin); 
    if(FAILED(hr)) 
    { 
     printf("init icertadmin error\n"); 
     goto error; 
    } 

    ICertConfig* pCertConfig = NULL; 
    BSTR strCAConfig = NULL; 

    // Create ICertConfig 
    hr = CoCreateInstance(
     __uuidof(CCertConfig), 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     __uuidof(ICertConfig), 
     (void**)&pCertConfig); 

    // Get CA config 
    hr = pCertConfig->GetConfig(CC_FIRSTCONFIG, &strCAConfig); 
    if (FAILED(hr)) 
    { 
     printf("Failed GetConfig [%x]\n", hr); 
     goto error; 
    } 

    hr = pCertAdmin->IsValidCertificate(strCAConfig, bstrSerial, &nDisp); 
    if (FAILED(hr)) 
    { 
     printf("Failed IsValidCertificate [%x]\n", hr); 
     goto error; 
    } 

    if(nDisp != CA_DISP_VALID) 
    { 
     printf("givin certificate is not valid\n"); 
     goto error; 
    } 

    // Revoke the certificate. 
    // pCertAdmin is a previously instantiated ICertAdmin object. 
    hr = pCertAdmin->RevokeCertificate(strCAConfig, 
     bstrSerial, 
     0, 
     0); 
    if (FAILED(hr)) 
    { 
     /*_com_error err(hr); 
     LPCTSTR errMsg = err.ErrorMessage();*/ 
     //printf("Failed RevokeCertificate. [%x] [%s]\n", hr, ConvertWCSToMBS(errMsg, sizeof(errMsg)).c_str()); 
     printf("Failed RevokeCertificate. [%x] \n", hr); 
     goto error; 
    } 
    else 
     printf("Certificate %ws revoked.\n", bstrSerial); 

    // Done processing. 

    error: 

    // Free resources. 
    if (bstrSerial) 
     SysFreeString(bstrSerial); 
    if(strCAConfig) 
     SysFreeString(strCAConfig); 
    if(pCertAdmin != NULL) { pCertAdmin->Release(); } 
    if(pCertConfig != NULL) { pCertConfig->Release(); } 

    return SUCCEEDED(hr); 
} 

回答

0

一旦你得到了所頒發的證書到您的cert_base64字符串,將它轉換爲一個字節數組,然後創建一個從字節數組新X509Certificate2對象。然後您可以從X509Certificate2.SerialNumber屬性中訪問序列號。在C#中這將是:

  X509Certificate2 x509cert = new X509Certificate2(getBytes(cert_base64)); 
      string serialNumber = x509cert.SerialNumber; 


    private byte[] getBytes(string str) 
    { 
     byte[] bytes = new byte[str.Length * sizeof(char)]; 
     System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); 
     return bytes; 
    }