void pki_crl::fload(const QString fname) { FILE *fp = fopen(QString2filename(fname), "r"); X509_CRL *_crl; if (fp != NULL) { _crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); if (!_crl) { pki_ign_openssl_error(); rewind(fp); _crl = d2i_X509_CRL_fp(fp, NULL); } fclose(fp); if (pki_ign_openssl_error()) { if (_crl) X509_CRL_free(_crl); throw errorEx(tr("Unable to load the revokation list in file %1. Tried PEM and DER formatted CRL.").arg(fname)); } if (crl) X509_CRL_free(crl); crl = _crl; setIntName(rmslashdot(fname)); pki_openssl_error(); } else fopen_error(fname); }
/* XXX share code with x509_read_from_dir() ? */ int x509_read_crls_from_dir(X509_STORE *ctx, char *name) { #if OPENSSL_VERSION_NUMBER >= 0x00907000L FILE *crlfp; X509_CRL *crl; struct stat sb; char fullname[PATH_MAX]; char file[PATH_MAX]; int fd, off, size; if (strlen(name) >= sizeof fullname - 1) { log_print("x509_read_crls_from_dir: directory name too long"); return 0; } LOG_DBG((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs " "from %s", name)); if (monitor_req_readdir(name) == -1) { LOG_DBG((LOG_CRYPTO, 10, "x509_read_crls_from_dir: opendir " "(\"%s\") failed: %s", name, strerror(errno))); return 0; } strlcpy(fullname, name, sizeof fullname); off = strlen(fullname); size = sizeof fullname - off; while ((fd = monitor_readdir(file, sizeof file)) != -1) { LOG_DBG((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading " "CRL %s", file)); if (fstat(fd, &sb) == -1) { log_error("x509_read_crls_from_dir: fstat failed"); close(fd); continue; } if (!S_ISREG(sb.st_mode)) { close(fd); continue; } if ((crlfp = fdopen(fd, "r")) == NULL) { log_error("x509_read_crls_from_dir: fdopen failed"); close(fd); continue; } crl = PEM_read_X509_CRL(crlfp, NULL, NULL, NULL); fclose(crlfp); if (crl == NULL) { log_print("x509_read_crls_from_dir: " "PEM_read_X509_CRL failed for %s", file); continue; } if (!X509_STORE_add_crl(ctx, crl)) { LOG_DBG((LOG_CRYPTO, 50, "x509_read_crls_from_dir: " "X509_STORE_add_crl failed for %s", file)); continue; } /* * XXX This is to make x509_cert_validate set this (and * XXX another) flag when validating certificates. Currently, * XXX OpenSSL defaults to reject an otherwise valid * XXX certificate (chain) if these flags are set but there * XXX are no CRLs to check. The current workaround is to only * XXX set the flags if we actually loaded some CRL data. */ X509_STORE_set_flags(ctx, X509_V_FLAG_CRL_CHECK); } #endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */ return 1; }
static int load_crl(SSL_CTX * ctx, char *crl_directory, int crl_check_all) { #if OPENSSL_VERSION_NUMBER >= 0x10000000L DIR *d; struct dirent *dir; int crl_added = 0; LM_DBG("Loading CRL from directory\n"); /*Get X509 store from SSL context*/ X509_STORE *store = SSL_CTX_get_cert_store(ctx); if(!store) { LM_ERR("Unable to get X509 store from ssl context\n"); return -1; } /*Parse directory*/ d = opendir(crl_directory); if(!d) { LM_ERR("Unable to open crl directory '%s'\n", crl_directory); return -1; } while ((dir = readdir(d)) != NULL) { /*Skip if not regular file*/ if (dir->d_type != DT_REG) continue; /*Create filename*/ char* filename = (char*) pkg_malloc(sizeof(char)*(strlen(crl_directory)+strlen(dir->d_name)+2)); if (!filename) { LM_ERR("Unable to allocate crl filename\n"); closedir(d); return -1; } strcpy(filename,crl_directory); if(filename[strlen(filename)-1] != '/') strcat(filename,"/"); strcat(filename,dir->d_name); /*Get CRL content*/ FILE *fp = fopen(filename,"r"); pkg_free(filename); if(!fp) continue; X509_CRL *crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); fclose(fp); if(!crl) continue; /*Add CRL to X509 store*/ if (X509_STORE_add_crl(store, crl) == 1) crl_added++; else LM_ERR("Unable to add crl to ssl context\n"); X509_CRL_free(crl); } closedir(d); if (!crl_added) { LM_ERR("No suitable CRL files found in directory %s\n", crl_directory); return -1; } /*Enable CRL checking*/ X509_VERIFY_PARAM *param; param = X509_VERIFY_PARAM_new(); int flags = X509_V_FLAG_CRL_CHECK; if(crl_check_all) flags |= X509_V_FLAG_CRL_CHECK_ALL; X509_VERIFY_PARAM_set_flags(param, flags); SSL_CTX_set1_param(ctx, param); X509_VERIFY_PARAM_free(param); return 0; #else static int already_warned = 0; if (!already_warned) { LM_WARN("CRL not supported in %s\n", OPENSSL_VERSION_TEXT); already_warned = 1; } return 0; #endif }
int main(int argc, char *argv[]) { X509 *cert; X509 *cacert; X509_CRL *crl; X509_STORE *store; X509_LOOKUP *lookup; X509_STORE_CTX *verify_ctx; STACK_OF(X509) *untrusted; STACK_OF(X509_CRL) *crls; FILE *fp; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* read the client certificate */ if (!(fp = fopen(CLIENT_CERT, "r"))) { int_error("Error reading client certificate file"); } if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL))) { int_error("Error reading client certificate in file"); } fclose(fp); /* read CA certificate */ if (!(fp = fopen(CA_FILE, "r"))) { int_error("Error reading CA certificate file"); } if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) { int_error("Error reading CA certificate in file"); } fclose(fp); // Read CRL if (!(fp = fopen(CRL_FILE, "r"))) { int_error("Error opening CRL file"); } if (!(crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL))) { int_error("Error reading CRL"); } fclose(fp); /* create the cert store and set the verify callback */ if (!(store = X509_STORE_new())) { int_error("Error creating X509_STORE_CTX object"); } // Add CA cert to Store if (X509_STORE_add_cert(store, cacert) != 1) { int_error("Error adding CA certificate to certificate store"); } // Add CRL to Store if (X509_STORE_add_crl(store, crl) != 1) { int_error("Error adding CRL to certificate store"); } X509_STORE_set_verify_cb_func(store, verify_callback); /* set the flags of the store so that the CRLs are consulted */ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); // Create an empty X509_Stack for untrusted if (!(untrusted = sk_X509_new_null())) { int_error("Error creating X509_Stack"); } // Create a CRL_Stack if (!(crls = sk_X509_CRL_new_null())) { int_error("Error creating X509_CRL"); } // Add CRL to CRL_Stack if (sk_X509_CRL_push(crls, crl) != 1) { int_error("Error adding a CRL to the Stack of CRLs"); } /* create a verification context and initialize it */ if (!(verify_ctx = X509_STORE_CTX_new())) { int_error("Error creating X509_STORE_CTX object"); } // We are explicitly adding an empty X509_Stack for untrusted if (X509_STORE_CTX_init(verify_ctx, store, cert, untrusted) != 1) { int_error("Error initializing verification context"); } X509_STORE_CTX_set0_crls(verify_ctx, crls); /* verify the certificate */ if (X509_verify_cert(verify_ctx) != 1) { int_error("Error verifying the certificate"); } else { printf("Certificate verified correctly!\n"); } return 0; }