[Box Backup-commit] COMMIT r2815 - in box/invisnet/vs2010/0.11: bin/bbackupd lib/server

subversion at boxbackup.org subversion at boxbackup.org
Wed Dec 1 12:25:31 GMT 2010


Author: invisnet
Date: 2010-12-01 12:25:31 +0000 (Wed, 01 Dec 2010)
New Revision: 2815

Modified:
   box/invisnet/vs2010/0.11/bin/bbackupd/BackupDaemon.cpp
   box/invisnet/vs2010/0.11/lib/server/ServerTLS.h
   box/invisnet/vs2010/0.11/lib/server/TLSContext.cpp
   box/invisnet/vs2010/0.11/lib/server/TLSContext.h
Log:
Improved certificate handling; handles cert export/import better.

Modified: box/invisnet/vs2010/0.11/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/invisnet/vs2010/0.11/bin/bbackupd/BackupDaemon.cpp	2010-12-01 12:13:35 UTC (rev 2814)
+++ box/invisnet/vs2010/0.11/bin/bbackupd/BackupDaemon.cpp	2010-12-01 12:25:31 UTC (rev 2815)
@@ -413,7 +413,7 @@
 	const Configuration &conf(GetConfiguration());
 
 #ifdef WIN32
-	std::string certFile;
+	std::string certFile(conf.GetKeyValue("AccountNumber")); // abuse certFile so we know which one to look for
 	std::string keyFile;
 	std::string caFile;
 	std::string keysFile;

Modified: box/invisnet/vs2010/0.11/lib/server/ServerTLS.h
===================================================================
--- box/invisnet/vs2010/0.11/lib/server/ServerTLS.h	2010-12-01 12:13:35 UTC (rev 2814)
+++ box/invisnet/vs2010/0.11/lib/server/ServerTLS.h	2010-12-01 12:25:31 UTC (rev 2815)
@@ -50,7 +50,7 @@
 		const Configuration &conf(this->GetConfiguration());
 		const Configuration &serverconf(conf.GetSubConfiguration("Server"));
 #ifdef WIN32
-		std::string certFile;
+		std::string certFile(serverconf.GetKeyValue("AccountNumber"));
 		std::string keyFile;
 		std::string caFile;
 #else

Modified: box/invisnet/vs2010/0.11/lib/server/TLSContext.cpp
===================================================================
--- box/invisnet/vs2010/0.11/lib/server/TLSContext.cpp	2010-12-01 12:13:35 UTC (rev 2814)
+++ box/invisnet/vs2010/0.11/lib/server/TLSContext.cpp	2010-12-01 12:25:31 UTC (rev 2815)
@@ -22,10 +22,6 @@
 
 #include "MemLeakFindOn.h"
 
-#ifdef WIN32
-#include <WinCrypt.h>
-#endif
-
 #define MAX_VERIFICATION_DEPTH		2
 #define CIPHER_LIST					"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
 
@@ -81,42 +77,7 @@
 	
 	// Setup our identity
 #ifdef WIN32
-	{
-		X509 *x509 = GetTrustedCertificate();
-		X509_LOOKUP *lookup = ::X509_STORE_add_lookup(mpContext->cert_store, X509_LOOKUP_file());
-		if(lookup == NULL)
-		{
-			SSLLib::LogError("X509_STORE_add_lookup");
-			THROW_EXCEPTION(ServerException, TLSLoadTrustedCAsFailed)
-		}
-		if(::X509_STORE_add_cert(lookup->store_ctx, x509) != 1)
-		{
-			SSLLib::LogError("X509_STORE_add_cert");
-			THROW_EXCEPTION(ServerException, TLSLoadTrustedCAsFailed)
-		}
-		// don't free lookup
-		X509_free(x509);
-	}
-
-	{
-		X509 *x509 = GetCertificate();
-		if(::SSL_CTX_use_certificate(mpContext, x509) != 1)
-		{
-			SSLLib::LogError("SSL_CTX_use_certificate");
-			THROW_EXCEPTION(ServerException, TLSLoadCertificatesFailed)
-		}
-		X509_free(x509);
-	}
-
-	{
-		EVP_PKEY *evpPK = GetPrivateKey();
-		if(::SSL_CTX_use_PrivateKey(mpContext, evpPK) != 1)
-		{
-			SSLLib::LogError("SSL_CTX_use_PrivateKey");
-			THROW_EXCEPTION(ServerException, TLSLoadPrivateKeyFailed)
-		}
-		EVP_PKEY_free(evpPK);
-	}
+	ImportCertificatesAndPrivateKeyFromStore(CertificatesFile);
 #else
 	if(::SSL_CTX_use_certificate_chain_file(mpContext, CertificatesFile) != 1)
 	{
@@ -173,228 +134,223 @@
 	return mpContext;
 }
 
