Example #1
0
int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
{
    X509_OBJECT *obj;
    int ret = 1;

    if (x == NULL)
        return 0;
    obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
    if (obj == NULL) {
        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    obj->type = X509_LU_CRL;
    obj->data.crl = x;

    CRYPTO_MUTEX_lock_write(&ctx->objs_lock);

    X509_OBJECT_up_ref_count(obj);

    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
        X509_OBJECT_free_contents(obj);
        OPENSSL_free(obj);
        OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
        ret = 0;
    } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
        X509_OBJECT_free_contents(obj);
        OPENSSL_free(obj);
        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
        ret = 0;
    }

    CRYPTO_MUTEX_unlock_write(&ctx->objs_lock);

    return ret;
}
Example #2
0
int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
{
    X509_OBJECT *obj;
    int ret = 1;

    if (x == NULL)
        return 0;
    obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
    if (obj == NULL) {
        X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    obj->type = X509_LU_CRL;
    obj->data.crl = x;

    CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);

    X509_OBJECT_up_ref_count(obj);

    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
        X509_OBJECT_free_contents(obj);
        OPENSSL_free(obj);
        X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
        ret = 0;
    } else
        sk_X509_OBJECT_push(ctx->objs, obj);

    CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);

    return ret;
}
Example #3
0
void X509_OBJECT_free(X509_OBJECT *a)
{
    if (a == NULL)
        return;
    X509_OBJECT_free_contents(a);
    OPENSSL_free(a);
}
Example #4
0
int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
{
    X509_OBJECT *obj;
    int ret = 1;

    if (x == NULL)
        return 0;
    obj = OPENSSL_malloc(sizeof(*obj));
    if (obj == NULL) {
        X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    obj->type = X509_LU_X509;
    obj->data.x509 = x;

    CRYPTO_THREAD_write_lock(ctx->lock);

    X509_OBJECT_up_ref_count(obj);

    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
        X509_OBJECT_free_contents(obj);
        OPENSSL_free(obj);
        X509err(X509_F_X509_STORE_ADD_CERT,
                X509_R_CERT_ALREADY_IN_HASH_TABLE);
        ret = 0;
    } else
        sk_X509_OBJECT_push(ctx->objs, obj);

    CRYPTO_THREAD_unlock(ctx->lock);

    return ret;
}
MONO_API X509 *
mono_btls_x509_lookup_by_fingerprint (MonoBtlsX509Lookup *lookup, unsigned char *bytes, int len)
{
    X509_OBJECT obj;
    X509 *x509;
    int ret;

    ret = X509_LOOKUP_by_fingerprint (lookup->lookup, X509_LU_X509, bytes, len, &obj);
    if (ret != X509_LU_X509) {
        X509_OBJECT_free_contents (&obj);
        return NULL;
    }

    x509 = X509_up_ref (obj.data.x509);
    return x509;
}
MONO_API X509 *
mono_btls_x509_lookup_by_subject (MonoBtlsX509Lookup *lookup, MonoBtlsX509Name *name)
{
    X509_OBJECT obj;
    X509 *x509;
    int ret;

    ret = X509_LOOKUP_by_subject (lookup->lookup, X509_LU_X509, mono_btls_x509_name_peek_name (name), &obj);
    if (ret != X509_LU_X509) {
        X509_OBJECT_free_contents (&obj);
        return NULL;
    }

    x509 = X509_up_ref (obj.data.x509);
    return x509;
}
/*****************************************************************************
 *
 * Low-level x509 functions
 *
 *****************************************************************************/
static int
xmlSecOpenSSLX509VerifyCRL(X509_STORE* xst, X509_CRL *crl ) {
    X509_STORE_CTX xsc;
    X509_OBJECT xobj;
    EVP_PKEY *pkey;
    int ret;

    xmlSecAssert2(xst != NULL, -1);
    xmlSecAssert2(crl != NULL, -1);

    X509_STORE_CTX_init(&xsc, xst, NULL, NULL);
    ret = X509_STORE_get_by_subject(&xsc, X509_LU_X509,
                                    X509_CRL_get_issuer(crl), &xobj);
    if(ret <= 0) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "X509_STORE_get_by_subject",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(-1);
    }
    pkey = X509_get_pubkey(xobj.data.x509);
    X509_OBJECT_free_contents(&xobj);
    if(pkey == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "X509_get_pubkey",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        return(-1);
    }
    ret = X509_CRL_verify(crl, pkey);
    EVP_PKEY_free(pkey);
    if(ret != 1) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "X509_CRL_verify",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
    }
    X509_STORE_CTX_cleanup (&xsc);
    return((ret == 1) ? 1 : 0);
}
Example #8
0
SISCertificateChain* makeChain(const char* certData, EVP_PKEY** publicKey) {
	BIO* in = BIO_new_mem_buf((void*) certData, -1);
	BIO* out = BIO_new(BIO_s_mem());

	while (true) {
		X509* cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
		if (!cert) {
			unsigned long err = ERR_peek_last_error();
			int lib = ERR_GET_LIB(err);
			int func = ERR_GET_FUNC(err);
			int reason = ERR_GET_REASON(err);
			if (lib == ERR_LIB_PEM && func == PEM_F_PEM_READ_BIO && reason == PEM_R_NO_START_LINE)
				break;
			ERR_print_errors_fp(stderr);
			throw SignBadCert;
		}
		if (!*publicKey)
			*publicKey = X509_PUBKEY_get(X509_get_X509_PUBKEY(cert));
		i2d_X509_bio(out, cert);

		X509_OBJECT obj;
		obj.type = X509_LU_X509;
		obj.data.x509 = cert;
		X509_OBJECT_free_contents(&obj);
	}
	BIO_free_all(in);

	char* ptr;
	long length = BIO_get_mem_data(out, &ptr);
	if (length <= 0) {
		fprintf(stderr, "Bad certificate file\n");
		throw SignBadCert;
	}
	SISBlob* blob = new SISBlob((uint8_t*) ptr, length);
	BIO_free_all(out);

	return new SISCertificateChain(blob);
}
Example #9
0
/*
 * Given an X509 certificate, create a KeyNote assertion where
 * Issuer/Subject -> Authorizer/Licensees.
 * XXX RSA-specific.
 */
