Пример #1
0
String SHA256(const String& s)
{
	SHA256_CTX context;
	unsigned char digest[SHA256_DIGEST_LENGTH];

	if (!SHA256_Init(&context)) {
		BOOST_THROW_EXCEPTION(openssl_error()
			<< boost::errinfo_api_function("SHA256_Init")
			<< errinfo_openssl_error(ERR_get_error()));
	}

	if (!SHA256_Update(&context, (unsigned char*)s.CStr(), s.GetLength())) {
		BOOST_THROW_EXCEPTION(openssl_error()
			<< boost::errinfo_api_function("SHA256_Update")
			<< errinfo_openssl_error(ERR_get_error()));
	}

	if (!SHA256_Final(digest, &context)) {
		BOOST_THROW_EXCEPTION(openssl_error()
			<< boost::errinfo_api_function("SHA256_Final")
			<< errinfo_openssl_error(ERR_get_error()));
	}

	int i;
	char output[SHA256_DIGEST_LENGTH*2+1];
	for (i = 0; i < 32; i++)
		sprintf(output + 2 * i, "%02x", digest[i]);

	return output;
}
Пример #2
0
/**
 * Retrieves an X509 certificate from the specified file.
 *
 * @param pemfile The filename.
 * @returns An X509 certificate.
 */
shared_ptr<X509> GetX509Certificate(const String& pemfile)
{
	X509 *cert;
	BIO *fpcert = BIO_new(BIO_s_file());

	if (fpcert == NULL) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("BIO_new")
		    << errinfo_openssl_error(ERR_get_error()));
	}

	if (BIO_read_filename(fpcert, pemfile.CStr()) < 0) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("BIO_read_filename")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(pemfile));
	}

	cert = PEM_read_bio_X509_AUX(fpcert, NULL, NULL, NULL);
	if (cert == NULL) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("PEM_read_bio_X509_AUX")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(pemfile));
	}

	BIO_free(fpcert);

	return shared_ptr<X509>(cert, X509_free);
}
Пример #3
0
/**
 * Loads a CRL and appends its certificates to the specified SSL context.
 *
 * @param context The SSL context.
 * @param crlPath The path to the CRL file.
 */
void AddCRLToSSLContext(const shared_ptr<SSL_CTX>& context, const String& crlPath)
{
	X509_STORE *x509_store = SSL_CTX_get_cert_store(context.get());

	X509_LOOKUP *lookup;
	lookup = X509_STORE_add_lookup(x509_store, X509_LOOKUP_file());

	if (!lookup) {
		BOOST_THROW_EXCEPTION(openssl_error()
			<< boost::errinfo_api_function("X509_STORE_add_lookup")
			<< errinfo_openssl_error(ERR_get_error()));
	}

	if (X509_LOOKUP_load_file(lookup, crlPath.CStr(), X509_FILETYPE_PEM) != 0) {
		BOOST_THROW_EXCEPTION(openssl_error()
			<< boost::errinfo_api_function("X509_LOOKUP_load_file")
			<< errinfo_openssl_error(ERR_get_error())
			<< boost::errinfo_file_name(crlPath));
	}

	X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
	X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
	X509_STORE_set1_param(x509_store, param);
	X509_VERIFY_PARAM_free(param);
}
Пример #4
0
void pki_pkcs7::signBio(pki_x509 *crt, BIO *bio)
{
	pki_key *privkey;
	EVP_PKEY *pk;
	STACK_OF(X509) *certstack;
	if (!crt)
		return;
	privkey = crt->getRefKey();
	if (!privkey)
		throw errorEx("No private key for signing found", getClassName());
	certstack = sk_X509_new_null();

	pki_x509 *signer = crt->getSigner();
	if (signer == crt)
		signer = NULL;
	while (signer != NULL ) {
		sk_X509_push(certstack, signer->getCert());
	        openssl_error();
		if (signer == signer->getSigner() )
			signer = NULL;
		else
			signer = signer->getSigner();
	}
	if (p7)
		PKCS7_free(p7);
	pk = privkey->decryptKey();
	p7 = PKCS7_sign(crt->getCert(), pk, certstack, bio, PKCS7_BINARY);
	EVP_PKEY_free(pk);
	openssl_error();
	sk_X509_free(certstack);
}
Пример #5
0
BIO *neo4j_openssl_new_bio(BIO *delegate, const char *hostname, int port,
        const neo4j_config_t *config, uint_fast32_t flags)
{
    neo4j_logger_t *logger = neo4j_get_logger(config, "tls");

    SSL_CTX *ctx = new_ctx(config, logger);
    if (ctx == NULL)
    {
        return NULL;
    }

    BIO *ssl_bio = BIO_new_ssl(ctx, 1);
    if (ssl_bio == NULL)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        SSL_CTX_free(ctx);
        goto failure;
    }

    SSL_CTX_free(ctx);

    BIO_push(ssl_bio, delegate);
    if (BIO_set_close(ssl_bio, BIO_CLOSE) != 1)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        goto failure;
    }

    int result = BIO_do_handshake(ssl_bio);
    if (result != 1)
    {
        if (result == 0)
        {
            errno = NEO4J_NO_SERVER_TLS_SUPPORT;
            goto failure;
        }
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        goto failure;
    }

    SSL *ssl = NULL;
    BIO_get_ssl(ssl_bio, &ssl);
    assert(ssl != NULL);
    if (verify(ssl, hostname, port, config, flags, logger))
    {
        goto failure;
    }

    return ssl_bio;

    int errsv;
