2014-12-08 2 views
1

서버에 SSL 연결이 있습니다. 나는 루트 CA를 가졌으며 서버 인증서이기도했다. 클라이언트 인증서를 가지고 있지 않습니다. 연결이 시작되면 클라이언트는 서버 인증서를 확인하고 유효한 인증서인지 확인합니다. 이제는 루트 CA에서 중급 CA를 만들어 서버 인증서로 바꿨습니다. 이제 서버 인증서가 루트 CA에 의해 신뢰되는지 클라이언트가 확인하도록하겠습니다. openSSL API를 사용하여 C++로 클라이언트를 인증합니다. 내가 어떻게 해? 여기 내가 시도한 것은 있지만 더 많은 것을 필요로합니다.중간 CA를 확인하는 방법

const Char *caCert = "/home/omar/CA/host/host_rsa_key.crt"; 

     X509_LOOKUP *lookup = X509_STORE_add_lookup(ctx_ -> cert_store,X509_LOOKUP_file()); 


     result=X509_LOOKUP_load_file(lookup,caCert,X509_FILETYPE_PEM); 
     if(result != 1) 
     { 
     log()<<ERROR! Cannot load file to lookup structure\n"; 
     return; 
     } 


     SSL_CTX_sess_set_new_cb(ctx_, handshakeCallback); 

     SSL_CTX_set_verify(ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 
         verifyCallback); 
     SSL_CTX_set_verify_depth(ctx_, 8); 

여기에는 모든 인증서가 ssl_ctx에로드됩니다.

가 나는

Int verifyCertificate(Int preverify, X509_STORE_CTX *store) 
    { 
    X509 *cert = NULL; 
// X509_NAME *name = NULL; 

    SSL *ssl = NULL; 

Int certDepth = -1; 
Int certErr = 0; 

Char *certHost = NULL; 
Char *certHash = NULL; 
Char *certData = NULL; 


cert = X509_STORE_CTX_get_current_cert(store); 

if (cert == NULL) 

log() << " ERROR! Failed to get certificate.\n"; 


goto VerifyCertificateError; 
} 



certDepth = X509_STORE_CTX_get_error_depth(store); 
certErr = X509_STORE_CTX_get_error(store); 



ssl = (SSL *) X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()); 

if (ssl == NULL) 
{ 
log() << ERROR! Failed to get SSL context from store context.\n"; 

goto VerifyCertificateError; 
} 

if (preverify == 0) 
{ 
// 
// Self signed certificate allowed, SSH host auth style. 
// 

if (certErr == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) 
{ 

    log() << " Certificate preverify failed on self"; 

    return 1; 
} 
else if (certErr == X509_V_ERR_CERT_NOT_YET_VALID) 
{ 

    log() << Allowing not yet valid certificate.\n"; 

    return 1; 
} 
else if (certErr == X509_V_ERR_CERT_HAS_EXPIRED) 
{ 

    log() << " Allowing expired certificate.\n"; 


    return 1; 
} 
else if(certErr == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) 
{ 

    log()<<" Unable to get issuer cert.\n" 


    return 1; 
} 


if (certDepth == 0) 
{ 
if (parseCertificate(store, certHost, certHash, certData) == 0) 
{ 
    log() << "Encryptable: ERROR! Failed to parse certificate.\n"; 
    goto VerifyCertificateError; 
} 


    goto VerifyCertificateError; 
} 


if (authCallback_(certHost, certHash, certData, certCallback_, 
         callbackParameter_) == 0) 
{ 

    log() << " ERROR! Failed to authorize " 
     << "the server certificate.\n"; 

    goto VerifyCertificateError; 


if (certData != NULL) 
{ 
    delete [] certData; 
} 

return 0; 
} 

답변

1

중간 인증서가 OpenSSL에 의해 확인되어이며, 당신이해야 할 특별한 아무것도 여기 verifyCertificate() 메서드를 호출 verifyCallback 기능을 가지고있다. 물론 여전히 핸드 셰이크에 중간 인증서를 제공해야 피어가

당신은 때문에 verify_callback 필요하지 않습니다

  • (당신이) 신뢰 앵커를 지정해야

    • 기본 콜백은 이미 검증을 수행합니다. 즉, 중간 인증서를 포함하여 전체 트러스트 체인을 검사합니다. 여전히 OpenSSL을 사용하고 있다면 preverify에는 OpenSSL이 이미 수행하고있는 확인 결과가 포함되어 있으며 확인 동작이 다르게 작동해야하는 특정 상황이 아니라면 확인 콜백은이 값을 반환해야합니다.