-
 #ifdef WIN32
-// --------------------------------------------------------------------------
-//
-// Function
-//		Name:    TLSContext::GetCertificate()
-//		Purpose: Get the certificate from the store
-//		Created: 2010/09/03
-//
-// --------------------------------------------------------------------------
-X509* TLSContext::GetCertificate()
+void TLSContext::ImportCertificatesAndPrivateKeyFromStore(const char *CertificatesFile)
 {
-	HCRYPTPROV	hCryptProv	= NULL;
-	X509			*x509			= NULL;
+	HCERTSTORE  hSystemStore;
 
-	if (FALSE == CryptAcquireContext(&hCryptProv,"BoxBackup",NULL,PROV_RSA_FULL,CRYPT_MACHINE_KEYSET))
+	if (NULL == (hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
+															0,
+															NULL,
+															CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG,
+															L"MY")))
 	{
-		BOX_ERROR("CryptAcquireContext failed");
+		BOX_LOG_WIN_ERROR("Failed to open store");
 	}
 	else
 	{
-		DWORD cbPublicKeyInfo = 0;
+		PCCERT_CONTEXT  pDesiredCert = NULL;
 
-		if(FALSE == CryptExportPublicKeyInfo(hCryptProv, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, &cbPublicKeyInfo))
+		//
+		// serverCA
+		//
+		if(NULL == (pDesiredCert = CertFindCertificateInStore(hSystemStore,
+																				PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
+																				0,
+																				CERT_FIND_SUBJECT_STR,
+																				L"Backup system server root",
+																				NULL)))
 		{
-			BOX_ERROR("Failed to get buffer length for public key");
+			BOX_LOG_WIN_ERROR("No matching root certificate");
 		}
 		else
 		{
-			char	*PublicKeyBuffer	= new char[cbPublicKeyInfo];
-			CERT_PUBLIC_KEY_INFO*	pbPublicKeyInfo	= (CERT_PUBLIC_KEY_INFO*) PublicKeyBuffer;
+			const unsigned char *pbCertEncoded = pDesiredCert->pbCertEncoded;
+			X509_LOOKUP *lookup	= NULL;
+			X509 *x509	= NULL;
 
-			if(FALSE == CryptExportPublicKeyInfo(hCryptProv, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pbPublicKeyInfo, &cbPublicKeyInfo))
+			if(NULL == (x509 = d2i_X509(NULL, &pbCertEncoded, pDesiredCert->cbCertEncoded)))
 			{
-				BOX_ERROR("Failed to export public key");
+				SSLLib::LogError("d2i_X509");
+				THROW_EXCEPTION(ServerException, TLSLoadTrustedCAsFailed)
 			}
-			else
+			if(NULL == (lookup = ::X509_STORE_add_lookup(mpContext->cert_store, X509_LOOKUP_file())))
 			{
-				HCERTSTORE  hSystemStore;
-
-				if (NULL == (hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY")))
-				{
-					BOX_ERROR("Failed to open store");
-				}
-				else
-				{
-					PCCERT_CONTEXT  pDesiredCert = NULL;
-
-					if(NULL == (pDesiredCert = CertFindCertificateInStore(hSystemStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_PUBLIC_KEY, pbPublicKeyInfo, NULL)))
-					{
-						BOX_ERROR("No matching certificate");
-					}
-					else
-					{
-						const unsigned char *pbCertEncoded = pDesiredCert->pbCertEncoded;
-
-						x509 = d2i_X509(NULL, &pbCertEncoded, pDesiredCert->cbCertEncoded);
-
-						DWORD pcbData = 0;
-						if (CertGetCertificateContextProperty(pDesiredCert,CERT_KEY_PROV_INFO_PROP_ID,NULL,&pcbData))
-						{
-							BOX_TRACE("Certificate has associated Private Key");
-						}
-						else
-						{
-							CRYPT_KEY_PROV_INFO cryptKeyProvInfo = { L"BoxBackup",MS_DEF_PROV_W,PROV_RSA_FULL,CRYPT_MACHINE_KEYSET,0,NULL,AT_SIGNATURE };
-
-							if (!CertSetCertificateContextProperty(pDesiredCert,CERT_KEY_PROV_INFO_PROP_ID,0,&cryptKeyProvInfo))
-							{
-								BOX_ERROR("SetCertProp failed");
-							}
-							else
-							{
-								BOX_INFO("Associated Private Key with certificate");
-							}
-						}
-
-						CertFreeCertificateContext(pDesiredCert);
-					}
-
-					CertCloseStore(hSystemStore,CERT_CLOSE_STORE_CHECK_FLAG); // TODO: check this
-				}
+				SSLLib::LogError("X509_STORE_add_lookup");
+				THROW_EXCEPTION(ServerException, TLSLoadTrustedCAsFailed)
 			}
+			if(::X509_STORE_add_cert(lookup->store_ctx, x509) != 1)
+			{
+				SSLLib::LogError("X509_STORE_add_cert");
+				THROW_EXCEPTION(ServerException, TLSLoadTrustedCAsFailed)
+			}
+			// don't free lookup
+			X509_free(x509);
 
-			delete[] PublicKeyBuffer;
+			CertFreeCertificateContext(pDesiredCert);
 		}
 
-		CryptReleaseContext(hCryptProv,0);
-	}
 
-	if(NULL == x509)
-	{
-		THROW_EXCEPTION(ServerException, TLSLoadCertificatesFailed)
-	}
+		//
+		// BACKUP-12345
+		//
+		std::string subject("BACKUP-");
+		subject.append(&CertificatesFile[2]);
 
-	return x509;
-}
-
-
-// --------------------------------------------------------------------------
-//
-// Function
-//		Name:    TLSContext::GetTrustedCertificate()
-//		Purpose: Get the certificate from the store
-//		Created: 2010/10/09
-//
-// --------------------------------------------------------------------------
-X509* TLSContext::GetTrustedCertificate()
-{
-	X509			*x509			= NULL;
-	HCERTSTORE  hSystemStore;
-
-	if (NULL == (hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG, L"MY")))
-	{
-		BOX_ERROR("Failed to open store");
-	}
-	else
-	{
-		PCCERT_CONTEXT  pDesiredCert = NULL;
-
-		if(NULL == (pDesiredCert = CertFindCertificateInStore(hSystemStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, L"Backup system server root", NULL)))
+		if(NULL == (pDesiredCert = CertFindCertificateInStore(hSystemStore,
+																				PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
+																				0,
+																				CERT_FIND_SUBJECT_STR,
+																				Win32::multi2wide(subject).c_str(),
+																				NULL)))
 		{
-			BOX_ERROR("No matching root certificate");
+			BOX_LOG_WIN_ERROR("No matching certificate");
 		}
 		else
 		{
 			const unsigned char *pbCertEncoded = pDesiredCert->pbCertEncoded;
+			X509 *x509	= NULL;
+					
+			if(NULL == (x509 = d2i_X509(NULL, &pbCertEncoded, pDesiredCert->cbCertEncoded)))
+			{
+				SSLLib::LogError("d2i_X509");
+				THROW_EXCEPTION(ServerException, TLSLoadCertificatesFailed)
+			}
+			if(::SSL_CTX_use_certificate(mpContext, x509) != 1)
+			{
+				SSLLib::LogError("SSL_CTX_use_certificate");
+				THROW_EXCEPTION(ServerException, TLSLoadCertificatesFailed)
+			}
+			X509_free(x509);
 
-			x509 = d2i_X509(NULL, &pbCertEncoded, pDesiredCert->cbCertEncoded);
 
-			CertFreeCertificateContext(pDesiredCert);
-		}
+			//
+			// Check the Private Key is associated with the Certificate
+			//
+			DWORD pcbData = 0;
+			if (CertGetCertificateContextProperty(pDesiredCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &pcbData))
+			{
+				BOX_TRACE("Certificate has associated Private Key");
+			}
+			else
+			{
+				CRYPT_KEY_PROV_INFO cryptKeyProvInfo = { L"BoxBackup",
+																	  MS_DEF_PROV_W,
+																	  PROV_RSA_FULL,
+																	  CRYPT_MACHINE_KEYSET,
+																	  0,
+																	  NULL,
+																	  AT_KEYEXCHANGE };
 
-		CertCloseStore(hSystemStore,CERT_CLOSE_STORE_CHECK_FLAG); // TODO: check this
-	}
+				if (!CertSetCertificateContextProperty(pDesiredCert,
+																	CERT_KEY_PROV_INFO_PROP_ID,
+																	0,
+																	&cryptKeyProvInfo))
+				{
+					BOX_LOG_WIN_ERROR("SetCertProp failed");
+				}
+				else
+				{
+					BOX_INFO("Associated Private Key with certificate");
+				}
+			}
 
-	if(NULL == x509)
-	{
-		THROW_EXCEPTION(ServerException, TLSLoadTrustedCAsFailed)
-	}
 
-	return x509;
-}
+			//
+			// Private Key
+			//
+			HCRYPTPROV hCryptProv;
+			DWORD keySpec;
+			BOOL mustFree;
 
