Beispiel #1
0
STACK_OF(X509) *TS_CONF_load_certs(const char *file)
	{
	BIO *certs = NULL;
	STACK_OF(X509) *othercerts = NULL;
	STACK_OF(X509_INFO) *allcerts = NULL;
	int i;

	if (!(certs = BIO_new_file(file, "r"))) goto end;

	if (!(othercerts = sk_X509_new_null())) goto end;
	allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
	for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
		{
		X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
		if (xi->x509)
			{
			sk_X509_push(othercerts, xi->x509);
			xi->x509 = NULL;
			}
		}
end:
	if (othercerts == NULL)
		fprintf(stderr, "unable to load certificates: %s\n", file);
	sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
	BIO_free(certs);
	return othercerts;
	}
Beispiel #2
0
bool CERTIFICATE_FILE_CLASS::removeCertificate(int index)

//  DESCRIPTION     : Remove the certificate at the given index.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           :
//<<===========================================================================
{
	int numberOfCerts;

	if ((openSslM_ptr == NULL) || (x509InfoListM_ptr == NULL))
	{
		return NULL;
	}

	numberOfCerts = sk_X509_INFO_num(x509InfoListM_ptr);
	if ( (index < 0) || (index >= numberOfCerts))
	{
		// index out of range
		if (loggerM_ptr)
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Index out of bounds in CERTIFICATE_FILE_CLASS::removeCertificate()");
		}
		return false;
	}

	// delete the certificate
	sk_X509_INFO_delete(x509InfoListM_ptr, index);

	changedM = true;

	return true;
;
}
Beispiel #3
0
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
    STACK_OF(X509_INFO) *inf;
    X509_INFO *itmp;
    BIO *in;
    int i, count = 0;
    if (type != X509_FILETYPE_PEM)
        return X509_load_cert_file(ctx, file, type);
    in = BIO_new_file(file, "r");
    if (!in) {
        X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB);
        return 0;
    }
    inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
    BIO_free(in);
    if (!inf) {
        X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB);
        return 0;
    }
    for (i = 0; i < sk_X509_INFO_num(inf); i++) {
        itmp = sk_X509_INFO_value(inf, i);
        if (itmp->x509) {
            X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
            count++;
        }
        if (itmp->crl) {
            X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
            count++;
        }
    }
    sk_X509_INFO_pop_free(inf, X509_INFO_free);
    return count;
}
Beispiel #4
0
STACK_OF(X509) *TS_CONF_load_certs(const char *file)
{
    BIO *certs = NULL;
    STACK_OF(X509) *othercerts = NULL;
    STACK_OF(X509_INFO) *allcerts = NULL;
    int i;

    if ((certs = BIO_new_file(file, "r")) == NULL)
        goto end;
    if ((othercerts = sk_X509_new_null()) == NULL)
        goto end;

    allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
    for (i = 0; i < sk_X509_INFO_num(allcerts); i++) {
        X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
        if (xi->x509) {
            sk_X509_push(othercerts, xi->x509);
            xi->x509 = NULL;
        }
    }
 end:
    if (othercerts == NULL)
        TSerr(TS_F_TS_CONF_LOAD_CERTS, TS_R_CANNOT_LOAD_CERT);
    sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
    BIO_free(certs);
    return othercerts;
}
Beispiel #5
0
static STACK_OF(X509) *
read_fullchain(const char *file, int *count)
{
	int i;
	BIO *bio;
	STACK_OF(X509_INFO) *xis = NULL;
	X509_INFO *xi;
	STACK_OF(X509) *rv = NULL;

	*count = 0;

	if ((bio = BIO_new_file(file, "r")) == NULL) {
		warn("Unable to read a certificate from %s", file);
		return NULL;
	}
	if ((xis = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL)) == NULL) {
		warnx("Unable to read PEM format from %s", file);
		return NULL;
	}
	BIO_free(bio);

	if (sk_X509_INFO_num(xis) <= 0) {
		warnx("No certificates in file %s", file);
		goto end;
	}
	if ((rv = sk_X509_new_null()) == NULL) {
		warnx("malloc failed");
		goto end;
	}

	for (i = 0; i < sk_X509_INFO_num(xis); i++) {
		xi = sk_X509_INFO_value(xis, i);
		if (xi->x509 == NULL)
		    continue;
		if (!sk_X509_push(rv, xi->x509)) {
			warnx("unable to build x509 chain");
			sk_X509_pop_free(rv, X509_free);
			rv = NULL;
			goto end;
		}
		xi->x509 = NULL;
		(*count)++;
	}
