Exemple #1
0
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);
}
Exemple #2
0
/* 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;
}
Exemple #3
0
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;
}