int
x509_generate_kn(int id, X509 *cert)
{
	static const char fmt[] = "Authorizer: \"rsa-hex:%s\"\nLicensees: \"rsa-hex:%s"
		    "\"\nConditions: %s >= \"%s\" && %s <= \"%s\";\n";
	char	*ikey = NULL, *skey = NULL, *buf = NULL;
	char	isname[256], subname[256];
	static const char fmt2[] = "Authorizer: \"DN:%s\"\nLicensees: \"DN:%s\"\n"
		    "Conditions: %s >= \"%s\" && %s <= \"%s\";\n";
	X509_NAME *issuer, *subject;
	struct keynote_deckey dc;
	X509_STORE_CTX csc;
	X509_OBJECT obj;
	X509	*icert;
	RSA	*key = NULL;
	time_t	tt;
	char	before[15], after[15], *timecomp, *timecomp2;
	ASN1_TIME *tm;
	int	i;

	LOG_DBG((LOG_POLICY, 90,
	    "x509_generate_kn: generating KeyNote policy for certificate %p",
	    cert));

	issuer = X509_get_issuer_name(cert);
	subject = X509_get_subject_name(cert);

	/* Missing or self-signed, ignore cert but don't report failure.  */
	if (!issuer || !subject || !X509_name_cmp(issuer, subject))
		return 1;

	if (!x509_cert_get_key(cert, &key)) {
		LOG_DBG((LOG_POLICY, 30,
		    "x509_generate_kn: failed to get public key from cert"));
		return 0;
	}
	dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
	dc.dec_key = key;
	ikey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
	    KEYNOTE_PUBLIC_KEY);
	if (keynote_errno == ERROR_MEMORY) {
		log_print("x509_generate_kn: failed to get memory for "
		    "public key");
		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get "
		    "subject key"));
		goto fail;
	}
	if (!ikey) {
		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get "
		    "subject key"));
		goto fail;
	}

	RSA_free(key);
	key = NULL;

	/* Now find issuer's certificate so we can get the public key.  */
	X509_STORE_CTX_init(&csc, x509_cas, cert, NULL);
	if (X509_STORE_get_by_subject(&csc, X509_LU_X509, issuer, &obj) !=
	    X509_LU_X509) {
		X509_STORE_CTX_cleanup(&csc);
		X509_STORE_CTX_init(&csc, x509_certs, cert, NULL);
		if (X509_STORE_get_by_subject(&csc, X509_LU_X509, issuer, &obj)
		    != X509_LU_X509) {
			X509_STORE_CTX_cleanup(&csc);
			LOG_DBG((LOG_POLICY, 30,
			    "x509_generate_kn: no certificate found for "
			    "issuer"));
			goto fail;
		}
	}
	X509_STORE_CTX_cleanup(&csc);
	icert = obj.data.x509;

	if (icert == NULL) {
		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: "
		    "missing certificates, cannot construct X509 chain"));
		goto fail;
	}
	if (!x509_cert_get_key(icert, &key)) {
		LOG_DBG((LOG_POLICY, 30,
		    "x509_generate_kn: failed to get public key from cert"));
		goto fail;
	}
	X509_OBJECT_free_contents(&obj);

	dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
	dc.dec_key = key;
	skey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
	    KEYNOTE_PUBLIC_KEY);
	if (keynote_errno == ERROR_MEMORY) {
		log_error("x509_generate_kn: failed to get memory for public "
		    "key");
		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer "
		    "key"));
		goto fail;
	}
	if (!skey) {
		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer "
		    "key"));
		goto fail;
	}

	RSA_free(key);
	key = NULL;

	if (((tm = X509_get_notBefore(cert)) == NULL) ||
	    (tm->type != V_ASN1_UTCTIME &&
		tm->type != V_ASN1_GENERALIZEDTIME)) {
		tt = time(0);
		strftime(before, 14, "%Y%m%d%H%M%S", localtime(&tt));
		timecomp = "LocalTimeOfDay";
	} else {
		if (tm->data[tm->length - 1] == 'Z') {
			timecomp = "GMTTimeOfDay";
			i = tm->length - 2;
		} else {
			timecomp = "LocalTimeOfDay";
			i = tm->length - 1;
		}

		for (; i >= 0; i--) {
			if (tm->data[i] < '0' || tm->data[i] > '9') {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid data in "
				    "NotValidBefore time field"));
				goto fail;
			}
		}

		if (tm->type == V_ASN1_UTCTIME) {
			if ((tm->length < 10) || (tm->length > 13)) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid length "
				    "of NotValidBefore time field (%d)",
				    tm->length));
				goto fail;
			}
			/* Validity checks.  */
			if ((tm->data[2] != '0' && tm->data[2] != '1') ||
			    (tm->data[2] == '0' && tm->data[3] == '0') ||
			    (tm->data[2] == '1' && tm->data[3] > '2') ||
			    (tm->data[4] > '3') ||
			    (tm->data[4] == '0' && tm->data[5] == '0') ||
			    (tm->data[4] == '3' && tm->data[5] > '1') ||
			    (tm->data[6] > '2') ||
			    (tm->data[6] == '2' && tm->data[7] > '3') ||
			    (tm->data[8] > '5')) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid value in "
				    "NotValidBefore time field"));
				goto fail;
			}
			/* Stupid UTC tricks.  */
			if (tm->data[0] < '5')
				snprintf(before, sizeof before, "20%s",
				    tm->data);
			else
				snprintf(before, sizeof before, "19%s",
				    tm->data);
		} else {	/* V_ASN1_GENERICTIME */
			if ((tm->length < 12) || (tm->length > 15)) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid length of "
				    "NotValidBefore time field (%d)",
				    tm->length));
				goto fail;
			}
			/* Validity checks.  */
			if ((tm->data[4] != '0' && tm->data[4] != '1') ||
			    (tm->data[4] == '0' && tm->data[5] == '0') ||
			    (tm->data[4] == '1' && tm->data[5] > '2') ||
			    (tm->data[6] > '3') ||
			    (tm->data[6] == '0' && tm->data[7] == '0') ||
			    (tm->data[6] == '3' && tm->data[7] > '1') ||
			    (tm->data[8] > '2') ||
			    (tm->data[8] == '2' && tm->data[9] > '3') ||
			    (tm->data[10] > '5')) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid value in "
				    "NotValidBefore time field"));
				goto fail;
			}
			snprintf(before, sizeof before, "%s", tm->data);
		}

		/* Fix missing seconds.  */
		if (tm->length < 12) {
			before[12] = '0';
			before[13] = '0';
		}
		/* This will overwrite trailing 'Z'.  */
		before[14] = '\0';
	}

	tm = X509_get_notAfter(cert);
	if (tm == NULL &&
	    (tm->type != V_ASN1_UTCTIME &&
		tm->type != V_ASN1_GENERALIZEDTIME)) {
		tt = time(0);
		strftime(after, 14, "%Y%m%d%H%M%S", localtime(&tt));
		timecomp2 = "LocalTimeOfDay";
	} else {
		if (tm->data[tm->length - 1] == 'Z') {
			timecomp2 = "GMTTimeOfDay";
			i = tm->length - 2;
		} else {
			timecomp2 = "LocalTimeOfDay";
			i = tm->length - 1;
		}

		for (; i >= 0; i--) {
			if (tm->data[i] < '0' || tm->data[i] > '9') {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid data in "
				    "NotValidAfter time field"));
				goto fail;
			}
		}

		if (tm->type == V_ASN1_UTCTIME) {
			if ((tm->length < 10) || (tm->length > 13)) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid length of "
				    "NotValidAfter time field (%d)",
				    tm->length));
				goto fail;
			}
			/* Validity checks. */
			if ((tm->data[2] != '0' && tm->data[2] != '1') ||
			    (tm->data[2] == '0' && tm->data[3] == '0') ||
			    (tm->data[2] == '1' && tm->data[3] > '2') ||
			    (tm->data[4] > '3') ||
			    (tm->data[4] == '0' && tm->data[5] == '0') ||
			    (tm->data[4] == '3' && tm->data[5] > '1') ||
			    (tm->data[6] > '2') ||
			    (tm->data[6] == '2' && tm->data[7] > '3') ||
			    (tm->data[8] > '5')) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid value in "
				    "NotValidAfter time field"));
				goto fail;
			}
			/* Stupid UTC tricks.  */
			if (tm->data[0] < '5')
				snprintf(after, sizeof after, "20%s",
				    tm->data);
			else
				snprintf(after, sizeof after, "19%s",
				    tm->data);
		} else {	/* V_ASN1_GENERICTIME */
			if ((tm->length < 12) || (tm->length > 15)) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid length of "
				    "NotValidAfter time field (%d)",
				    tm->length));
				goto fail;
			}
			/* Validity checks.  */
			if ((tm->data[4] != '0' && tm->data[4] != '1') ||
			    (tm->data[4] == '0' && tm->data[5] == '0') ||
			    (tm->data[4] == '1' && tm->data[5] > '2') ||
			    (tm->data[6] > '3') ||
			    (tm->data[6] == '0' && tm->data[7] == '0') ||
			    (tm->data[6] == '3' && tm->data[7] > '1') ||
			    (tm->data[8] > '2') ||
			    (tm->data[8] == '2' && tm->data[9] > '3') ||
			    (tm->data[10] > '5')) {
				LOG_DBG((LOG_POLICY, 30,
				    "x509_generate_kn: invalid value in "
				    "NotValidAfter time field"));
				goto fail;
			}
			snprintf(after, sizeof after, "%s", tm->data);
		}

		/* Fix missing seconds.  */
		if (tm->length < 12) {
			after[12] = '0';
			after[13] = '0';
		}
		after[14] = '\0';	/* This will overwrite trailing 'Z' */
	}

	if (asprintf(&buf, fmt, skey, ikey, timecomp, before, timecomp2,
	    after) == -1) {
		log_error("x509_generate_kn: "
		    "failed to allocate memory for KeyNote credential");
		goto fail;
	}
	
	free(ikey);
	ikey = NULL;
	free(skey);
	skey = NULL;

	if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) {
		LOG_DBG((LOG_POLICY, 30,
		    "x509_generate_kn: failed to add new KeyNote credential"));
		goto fail;
	}
	/* We could print the assertion here, but log_print() truncates...  */
	LOG_DBG((LOG_POLICY, 60, "x509_generate_kn: added credential"));

	free(buf);
	buf = NULL;

	if (!X509_NAME_oneline(issuer, isname, 256)) {
		LOG_DBG((LOG_POLICY, 50,
		    "x509_generate_kn: "
		    "X509_NAME_oneline (issuer, ...) failed"));
		goto fail;
	}
	if (!X509_NAME_oneline(subject, subname, 256)) {
		LOG_DBG((LOG_POLICY, 50,
		    "x509_generate_kn: "
		    "X509_NAME_oneline (subject, ...) failed"));
		goto fail;
	}
	if (asprintf(&buf, fmt2, isname, subname, timecomp, before,
	    timecomp2, after) == -1) {
		log_error("x509_generate_kn: malloc failed");
		return 0;
	}

	if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) {
		LOG_DBG((LOG_POLICY, 30,
		    "x509_generate_kn: failed to add new KeyNote credential"));
		goto fail;
	}
	LOG_DBG((LOG_POLICY, 80, "x509_generate_kn: added credential:\n%s",
	    buf));

	free(buf);
	return 1;

