Überprüfen Sie, Fehlercode = 20 : unable to get local issuer certificate
Habe ich eine Zertifikat-Kette in server:
Certificate chain
0 s:/******/O=Foobar International BV/OU****
i:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/****
1 s:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/****
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=**** - G5
2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=**** - G5
i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
Und meine lokalen root-CA-Zertifikat:
s:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/****
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=**** - G5
Und ich bin mit diesem snippet um das Zertifikat zu überprüfen:
//gcc -lssl -lcrypto -o certverify certverify.c
#include <openssl/ssl.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <string.h>
int main() {
const char ca_bundlestr[] = "./ca-bundle.pem";
const char cert_filestr[] = "./cert-file.pem";
BIO *certbio = NULL;
BIO *outbio = NULL;
X509 *error_cert = NULL;
X509 *cert = NULL;
X509_NAME *certsubject = NULL;
X509_STORE *store = NULL;
X509_STORE_CTX *vrfy_ctx = NULL;
int ret;
/* ---------------------------------------------------------- *
* These function calls initialize openssl for correct work. *
* ---------------------------------------------------------- */
OpenSSL_add_all_algorithms();
ERR_load_BIO_strings();
ERR_load_crypto_strings();
/* ---------------------------------------------------------- *
* Create the Input/Output BIO's. *
* ---------------------------------------------------------- */
certbio = BIO_new(BIO_s_file());
outbio = BIO_new_fp(stdout, BIO_NOCLOSE);
/* ---------------------------------------------------------- *
* Initialize the global certificate validation store object. *
* ---------------------------------------------------------- */
if (!(store=X509_STORE_new()))
BIO_printf(outbio, "Error creating X509_STORE_CTX object\n");
/* ---------------------------------------------------------- *
* Create the context structure for the validation operation. *
* ---------------------------------------------------------- */
vrfy_ctx = X509_STORE_CTX_new();
/* ---------------------------------------------------------- *
* Load the certificate and cacert chain from file (PEM). *
* ---------------------------------------------------------- */
ret = BIO_read_filename(certbio, cert_filestr);
if (! (cert = PEM_read_bio_X509(certbio, NULL, 0, NULL))) {
BIO_printf(outbio, "Error loading cert into memory\n");
exit(-1);
}
ret = X509_STORE_load_locations(store, ca_bundlestr, NULL);
if (ret != 1)
BIO_printf(outbio, "Error loading CA cert or chain file\n");
/* ---------------------------------------------------------- *
* Initialize the ctx structure for a verification operation: *
* Set the trusted cert store, the unvalidated cert, and any *
* potential certs that could be needed (here we set it NULL) *
* ---------------------------------------------------------- */
X509_STORE_CTX_init(vrfy_ctx, store, cert, NULL);
/* ---------------------------------------------------------- *
* Check the complete cert chain can be build and validated. *
* Returns 1 on success, 0 on verification failures, and -1 *
* for trouble with the ctx object (i.e. missing certificate) *
* ---------------------------------------------------------- */
ret = X509_verify_cert(vrfy_ctx);
BIO_printf(outbio, "Verification return code: %d\n", ret);
if(ret == 0 || ret == 1)
BIO_printf(outbio, "Verification result text: %s\n",
X509_verify_cert_error_string(vrfy_ctx->error));
/* ---------------------------------------------------------- *
* The error handling below shows how to get failure details *
* from the offending certificate. *
* ---------------------------------------------------------- */
if(ret == 0) {
/* get the offending certificate causing the failure */
error_cert = X509_STORE_CTX_get_current_cert(vrfy_ctx);
certsubject = X509_NAME_new();
certsubject = X509_get_subject_name(error_cert);
BIO_printf(outbio, "Verification failed cert:\n");
X509_NAME_print_ex(outbio, certsubject, 0, XN_FLAG_MULTILINE);
BIO_printf(outbio, "\n");
}
/* ---------------------------------------------------------- *
* Free up all structures *
* ---------------------------------------------------------- */
X509_STORE_CTX_free(vrfy_ctx);
X509_STORE_free(store);
X509_free(cert);
BIO_free_all(certbio);
BIO_free_all(outbio);
exit(0);
}
Aber dieser code return folgende Ausgabe:
Verification return code: 0
Verification result text: unable to get issuer certificate
Verification failed cert:
countryName = US
organizationName = Symantec Corporation
organizationalUnitName = Symantec Trust Network
commonName = Symantec Class 3 Secure Server CA - G4
Was ist hier falsch?
InformationsquelleAutor Kaidul | 2014-12-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre root-CA verwendet wohl den gleichen öffentlichen Schlüssel als den ersten intermediate CA in der Kette (unterhalb der host-Zertifikat) und haben Sie wahrscheinlich keinen root-CA, die verwendet werden können, um das Vertrauen der letzten Kette-Zertifikat. Solche setups sind nicht sehr Häufig, aber tatsächlich geschehen. Leider OpenSSL hat Probleme mit diesem setup und wird nur versuchen, um zu überprüfen, die längste Kette, auch wenn Sie eine kürzere Kette bietet bereits das notwendige Vertrauen.
Es ist ein bug-Eintrag für das OpenSSL-problem, aber niemand von den OpenSSL-Entwicklern jemals kümmerte sich um ihn. Dort finden Sie auch einen patch, wenn Sie sind auf der Suche für X509_V_FLAG_TRUSTED_FIRST. Es sieht so aus, OpenSSL 1.0.2 (noch nicht veröffentlicht) wird diese option auch.
Aus meinem Verständnis nur OpenSSL hat diese Art von problem, also weder NSS (Firefox, Chrome auf dem Desktop) oder SChannel (Microsoft).
Ich bin in der Lage zu prüfen, Ablaufdatum, hotname überprüfung sind und ob diese von einer CA signiert Zertifikat. Aber wie bekomme ich die CRL-Listen und überprüfen, ob mein server-Zertifikat widerrufen wurde oder nicht. Können Sie mir einen funktionierenden code ?
Erhalten Sie die CRL-Listen, die Sie haben, extrahieren Sie die CRL-Verteilungspunkte aus dem Zertifikat und führen Sie dann HTTP-Anfragen zu tun, laden Sie diese CRL. Nachdem Sie dies getan haben, können Sie laden Sie, und fügen Sie für die überprüfung der CTX. Und Nein, ich habe keinen funktionierenden code für diese. Abgesehen davon ist es eine andere Frage und sollte somit besser gefragt, wie eine neue Frage.
InformationsquelleAutor Steffen Ullrich
Ich denke, Steffen hat wahrscheinlich geholfen, das problem zu lösen. Aber hier ist ein kleiner Fehler haben kann Seite trat der bug bei Ihnen Auftritt und verbessert Ihre Sicherheitslage.
Brauchen Sie nicht das CA-bundle. Sie müssen nur Verisign Class 3 Public Primary Certification Authority (G5). Sie können das ein CA-Zertifikat von Verisign auf Verwenden von Root-Zertifikaten.
Seine eine Verbesserung Ihrer Sicherheitslage, da bist du so CA für die Zertifizierung von server-Zertifikat (auch falsch) und nicht mit dem eines bekannten zu zertifizieren, die das server-Zertifikat (Verisign).
Wenn Sie möchten, um zu sehen, ein Beispiel für ein einfaches TLS-client, dann schauen Sie sich SSL - /TLS-Client auf die OpenSSL-wiki. Es bietet ein Beispiel für das abrufen von Zufallszahlen von
random.org
. Es Bedarf nicht viel Arbeit, es zu ändern, umexample.com
.Beachten Sie auch: OpenSSL hat nicht durchführen hostname matching bei der Validierung. Sie immer noch müssen, tun Sie es selbst, wenn Sie mithilfe von OpenSSL 1.0.2, 1.0.1, 1.0.0 und weniger Versionen. OpenSSL bietet hostname matching in 1.1.0, aber seine noch nicht verfügbar.
Den sample-code zu extrahieren, die Hostnamen aus dem Common Name (CN) und Subject Alt Names (SAN) in das X. 509-Zertifikat ist in der SSL - /TLS-Client, aber Sie müssen um den eigentlichen code entsprechen.
Basierend auf den Informationen in den Kommentaren, benötigen Sie das Zertifikat: "Symantec Class 3 Secure Server CA - G5". Unten sieht es aus, wenn die Bereitstellung der richtigen Anker - es endet in einem
Verify return code: 0 (ok)
(und nicht den Fehler 20)."Symantec Class 3 Secure Server CA - G5", ist das mit dem Fingerabdruck
4e b6 d5 78 49 9b 1c cf 5f 58 1e ad 56 be 3d 9b 67 44 a5 e5
. Holen Sie es von Verisign Verwenden von Root-Zertifikaten.Den
CAfile
option verwendet werdens_client
(unten) ist ein Satz ins_client.c
mit einem AufrufSSL_CTX_load_verify_locations
. Sein Satz, der einen CA-Bedarf zu zertifizieren, die das Zertifikat des Servers, und nicht die CA-Zoo (d.h.,cacerts.pem
).Können Sie die Subject Alternative Names (SAN) in das Zertifikat mit
$ openssl s_client -connect www.smartbabymonitor.ugrow.example.com:443 | openssl x509 -text -noout
. Sie wird OK sein, weil der hostwww.smartbabymonitor.ugrow.example.com
ist aufgeführt im SAN. Man könnte sogar hinzufügen, die-servername
option, um den Befehl mit Server Name Indication (SNI).cert-file.pem
enthalten?0 s:/******/O=Foobar International BV/OU**** i:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/****
?Durch die Einstellung der 0. Zertifikat als
const char cert_filestr[] = "./cert-file.pem"
und Verisign Class 3 Public Primary Certification Authority (G5) alsconst char ca_bundlestr[] = "./ca-bundle.pem"
der code noch zurückunable to get local issuer certificate
.siehe aktualisierte Antwort. Ich kann nicht dupliziert werden, wenn mithilfe der Verisign-CA (G5). Sollten Sie verwenden
SSL_CTX_load_verify_locations
um die Verisgn CA als Vertrauensanker in Ihrem client.Ich vergaß zu erwähnen, dass ich bereits verwenden, dieses snippet - etutorials.org/Programming/secure+Programmierung/... für "hostname verification". Also ich denke, das Teil ist okay 🙂 Kannst du mir einige richtige
./ca-bundle.pem
und./cert-file.pem
- Datei für die Arbeit mit meinem obigen code mit einer Erläuterung?Ich halte das verisign-Zertifikat auch in meinem desktop und ausgeführt wurde dieser Befehl vom desktop
openssl s_client -showcerts -connect www.smartbabymonitor.ugrow.mysite.com:443 -CAfile VeriSign-Class3-Public-Primary-Certification-Authority-G5.pem
aber noch zurückerrorcode = 20 : unable to get local issuer certificate
. Können Sie mir bitte sagen, was passiert ist? Auch laden verisgn das ZertifikatSSL_CTX_load_verify_locations
sollte mit obigen code?InformationsquelleAutor jww