2017-02-01 6 views
0

Windows API, C++를 사용하여 템플릿 이름 (템플릿이 확장 필드에 있음)으로 Windows 인증서를 검색해야합니다.템플릿으로 Windows 인증서를 검색하는 데 도움이 필요합니까?

내 단계 :

  1. 열기 가기 : CertOpenStore (..) (완료, 나는 CertEnumCertificatesInStore (..)를 사용하여 인증서를 열거 할 수 있지만, 나는 단지 그들의 "버전 1 필드"를 참조 아니라 "Extensions"템플릿은 Extension에 있으므로 찾을 수 없습니다.)

  2. CertFindCertificateInStore()를 사용하여 찾으려고했지만 성공하지 못했습니다. 누구든지 정확한 유형 및 매개 변수를 찾거나 다른 기능을 사용하여 나를 도울 수 있습니까?

  3. CertFreeCertificateContext (..), CertCloseStore (..) (완료).

+0

'하지만 난 그들의 "버전 1 필드"를 참조 아니라 "확장"'- 당신은'CERT_INFO .cExtension == 0 '말? – RbMm

+0

디버거에서 템플릿 이름을 볼 수 없다는 뜻입니다. 내 사건에 맞는 CERT_INFO.cExtension == 9. 하지만 검색된 인증서와 템플릿 이름을 비교하여 내 검색 문자열과 비교하는 방법을 모르겠습니다. 디버거에서 템플릿 이름 문자열을 볼 수 없습니다 ... – teoSpeo

+1

당신은'CERT_EXTENSION' 배열을 열거하고 필요한'pszObjId'를 검색해야합니다. Declared data를 얻고 비교하기 위해서'CryptDecodeObject (X509_ASN_ENCODING, rgExtension-> pszObjId, rgExtension-> Value.pbData, rgExtension-> Value.cbData, ..')를 호출하고 – RbMm

답변

0

내 코드를 게시하고 싶습니다. 누군가 도움이되기를 바랍니다.

void GetCertificateByTemplate(char *certificateTemplate) 
{ 
    HCERTSTORE   hCertStore; 
    PCCERT_CONTEXT  pCertContext = NULL; 
    BYTE    *pbDecoded; 
    DWORD    cbDecoded; 
    _CERT_TEMPLATE_EXT *pbDecodedTemplate = NULL; 

    // 1). Open Local Machine certificate store 
    if (hCertStore = CertOpenStore(
     CERT_STORE_PROV_SYSTEM, 
     0, 
     NULL, 
     CERT_SYSTEM_STORE_LOCAL_MACHINE, 
     L"My")) 
    { 
     fprintf(stderr, "The store has been opened. \n"); 
    } 

    // 2). Enumerate certificates 
    while (pCertContext = CertEnumCertificatesInStore(
     hCertStore, 
     pCertContext)) 
    { 
     // 3). Check certificate extended data 
     for (int i = 0; i < pCertContext->pCertInfo->cExtension; i++) 
     { 
      // 4). Decode certificate extended data 
      if (CryptDecodeObject(
       X509_ASN_ENCODING, 
       pCertContext->pCertInfo->rgExtension[i].pszObjId, 
       pCertContext->pCertInfo->rgExtension[i].Value.pbData, 
       pCertContext->pCertInfo->rgExtension[i].Value.cbData, 
       0, 
       NULL, 
       &cbDecoded)) 
      { 
       ; // error !!! 
      } 
      if (!(pbDecoded = (BYTE*)malloc(cbDecoded))) 
      { 
       ; // error !!! 
      } 
      if (CryptDecodeObject(
       X509_ASN_ENCODING, 
       pCertContext->pCertInfo->rgExtension[i].pszObjId, 
       pCertContext->pCertInfo->rgExtension[i].Value.pbData, 
       pCertContext->pCertInfo->rgExtension[i].Value.cbData, 
       0, 
       pbDecoded, 
       &cbDecoded)) 
      { 
       pbDecodedTemplate = (_CERT_TEMPLATE_EXT*)pbDecoded; 

       char* objectId = pbDecodedTemplate->pszObjId; 

       // todo: check pDecodeTemplate->pszObjId 

       // 5). Compare the template string with the search one 
       if (strcmp(pbDecodedTemplate->pszObjId, certificateTemplate) == 0) 
       { 
        // todo: return certificate 
        printf("\nCertificate template found: %s \n", pbDecodedTemplate->pszObjId); 
        break; 
       } 
      } 
     } 
    } 

    // 6). Free certificate, close store 
    if (pCertContext) 
    { 
     CertFreeCertificateContext(pCertContext); 
    } 
    CertCloseStore(hCertStore, 0); 
} 
+0

을 얻을 때마다'pCertContext-> pCertInfo pCertContext-> pCertContext-> pCertContext-> pCertContext-> pCertInfo-> cExtension) -> cCertContext-> cCertInfo-> cCertInfo-> cExtension.pcertInfo-> rgExtension [i] > rgExtension; do {..} while (rgExtension ++, --cExtension);}' – RbMm

+0

@RbMm : 더 좋게 보입니다. 더 효과적이라고 저는 믿습니다. 그러나 그 이유를 설명해 주시겠습니까? – teoSpeo

+0

What 's BYTE *를 _CERT_TEMPLATE_EXT *로 캐스팅하고 확인하는 가장 좋은 방법은? dynamic_cast를 생각하고 있었지만 클래스가 관련되어있을 때만 작동한다는 것을 알았습니다. – teoSpeo