failure:
    errsv = errno;
    BIO_free(ssl_bio);
    errno = errsv;
    return NULL;
}
Пример #6
0
void pki_pkcs7::encryptBio(pki_x509 *crt, BIO *bio)
{
	STACK_OF(X509) *certstack;
	if (!crt)
		return;
	certstack = sk_X509_new_null();
	sk_X509_push(certstack, crt->getCert());
	openssl_error();
	if (p7)
		PKCS7_free(p7);
	p7 = PKCS7_encrypt(certstack, bio, EVP_des_ede3_cbc(), PKCS7_BINARY);
	openssl_error();
	sk_X509_free(certstack);
}
Пример #7
0
/**
 * Initializes an SSL context using the specified certificates.
 *
 * @param pubkey The public key.
 * @param privkey The matching private key.
 * @param cakey CA certificate chain file.
 * @returns An SSL context.
 */
shared_ptr<SSL_CTX> MakeSSLContext(const String& pubkey, const String& privkey, const String& cakey)
{
	InitializeOpenSSL();

	shared_ptr<SSL_CTX> sslContext = shared_ptr<SSL_CTX>(SSL_CTX_new(TLSv1_method()), SSL_CTX_free);

	SSL_CTX_set_mode(sslContext.get(), 0);

	if (!SSL_CTX_use_certificate_chain_file(sslContext.get(), pubkey.CStr())) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("SSL_CTX_use_certificate_chain_file")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(pubkey));
	}

	if (!SSL_CTX_use_PrivateKey_file(sslContext.get(), privkey.CStr(), SSL_FILETYPE_PEM)) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("SSL_CTX_use_PrivateKey_file")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(privkey));
	}

	if (!SSL_CTX_check_private_key(sslContext.get())) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("SSL_CTX_check_private_key")
		    << errinfo_openssl_error(ERR_get_error()));
	}

	if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.CStr(), NULL)) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("SSL_CTX_load_verify_locations")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(cakey));
	}

	STACK_OF(X509_NAME) *cert_names;

	cert_names = SSL_load_client_CA_file(cakey.CStr());
	if (cert_names == NULL) {
		BOOST_THROW_EXCEPTION(openssl_error()
		    << boost::errinfo_api_function("SSL_load_client_CA_file")
		    << errinfo_openssl_error(ERR_get_error())
		    << boost::errinfo_file_name(cakey));
	}

	SSL_CTX_set_client_CA_list(sslContext.get(), cert_names);

	return sslContext;
}
Пример #8
0
void pki_pkcs7::addCert(pki_x509 *crt)
{
	if (p7 == NULL || crt == NULL)
		return;
	PKCS7_add_certificate(p7, crt->getCert());
	openssl_error();
}
Пример #9
0
int cert_fingerprint(X509* cert, char *buf, size_t n, neo4j_logger_t *logger)
{
    unsigned char *der = NULL;
    int derlen = i2d_X509(cert, &der);
    if (derlen < 0)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        return -1;
    }

    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int dlen;
    if (sha512_digest(digest, &dlen, der, derlen, logger))
    {
        free(der);
        return -1;
    }
    assert(dlen <= EVP_MAX_MD_SIZE);

    size_t c = 0;
    for (unsigned int i = 0; i < dlen && c < n; i++)
    {
        snprintf(buf + c, n - c, "%02x", digest[i]);
        c += 2;
    }

    return 0;
}
Пример #10
0
void pki_pkcs12::writePKCS12(const QString fname)
{
	Passwd pass;
	pass_info p(XCA_TITLE, tr("Please enter the password to encrypt the PKCS#12 file"));
	if (cert == NULL || key == NULL) {
		my_error(tr("No key or no Cert and no pkcs12"));
	}

	FILE *fp = fopen(QString2filename(fname), "wb");
	if (fp != NULL) {
		if (PwDialog::execute(&p, &pass, true) != 1) {
			fclose(fp);
			return;
		}
		PKCS12 *pkcs12 = PKCS12_create(pass.data(),
			getIntName().toUtf8().data(),
			key->decryptKey(),
			cert->getCert(), certstack, 0, 0, 0, 0, 0);
		i2d_PKCS12_fp(fp, pkcs12);
		fclose (fp);
		openssl_error();
		PKCS12_free(pkcs12);
	}
	else fopen_error(fname);
}
Пример #11
0
void pki_x509req::fload(const QString fname)
{
	FILE *fp = fopen_read(fname);
	X509_REQ *_req;
	int ret = 0;

	if (fp != NULL) {
		_req = PEM_read_X509_REQ(fp, NULL, NULL, NULL);
		if (!_req) {
			pki_ign_openssl_error();
			rewind(fp);
			_req = d2i_X509_REQ_fp(fp, NULL);
		}
		fclose(fp);
		if (ret || pki_ign_openssl_error()) {
			if (_req)
				X509_REQ_free(_req);
			throw errorEx(tr("Unable to load the certificate request in file %1. Tried PEM, DER and SPKAC format.").arg(fname));
		}
	} else {
		fopen_error(fname);
		return;
	}

	if (_req) {
		X509_REQ_free(request);
		request = _req;
	}
	autoIntName();
	if (getIntName().isEmpty())
		setIntName(rmslashdot(fname));
	openssl_error(fname);
}
Пример #12
0
void pki_pkcs7::encryptFile(pki_x509 *crt, QString filename)
{
	BIO *bio = NULL;
	bio = BIO_new_file(QString2filename(filename), "r");
        openssl_error();
	encryptBio(crt, bio);
	BIO_free(bio);
}
Пример #13
0
void pki_x509req::fromPEM_BIO(BIO *bio, QString name)
{
	X509_REQ *req;
	req = PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
	openssl_error(name);
	X509_REQ_free(request);
	request = req;
}
Пример #14
0
pki_x509 *pki_pkcs7::getCert(int x)
{
	pki_x509 *cert;
	cert = new pki_x509(X509_dup(sk_X509_value(getCertStack(), x)));
	openssl_error();
	cert->autoIntName();
	cert->pkiSource = imported;
	return cert;
}
Пример #15
0
void pki_pkcs7::fromPEM_BIO(BIO *bio, QString name)
{
	PKCS7 *_p7 = PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
	openssl_error(name);
	if (p7)
		PKCS7_free(p7);
	p7 = _p7;
	setIntName(rmslashdot(name));
}
Пример #16
0
a1int &a1int::setRaw(const unsigned char *data, unsigned len)
{
	BIGNUM *bn = BN_bin2bn(data, len, NULL);
	if (!bn)
		openssl_error();
	BN_to_ASN1_INTEGER(bn, in);
	BN_free(bn);
	return *this;
}
Пример #17
0
a1int &a1int::setDec(const QString &s)
{
	BIGNUM *bn=0;
	if (!BN_dec2bn(&bn,s.toAscii()))
		openssl_error();
	BN_to_ASN1_INTEGER(bn, in);
	BN_free(bn);
	return *this;
}
Пример #18
0
void pki_crl::fromPEM_BIO(BIO *bio, QString name)
{
	X509_CRL*_crl;
	_crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
	openssl_error(name);
	X509_CRL_free(crl);
	crl = _crl;
	setIntName(rmslashdot(name));
}
Пример #19
0
QString OBJ_obj2QString(ASN1_OBJECT *a, int no_name)
{
	char buf[512];
	int len;

	len = OBJ_obj2txt(buf, 256, a, no_name);
	openssl_error();
	return QString::fromAscii(buf, len);
}
Пример #20
0
pki_pkcs12::pki_pkcs12(const QString d, pki_x509 *acert, pki_evp *akey)
	:pki_base(d)
{
	class_name="pki_pkcs12";
	key = new pki_evp(akey);
	cert = new pki_x509(acert);
	certstack = sk_X509_new_null();
	openssl_error();
}
Пример #21
0
void pki_x509req::addAttribute(int nid, QString content)
{
	if (content.isEmpty())
		return;

	ASN1_STRING *a = QStringToAsn1(content, nid);
	X509_REQ_add1_attr_by_NID(request, nid, a->type, a->data, a->length);
	ASN1_STRING_free(a);
	openssl_error(QString("'%1' (%2)").arg(content).arg(OBJ_nid2ln(nid)));
}
Пример #22
0
void pki_pkcs7::writeP7(XFile &file, bool PEM) const
{
	if (!p7)
		return;
	if (PEM)
		PEM_write_PKCS7(file.fp(), p7);
	else
		i2d_PKCS7_fp(file.fp(), p7);
	openssl_error();
}
Пример #23
0
void pki_pkcs7::signFile(pki_x509 *crt, QString filename)
{
	BIO *bio;
	if (!crt)
		return;
	bio = BIO_new_file(QString2filename(filename), "r");
        openssl_error();
	signBio(crt, bio);
	BIO_free(bio);
}
Пример #24
0
void pki_x509req::fromPEM_BIO(BIO *bio, QString name)
{
	X509_REQ *req;
	req = PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
	openssl_error(name);
	X509_REQ_free(request);
	request = req;
	autoIntName();
	if (getIntName().isEmpty())
		setIntName(rmslashdot(name));
}
Пример #25
0
void *d2i_bytearray(void *(*d2i)(void *, unsigned char **, long),
		QByteArray &ba)
{
	unsigned char *p, *p1;
	void *ret;
	p = p1 = (unsigned char *)ba.constData();
	ret = d2i(NULL, &p1, ba.count());
	ba = ba.mid(p1-p);
	openssl_error();
	return ret;
}
Пример #26
0
QByteArray i2d_bytearray(int(*i2d)(const void*, unsigned char **),
		const void *data)
{
	QByteArray ba;

	ba.resize(i2d(data, NULL));
	unsigned char *p = (unsigned char*)ba.data();
	i2d(data, &p);
	openssl_error();
	return ba;
}
Пример #27
0
void pki_pkcs7::signCert(pki_x509 *crt, pki_x509 *contCert)
{
	BIO *bio;
	if (!crt)
		return;
	bio = BIO_new(BIO_s_mem());
        openssl_error();
	i2d_X509_bio(bio, contCert->getCert());
	signBio(crt, bio);
	BIO_free(bio);
}
Пример #28
0
a1int &a1int::setHex(const QString &s)
{
	BIGNUM *bn=0;
	if (s.isEmpty()) {
		return *this;
	}
	if (!BN_hex2bn(&bn,s.toAscii()))
		openssl_error();
	BN_to_ASN1_INTEGER(bn, in);
	BN_free(bn);
	return *this;
}
Пример #29
0
SSL_CTX *new_ctx(const neo4j_config_t *config, neo4j_logger_t *logger)
{
    SSL_CTX *ctx = SSL_CTX_new(TLSv1_method());
    if (ctx == NULL)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        return NULL;
    }

    if (SSL_CTX_set_cipher_list(ctx, "HIGH:!EXPORT:!aNULL@STRENGTH") != 1)
    {
        errno = openssl_error(logger, NEO4J_LOG_ERROR, __FILE__, __LINE__);
        goto failure;
    }

    // Necessary when using blocking sockets
    SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);

    // Caching should be done at the protocol layer anyway
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

    if (load_private_key(ctx, config, logger))
    {
        goto failure;
    }

    if (load_certificate_authorities(ctx, config, logger))
    {
        goto failure;
    }

    return ctx;

    int errsv;
failure:
    errsv = errno;
    SSL_CTX_free(ctx);
    errno = errsv;
    return NULL;
}
Пример #30
0
pki_pkcs12::~pki_pkcs12()
{
	if (sk_X509_num(certstack)>0) {
		// free the certs itself, because we own a copy of them
		sk_X509_pop_free(certstack, X509_free);
	}
	if (key) {
		delete(key);
	}
	if (cert) {
		delete(cert);
	}
	openssl_error();
}