/// <summary>
        /// Creates certificate authority certificate if required.
        /// </summary>
        /// <param name="proxyServerConfiguration"></param>
        /// <param name="certificateGenerator"></param>
        /// <param name="certificateCache"></param>
        /// <returns></returns>
        private static CertificateManager GetCertificateManager(ProxyServerConfiguration proxyServerConfiguration, CertificateGenerator certificateGenerator, CertificateCache certificateCache)
        {
            var caCertificateFileName = Path.Combine(proxyServerConfiguration.CertificatePath, proxyServerConfiguration.CaCertificateFileName);
            if (!File.Exists(caCertificateFileName))
            {
                CreateCaCertificate(certificateGenerator, proxyServerConfiguration);
            }

            AsymmetricCipherKeyPair caKeyPair = null;
            try
            {
                var caKeyPairText = File.ReadAllText(Path.Combine(proxyServerConfiguration.CertificatePath, proxyServerConfiguration.CaKeyPairFileName));
                caKeyPair = certificateGenerator.ImportKeyPair(caKeyPairText);
            }
            catch (Exception ex)
            {
                throw new ConfigurationErrorsException(string.Format("Could not read the ca private key from file from {0}", proxyServerConfiguration.CaKeyPairFileName), ex);
            }

            X509Certificate caCertificate = null;
            try
            {
                var caCertificateText = File.ReadAllText(Path.Combine(proxyServerConfiguration.CertificatePath, proxyServerConfiguration.CaCertificateFileName));
                caCertificate = certificateGenerator.ImportCertificate(caCertificateText);
            }
            catch (Exception ex)
            {
                throw new ConfigurationErrorsException(string.Format("Could not read the ca certificate from file from {0}", proxyServerConfiguration.CaCertificateFileName), ex);
            }

            var certificateManager = new CertificateManager(certificateCache, caKeyPair, caCertificate);
            return certificateManager;
        }
 public ProxyServer(IProxyServerConfiguration proxyServerConfiguration, IProfileManager profileManager, IProxyCache proxyCache, CertificateGenerator certificateGenerator, ICertificateManager certificateManager)
 {
     _proxyServerConfiguration = proxyServerConfiguration;
     _profileManager = profileManager;
     _proxyCache = proxyCache;
     _certificateGenerator = certificateGenerator;
     _certificateManager = certificateManager;
     ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
 }
        public void ExportPrivateKey_InPemFormat()
        {
            // Arrange
            var certificateGenerator = new CertificateGenerator();
            var keyPair = certificateGenerator.GetKeyPair();

            //Act
            var privateKeyText = certificateGenerator.ExportKeyPair(keyPair);

            //Assert
            Assert.True(privateKeyText.StartsWith("-----BEGIN RSA PRIVATE KEY-----\r\n"));
            Assert.True(privateKeyText.EndsWith("\r\n-----END RSA PRIVATE KEY-----\r\n"));
        }
        private void GenerateSiteCertificate(CertificateGenerator certificateGenerator, string certificatePath, string host, string password)
        {
            var keyPair = _caKeyPair;

            IDictionary certificateDetails = new Hashtable();
            certificateDetails[X509Name.CN] = host;

            IList certificateDetailsOrder = new ArrayList();
            certificateDetailsOrder.Add(X509Name.CN);

            var certificate = certificateGenerator.GenerateCertificateSignedWithCaCertificate(_caKeyPair, _caCertificate, keyPair, certificateDetails, certificateDetailsOrder);
            var certificateData = certificateGenerator.ExportPfxCertificateWithPrivateKey(certificate, keyPair, password);
            var certificateFileName = Path.Combine(certificatePath, host + ".pfx");

            File.WriteAllBytes(certificateFileName, certificateData);

            Logger.InfoFormat("Create certificate for host: {0}", host);
        }
        public void GenerateCaCertificate_SubjectValid_ValidCertificate()
        {
            // Arrange
            var certificateGenerator = new CertificateGenerator();
            var caKeyPair = certificateGenerator.GetKeyPair();
            const string subjectName = "Test CA";

            IDictionary caCertificateDetails = new Hashtable();
            caCertificateDetails[X509Name.CN] = subjectName;

            IList caCertificateDetailsOrder = new ArrayList();
            caCertificateDetailsOrder.Add(X509Name.CN);

            // Act
            var caCertificate = certificateGenerator.GenerateCaCertificate(caKeyPair, caCertificateDetails, caCertificateDetailsOrder);

            // Assert
            Assert.AreEqual("CN=" + subjectName, caCertificate.SubjectDN.ToString());
        }
        private static void CreateCaCertificate(CertificateGenerator certificateGenerator, IProxyServerConfiguration proxyServerConfiguration)
        {
            var caKeyPair = certificateGenerator.GetKeyPair();

            IDictionary caCertificateDetails = new Hashtable();
            caCertificateDetails[X509Name.C] = "UK";
            caCertificateDetails[X509Name.O] = "Acceptance Test Proxy Organization";
            caCertificateDetails[X509Name.OU] = "Testing Department";
            //caCertificateDetails[X509Name.DnQualifier]; //populatated automatically from CN
            caCertificateDetails[X509Name.ST] = "London";
            caCertificateDetails[X509Name.CN] = "AcceptanceTestProxy CA";
            //caCertificateDetails[X509Name.SerialNumber] = CaCertificateName;  //populatated automatically

            //RFC 5208
            IList caCertificateDetailsOrder = new ArrayList();
            caCertificateDetailsOrder.Add(X509Name.C);
            caCertificateDetailsOrder.Add(X509Name.O);
            caCertificateDetailsOrder.Add(X509Name.OU);
            //caCertificateDetailsOrder.Add(X509Name.DnQualifier);
            caCertificateDetailsOrder.Add(X509Name.ST);
            caCertificateDetailsOrder.Add(X509Name.CN);
            //caCertificateDetailsOrder.Add(X509Name.SerialNumber);

            var caCertificate = certificateGenerator.GenerateCaCertificate(caKeyPair, caCertificateDetails, caCertificateDetailsOrder);

            var caKeyPairFileName = Path.Combine(proxyServerConfiguration.CertificatePath, proxyServerConfiguration.CaKeyPairFileName);
            if (File.Exists(caKeyPairFileName))
            {
                File.Delete(caKeyPairFileName);
            }
            var privateKeyText = certificateGenerator.ExportKeyPair(caKeyPair);
            File.WriteAllText(caKeyPairFileName, privateKeyText);

            var caCertificateFileName = Path.Combine(proxyServerConfiguration.CertificatePath, proxyServerConfiguration.CaCertificateFileName);
            if (File.Exists(caCertificateFileName))
            {
                File.Delete(caCertificateFileName);
            }
            var certificateText = certificateGenerator.ExportCertificate(caCertificate);
            File.WriteAllText(caCertificateFileName, certificateText);
        }
        public void ExportCertificate_InPemFormat()
        {
            // Arrange
            var certificateGenerator = new CertificateGenerator();
            var caKeyPair = certificateGenerator.GetKeyPair();
            const string caSubjectName = "Test CA";

            IDictionary caCertificateDetails = new Hashtable();
            caCertificateDetails[X509Name.CN] = caSubjectName;

            IList caCertificateDetailsOrder = new ArrayList();
            caCertificateDetailsOrder.Add(X509Name.CN);

            var caCertificate = certificateGenerator.GenerateCaCertificate(caKeyPair, caCertificateDetails, caCertificateDetailsOrder);

            //Act
            var certificateText = certificateGenerator.ExportCertificate(caCertificate);

            //Assert
            Assert.True(certificateText.StartsWith("-----BEGIN CERTIFICATE-----\r\n"));
            Assert.True(certificateText.EndsWith("\r\n-----END CERTIFICATE-----\r\n"));
        }
        public X509Certificate2 GetSiteCertificate(CertificateGenerator certificateGenerator, string certificatePath, string host, string password)
        {
            var certificate = _certificateCache.GetCertificate(host);
            if (certificate != null)
            {
                return certificate;
            }

            var filename = Path.Combine(certificatePath, host + ".pfx");

            lock (CertificateCreatorLock)
            {
                if (!File.Exists(filename))
                {
                    GenerateSiteCertificate(certificateGenerator, certificatePath, host, password);
                }

                certificate = GetSiteCertificateFromFile(certificatePath, host, password);
                _certificateCache.AddCertificate(host, certificate);
            }

            return certificate;
        }
        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure();

            var proxyServerConfiguration = new ProxyServerConfiguration()
                {
                    DumpHeaders = false,
                    DumpPostData = false,
                    DumpResponseData = false
                };

            if (args.Length > 0)
            {
                if (args.Length <= 3)
                {
                    var argRegHelp = new Regex(@"^(/|-)\?$");
                    var argRexH = new Regex("^(/|-)h$");
                    var argRexP = new Regex("^(/|-)p$");
                    var argRexR = new Regex("^(/|-)r$");

                    foreach (var s in args)
                    {
                        if (argRexH.IsMatch(s.ToLower()))
                        {
                            proxyServerConfiguration.DumpHeaders = true;
                        }
                        else if (argRexP.IsMatch(s.ToLower()))
                        {
                            proxyServerConfiguration.DumpPostData = true;
                        }
                        else if (argRexR.IsMatch(s.ToLower()))
                        {
                            proxyServerConfiguration.DumpResponseData = true;
                        }
                        else
                        {
                            PrintUsageInfo();
                            return;
                        }
                    }
                }
                else if (args.Length > 4)
                {
                    PrintUsageInfo();
                    return;
                }
            }

            var proxyCache = new ProxyCache();
            var profileCache = new ProfileCache();
            var profileManager = new ProfileManager(profileCache);
            var certificateGenerator = new CertificateGenerator();
            var certificateCache = new CertificateCache();
            var certificateManager = GetCertificateManager(proxyServerConfiguration, certificateGenerator, certificateCache);
            var proxyServer = new ProxyServer(proxyServerConfiguration, profileManager, proxyCache, certificateGenerator, certificateManager);

            if (proxyServer.Start())
            {
                Console.WriteLine("Server started on {0}:{1}...Press enter key to end", proxyServerConfiguration.ListeningIpInterface, proxyServerConfiguration.ListeningPort);
                Console.ReadLine();
                Console.WriteLine("Shutting down");
                proxyServer.Stop();
                Console.WriteLine("Server stopped...");
            }
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }
        public void GenerateCertificateSignedWithCaCertificate_SignedWithCaCertificate_ValidCertificate()
        {
            // Arrange
            var certificateGenerator = new CertificateGenerator();
            var caKeyPair = certificateGenerator.GetKeyPair();
            const string caSubjectName = "Test CA";

            IDictionary caCertificateDetails = new Hashtable();
            caCertificateDetails[X509Name.CN] = caSubjectName;

            IList caCertificateDetailsOrder = new ArrayList();
            caCertificateDetailsOrder.Add(X509Name.CN);

            var caCertificate = certificateGenerator.GenerateCaCertificate(caKeyPair, caCertificateDetails, caCertificateDetailsOrder);

            var keyPair = certificateGenerator.GetKeyPair();
            const string subjectName = "www.google.com";

            IDictionary certificateDetails = new Hashtable();
            certificateDetails[X509Name.CN] = subjectName;

            IList certificateDetailsOrder = new ArrayList();
            certificateDetailsOrder.Add(X509Name.CN);

            // Act
            var certificate = certificateGenerator.GenerateCertificateSignedWithCaCertificate(caKeyPair, caCertificate, keyPair, certificateDetails, certificateDetailsOrder);

            // Assert
            Assert.AreEqual("CN=" + caSubjectName, certificate.IssuerDN.ToString()); //Signed with CA
        }
        public void ImportKeyPair_InPemFormat()
        {
            // Arrange
            var certificateGenerator = new CertificateGenerator();
            var caKeyPair = certificateGenerator.GetKeyPair();

            var privateKeyText = certificateGenerator.ExportKeyPair(caKeyPair);

            //Act
            var keyPair = certificateGenerator.ImportKeyPair(privateKeyText);

            //Assert
            Assert.AreEqual(caKeyPair.Private, keyPair.Private);
            Assert.AreEqual(caKeyPair.Public, keyPair.Public);
        }
        public void ImportCertificate_InPemFormat()
        {
            // Arrange
            var certificateGenerator = new CertificateGenerator();
            var caKeyPair = certificateGenerator.GetKeyPair();
            const string caSubjectName = "Test CA";

            IDictionary caCertificateDetails = new Hashtable();
            caCertificateDetails[X509Name.CN] = caSubjectName;

            IList caCertificateDetailsOrder = new ArrayList();
            caCertificateDetailsOrder.Add(X509Name.CN);

            var caCertificate = certificateGenerator.GenerateCaCertificate(caKeyPair, caCertificateDetails, caCertificateDetailsOrder);
            var certificateText = certificateGenerator.ExportCertificate(caCertificate);

            //Act
            var certificate = certificateGenerator.ImportCertificate(certificateText);

            //Assert
            Assert.AreEqual(caCertificate.GetPublicKey(), certificate.GetPublicKey());
        }