Próbuję napisać funkcję sprawdzania poprawności certyfikatu w C przy użyciu biblioteki openssl. Ponieważ sprawdzany przeze mnie certyfikat jest samopodpisany i wygasł, oczekuję, że X509_verify_cert() zwróci błąd (wartość zwracana wynosi 1, a błąd store_ctx-> jest ustawiony na X509_V_OK). 'OpenSSL zweryfikować my_pem_cert_file' wyjścia:Weryfikowanie samopodpisanego/wygasłego certyfikatu z biblioteką openssl nie zwraca błędu
error 18 at 0 depth lookup:self signed certificate
error 10 at 0 depth lookup:certificate has expired
Co robię źle? Tu jest mój kodu:
static int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
{
/* Tolerate self-signed certificate */
if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) {
return 1;
}
/* Otherwise don't override */
return ok;
}
int cert_validate(const char* certFileName)
{
BIO *pBio = NULL;
X509 *pX509 = NULL;
X509 *CA = NULL;
X509_STORE *cert_store = NULL;
X509_STORE_CTX *store_ctx = NULL;
STACK_OF(X509) *stack_of_x509 = NULL;
time_t check_time;
int store_ctx_error;
int store_ctx_error_depth;
pBio = BIO_new(BIO_s_file_internal());
if(pBio == NULL)
/* error handling */
if(BIO_read_filename(pBio, certFileName) <= 0)
/* error handling */
pX509 = PEM_read_bio_X509(pBio, NULL, NULL, NULL);
if (pX509 == NULL)
/* error handling */
if((cert_store= X509_STORE_new()) == NULL)
/* error handling */
if((store_ctx= X509_STORE_CTX_new()) == NULL)
/* error handling */
/* edit1: this was wrong: don't add the certificate being verified to the trusted cert list */
/* if(!X509_STORE_add_cert(cert_store, pX509)) */
/* error handling */
if(!X509_STORE_CTX_init(store_ctx, cert_store, CA, stack_of_x509))
/* error handling */
X509_STORE_CTX_set_cert(store_ctx, pX509);
/* edit1: this was missing: set the verify time in order to check the certificate for expiry */
time(&check_time);
X509_STORE_CTX_set_time(store_ctx, 0, check_time);
X509_STORE_CTX_set_flags(store_ctx, X509_V_FLAG_USE_CHECK_TIME);
/* edit1: add callback function for ignoring self-signed error
* now, I'd like the validation to fail because of the expiry */
X509_STORE_set_verify_cb_func(store_ctx, cert_verify_callback);
switch(X509_verify_cert(store_ctx)) {
/* the certificate is valid */
case 1:
printf("The certificate is valid\n");
break;
/* the certificate cannot be validated */
case -1:
case 0:
printf("The certificate is not valid\n");
store_ctx_error= X509_STORE_CTX_get_error(store_ctx);
store_ctx_error_depth= X509_STORE_CTX_get_error_depth(store_ctx);
printf("Error %d at %d depth: %s\n", store_ctx_error, store_ctx_error_depth, X509_verify_cert_error_string(store_ctx->error));
default:
break;
}
/* free data ... */
}
Po walidacji autopodpisywany i aktualny certyfikat, moje odciski funkcyjne: błędach 0 w 0 głębokość: ok
Dziękuję bardzo! Zaktualizowałem swój kod, poprawiając te błędy. Pojawia się kolejny problem: skoro chcę tolerować samopodpisany błąd, w jaki sposób mogę wykryć błąd wygasłego certyfikatu? Przypuszczam, że raz wywołując X509_verify_cert(), wykrywasz pierwszy napotkany błąd. Jak mogę wykryć wszystkie błędy certyfikatów, takie jak polecenie "openssl verify"? (Chciałbym teraz, aby mój cert_validate() wydrukował "Certyfikat nie jest ważny", ponieważ certyfikat wygasł) – claudiu
@ caf, pomóż mi w tym pytaniu: http://stackoverflow.com/questions/27599985/ openssl-verify-errorcode-20-nie można uzyskać certyfikatu lokalnego wystawcy –