Пример #1
0
static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
					int ca)
{
	int i_ext;

	/* If ca is true we must return if this is a valid CA certificate. */
	if (ca) return check_ca(x);

	/* 
	 * Check the optional key usage field:
	 * if Key Usage is present, it must be one of digitalSignature 
	 * and/or nonRepudiation (other values are not consistent and shall
	 * be rejected).
	 */
	if ((x->ex_flags & EXFLAG_KUSAGE)
	    && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
		!(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
		return 0;

	/* Only time stamp key usage is permitted and it's required. */
	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
		return 0;

	/* Extended Key Usage MUST be critical */
	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
	if (i_ext >= 0)
		{
		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
		if (!X509_EXTENSION_get_critical(ext))
			return 0;
		}

	return 1;
}
Пример #2
0
/* common S/MIME checks */
static int purpose_smime(const X509 *x, int ca)
{
    if (xku_reject(x, XKU_SMIME))
        return 0;
    if (ca) {
        int ca_ret;
        ca_ret = check_ca(x);
        if (!ca_ret)
            return 0;
        /* check nsCertType if present */
        if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
            return ca_ret;
        else
            return 0;
    }
    if (x->ex_flags & EXFLAG_NSCERT) {
        if (x->ex_nscert & NS_SMIME)
            return 1;
        /* Workaround for some buggy certificates */
        if (x->ex_nscert & NS_SSL_CLIENT)
            return 2;
        return 0;
    }
    return 1;
}
Пример #3
0
static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  /* Must be a valid CA.  Should we really support the "I don't know"
     value (2)? */
  if(ca) return check_ca(x);
  /* leaf certificate is checked in OCSP_verify() */
  return 1;
}
Пример #4
0
int X509_check_ca(X509 *x)
{
	if(!(x->ex_flags & EXFLAG_SET)) {
		x509v3_cache_extensions(x);
	}

	return check_ca(x);
}
Пример #5
0
/* Check SSL CA: common checks for SSL client and server */
static int check_ssl_ca(const X509 *x)
{
  int ca_ret;
  ca_ret = check_ca(x);
  if(!ca_ret) return 0;
  /* check nsCertType if present */
  if(ca_ret != 5 || x->ex_nscert & NS_SSL_CA) return ca_ret;
  else return 0;
}
Пример #6
0
static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  if(ca) {
    int ca_ret;
    if((ca_ret = check_ca(x)) != 2) return ca_ret;
    else return 0;
  }
  if(ku_reject(x, KU_CRL_SIGN)) return 0;
  return 1;
}
Пример #7
0
int X509_check_ca(X509 *x)
{
  if(!(x->ex_flags & EXFLAG_SET)) {
    CRYPTO_w_lock(CRYPTO_LOCK_X509);
    x509v3_cache_extensions(x);
    CRYPTO_w_unlock(CRYPTO_LOCK_X509);
  }

  return check_ca(x);
}
Пример #8
0
int X509_check_ca(X509 *x)
{
    if (!(x->ex_flags & EXFLAG_SET)) {
        CRYPTO_THREAD_write_lock(x->lock);
        x509v3_cache_extensions(x);
        CRYPTO_THREAD_unlock(x->lock);
    }

    return check_ca(x);
}
Пример #9
0
int
easy_pkcs7_sign(const char *content, size_t len,
    char **signature, size_t *signature_len,
    const char *key_file, const char *cert_file)
{
	FILE *f;
	X509 *certificate;
	STACK_OF(X509) *c, *cert_chain;
	EVP_PKEY *private_key;
	char *tmp_sig;
	BIO *out, *in;
	PKCS7 *p7;
	int status;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	status = -1;
	private_key = NULL;
	cert_chain = NULL;
	in = NULL;

	c = file_to_certs(cert_file);

	if (sk_X509_num(c) != 1) {
		warnx("More then one certificate in the certificate file");
		goto cleanup;
	}
	certificate = sk_X509_value(c, 0);

	/* Compute ex_kusage */
	X509_check_purpose(certificate, -1, 0);

	if (check_ca(certificate)) {
		warnx("CA keys are not valid for signatures");
		goto cleanup;
	}

	if (certificate->ex_xkusage != pkg_key_usage) {
		warnx("Certificate must have CODE SIGNING "
		    "and EMAIL PROTECTION property");
		goto cleanup;
	}

	if (cert_chain_file)
		cert_chain = file_to_certs(cert_chain_file);

	if ((f = fopen(key_file, "r")) == NULL) {
		warn("Failed to open private key file %s", key_file);
		goto cleanup;
	}
	private_key = PEM_read_PrivateKey(f, NULL, ssl_pass_cb, NULL);
	fclose(f);
	if (private_key == NULL) {
		warnx("Can't read private key: %s", key_file);
		goto cleanup;
	}

	if (X509_check_private_key(certificate, private_key) != 1) {
		warnx("The private key %s doesn't match the certificate %s",
		    key_file, cert_file);
		goto cleanup;
	}

	in = BIO_new_mem_buf(__UNCONST(content), len);

	p7 = PKCS7_sign(certificate, private_key, cert_chain, in, 
	    PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY);
	if (p7 == NULL) {
		warnx("Failed to create signature structure");
		goto cleanup;
	}

	out = BIO_new(BIO_s_mem());
	PEM_write_bio_PKCS7(out, p7);
	*signature_len = BIO_get_mem_data(out, &tmp_sig);
	*signature = xmalloc(*signature_len);
	memcpy(*signature, tmp_sig, *signature_len);
	BIO_free_all(out);

	PKCS7_free(p7);

	status = 0;

cleanup:
	sk_X509_free(c);
	sk_X509_free(cert_chain);
	EVP_PKEY_free(private_key);
	BIO_free(in);

	return status;
}
Пример #10
0
int
easy_pkcs7_verify(const char *content, size_t len,
    const char *signature, size_t signature_len,
    const char *anchor, int is_pkg)
{
	STACK_OF(X509) *cert_chain, *signers;
	X509_STORE *store;
	BIO *sig, *in;
	PKCS7 *p7;
	int i, status;
	X509_NAME *name;
	char *subject;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	status = -1;

	if (cert_chain_file)
		cert_chain = file_to_certs(cert_chain_file);
	else
		cert_chain = NULL;

	store = X509_STORE_new();
	if (store == NULL) {
		sk_X509_free(cert_chain);
		warnx("Failed to create certificate store");
		return -1;
	}

	X509_STORE_load_locations(store, anchor, NULL);

	in = BIO_new_mem_buf(__UNCONST(content), len);
	sig = BIO_new_mem_buf(__UNCONST(signature), signature_len);
	signers = NULL;

	p7 = PEM_read_bio_PKCS7(sig, NULL, NULL, NULL);
	if (p7 == NULL) {
		warnx("Failed to parse the signature");
		goto cleanup;
	}

	if (PKCS7_verify(p7, cert_chain, store, in, NULL, 0) != 1) {
		warnx("Failed to verify signature");
		goto cleanup;
	}

	signers = PKCS7_get0_signers(p7, NULL, 0);
	if (signers == NULL) {
		warnx("Failed to get signers");
		goto cleanup;
	}
    
	if (sk_X509_num(signers) == 0) {
		warnx("No signers found");
		goto cleanup;
	}

	for (i = 0; i < sk_X509_num(signers); i++) {
		/* Compute ex_xkusage */
		X509_check_purpose(sk_X509_value(signers, i), -1, -1);

		if (check_ca(sk_X509_value(signers, i))) {
			warnx("CA keys are not valid for signatures");
			goto cleanup;
		}
		if (is_pkg) {
			if (sk_X509_value(signers, i)->ex_xkusage != pkg_key_usage) {
				warnx("Certificate must have CODE SIGNING "
				    "and EMAIL PROTECTION property");
				goto cleanup;
			}
		} else {
			if (sk_X509_value(signers, i)->ex_xkusage != 0) {
				warnx("Certificate must not have any property");
				goto cleanup;
			}
		}
	}

	printf("Sigature ok, signed by:\n");

	for (i = 0; i < sk_X509_num(signers); i++) {
		name = X509_get_subject_name(sk_X509_value(signers, i));
		subject = X509_NAME_oneline(name, NULL, 0);

		printf("\t%s\n", subject);

		OPENSSL_free(subject);
	}

	status = 0;

cleanup:
	sk_X509_free(cert_chain);
	sk_X509_free(signers);
	X509_STORE_free(store);

	PKCS7_free(p7);
	BIO_free(in);
	BIO_free(sig);

	return status;
}