← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3049: fix cert generation with wide character paths

 

------------------------------------------------------------
revno: 3049
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2012-09-13 23:15:43 +0200
message:
  fix cert generation with wide character paths
modified:
  changelog.txt
  dcpp/CryptoManager.cpp
  dcpp/File.cpp
  dcpp/File.h
  dcpp/GeoIP.cpp
  dcpp/SSL.cpp
  dcpp/SSL.h
  dcpp/SSLSocket.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt	2012-09-13 19:36:06 +0000
+++ changelog.txt	2012-09-13 21:15:43 +0000
@@ -39,7 +39,7 @@
 * Fix NAT-PMP renewal (poy)
 * [L#226968] Remember list sorting & splitter positions (poy)
 * [L#1041553] Fix help tooltips in Windows 8 (poy)
-* Fix GeoIP problems with wide character paths (poy)
+* Fix GeoIP & OpenSSL problems with wide character paths (poy)
 
 -- 0.799 2012-05-05 --
 * Add icons (iceman50)

=== modified file 'dcpp/CryptoManager.cpp'
--- dcpp/CryptoManager.cpp	2012-06-13 01:21:56 +0000
+++ dcpp/CryptoManager.cpp	2012-09-13 21:15:43 +0000
@@ -177,7 +177,7 @@
 	// Write the key and cert
 	{
 		File::ensureDirectory(SETTING(TLS_PRIVATE_KEY_FILE));
-		FILE* f = fopen(SETTING(TLS_PRIVATE_KEY_FILE).c_str(), "w");
+		FILE* f = dcpp_fopen(SETTING(TLS_PRIVATE_KEY_FILE).c_str(), "w");
 		if(!f) {
 			return;
 		}
@@ -186,7 +186,7 @@
 	}
 	{
 		File::ensureDirectory(SETTING(TLS_CERTIFICATE_FILE));
-		FILE* f = fopen(SETTING(TLS_CERTIFICATE_FILE).c_str(), "w");
+		FILE* f = dcpp_fopen(SETTING(TLS_CERTIFICATE_FILE).c_str(), "w");
 		if(!f) {
 			File::deleteFile(SETTING(TLS_PRIVATE_KEY_FILE));
 			return;
@@ -221,38 +221,38 @@
 		}
 	}
 
-	if(SSL_CTX_use_certificate_file(serverContext, cert.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
-		LogManager::getInstance()->message(_("Failed to load certificate file"));
-		return;
-	}
-	if(SSL_CTX_use_certificate_file(clientContext, cert.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
-		LogManager::getInstance()->message(_("Failed to load certificate file"));
-		return;
-	}
-
-	if(SSL_CTX_use_certificate_file(serverVerContext, cert.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
-		LogManager::getInstance()->message(_("Failed to load certificate file"));
-		return;
-	}
-	if(SSL_CTX_use_certificate_file(clientVerContext, cert.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
-		LogManager::getInstance()->message(_("Failed to load certificate file"));
-		return;
-	}
-
-	if(SSL_CTX_use_PrivateKey_file(serverContext, key.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
-		LogManager::getInstance()->message(_("Failed to load private key"));
-		return;
-	}
-	if(SSL_CTX_use_PrivateKey_file(clientContext, key.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
-		LogManager::getInstance()->message(_("Failed to load private key"));
-		return;
-	}
-
-	if(SSL_CTX_use_PrivateKey_file(serverVerContext, key.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
-		LogManager::getInstance()->message(_("Failed to load private key"));
-		return;
-	}
-	if(SSL_CTX_use_PrivateKey_file(clientVerContext, key.c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) {
+	if(!ssl::SSL_CTX_use_certificate_file(serverContext, cert.c_str(), SSL_FILETYPE_PEM)) {
+		LogManager::getInstance()->message(_("Failed to load certificate file"));
+		return;
+	}
+	if(!ssl::SSL_CTX_use_certificate_file(clientContext, cert.c_str(), SSL_FILETYPE_PEM)) {
+		LogManager::getInstance()->message(_("Failed to load certificate file"));
+		return;
+	}
+
+	if(!ssl::SSL_CTX_use_certificate_file(serverVerContext, cert.c_str(), SSL_FILETYPE_PEM)) {
+		LogManager::getInstance()->message(_("Failed to load certificate file"));
+		return;
+	}
+	if(!ssl::SSL_CTX_use_certificate_file(clientVerContext, cert.c_str(), SSL_FILETYPE_PEM)) {
+		LogManager::getInstance()->message(_("Failed to load certificate file"));
+		return;
+	}
+
+	if(!ssl::SSL_CTX_use_PrivateKey_file(serverContext, key.c_str(), SSL_FILETYPE_PEM)) {
+		LogManager::getInstance()->message(_("Failed to load private key"));
+		return;
+	}
+	if(!ssl::SSL_CTX_use_PrivateKey_file(clientContext, key.c_str(), SSL_FILETYPE_PEM)) {
+		LogManager::getInstance()->message(_("Failed to load private key"));
+		return;
+	}
+
+	if(!ssl::SSL_CTX_use_PrivateKey_file(serverVerContext, key.c_str(), SSL_FILETYPE_PEM)) {
+		LogManager::getInstance()->message(_("Failed to load private key"));
+		return;
+	}
+	if(!ssl::SSL_CTX_use_PrivateKey_file(clientVerContext, key.c_str(), SSL_FILETYPE_PEM)) {
 		LogManager::getInstance()->message(_("Failed to load private key"));
 		return;
 	}
@@ -278,19 +278,10 @@
 }
 
 bool CryptoManager::checkCertificate() noexcept {
-	FILE* f = fopen(SETTING(TLS_CERTIFICATE_FILE).c_str(), "r");
-	if(!f) {
-		return false;
-	}
-
-	X509* tmpx509 = NULL;
-	PEM_read_X509(f, &tmpx509, NULL, NULL);
-	fclose(f);
-
-	if(!tmpx509) {
-		return false;
-	}
-	ssl::X509 x509(tmpx509);
+	auto x509 = ssl::getX509(SETTING(TLS_CERTIFICATE_FILE).c_str());
+	if(!x509) {
+		return false;
+	}
 
 	ASN1_INTEGER* sn = X509_get_serialNumber(x509);
 	if(!sn || !ASN1_INTEGER_get(sn)) {
@@ -337,22 +328,10 @@
 }
 
 void CryptoManager::loadKeyprint(const string& file) noexcept {
-	FILE* f = fopen(SETTING(TLS_CERTIFICATE_FILE).c_str(), "r");
-	if(!f) {
-		return;
-	}
-
-	X509* tmpx509 = NULL;
-	PEM_read_X509(f, &tmpx509, NULL, NULL);
-	fclose(f);
-
-	if(!tmpx509) {
-		return;
-	}
-
-	ssl::X509 x509(tmpx509);
-	
-	keyprint = ssl::X509_digest(x509, EVP_sha256());
+	auto x509 = ssl::getX509(SETTING(TLS_CERTIFICATE_FILE).c_str());
+	if(x509) {
+		keyprint = ssl::X509_digest(x509, EVP_sha256());
+	}
 }
 
 SSLSocket* CryptoManager::getClientSocket(bool allowUntrusted) {

=== modified file 'dcpp/File.cpp'
--- dcpp/File.cpp	2012-01-13 20:55:20 +0000
+++ dcpp/File.cpp	2012-09-13 21:15:43 +0000
@@ -586,4 +586,10 @@
 
 #endif // _WIN32
 
+#ifdef _WIN32
+FILE* dcpp_fopen(const char* filename, const char* mode) {
+	return _wfopen(Text::toT(filename).c_str(), Text::toT(mode).c_str());
+}
+#endif
+
 } // namespace dcpp

=== modified file 'dcpp/File.h'
--- dcpp/File.h	2012-01-13 20:55:20 +0000
+++ dcpp/File.h	2012-09-13 21:15:43 +0000
@@ -157,6 +157,13 @@
 	DirData data;
 };
 
+#ifdef _WIN32
+	// on Windows, prefer _wfopen over fopen.
+	FILE* dcpp_fopen(const char* filename, const char* mode);
+#else
+#define dcpp_fopen fopen
+#endif
+
 } // namespace dcpp
 
 #endif // !defined(FILE_H)

=== modified file 'dcpp/GeoIP.cpp'
--- dcpp/GeoIP.cpp	2012-09-13 19:36:06 +0000
+++ dcpp/GeoIP.cpp	2012-09-13 21:15:43 +0000
@@ -130,7 +130,11 @@
 }
 
 void GeoIP::open() {
+#ifdef _WIN32
 	geo = GeoIP_open(Text::toT(path).c_str(), GEOIP_STANDARD);
+#else
+	geo = GeoIP_open(path, GEOIP_STANDARD);
+#endif
 	if(geo) {
 		GeoIP_set_charset(geo, GEOIP_CHARSET_UTF8);
 	}

=== modified file 'dcpp/SSL.cpp'
--- dcpp/SSL.cpp	2012-01-13 20:55:20 +0000
+++ dcpp/SSL.cpp	2012-09-13 21:15:43 +0000
@@ -17,16 +17,53 @@
  */
 
 #include "stdinc.h"
-
 #include "SSL.h"
 
 #include <vector>
 
+#include "File.h"
+
 namespace dcpp {
 namespace ssl {
 
 using std::vector;
 
+bool SSL_CTX_use_certificate_file(::SSL_CTX* ctx, const char* file, int type) {
+	auto x509 = getX509(file);
+	if(!x509) {
+		return false;
+	}
+	return SSL_CTX_use_certificate(ctx, x509) == SSL_SUCCESS;
+}
+
+bool SSL_CTX_use_PrivateKey_file(::SSL_CTX* ctx, const char* file, int type) {
+	FILE* f = dcpp_fopen(file, "r");
+	if(!f) {
+		return false;
+	}
+
+	::EVP_PKEY* tmpKey = nullptr;
+	PEM_read_PrivateKey(f, &tmpKey, nullptr, nullptr);
+	fclose(f);
+
+	if(!tmpKey) {
+		return false;
+	}
+	EVP_PKEY key(tmpKey);
+
+	return SSL_CTX_use_PrivateKey(ctx, key) == SSL_SUCCESS;
+}
+
+X509 getX509(const char* file) {
+	::X509* ret = nullptr;
+	FILE* f = dcpp_fopen(file, "r");
+	if(f) {
+		PEM_read_X509(f, &ret, nullptr, nullptr);
+		fclose(f);
+	}
+	return X509(ret);
+}
+
 vector<uint8_t> X509_digest(::X509* x509, const ::EVP_MD* md) {
 	unsigned int n;
 	unsigned char buf[EVP_MAX_MD_SIZE];

=== modified file 'dcpp/SSL.h'
--- dcpp/SSL.h	2012-01-13 20:55:20 +0000
+++ dcpp/SSL.h	2012-09-13 21:15:43 +0000
@@ -16,14 +16,18 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef SSL_H_
-#define SSL_H_
+#ifndef DCPLUSPLUS_DCPP_SSL_H
+#define DCPLUSPLUS_DCPP_SSL_H
 
 #include <openssl/ssl.h>
 
 #include <vector>
 #include <cstdint>
 
+#ifndef SSL_SUCCESS
+#define SSL_SUCCESS 1
+#endif
+
 namespace dcpp {
 
 namespace ssl {
@@ -31,16 +35,22 @@
 template<typename T, void (*Release)(T*)>
 class scoped_handle {
 public:
-	explicit scoped_handle(T* t_ = 0) : t(t_) { }
-	~scoped_handle() { Release(t); }
+	explicit scoped_handle(T* t_ = nullptr) : t(t_) { }
+	~scoped_handle() { if(t) { Release(t); } }
 
 	operator T*() { return t; }
 	operator const T*() const { return t; }
 
+	operator bool() const { return t; }
+
 	T* operator->() { return t; }
 	const T* operator->() const { return t; }
 
-	void reset(T* t_ = NULL) { Release(t); t = t_; }
+	void reset(T* t_ = nullptr) { Release(t); t = t_; }
+
+	scoped_handle(scoped_handle&& rhs) : t(rhs.t) { rhs.t = nullptr; }
+	scoped_handle& operator=(scoped_handle&& rhs) { if(&rhs != this) { t = rhs.t; rhs.t = nullptr; } return *this; }
+
 private:
 	scoped_handle(const scoped_handle<T, Release>&);
 	scoped_handle<T, Release>& operator=(const scoped_handle<T, Release>&);
@@ -59,8 +69,15 @@
 typedef scoped_handle<X509, X509_free> X509;
 typedef scoped_handle<X509_NAME, X509_NAME_free> X509_NAME;
 
+// functions that operate with file paths - here in order to support UTF16 Windows paths
+bool SSL_CTX_use_certificate_file(::SSL_CTX* ctx, const char* file, int type);
+bool SSL_CTX_use_PrivateKey_file(::SSL_CTX* ctx, const char* file, int type);
+
+X509 getX509(const char* file);
 std::vector<uint8_t> X509_digest(::X509* x509, const ::EVP_MD* md);
 
 }
+
 }
-#endif /*SSL_H_*/
+
+#endif

=== modified file 'dcpp/SSLSocket.h'
--- dcpp/SSLSocket.h	2012-01-13 20:55:20 +0000
+++ dcpp/SSLSocket.h	2012-09-13 21:15:43 +0000
@@ -24,10 +24,6 @@
 
 #include "SSL.h"
 
-#ifndef SSL_SUCCESS
-#define SSL_SUCCESS 1
-#endif
-
 namespace dcpp {
 
 class SSLSocketException : public SocketException {