-
-// --------------------------------------------------------------------------
-//
-// Function
-//		Name:    TLSContext::GetPrivateKey()
-//		Purpose: Get the private key from the container
-//		Created: 2010/09/03
-//
-// --------------------------------------------------------------------------
-EVP_PKEY* TLSContext::GetPrivateKey()
-{
-	HCRYPTPROV		hCryptProv		= NULL;
-	EVP_PKEY			*evpPK			= NULL;
-
-	if (FALSE == CryptAcquireContext(&hCryptProv,"BoxBackup",NULL,PROV_RSA_FULL,CRYPT_MACHINE_KEYSET))
-	{
-		BOX_ERROR("CryptAcquireContext failed");
-	}
-	else
-	{
-		HCRYPTKEY	hKey	= NULL;
-
-		if (FALSE == CryptGetUserKey(hCryptProv,AT_SIGNATURE,&hKey))
-		{
-			BOX_ERROR("CryptGetUserKey failed");
-		}
-		else
-		{
-			DWORD len = 0;
-
-			if(FALSE == CryptExportKey(hKey,NULL,PRIVATEKEYBLOB,0,NULL,&len))
+			if (!CryptAcquireCertificatePrivateKey(pDesiredCert,
+																CRYPT_ACQUIRE_SILENT_FLAG,
+																NULL,
+																&hCryptProv,
+																&keySpec,
+																&mustFree))
 			{
-				BOX_ERROR("CryptExportKey failed (first pass)");
+				BOX_LOG_WIN_ERROR("CryptAcquireCertificatePrivateKey failed");
 			}
 			else
 			{
-				BYTE *key = new BYTE[len];
+				HCRYPTKEY	hKey	= NULL;
 
-				if(FALSE == CryptExportKey(hKey,NULL,PRIVATEKEYBLOB,0,key,&len))
+				// must be one of these....
+				if (!CryptGetUserKey(hCryptProv, AT_KEYEXCHANGE, &hKey)
+					&& !CryptGetUserKey(hCryptProv, AT_SIGNATURE, &hKey))
 				{
-					BOX_ERROR("CryptExportKey failed (second pass)");
+					BOX_LOG_WIN_ERROR("CryptGetUserKey failed - no Private Key?!");
 				}
-				else if(FALSE == CryptEncodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, key, NULL, &len))
-				{
-					BOX_ERROR("CryptEncodeObject failed (first pass)");
-				}
 				else
 				{
-					BYTE *encodedKey = new BYTE[len];
+					DWORD len = 0;
 
-					if(FALSE == CryptEncodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, key, encodedKey, &len))
+					if(!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &len))
 					{
-						BOX_ERROR("CryptEncodeObject failed (second pass)");
+						BOX_LOG_WIN_ERROR("CryptExportKey failed (first pass)");
 					}
 					else
 					{
-						const unsigned char *pEncodedKey = encodedKey;
+						std::unique_ptr<BYTE[]> key(new BYTE[len]);
 
-						d2i_PrivateKey(EVP_PKEY_RSA, &evpPK, &pEncodedKey, len);
+						if(!CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, key.get(), &len))
+						{
+							BOX_LOG_WIN_ERROR("CryptExportKey failed (second pass)");
+						}
+						else if(!CryptEncodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+															PKCS_RSA_PRIVATE_KEY,
+															key.get(),
+															NULL,
+															&len))
+						{
+							BOX_LOG_WIN_ERROR("CryptEncodeObject failed (first pass)");
+						}
+						else
+						{
+							std::unique_ptr<BYTE[]> encodedKey(new BYTE[len]);
+
+							if(!CryptEncodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+														 PKCS_RSA_PRIVATE_KEY,
+														 key.get(),
+														 encodedKey.get(),
+														 &len))
+							{
+								BOX_LOG_WIN_ERROR("CryptEncodeObject failed (second pass)");
+							}
+							else
+							{
+								const unsigned char *pEncodedKey = encodedKey.get();
+								EVP_PKEY *evpPK = NULL;
+
+								if(!d2i_PrivateKey(EVP_PKEY_RSA, &evpPK, &pEncodedKey, len))
+								{
+									SSLLib::LogError("d2i_PrivateKey");
+									THROW_EXCEPTION(ServerException, TLSLoadPrivateKeyFailed)
+								}
+								if(::SSL_CTX_use_PrivateKey(mpContext, evpPK) != 1)
+								{
+									SSLLib::LogError("SSL_CTX_use_PrivateKey");
+									THROW_EXCEPTION(ServerException, TLSLoadPrivateKeyFailed)
+								}
+								EVP_PKEY_free(evpPK);
+							}
+						}
 					}
 
