2016-07-14 6 views

答えて

1

ロードされたSSL証明書のリストを取得したいSSL_CTX()OpenSSLが提供するAPIがありますか?

種類。証明書には発行者と件名があります。 "CA Name"と言うと、あなたは発行者を求めています。そして、それは通常の上にSSL*; CTX*ではなく

次のような操作を行います。印刷する証明書を取得する方法を理解する必要があります。以下では、ピアの証明書でそれを行う方法を示します。

/* Drops out of a handshake */ 
SSL* ssl = ...; 

/* Get the certificate from the session object */ 
X509* cert = SSL_get_peer_certificate(ssl); 

/* Get the issuer name */ 
X509_NAME* iname = cert ? X509_get_issuer_name(cert) : NULL; 

/* Get the subject name */ 
X509_NAME* sname = cert ? X509_get_subject_name(cert) : NULL; 

if (iname) 
    print_cn_name("Issuer name", iname); 

if (sname) 
    print_cn_name("Subject name", sname); 

X509_free(cert); 

そして:

/* This prints the Common Name (CN), which is the "friendly" */ 
/* name displayed to users in many tools     */ 
void print_cn_name(const char* label, X509_NAME* const name) 
{ 
    int idx = -1, success = 0; 
    unsigned char *utf8 = NULL; 

    do 
    { 
     if(!name) break; /* failed */ 

     idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1); 
     if(!(idx > -1)) break; /* failed */ 

     X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx); 
     if(!entry) break; /* failed */ 

     ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry); 
     if(!data) break; /* failed */ 

     int length = ASN1_STRING_to_UTF8(&utf8, data); 
     if(!utf8 || !(length > 0)) break; /* failed */ 

     fprintf(stdout, "%s: %s\n", label, utf8); 
     success = 1; 

    } while (0); 

    if(utf8) 
     OPENSSL_free(utf8); 

    if(!success) 
     fprintf(stdout, " %s: <not available>\n", label); 
} 

を、サーバー証明書のサブジェクト代替名(SAN)、その後、あなたのような何かをするかもしれませんが欲しかったのIF

void print_san_name(const char* label, X509* const cert) 
{ 
    int success = 0; 
    GENERAL_NAMES* names = NULL; 
    unsigned char* utf8 = NULL; 

    do 
    { 
     if(!cert) break; /* failed */ 

     names = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0); 
     if(!names) break; 

     int i = 0, count = sk_GENERAL_NAME_num(names); 
     if(!count) break; /* failed */ 

     for(i = 0; i < count; ++i) 
     { 
      GENERAL_NAME* entry = sk_GENERAL_NAME_value(names, i); 
      if(!entry) continue; 

      if(GEN_DNS == entry->type) 
      { 
       int len1 = 0, len2 = -1; 

       len1 = ASN1_STRING_to_UTF8(&utf8, entry->d.dNSName); 
       if(utf8) { 
        len2 = (int)strlen((const char*)utf8); 
       } 

       if(len1 != len2) { 
        fprintf(stderr, " Strlen and ASN1_STRING size do not match (embedded null?): %d vs %d\n", len2, len1); 
       } 

       /* If there's a problem with string lengths, then  */ 
       /* we skip the candidate and move on to the next.  */ 
       /* Another policy would be to fails since it probably */ 
       /* indicates the client is under attack.    */ 
       if(utf8 && len1 && len2 && (len1 == len2)) { 
        fprintf(stdout, " %s: %s\n", label, utf8); 
        success = 1; 
       } 

       if(utf8) { 
        OPENSSL_free(utf8), utf8 = NULL; 
       } 
      } 
      else 
      { 
       fprintf(stderr, " Unknown GENERAL_NAME type: %d\n", entry->type); 
      } 
     } 

    } while (0); 

    if(names) 
     GENERAL_NAMES_free(names); 

    if(utf8) 
     OPENSSL_free(utf8); 

    if(!success) 
     fprintf(stdout, " %s: <not available>\n", label);  
} 

上記はOpenSSLのTLS clientのwikiの例から取られました。また、検証コールバックでチェーンを印刷する方法も示します。

+0

最初に感謝の@jww。私は2つのセッションを持っています。最初のセッションでは、私はSSL証明書にSSL証明書をロードしました。私は新しいセッションを作成しましたが、私は最初のセッションからのSSLコンテキストを継承し、そのようなシングルトーンクラスを意味します。 2つの状況があります。 1.最初のセッションCA証明書と2番目のセッションCA証明書が同じでない場合 2.最初のセッションCA証明書と2番目のセッションCA証明書が同じでない場合 SSL用にロードされている現在のCA証明書サブジェクト名を確認する必要があります最初のセッション中のコンテキスト。次に、セッション2のCA証明書サブジェクト名と比較します。 –

関連する問題