fail:
	free(buf);
	free(skey);
	free(ikey);
	if (key)
		RSA_free(key);

	return 0;
}
Example #10
0
/* based on the code of stunnel utility */
int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) {
	X509_STORE* store;
	X509_STORE_CTX store_ctx;
	X509_OBJECT obj;
	X509_NAME* subject;
	X509_NAME* issuer;
	X509* cert;
	X509_CRL* crl;
	X509_REVOKED* revoked;
	EVP_PKEY* pubkey;
	int i, n, rc;
	ASN1_TIME* next_update = NULL;

	if (!preverify_ok) {
		return 0;
	}

	if ((store = pthread_getspecific(tls_store_key)) == NULL) {
		ERROR("Failed to get thread-specific X509 store");
		return 1; /* fail */
	}

	cert = X509_STORE_CTX_get_current_cert(x509_ctx);
	subject = X509_get_subject_name(cert);
	issuer = X509_get_issuer_name(cert);

	/* try to retrieve a CRL corresponding to the _subject_ of
	 * the current certificate in order to verify it's integrity */
	memset((char *)&obj, 0, sizeof obj);
	X509_STORE_CTX_init(&store_ctx, store, NULL, NULL);
	rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
	X509_STORE_CTX_cleanup(&store_ctx);
	crl = obj.data.crl;
	if (rc > 0 && crl) {
		next_update = X509_CRL_get_nextUpdate(crl);

		/* verify the signature on this CRL */
		pubkey = X509_get_pubkey(cert);
		if (X509_CRL_verify(crl, pubkey) <= 0) {
			X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
			X509_OBJECT_free_contents(&obj);
			if (pubkey) {
				EVP_PKEY_free(pubkey);
			}
			return 0; /* fail */
		}
		if (pubkey) {
			EVP_PKEY_free(pubkey);
		}

		/* check date of CRL to make sure it's not expired */
		if (!next_update) {
			X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
			X509_OBJECT_free_contents(&obj);
			return 0; /* fail */
		}
		if (X509_cmp_current_time(next_update) < 0) {
			X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
			X509_OBJECT_free_contents(&obj);
			return 0; /* fail */
		}
		X509_OBJECT_free_contents(&obj);
	}

	/* try to retrieve a CRL corresponding to the _issuer_ of
	 * the current certificate in order to check for revocation */
	memset((char *)&obj, 0, sizeof obj);
	X509_STORE_CTX_init(&store_ctx, store, NULL, NULL);
	rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
	X509_STORE_CTX_cleanup(&store_ctx);
	crl = obj.data.crl;
	if (rc > 0 && crl) {
		/* check if the current certificate is revoked by this CRL */
		n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
		for (i = 0; i < n; i++) {
			revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
			if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) {
				ERROR("Certificate revoked");
				X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_CERT_REVOKED);
				X509_OBJECT_free_contents(&obj);
				return 0; /* fail */
			}
		}
		X509_OBJECT_free_contents(&obj);
	}
	return 1; /* success */
}
int MAIN(int argc, char **argv)
{
    X509_CRL *x=NULL;
    char *CAfile = NULL, *CApath = NULL;
    int ret=1,i,num,badops=0;
    BIO *out=NULL;
    int informat,outformat;
    char *infile=NULL,*outfile=NULL;
    int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
    int fingerprint = 0;
    char **pp,buf[256];
    X509_STORE *store = NULL;
    X509_STORE_CTX ctx;
    X509_LOOKUP *lookup = NULL;
    X509_OBJECT xobj;
    EVP_PKEY *pkey;
    int do_ver = 0;
    const EVP_MD *md_alg,*digest=EVP_md5();

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err=BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

    if (bio_out == NULL)
        if ((bio_out=BIO_new(BIO_s_file())) != NULL)
        {
            BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
#ifdef VMS
            {
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
                bio_out = BIO_push(tmpbio, bio_out);
            }
#endif
        }

    informat=FORMAT_PEM;
    outformat=FORMAT_PEM;

    argc--;
    argv++;
    num=0;
    while (argc >= 1)
    {
#ifdef undef
        if	(strcmp(*argv,"-p") == 0)
        {
            if (--argc < 1) goto bad;
            if (!args_from_file(++argv,Nargc,Nargv)) {
                goto end;
            }*/
        }
#endif
        if 	(strcmp(*argv,"-inform") == 0)
        {
            if (--argc < 1) goto bad;
            informat=str2fmt(*(++argv));
        }
        else if (strcmp(*argv,"-outform") == 0)
        {
            if (--argc < 1) goto bad;
            outformat=str2fmt(*(++argv));
        }
        else if (strcmp(*argv,"-in") == 0)
        {
            if (--argc < 1) goto bad;
            infile= *(++argv);
        }
        else if (strcmp(*argv,"-out") == 0)
        {
            if (--argc < 1) goto bad;
            outfile= *(++argv);
        }
        else if (strcmp(*argv,"-CApath") == 0)
        {
            if (--argc < 1) goto bad;
            CApath = *(++argv);
            do_ver = 1;
        }
        else if (strcmp(*argv,"-CAfile") == 0)
        {
            if (--argc < 1) goto bad;
            CAfile = *(++argv);
            do_ver = 1;
        }
        else if (strcmp(*argv,"-verify") == 0)
            do_ver = 1;
        else if (strcmp(*argv,"-text") == 0)
            text = 1;
        else if (strcmp(*argv,"-hash") == 0)
            hash= ++num;
        else if (strcmp(*argv,"-issuer") == 0)
            issuer= ++num;
        else if (strcmp(*argv,"-lastupdate") == 0)
            lastupdate= ++num;
        else if (strcmp(*argv,"-nextupdate") == 0)
            nextupdate= ++num;
        else if (strcmp(*argv,"-noout") == 0)
            noout= ++num;
        else if (strcmp(*argv,"-fingerprint") == 0)
            fingerprint= ++num;
        else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
        {
            /* ok */
            digest=md_alg;
        }
        else
        {
            BIO_printf(bio_err,"unknown option %s\n",*argv);
            badops=1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops)
    {
bad:
        for (pp=crl_usage; (*pp != NULL); pp++)
            BIO_printf(bio_err,*pp);
        goto end;
    }

    ERR_load_crypto_strings();
    x=load_crl(infile,informat);
    if (x == NULL) {
        goto end;
    }

    if(do_ver) {
        store = X509_STORE_new();
        lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
        if (lookup == NULL) goto end;
        if (!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
            X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);

        lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
        if (lookup == NULL) goto end;
        if (!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM))
            X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
        ERR_clear_error();

        X509_STORE_CTX_init(&ctx, store, NULL, NULL);

        i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
                                      X509_CRL_get_issuer(x), &xobj);
        if(i <= 0) {
            BIO_printf(bio_err,
                       "Error getting CRL issuer certificate\n");
            goto end;
        }
        pkey = X509_get_pubkey(xobj.data.x509);
        X509_OBJECT_free_contents(&xobj);
        if(!pkey) {
            BIO_printf(bio_err,
                       "Error getting CRL issuer public key\n");
            goto end;
        }
        i = X509_CRL_verify(x, pkey);
        EVP_PKEY_free(pkey);
        if(i < 0) goto end;
        if(i == 0) BIO_printf(bio_err, "verify failure\n");
        else BIO_printf(bio_err, "verify OK\n");
    }

    if (num)
    {
        for (i=1; i<=num; i++)
        {
            if (issuer == i)
            {
                X509_NAME_oneline(X509_CRL_get_issuer(x),
                                  buf,256);
                BIO_printf(bio_out,"issuer= %s\n",buf);
            }

            if (hash == i)
            {
                BIO_printf(bio_out,"%08lx\n",
                           X509_NAME_hash(X509_CRL_get_issuer(x)));
            }
            if (lastupdate == i)
            {
                BIO_printf(bio_out,"lastUpdate=");
                ASN1_TIME_print(bio_out,
                                X509_CRL_get_lastUpdate(x));
                BIO_printf(bio_out,"\n");
            }
            if (nextupdate == i)
            {
                BIO_printf(bio_out,"nextUpdate=");
                if (X509_CRL_get_nextUpdate(x))
                    ASN1_TIME_print(bio_out,
                                    X509_CRL_get_nextUpdate(x));
                else
                    BIO_printf(bio_out,"NONE");
                BIO_printf(bio_out,"\n");
            }
            if (fingerprint == i)
            {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];

                if (!X509_CRL_digest(x,digest,md,&n))
                {
                    BIO_printf(bio_err,"out of memory\n");
                    goto end;
                }
                BIO_printf(bio_out,"%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(digest)));
                for (j=0; j<(int)n; j++)
                {
                    BIO_printf(bio_out,"%02X%c",md[j],
                               (j+1 == (int)n)
                               ?'\n':':');
                }
            }
        }
    }

    out=BIO_new(BIO_s_file());
    if (out == NULL)
    {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (outfile == NULL)
    {
        BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
#endif
    }
    else
    {
        if (BIO_write_filename(out,outfile) <= 0)
        {
            perror(outfile);
            goto end;
        }
    }

    if (text) X509_CRL_print(out, x);

    if (noout) goto end;

    if 	(outformat == FORMAT_ASN1)
        i=(int)i2d_X509_CRL_bio(out,x);
    else if (outformat == FORMAT_PEM)
        i=PEM_write_bio_X509_CRL(out,x);
    else
    {
        BIO_printf(bio_err,"bad output format specified for outfile\n");
        goto end;
    }
    if (!i) {
        BIO_printf(bio_err,"unable to write CRL\n");
        goto end;
    }
    ret=0;
end:
    BIO_free_all(out);
    BIO_free_all(bio_out);
    bio_out=NULL;
    X509_CRL_free(x);
    if(store) {
        X509_STORE_CTX_cleanup(&ctx);
        X509_STORE_free(store);
    }
    EXIT(ret);
}
Example #12
0
int crl_main(int argc, char **argv)
{
    X509_CRL *x = NULL;
    BIO *out = NULL;
    X509_STORE *store = NULL;
    X509_STORE_CTX ctx;
    X509_LOOKUP *lookup = NULL;
    X509_OBJECT xobj;
    EVP_PKEY *pkey;
    const EVP_MD *digest = EVP_sha1();
    unsigned long nmflag = 0;
    char nmflag_set = 0;
    char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL;
    char *CAfile = NULL, *CApath = NULL, *prog;
    OPTION_CHOICE o;
    int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
    int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0;
    int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0;
    int i;
#ifndef OPENSSL_NO_MD5
    int hash_old = 0;
#endif

    prog = opt_init(argc, argv, crl_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(crl_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
                goto opthelp;
            break;
        case OPT_KEY:
            keyfile = opt_arg();
            break;
        case OPT_GENDELTA:
            crldiff = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            do_ver = 1;
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            do_ver = 1;
            break;
        case OPT_NOCAPATH:
            noCApath =  1;
            break;
        case OPT_NOCAFILE:
            noCAfile =  1;
            break;
        case OPT_HASH_OLD:
#ifndef OPENSSL_NO_MD5
            hash_old = ++num;
#endif
            break;
        case OPT_VERIFY:
            do_ver = 1;
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_HASH:
            hash = ++num;
            break;
        case OPT_ISSUER:
            issuer = ++num;
            break;
        case OPT_LASTUPDATE:
            lastupdate = ++num;
            break;
        case OPT_NEXTUPDATE:
            nextupdate = ++num;
            break;
        case OPT_NOOUT:
            noout = ++num;
            break;
        case OPT_FINGERPRINT:
            fingerprint = ++num;
            break;
        case OPT_CRLNUMBER:
            crlnumber = ++num;
            break;
        case OPT_BADSIG:
            badsig = 1;
            break;
        case OPT_NAMEOPT:
            nmflag_set = 1;
            if (!set_name_ex(&nmflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_MD:
            if (!opt_md(opt_unknown(), &digest))
                goto opthelp;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (!nmflag_set)
        nmflag = XN_FLAG_ONELINE;

    x = load_crl(infile, informat);
    if (x == NULL)
        goto end;

    if (do_ver) {
        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
            goto end;
        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
        if (lookup == NULL)
            goto end;
        if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
            BIO_printf(bio_err, "Error initialising X509 store\n");
            goto end;
        }

        i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
                                      X509_CRL_get_issuer(x), &xobj);
        if (i <= 0) {
            BIO_printf(bio_err, "Error getting CRL issuer certificate\n");
            goto end;
        }
        pkey = X509_get0_pubkey(xobj.data.x509);
        X509_OBJECT_free_contents(&xobj);
        if (!pkey) {
            BIO_printf(bio_err, "Error getting CRL issuer public key\n");
            goto end;
        }
        i = X509_CRL_verify(x, pkey);
        if (i < 0)
            goto end;
        if (i == 0)
            BIO_printf(bio_err, "verify failure\n");
        else
            BIO_printf(bio_err, "verify OK\n");
    }

    if (crldiff) {
        X509_CRL *newcrl, *delta;
        if (!keyfile) {
            BIO_puts(bio_err, "Missing CRL signing key\n");
            goto end;
        }
        newcrl = load_crl(crldiff, informat);
        if (!newcrl)
            goto end;
        pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key");
        if (!pkey) {
            X509_CRL_free(newcrl);
            goto end;
        }
        delta = X509_CRL_diff(x, newcrl, pkey, digest, 0);
        X509_CRL_free(newcrl);
        EVP_PKEY_free(pkey);
        if (delta) {
            X509_CRL_free(x);
            x = delta;
        } else {
            BIO_puts(bio_err, "Error creating delta CRL\n");
            goto end;
        }
    }

    if (num) {
        for (i = 1; i <= num; i++) {
            if (issuer == i) {
                print_name(bio_out, "issuer=", X509_CRL_get_issuer(x),
                           nmflag);
            }
            if (crlnumber == i) {
                ASN1_INTEGER *crlnum;
                crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL);
                BIO_printf(bio_out, "crlNumber=");
                if (crlnum) {
                    i2a_ASN1_INTEGER(bio_out, crlnum);
                    ASN1_INTEGER_free(crlnum);
                } else
                    BIO_puts(bio_out, "<NONE>");
                BIO_printf(bio_out, "\n");
            }
            if (hash == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash(X509_CRL_get_issuer(x)));
            }
#ifndef OPENSSL_NO_MD5
            if (hash_old == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash_old(X509_CRL_get_issuer(x)));
            }
#endif
            if (lastupdate == i) {
                BIO_printf(bio_out, "lastUpdate=");
                ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(x));
                BIO_printf(bio_out, "\n");
            }
            if (nextupdate == i) {
                BIO_printf(bio_out, "nextUpdate=");
                if (X509_CRL_get_nextUpdate(x))
                    ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(x));
                else
                    BIO_printf(bio_out, "NONE");
                BIO_printf(bio_out, "\n");
            }
            if (fingerprint == i) {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];

                if (!X509_CRL_digest(x, digest, md, &n)) {
                    BIO_printf(bio_err, "out of memory\n");
                    goto end;
                }
                BIO_printf(bio_out, "%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(digest)));
                for (j = 0; j < (int)n; j++) {
                    BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n)
                               ? '\n' : ':');
                }
            }
        }
    }
    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    if (text)
        X509_CRL_print(out, x);

    if (noout) {
        ret = 0;
        goto end;
    }

    if (badsig) {
        ASN1_BIT_STRING *sig;
        unsigned char *psig;
        X509_CRL_get0_signature(&sig, NULL, x);
        psig = ASN1_STRING_data(sig);
        psig[ASN1_STRING_length(sig) - 1] ^= 0x1;
    }

    if (outformat == FORMAT_ASN1)
        i = (int)i2d_X509_CRL_bio(out, x);
    else
        i = PEM_write_bio_X509_CRL(out, x);
    if (!i) {
        BIO_printf(bio_err, "unable to write CRL\n");
        goto end;
    }
    ret = 0;

 end:
    if (ret != 0)
        ERR_print_errors(bio_err);
    BIO_free_all(out);
    X509_CRL_free(x);
    if (store) {
        X509_STORE_CTX_cleanup(&ctx);
        X509_STORE_free(store);
    }
    return (ret);
}
Example #13
0
/* based on BSD-style licensed code of mod_ssl */
static int crl_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509_STORE_CTX store_ctx;
    X509_OBJECT obj;
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    X509_CRL *crl;
    X509_REVOKED *revoked;
    EVP_PKEY *pubkey;
    long serial;
    int i, n, rc;
    char *cp;
    ASN1_TIME *last_update=NULL, *next_update=NULL;

    /* determine certificate ingredients in advance */
    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    subject=X509_get_subject_name(cert);
    issuer=X509_get_issuer_name(cert);

    /* try to retrieve a CRL corresponding to the _subject_ of
     * the current certificate in order to verify it's integrity */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        cp=X509_NAME_oneline(subject, NULL, 0);
        s_log(LOG_INFO, "CRL: issuer: %s", cp);
        OPENSSL_free(cp);
        last_update=X509_CRL_get_lastUpdate(crl);
        next_update=X509_CRL_get_nextUpdate(crl);
        log_time(LOG_INFO, "CRL: last update", last_update);
        log_time(LOG_INFO, "CRL: next update", next_update);

        /* verify the signature on this CRL */
        pubkey=X509_get_pubkey(cert);
        if(X509_CRL_verify(crl, pubkey)<=0) {
            s_log(LOG_WARNING, "CRL: Invalid signature");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_CRL_SIGNATURE_FAILURE);
            X509_OBJECT_free_contents(&obj);
            if(pubkey)
                EVP_PKEY_free(pubkey);
            return 0; /* reject connection */
        }
        if(pubkey)
            EVP_PKEY_free(pubkey);

        /* check date of CRL to make sure it's not expired */
        if(!next_update) {
            s_log(LOG_WARNING, "CRL: Invalid nextUpdate field");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        if(X509_cmp_current_time(next_update)<0) {
            s_log(LOG_WARNING, "CRL: CRL Expired - revoking all certificates");
            X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        X509_OBJECT_free_contents(&obj);
    }

    /* try to retrieve a CRL corresponding to the _issuer_ of
     * the current certificate in order to check for revocation */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        /* check if the current certificate is revoked by this CRL */
        n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
        for(i=0; i<n; i++) {
            revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
            if(ASN1_INTEGER_cmp(revoked->serialNumber,
                    X509_get_serialNumber(cert)) == 0) {
                serial=ASN1_INTEGER_get(revoked->serialNumber);
                cp=X509_NAME_oneline(issuer, NULL, 0);
                s_log(LOG_WARNING, "CRL: Certificate with serial %ld (0x%lX) "
                    "revoked per CRL from issuer %s", serial, serial, cp);
                OPENSSL_free(cp);
                X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
                X509_OBJECT_free_contents(&obj);
                return 0; /* reject connection */
            }
        }
        X509_OBJECT_free_contents(&obj);
    }
    return 1; /* accept connection */
}
Example #14
0
int MAIN(int argc, char **argv)
{
    unsigned long nmflag = 0;
    X509_CRL *x = NULL;
    char *CAfile = NULL, *CApath = NULL;
    int ret = 1, i, num, badops = 0, badsig = 0;
    BIO *out = NULL;
    int informat, outformat, keyformat;
    char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL;
    int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout =
        0, text = 0;
#ifndef OPENSSL_NO_MD5
    int hash_old = 0;
#endif
    int fingerprint = 0, crlnumber = 0;
    const char **pp;
    X509_STORE *store = NULL;
    X509_STORE_CTX ctx;
    X509_LOOKUP *lookup = NULL;
    X509_OBJECT xobj;
    EVP_PKEY *pkey;
    int do_ver = 0;
    const EVP_MD *md_alg, *digest = EVP_sha1();

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (!load_config(bio_err, NULL))
        goto end;

    if (bio_out == NULL)
        if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
            BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
            {
                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
                bio_out = BIO_push(tmpbio, bio_out);
            }
#endif
        }

    informat = FORMAT_PEM;
    outformat = FORMAT_PEM;
    keyformat = FORMAT_PEM;

    argc--;
    argv++;
    num = 0;
    while (argc >= 1) {
#ifdef undef
        if (sgx_strcmp(*argv, "-p") == 0) {
            if (--argc < 1)
                goto bad;
            if (!args_from_file(++argv, Nargc, Nargv)) {
                goto end;
            }
        */}
#endif
        if (sgx_strcmp(*argv, "-inform") == 0) {
            if (--argc < 1)
                goto bad;
            informat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-outform") == 0) {
            if (--argc < 1)
                goto bad;
            outformat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-in") == 0) {
            if (--argc < 1)
                goto bad;
            infile = *(++argv);
        } else if (sgx_strcmp(*argv, "-gendelta") == 0) {
            if (--argc < 1)
                goto bad;
            crldiff = *(++argv);
        } else if (sgx_strcmp(*argv, "-key") == 0) {
            if (--argc < 1)
                goto bad;
            keyfile = *(++argv);
        } else if (sgx_strcmp(*argv, "-keyform") == 0) {
            if (--argc < 1)
                goto bad;
            keyformat = str2fmt(*(++argv));
        } else if (sgx_strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                goto bad;
            outfile = *(++argv);
        } else if (sgx_strcmp(*argv, "-CApath") == 0) {
            if (--argc < 1)
                goto bad;
            CApath = *(++argv);
            do_ver = 1;
        } else if (sgx_strcmp(*argv, "-CAfile") == 0) {
            if (--argc < 1)
                goto bad;
            CAfile = *(++argv);
            do_ver = 1;
        } else if (sgx_strcmp(*argv, "-verify") == 0)
            do_ver = 1;
        else if (sgx_strcmp(*argv, "-text") == 0)
            text = 1;
        else if (sgx_strcmp(*argv, "-hash") == 0)
            hash = ++num;
#ifndef OPENSSL_NO_MD5
        else if (sgx_strcmp(*argv, "-hash_old") == 0)
            hash_old = ++num;
#endif
        else if (sgx_strcmp(*argv, "-nameopt") == 0) {
            if (--argc < 1)
                goto bad;
            if (!set_name_ex(&nmflag, *(++argv)))
                goto bad;
        } else if (sgx_strcmp(*argv, "-issuer") == 0)
            issuer = ++num;
        else if (sgx_strcmp(*argv, "-lastupdate") == 0)
            lastupdate = ++num;
        else if (sgx_strcmp(*argv, "-nextupdate") == 0)
            nextupdate = ++num;
        else if (sgx_strcmp(*argv, "-noout") == 0)
            noout = ++num;
        else if (sgx_strcmp(*argv, "-fingerprint") == 0)
            fingerprint = ++num;
        else if (sgx_strcmp(*argv, "-crlnumber") == 0)
            crlnumber = ++num;
        else if (sgx_strcmp(*argv, "-badsig") == 0)
            badsig = 1;
        else if ((md_alg = EVP_get_digestbyname(*argv + 1))) {
            /* ok */
            digest = md_alg;
        } else {
            BIO_printf(bio_err, "unknown option %s\n", *argv);
            badops = 1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops) {
 bad:
        for (pp = crl_usage; (*pp != NULL); pp++)
            BIO_printf(bio_err, "%s", *pp);
        goto end;
    }

    ERR_load_crypto_strings();
    x = load_crl(infile, informat);
    if (x == NULL) {
        goto end;
    }

    if (do_ver) {
        store = X509_STORE_new();
        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
        if (lookup == NULL)
            goto end;
        if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM))
            X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);

        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
        if (lookup == NULL)
            goto end;
        if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM))
            X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
        ERR_clear_error();

        if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
            BIO_printf(bio_err, "Error initialising X509 store\n");
            goto end;
        }

        i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
                                      X509_CRL_get_issuer(x), &xobj);
        if (i <= 0) {
            BIO_printf(bio_err, "Error getting CRL issuer certificate\n");
            goto end;
        }
        pkey = X509_get_pubkey(xobj.data.x509);
        X509_OBJECT_free_contents(&xobj);
        if (!pkey) {
            BIO_printf(bio_err, "Error getting CRL issuer public key\n");
            goto end;
        }
        i = X509_CRL_verify(x, pkey);
        EVP_PKEY_free(pkey);
        if (i < 0)
            goto end;
        if (i == 0)
            BIO_printf(bio_err, "verify failure\n");
        else
            BIO_printf(bio_err, "verify OK\n");
    }

    if (crldiff) {
        X509_CRL *newcrl, *delta;
        if (!keyfile) {
            BIO_puts(bio_err, "Missing CRL signing key\n");
            goto end;
        }
        newcrl = load_crl(crldiff, informat);
        if (!newcrl)
            goto end;
        pkey = load_key(bio_err, keyfile, keyformat, 0, NULL, NULL,
                        "CRL signing key");
        if (!pkey) {
            X509_CRL_free(newcrl);
            goto end;
        }
        delta = X509_CRL_diff(x, newcrl, pkey, digest, 0);
        X509_CRL_free(newcrl);
        EVP_PKEY_free(pkey);
        if (delta) {
            X509_CRL_free(x);
            x = delta;
        } else {
            BIO_puts(bio_err, "Error creating delta CRL\n");
            goto end;
        }
    }

    if (num) {
        for (i = 1; i <= num; i++) {
            if (issuer == i) {
                print_name(bio_out, "issuer=", X509_CRL_get_issuer(x),
                           nmflag);
            }
            if (crlnumber == i) {
                ASN1_INTEGER *crlnum;
                crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL);
                BIO_printf(bio_out, "crlNumber=");
                if (crlnum) {
                    i2a_ASN1_INTEGER(bio_out, crlnum);
                    ASN1_INTEGER_free(crlnum);
                } else
                    BIO_puts(bio_out, "<NONE>");
                BIO_printf(bio_out, "\n");
            }
            if (hash == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash(X509_CRL_get_issuer(x)));
            }