end:
	sk_X509_INFO_pop_free(xis, X509_INFO_free);
	return rv;
}
Beispiel #6
0
CERTIFICATE_CLASS* CERTIFICATE_FILE_CLASS::getCertificate(int index)

//  DESCRIPTION     : Return the certificate at the given index.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : The caller needs to delete the certificate
//<<===========================================================================
{
	int numberOfCerts;
	X509_INFO* x509Info_ptr;
	CERTIFICATE_CLASS* cert_ptr;

	if ((openSslM_ptr == NULL) || (x509InfoListM_ptr == NULL))
	{
		return NULL;
	}

	numberOfCerts = sk_X509_INFO_num(x509InfoListM_ptr);
	if ( (index < 0) || (index >= numberOfCerts))
	{
		// index out of range
		if (loggerM_ptr)
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Index out of bounds in CERTIFICATE_FILE_CLASS::getCertificate()");
		}
		return NULL;
	}

	// get the certificate
	x509Info_ptr = sk_X509_INFO_value(x509InfoListM_ptr, index);
	if (x509Info_ptr == NULL)
	{
		openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "getting certificate");
		return NULL;
	}
	if (x509Info_ptr->x509 != NULL)
	{
		cert_ptr = new CERTIFICATE_CLASS(x509Info_ptr->x509);
	}
	else if (x509Info_ptr->x_pkey != NULL)
	{
		cert_ptr = new CERTIFICATE_CLASS(x509Info_ptr->x_pkey->dec_pkey);
	}
	else
	{
		if (loggerM_ptr)
		{
			loggerM_ptr->text(LOG_ERROR, 1, "No data in information structure while getting certificate");
		}
		return NULL;
	}

	return cert_ptr;
}
Beispiel #7
0
bool CERTIFICATE_FILE_CLASS::moveCertificate(int oldIndex, int newIndex)

//  DESCRIPTION     : Moves the certificate at the given index to the new index.
//					: The newIndex will be the index the certificate will be at 
//					: after the move is complete.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           :
//<<===========================================================================
{
	int numberOfCerts;
	X509_INFO* x509Info_ptr;

	if ((openSslM_ptr == NULL) || (x509InfoListM_ptr == NULL))
	{
		return NULL;
	}

	numberOfCerts = sk_X509_INFO_num(x509InfoListM_ptr);
	if ((oldIndex < 0) || (oldIndex >= numberOfCerts) ||
		(newIndex < 0) || (newIndex >= numberOfCerts))
	{
		// index out of range
		if (loggerM_ptr)
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Index out of bounds in CERTIFICATE_FILE_CLASS::moveCertificate()");
		}
		return false;
	}

	// get the certificate
	x509Info_ptr = sk_X509_INFO_value(x509InfoListM_ptr, oldIndex);
	if (x509Info_ptr == NULL)
	{
		openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "getting certificate");
		return NULL;
	}

	// delete the certificate
	sk_X509_INFO_delete(x509InfoListM_ptr, oldIndex);

	// add the certificate back in
	if (newIndex > oldIndex)
	{
		newIndex--; // adjust the index value for the deleted certificate
	}
	sk_X509_INFO_insert(x509InfoListM_ptr, x509Info_ptr, newIndex);

	changedM = true;

	return true;