-					delete[] encodedKey;
-				}
+					CryptDestroyKey(hKey);
 
-				delete[] key;
+					if(mustFree)
+					{
+						CryptReleaseContext(hCryptProv, 0);
+					}
+				}
 			}
 
-			CryptDestroyKey(hKey);
+			CertFreeCertificateContext(pDesiredCert);
 		}
-		CryptReleaseContext(hCryptProv,0);
-	}
 
-	if(NULL == evpPK)
-	{
-		THROW_EXCEPTION(ServerException, TLSLoadPrivateKeyFailed)
+		CertCloseStore(hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG); // TODO: check this
 	}
-
-	return evpPK;
 }
-
-#endif
\ No newline at end of file
+#endif

Modified: box/invisnet/vs2010/0.11/lib/server/TLSContext.h
===================================================================
--- box/invisnet/vs2010/0.11/lib/server/TLSContext.h	2010-12-01 12:13:35 UTC (rev 2814)
+++ box/invisnet/vs2010/0.11/lib/server/TLSContext.h	2010-12-01 12:25:31 UTC (rev 2815)
@@ -38,12 +38,9 @@
 
 private:
 	SSL_CTX *mpContext;
-
 #ifdef WIN32
 private:
-	EVP_PKEY *GetPrivateKey();
-	X509 *GetCertificate();
-	X509 *GetTrustedCertificate();
+	void ImportCertificatesAndPrivateKeyFromStore(const char *CertificatesFile);
 #endif
 };
 




More information about the Boxbackup-commit mailing list