2016-07-14 10 views

Antwort

1

Ich möchte die CA-Zertifikatsnamensliste von geladenem SSL_CTX() abrufen Gibt es APIs, die von openSSL zur Verfügung gestellt werden, um den Namen zurückzuerhalten?

Art von. Ein Zertifikat hat einen Aussteller und einen Betreff. Wenn Sie den "CA Name" sagen, fragen Sie nach dem Emittenten. Und es ist normalerweise auf der SSL*; und nicht die CTX*.

Sie würden etwas wie das folgende durchführen. Sie müssen herausfinden, wie Sie das Zertifikat erhalten, das Sie drucken möchten. Im Folgenden sehen Sie, wie Sie es mit dem Zertifikat des Peers machen.

/* 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); 

Und dann:

/* 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); 
} 

IF wollten Sie Betreff Alternative Namen (SAN) für ein Server-Zertifikat, dann könnten Sie so etwas wie:

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);  
} 

Das obige wurde von OpenSSL TLS client Beispiel in ihrem Wiki übernommen. Außerdem wird gezeigt, wie Sie die Kette im Bestätigungsrückruf drucken.

+0

vor allem dank @jww. Ich habe zwei Sitzungen. In der ersten Sitzung habe ich ein CA-Zertifikat mit crl in den SSL-Kontext geladen. Wieder habe ich eine neue Sitzung erstellt, aber ich habe den SSL-Kontext von der ersten Sitzung geerbt, bedeutet eine Einzelton-Klasse wie diese. gibt es zwei Situationen. 1. Wenn CA-Zertifikat der ersten Sitzung und CA-Zertifikat der zweiten Sitzung nicht identisch sind 2. Wenn CA-Zertifikat der ersten Sitzung und Zertifikat der zweiten Sitzung CA nicht übereinstimmen dafür muss ich den aktuellen CA-Zertifikatsantrag prüfen, der in SSL geladen wurde Kontext während der ersten Sitzung. Dann werde ich mit dem Namen des CA-Zertifikats der Session 2 vergleichen. –