;
}
Beispiel #8
0
static int handle_certificate(const char *filename, const char *fullpath)
{
	STACK_OF(X509_INFO) *inf;
	X509_INFO *x;
	BIO *b;
	const char *ext;
	unsigned char digest[EVP_MAX_MD_SIZE];
	X509_NAME *name = NULL;
	int i, type, ret = -1;

	ext = strrchr(filename, '.');
	if (ext == NULL) return 0;
	for (i = 0; i < countof(file_extensions); i++) {
		if (strcasecmp(file_extensions[i], ext+1) == 0)
			break;
	}
	if (i >= countof(file_extensions)) return -1;

	b = BIO_new_file(fullpath, "r");
	if (!b) return -1;
	inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
	BIO_free(b);
	if (!inf) return -1;

	if (sk_X509_INFO_num(inf) == 1) {
		x = sk_X509_INFO_value(inf, 0);
		if (x->x509) {
			type = TYPE_CERT;
			name = X509_get_subject_name(x->x509);
			X509_digest(x->x509, evpmd, digest, NULL);
		} else if (x->crl) {
			type = TYPE_CRL;
			name = X509_CRL_get_issuer(x->crl);
			X509_CRL_digest(x->crl, evpmd, digest, NULL);
		}
		if (name && do_hash_new)
			add_entry(type, X509_NAME_hash(name), filename, digest, 1, ~0);
		if (name && do_hash_old)
			add_entry(type, X509_NAME_hash_old(name), filename, digest, 1, ~0);
	} else {
		fprintf(stderr,
			"WARNING: %s does not contain exactly one certificate or CRL: skipping\n",
			filename);
	}

	sk_X509_INFO_pop_free(inf, X509_INFO_free);

	return ret;
}
Beispiel #9
0
/**
 * Parses X.509 PEM formatted certificates from file. The file can contain multiple
 * certificates. You can just use 'cat' command in linux to add multiple PEM formatted
 * X.509 certificates to one file (e.g. <code>cat cert1.pem cert2.pem > certs.pem</code>).
 * NB! This struct must be freed using sk_X509_free() function from OpenSSL or
 * with X509Stack_scope struct.
 *
 * @param path PEM formatted X.509 certificates file path.
 * @return returns stack of parsed X.509 certificates.
 * @throws IOException throws exception if the file does not contain X.509
 *         PEM formatted certificate(s).
 */
STACK_OF(X509)* digidoc::X509Cert::loadX509Stack(const std::string& path) throw(IOException)
{
    // Create an empty X.509 stack.
    STACK_OF(X509)* stack = sk_X509_new_null();
    if(stack == NULL)
    {
        THROW_IOEXCEPTION("Failed to create X.509 certificate stack.");
    }

    // Initialize OpenSSL file.
    BIO* file = BIO_new(BIO_s_file()); BIO_scope fileScope(&file);
    if(file == NULL)
    {
        THROW_IOEXCEPTION("Failed to open X.509 certificates file '%s': %s",
                path.c_str(), ERR_reason_error_string(ERR_get_error()));
    }

    // Open file, which can contain multiple X.509 certificates.
    if(BIO_read_filename(file, path.c_str()) <= 0)
    {
        THROW_IOEXCEPTION("Failed to open X.509 certificates file '%s': %s",
                path.c_str(), ERR_reason_error_string(ERR_get_error()));
    }

    // Read certificates info from the file.
    STACK_OF(X509_INFO)* certsInfo = PEM_X509_INFO_read_bio(file, NULL, NULL, NULL);
    if(certsInfo == NULL)
    {
        THROW_IOEXCEPTION("Failed to read X.509 certificates from file '%s': %s",
                path.c_str(), ERR_reason_error_string(ERR_get_error()));
    }

    // Put all found certificates to the stack.
    for(int i = 0; i < sk_X509_INFO_num(certsInfo); i++)
    {
        X509_INFO* xi = sk_X509_INFO_value(certsInfo, i);
        if(xi->x509 != NULL)
        {
            sk_X509_push(stack, xi->x509);
            xi->x509 = NULL;
        }
    }

    // Release resources.
    sk_X509_INFO_pop_free(certsInfo, X509_INFO_free);

    return stack;
}
Beispiel #10
0
int CERTIFICATE_FILE_CLASS::getNumberOfCertificates()

//  DESCRIPTION     : Return the number of certificates available.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : 
//<<===========================================================================
{
	if ((openSslM_ptr == NULL) || (x509InfoListM_ptr == NULL))
	{
		return 0;
	}

	return sk_X509_INFO_num(x509InfoListM_ptr);
}
Beispiel #11
0
/*
 * This function is used to load an X509_STORE using raw
 * data from a buffer.  The data is expected to be PEM
 * encoded.
 *
 * Returns the number of certs added to the store
 */