#ifndef OPENSSL_NO_MD5
            if (hash_old == i) {
                BIO_printf(bio_out, "%08lx\n",
                           X509_NAME_hash_old(X509_CRL_get_issuer(x)));
            }
#endif
            if (lastupdate == i) {
                BIO_printf(bio_out, "lastUpdate=");
                ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(x));
                BIO_printf(bio_out, "\n");
            }
            if (nextupdate == i) {
                BIO_printf(bio_out, "nextUpdate=");
                if (X509_CRL_get_nextUpdate(x))
                    ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(x));
                else
                    BIO_printf(bio_out, "NONE");
                BIO_printf(bio_out, "\n");
            }
            if (fingerprint == i) {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];

                if (!X509_CRL_digest(x, digest, md, &n)) {
                    BIO_printf(bio_err, "out of memory\n");
                    goto end;
                }
                BIO_printf(bio_out, "%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(digest)));
                for (j = 0; j < (int)n; j++) {
                    BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n)
                               ? '\n' : ':');
                }
            }
        }
    }

    out = BIO_new(BIO_s_file());
    if (out == NULL) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (outfile == NULL) {
        BIO_set_fp(out, stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
#endif
    } else {
        if (BIO_write_filename(out, outfile) <= 0) {
            perror(outfile);
            goto end;
        }
    }

    if (text)
        X509_CRL_print(out, x);

    if (noout) {
        ret = 0;
        goto end;
    }

    if (badsig)
        x->signature->data[x->signature->length - 1] ^= 0x1;

    if (outformat == FORMAT_ASN1)
        i = (int)i2d_X509_CRL_bio(out, x);
    else if (outformat == FORMAT_PEM)
        i = PEM_write_bio_X509_CRL(out, x);
    else {
        BIO_printf(bio_err, "bad output format specified for outfile\n");
        goto end;
    }
    if (!i) {
        BIO_printf(bio_err, "unable to write CRL\n");
        goto end;
    }
    ret = 0;
 end:
    if (ret != 0)
        ERR_print_errors(bio_err);
    BIO_free_all(out);
    BIO_free_all(bio_out);
    bio_out = NULL;
    X509_CRL_free(x);
    if (store) {
        X509_STORE_CTX_cleanup(&ctx);
        X509_STORE_free(store);
    }
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Example #15
0
int
crl_main(int argc, char **argv)
{
	unsigned long nmflag = 0;
	X509_CRL *x = NULL;
	int ret = 1, i;
	BIO *out = NULL;
	X509_STORE *store = NULL;
	X509_STORE_CTX ctx;
	X509_LOOKUP *lookup = NULL;
	X509_OBJECT xobj;
	EVP_PKEY *pkey;
	const EVP_MD *digest;
	char *digest_name = NULL;

	if (single_execution) {
		if (pledge("stdio cpath wpath rpath", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	if (bio_out == NULL) {
		if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
			BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
		}
	}

	digest = EVP_sha256();

	memset(&crl_config, 0, sizeof(crl_config));
	crl_config.informat = FORMAT_PEM;
	crl_config.outformat = FORMAT_PEM;

	if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) {
		crl_usage();
		goto end;
	}

	if (crl_config.cafile != NULL || crl_config.capath != NULL)
		crl_config.verify = 1;

	if (crl_config.nameopt != NULL) {
		if (set_name_ex(&nmflag, crl_config.nameopt) != 1) {
			fprintf(stderr,
			    "Invalid -nameopt argument '%s'\n",
			    crl_config.nameopt);
			goto end;
		}
	}

	if (digest_name != NULL) {
		if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
			fprintf(stderr,
			    "Unknown message digest algorithm '%s'\n",
			    digest_name);
			goto end;
		}
	}

	x = load_crl(crl_config.infile, crl_config.informat);
	if (x == NULL)
		goto end;

	if (crl_config.verify) {
		store = X509_STORE_new();
		lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
		if (lookup == NULL)
			goto end;
		if (!X509_LOOKUP_load_file(lookup, crl_config.cafile,
		    X509_FILETYPE_PEM))
			X509_LOOKUP_load_file(lookup, NULL,
			    X509_FILETYPE_DEFAULT);

		lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
		if (lookup == NULL)
			goto end;
		if (!X509_LOOKUP_add_dir(lookup, crl_config.capath,
		    X509_FILETYPE_PEM))
			X509_LOOKUP_add_dir(lookup, NULL,
			    X509_FILETYPE_DEFAULT);
		ERR_clear_error();

		if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) {
			BIO_printf(bio_err,
			    "Error initialising X509 store\n");
			goto end;
		}
		i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,
		    X509_CRL_get_issuer(x), &xobj);
		if (i <= 0) {
			BIO_printf(bio_err,
			    "Error getting CRL issuer certificate\n");
			goto end;
		}
		pkey = X509_get_pubkey(xobj.data.x509);
		X509_OBJECT_free_contents(&xobj);
		if (!pkey) {
			BIO_printf(bio_err,
			    "Error getting CRL issuer public key\n");
			goto end;
		}
		i = X509_CRL_verify(x, pkey);
		EVP_PKEY_free(pkey);
		if (i < 0)
			goto end;
		if (i == 0)
			BIO_printf(bio_err, "verify failure\n");
		else
			BIO_printf(bio_err, "verify OK\n");
	}

	/* Print requested information the order that the flags were given. */
	for (i = 1; i <= argc; i++) {
		if (crl_config.issuer == i) {
			print_name(bio_out, "issuer=",
			    X509_CRL_get_issuer(x), nmflag);
		}
		if (crl_config.crlnumber == i) {
			ASN1_INTEGER *crlnum;
			crlnum = X509_CRL_get_ext_d2i(x,
			    NID_crl_number, NULL, NULL);
			BIO_printf(bio_out, "crlNumber=");
			if (crlnum) {
				i2a_ASN1_INTEGER(bio_out, crlnum);
				ASN1_INTEGER_free(crlnum);
			} else
				BIO_puts(bio_out, "<NONE>");
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.hash == i) {
			BIO_printf(bio_out, "%08lx\n",
			    X509_NAME_hash(X509_CRL_get_issuer(x)));
		}
#ifndef OPENSSL_NO_MD5
		if (crl_config.hash_old == i) {
			BIO_printf(bio_out, "%08lx\n",
			    X509_NAME_hash_old(X509_CRL_get_issuer(x)));
		}
#endif
		if (crl_config.lastupdate == i) {
			BIO_printf(bio_out, "lastUpdate=");
			ASN1_TIME_print(bio_out,
			    X509_CRL_get_lastUpdate(x));
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.nextupdate == i) {
			BIO_printf(bio_out, "nextUpdate=");
			if (X509_CRL_get_nextUpdate(x))
				ASN1_TIME_print(bio_out,
				    X509_CRL_get_nextUpdate(x));
			else
				BIO_printf(bio_out, "NONE");
			BIO_printf(bio_out, "\n");
		}
		if (crl_config.fingerprint == i) {
			int j;
			unsigned int n;
			unsigned char md[EVP_MAX_MD_SIZE];

			if (!X509_CRL_digest(x, digest, md, &n)) {
				BIO_printf(bio_err, "out of memory\n");
				goto end;
			}
			BIO_printf(bio_out, "%s Fingerprint=",
			    OBJ_nid2sn(EVP_MD_type(digest)));
			for (j = 0; j < (int) n; j++) {
				BIO_printf(bio_out, "%02X%c", md[j],
				    (j + 1 == (int)n) ? '\n' : ':');
			}
		}
	}

	out = BIO_new(BIO_s_file());
	if (out == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (crl_config.outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, crl_config.outfile) <= 0) {
			perror(crl_config.outfile);
			goto end;
		}
	}

	if (crl_config.text)
		X509_CRL_print(out, x);

	if (crl_config.noout) {
		ret = 0;
		goto end;
	}
	if (crl_config.outformat == FORMAT_ASN1)
		i = (int) i2d_X509_CRL_bio(out, x);
	else if (crl_config.outformat == FORMAT_PEM)
		i = PEM_write_bio_X509_CRL(out, x);
	else {
		BIO_printf(bio_err,
		    "bad output format specified for outfile\n");
		goto end;
	}
	if (!i) {
		BIO_printf(bio_err, "unable to write CRL\n");
		goto end;
	}
	ret = 0;

 end:
	BIO_free_all(out);
	BIO_free_all(bio_out);
	bio_out = NULL;
	X509_CRL_free(x);
	if (store) {
		X509_STORE_CTX_cleanup(&ctx);
		X509_STORE_free(store);
	}

	return (ret);
}