static int ossl_init_cert_store_from_raw (X509_STORE *store,
                                           unsigned char *raw, int size)
{
    STACK_OF(X509_INFO) * sk = NULL;
    X509_INFO *xi;
    BIO *in;
    int cert_cnt = 0;

    in = BIO_new_mem_buf(raw, size);
    if (in == NULL) {
        EST_LOG_ERR("Unable to open the raw CA cert buffer");
        return 0;
    }

    /* This loads from a file, a stack of x509/crl/pkey sets */
    sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
    if (sk == NULL) {
        EST_LOG_ERR("Unable to read PEM encoded certs from BIO");
        BIO_free(in);
        return 0;
    }
    BIO_free(in);

    /* scan over it and pull out the CRL's */
    while (sk_X509_INFO_num(sk)) {
        xi = sk_X509_INFO_shift(sk);
        if (xi->x509 != NULL) {
            EST_LOG_INFO("Adding cert to store (%s)", xi->x509->name);
            X509_STORE_add_cert(store, xi->x509);
	    cert_cnt++;
        }
        if (xi->crl != NULL) {
            EST_LOG_INFO("Adding CRL to store");
            X509_STORE_add_crl(store, xi->crl);
        }
        X509_INFO_free(xi);
    }

    if (sk != NULL) {
        sk_X509_INFO_pop_free(sk, X509_INFO_free);
    }
    return (cert_cnt);
}
Beispiel #12
0
static int hash_file(int dirfd, const char *filename)
{
	STACK_OF(X509_INFO) *inf;
	X509_INFO *x;
	BIO *b;
	int i, count = 0;
	unsigned char digest[EVP_MAX_MD_SIZE];

	b = BIO_openat(dirfd, filename);
	if (!b)
		return -1;

	inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
	BIO_free(b);
	if (!inf)
		return -1;

	for(i = 0; i < sk_X509_INFO_num(inf); i++) {
		x = sk_X509_INFO_value(inf, i);
		if (x->x509) {
			X509_digest(x->x509, evpmd, digest, NULL);
			link_file(dirfd, filename, TYPE_CERT,
				  X509_subject_name_hash(x->x509), digest);
			count++;
		}
		if (x->crl) {
			X509_CRL_digest(x->crl, evpmd, digest, NULL);
			link_file(dirfd, filename, TYPE_CRL,
				  X509_NAME_hash(X509_CRL_get_issuer(x->crl)),
				  digest);
			count++;
		}
	}
	sk_X509_INFO_pop_free(inf, X509_INFO_free);

	if (count == 0) {
		fprintf(stderr,
			"WARNING: %s does not contain a certificate or CRL: skipping\n",
			filename);
	}

	return count;
}
Beispiel #13
0
/* load a stack of x509 certificates */
STACK_OF(X509)*
ocsp_load_certs(const char *file)
{
	BIO			*bio = NULL;
	STACK_OF(X509)		*certs = NULL;
	STACK_OF(X509_INFO)	*xis = NULL;
	X509_INFO		*xi;
	int			 i;

	if ((bio = BIO_new_file(file, "r")) == NULL) {
		log_warn("%s: BIO_new_file failed for %s",
		    __func__, file);
		return (NULL);
	}
	if ((xis = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL)) == NULL) {
		ca_sslerror(__func__);
		goto done;
	}
	if ((certs = sk_X509_new_null()) == NULL) {
		log_debug("%s: sk_X509_new_null failed for %s", __func__, file);
		goto done;
	}
	for (i = 0; i < sk_X509_INFO_num(xis); i++) {
		xi = sk_X509_INFO_value(xis, i);
		if (xi->x509) {
			if (!sk_X509_push(certs, xi->x509))
				goto done;
			xi->x509 = NULL;
		}
	}

 done:
	if (bio)
		BIO_free(bio);
	if (xis)
		sk_X509_INFO_pop_free(xis, X509_INFO_free);
	if (certs && sk_X509_num(certs) <= 0) {
		sk_X509_pop_free(certs, X509_free);
		certs = NULL;
	}
	return (certs);
}
Beispiel #14
0
int
ssl_by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf,
    long type, char **ret)
{
	STACK_OF(X509_INFO)	*inf;
	const struct iovec	*iov;
	X509_INFO		*itmp;
	BIO			*in = NULL;
	int			 i, count = 0;

	iov = (const struct iovec *)buf;

	if (type != X509_FILETYPE_PEM)
		goto done;

	if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL)
		goto done;

	if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL)
		goto done;

	for (i = 0; i < sk_X509_INFO_num(inf); i++) {
		itmp = sk_X509_INFO_value(inf, i);
		if (itmp->x509) {
			X509_STORE_add_cert(lu->store_ctx, itmp->x509);
			count++;
		}
		if (itmp->crl) {
			X509_STORE_add_crl(lu->store_ctx, itmp->crl);
			count++;
		}
	}
	sk_X509_INFO_pop_free(inf, X509_INFO_free);

 done:
	if (!count)
		X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_PEM_LIB);

	if (in != NULL)
		BIO_free(in);
	return (count);
}
Beispiel #15
0
Datei: ctx.c Projekt: bupt007/deo
static STACK_OF(X509_INFO) *
load_decryption_certs_keys(const char *dirname)
{
    AUTO_STACK(X509_INFO, infos);
    AUTO(DIR, dir);

    if (dirname == NULL)
        return NULL;

    infos = sk_X509_INFO_new_null();
    if (infos == NULL)
        return NULL;

    dir = opendir(dirname);
    if (dir == NULL)
        return NULL;

    for (struct dirent *de = readdir(dir); de != NULL; de = readdir(dir)) {
        char path[strlen(dirname) + strlen(de->d_name) + 2];
        AUTO(FILE, file);

        if (!deo_isreg(dirname, de))
            continue;

        strcpy(path, dirname);
        strcat(path, "/");
        strcat(path, de->d_name);

        file = fopen(path, "r");
        if (file == NULL)
            return NULL;

        if (PEM_X509_INFO_read(file, infos, NULL, NULL) == NULL)
            return NULL;
    }

    if (sk_X509_INFO_num(infos) == 0)
        return NULL;

    return STEAL(infos);
}
Beispiel #16
0
static int X509_load_cert_crl_mem(X509_LOOKUP *ctx, const char *mem)
{
  STACK_OF(X509_INFO) *inf;
  X509_INFO *itmp;
  BIO *in;
  int i, count = 0;

  in = BIO_new(BIO_s_mem());
  if (!in) {
    printk("X509_load_cert_crl_mem: cannot allocate BIO\n");
    return 0;
  }

  BIO_write(in, mem, strlen(mem));

  inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
  BIO_free(in);

  if (!inf) {
    printk("X509_load_cert_crl_mem: cannot read X509_INFO\n");
    return 0;
  }

  for (i = 0; i < sk_X509_INFO_num(inf); i++) {
    itmp = sk_X509_INFO_value(inf, i);
    if (itmp->x509) {
      X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
      count++;
    }
    else if (itmp->crl) {
      X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
      count++;
    }
  }

  sk_X509_INFO_pop_free(inf, X509_INFO_free);

  return count;
}
Beispiel #17
0
int SSL_CTX_load_verify_mem(SSL_CTX *ctx, void *data, int data_len)
{
	STACK_OF(X509_INFO) *stack = NULL;
	X509_INFO *info;
	int nstack, i, ret = 0, got = 0;
	BIO *bio;

	/* Read from memory */
	bio = BIO_new_mem_buf(data, data_len);
	if (!bio)
		goto failed;

	/* Parse X509_INFO records */
	stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
	if (!stack)
		goto failed;

	/* Loop over stack, add certs and revocation records to store */
	nstack = sk_X509_INFO_num(stack);
	for (i = 0; i < nstack; i++) {
		info = sk_X509_INFO_value(stack, i);
		if (info->x509 && !X509_STORE_add_cert(ctx->cert_store, info->x509))
			goto failed;
		if (info->crl && !X509_STORE_add_crl(ctx->cert_store, info->crl))
			goto failed;
		if (info->x509 || info->crl)
			got = 1;
	}
	ret = got;
failed:
	if (bio)
		BIO_free(bio);
	if (stack)
		sk_X509_INFO_pop_free(stack, X509_INFO_free);
	if (!ret)
		X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB);
	return ret;
}
Beispiel #18
0
STACK_OF(X509)* bdoc::X509Cert::loadX509Stack(const std::string& path)
{
	STACK_OF(X509)* stack = sk_X509_new_null();
	if (stack == NULL) {
		THROW_STACK_EXCEPTION("Failed to create X.509 certificate stack.");
	}

	BIO* file = BIO_new(BIO_s_file());
	BIO_scope fileScope(&file);
	if (file == NULL) {
		THROW_STACK_EXCEPTION("Failed to open X.509 certificates file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	if (BIO_read_filename(file, path.c_str()) <= 0) {
		THROW_STACK_EXCEPTION("Failed to open X.509 certificates file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	STACK_OF(X509_INFO)* certsInfo = PEM_X509_INFO_read_bio(file, NULL, NULL, NULL);
	if (certsInfo == NULL) {
		THROW_STACK_EXCEPTION("Failed to read X.509 certificates from file '%s': %s",
				path.c_str(), ERR_reason_error_string(ERR_get_error()));
	}

	for (int i = 0; i < sk_X509_INFO_num(certsInfo); i++) {
		X509_INFO* xi = sk_X509_INFO_value(certsInfo, i);
		if (xi->x509 != NULL) {
			sk_X509_push(stack, xi->x509);
			xi->x509 = NULL;
		}
	}

	sk_X509_INFO_pop_free(certsInfo, X509_INFO_free);

	return stack;
}
Beispiel #19
0
Datei: ctx.c Projekt: bupt007/deo
ctx *
ctx_init(const char *tls, const char *enc, const char *dec)
{
    const int ops = SSL_OP_NO_COMPRESSION | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
    AUTO(EVP_PKEY, prv);
    AUTO(FILE, file);
    AUTO(ctx, ctx);

    if (tls == NULL || enc == NULL || dec == NULL)
        return NULL;

    ctx = OPENSSL_malloc(sizeof(*ctx));
    if (ctx == NULL)
        return NULL;
    memset(ctx, 0, sizeof(*ctx));

    ctx->ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx->ctx == NULL)
        return NULL;

    if (SSL_CTX_set_options(ctx->ctx, ops) <= 0)
        return NULL;

    if (SSL_CTX_use_certificate_chain_file(ctx->ctx, tls) <= 0)
        return NULL;

    prv = load_prv(tls);
    if (prv == NULL)
        return NULL;

    if (SSL_CTX_use_PrivateKey(ctx->ctx, prv) <= 0)
        return NULL;

    file = fopen(enc, "r");
    if (file == NULL)
        return NULL;

    ctx->crt = sk_X509_new_null();
    if (ctx->crt == NULL)
        return NULL;

    if (!deo_load(file, ctx->crt))
        return NULL;

    ctx->dec = load_decryption_certs_keys(dec);
    if (ctx->dec == NULL)
        return NULL;

    /* Check to ensure that the TLS connection key is not also listed
     * in the decryption keys. This prevents an attack where, upon
     * misconfiguration, this service could be used to decrypt its own
     * traffic. */
    for (int i = 0; i < sk_X509_INFO_num(ctx->dec); i++) {
        X509_INFO *info = sk_X509_INFO_value(ctx->dec, i);

        if (info->x_pkey == NULL)
            continue;

        if (EVP_PKEY_cmp(prv, info->x_pkey->dec_pkey) == 1) {
            fprintf(stderr, "TLS private key is exposed!\n");
            return NULL;
        }
    }

    return STEAL(ctx);
}
Beispiel #20
0
int
tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify)
{
	size_t ca_len = ctx->config->ca_len;
	char *ca_mem = ctx->config->ca_mem;
	char *crl_mem = ctx->config->crl_mem;
	size_t crl_len = ctx->config->crl_len;
	char *ca_free = NULL;
	STACK_OF(X509_INFO) *xis = NULL;
	X509_STORE *store;
	X509_INFO *xi;
	BIO *bio = NULL;
	int rv = -1;
	int i;

	SSL_CTX_set_verify(ssl_ctx, verify, NULL);
	SSL_CTX_set_cert_verify_callback(ssl_ctx, tls_ssl_cert_verify_cb, ctx);

	if (ctx->config->verify_depth >= 0)
		SSL_CTX_set_verify_depth(ssl_ctx, ctx->config->verify_depth);

	if (ctx->config->verify_cert == 0)
		goto done;

	/* If no CA has been specified, attempt to load the default. */
	if (ctx->config->ca_mem == NULL && ctx->config->ca_path == NULL) {
		if (tls_config_load_file(&ctx->error, "CA", _PATH_SSL_CA_FILE,
		    &ca_mem, &ca_len) != 0)
			goto err;
		ca_free = ca_mem;
	}

	if (ca_mem != NULL) {
		if (ca_len > INT_MAX) {
			tls_set_errorx(ctx, "ca too long");
			goto err;
		}
		if (SSL_CTX_load_verify_mem(ssl_ctx, ca_mem, ca_len) != 1) {
			tls_set_errorx(ctx, "ssl verify memory setup failure");
			goto err;
		}
	} else if (SSL_CTX_load_verify_locations(ssl_ctx, NULL,
	    ctx->config->ca_path) != 1) {
		tls_set_errorx(ctx, "ssl verify locations failure");
		goto err;
	}

	if (crl_mem != NULL) {
		if (crl_len > INT_MAX) {
			tls_set_errorx(ctx, "crl too long");
			goto err;
		}
		if ((bio = BIO_new_mem_buf(crl_mem, crl_len)) == NULL) {
			tls_set_errorx(ctx, "failed to create buffer");
			goto err;
		}
		if ((xis = PEM_X509_INFO_read_bio(bio, NULL, tls_password_cb,
		    NULL)) == NULL) {
			tls_set_errorx(ctx, "failed to parse crl");
			goto err;
		}
		store = SSL_CTX_get_cert_store(ssl_ctx);
		for (i = 0; i < sk_X509_INFO_num(xis); i++) {
			xi = sk_X509_INFO_value(xis, i);
			if (xi->crl == NULL)
				continue;
			if (!X509_STORE_add_crl(store, xi->crl)) {
				tls_set_error(ctx, "failed to add crl");
				goto err;
			}
			xi->crl = NULL;
		}
		X509_VERIFY_PARAM_set_flags(store->param,
		    X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
	}

 done:
	rv = 0;

 err:
	sk_X509_INFO_pop_free(xis, X509_INFO_free);
	BIO_free(bio);
	free(ca_free);

	return (rv);
}
Beispiel #21
0
bool CERTIFICATE_FILE_CLASS::verify(bool isCredentials, char **msg_ptrptr)

//  DESCRIPTION     : verifies the contents of the file to make sure it is of the correct format
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : 
//<<===========================================================================
{
	int numberOfCerts;
	int i;
	X509_INFO* x509Info_ptr;

	if ((openSslM_ptr == NULL) || (x509InfoListM_ptr == NULL))
	{
		*msg_ptrptr = "Secure Socket Library not present";
		return false;
	}

	if (isCredentials)
	{
		// credentials file
		bool waitingForCertificate = false; // indicates that the next PEM read must be a certificate
		bool rsaKeyRead = false;
		bool dsaKeyRead = false;
		bool lastKeyReadRsa = false; // indicates that we are working on the RSA key and certificates,
									 // otherwise, we are working on the DSA key and certificate.

		numberOfCerts = sk_X509_INFO_num(x509InfoListM_ptr);
		for (i = 0; i < numberOfCerts; i++)
		{
			// get the PEM info
			x509Info_ptr = sk_X509_INFO_value(x509InfoListM_ptr, i);
			if (x509Info_ptr == NULL)
			{
				*msg_ptrptr = "internal error";
				return false;
			}

			if (x509Info_ptr->x_pkey != NULL)
			{
				// private key
				if (waitingForCertificate)
				{
					*msg_ptrptr = "Private key does not have a corresponding certificate";
					return false;
				}

				if (x509Info_ptr->x_pkey->dec_pkey->type == EVP_PKEY_RSA)
				{
					// rsa key
					if (rsaKeyRead)
					{
						*msg_ptrptr = "More than one RSA Private Key in credentials file";
						return false;
					}

					rsaKeyRead = true;
					lastKeyReadRsa = true; // we are reading rsa keys now
				}
				else if (x509Info_ptr->x_pkey->dec_pkey->type == EVP_PKEY_DSA)
				{
					// dsa key
					if (dsaKeyRead)
					{
						*msg_ptrptr = "More than one DSA Private Key in credentials file";
						return false;
					}

					dsaKeyRead = true;
					lastKeyReadRsa = false; // we are reading dsa keys now
				}
				else
				{
					*msg_ptrptr = "Unsupported private key type";
					return false;
				}

				waitingForCertificate = true;  // the next thing in the file needs to be the public key certificate
			}

			if (x509Info_ptr->x509 != NULL)
			{
				// certificate
				if (!rsaKeyRead && !dsaKeyRead)
				{
					// no private key read yet
					*msg_ptrptr = "Credentials file starts with a certificate.  Must start with a private key.";
					return false;
				}

				waitingForCertificate = false;

				// check certificate chain
			}
		}

		// check to make sure all is well
		if (waitingForCertificate)
		{
			// file didn't have required certificate
			*msg_ptrptr = "Private key does not have a corresponding certificate at end of credentials file";
			return false;
		}
		if (!rsaKeyRead && !dsaKeyRead && (numberOfCerts > 0))
		{
			// no private key read
			*msg_ptrptr = "Credentials file has no private keys";
			return false;
		}
	}
	else
	{
		// trusted certificate file
		numberOfCerts = sk_X509_INFO_num(x509InfoListM_ptr);
		for (i = 0; i < numberOfCerts; i++)
		{
			// get the PEM info
			x509Info_ptr = sk_X509_INFO_value(x509InfoListM_ptr, i);
			if (x509Info_ptr == NULL)
			{
				*msg_ptrptr = "internal error";
				return false;
			}

			if (x509Info_ptr->x_pkey != NULL)
			{
				// private key, not expected in certificate file
				*msg_ptrptr = "Private Key not expected in a trusted certificate file";
				return false;
			}

			if (x509Info_ptr->x509 != NULL)
			{
				// certificate, check certificate chain
			}
		}
	}

	// if we got here there were no errors
	return true;
}
Beispiel #22
0
void
tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
    const char *ca_file_inline,
    const char *ca_path, bool tls_server
    )
{
  STACK_OF(X509_INFO) *info_stack = NULL;
  STACK_OF(X509_NAME) *cert_names = NULL;
  X509_LOOKUP *lookup = NULL;
  X509_STORE *store = NULL;
  X509_NAME *xn = NULL;
  BIO *in = NULL;
  int i, added = 0;

  ASSERT(NULL != ctx);

  store = SSL_CTX_get_cert_store(ctx->ctx);
  if (!store)
    msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)");

  /* Try to add certificates and CRLs from ca_file */
  if (ca_file)
    {
      if (!strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
        in = BIO_new_mem_buf ((char *)ca_file_inline, -1);
      else
        in = BIO_new_file (ca_file, "r");

      if (in)
        info_stack = PEM_X509_INFO_read_bio (in, NULL, NULL, NULL);

      if (info_stack)
        {
          for (i = 0; i < sk_X509_INFO_num (info_stack); i++)
            {
              X509_INFO *info = sk_X509_INFO_value (info_stack, i);
              if (info->crl)
                  X509_STORE_add_crl (store, info->crl);

              if (info->x509)
                {
                  X509_STORE_add_cert (store, info->x509);
                  added++;

                  if (!tls_server)
                    continue;

                  /* Use names of CAs as a client CA list */
                  if (cert_names == NULL)
                    {
                      cert_names = sk_X509_NAME_new (sk_x509_name_cmp);
                      if (!cert_names)
                        continue;
                    }

                  xn = X509_get_subject_name (info->x509);
                  if (!xn)
                    continue;

                  /* Don't add duplicate CA names */
                  if (sk_X509_NAME_find (cert_names, xn) == -1)
                    {
                      xn = X509_NAME_dup (xn);
                      if (!xn)
                        continue;
                      sk_X509_NAME_push (cert_names, xn);
                    }
                }
            }
          sk_X509_INFO_pop_free (info_stack, X509_INFO_free);
        }

      if (tls_server)
        SSL_CTX_set_client_CA_list (ctx->ctx, cert_names);

      if (!added || (tls_server && sk_X509_NAME_num (cert_names) != added))
        msg (M_SSLERR, "Cannot load CA certificate file %s", np(ca_file));
      if (in)
        BIO_free (in);
    }

  /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
  if (ca_path)
    {
      lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ());
      if (lookup && X509_LOOKUP_add_dir (lookup, ca_path, X509_FILETYPE_PEM))
        msg(M_WARN, "WARNING: experimental option --capath %s", ca_path);
      else
        msg(M_SSLERR, "Cannot add lookup at --capath %s", ca_path);
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
      X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
#else
      msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath");
#endif
    }
}