// Requests a certificate to be generated by the Bridge
        // If the certificate requested is for the local machine, for example if
        // server hostname is: foo.bar.com
        // local address is considered to be: 127.0.0.1, localhost, foo, foo.bar.com
        // Then we also install the certificate to the local machine, because it means we are about to run an HTTPS/SSL test against
        // this machine.
        // Otherwise, don't bother installing as the cert is for a remote machine.
        public override ResourceResponse Put(ResourceRequestContext context)
        {
            X509Certificate2 certificate;

            string subject;

            if (!context.Properties.TryGetValue(subjectKeyName, out subject) || string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentException("When PUTting to this resource, specify an non-empty 'subject'", "context.Properties");
            }

            // There can be multiple subjects, separated by ,
            string[] subjects = subject.Split(',');

            bool isLocal = IsLocalMachineResource(subjects[0]);

            lock (s_certificateResourceLock)
            {
                if (!s_createdCertsBySubject.TryGetValue(subjects[0], out certificate))
                {
                    CertificateGenerator generator = CertificateResourceHelpers.GetCertificateGeneratorInstance(context.BridgeConfiguration);

                    if (isLocal)
                    {
                        // If we're PUTting a cert that refers to a hostname local to the bridge,
                        // return the Local Machine cert that CertificateManager caches and add it to the collection
                        //
                        // If we are receiving a PUT to the same endpoint address as the bridge server, it means that
                        // a test is going to be run on this box
                        //
                        // In keeping with the semantic of these classes, we must PUT before we can GET a cert
                        certificate = CertificateManager.CreateAndInstallLocalMachineCertificates(generator);
                    }
                    else
                    {
                        CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
                        {
                            Subjects = subjects,
                        };
                        certificate = generator.CreateMachineCertificate(certificateCreationSettings).Certificate;
                    }

                    X509Certificate2 dummy;
                    if (!isLocal || !s_createdCertsByThumbprint.TryGetValue(certificate.Thumbprint, out dummy))
                    {
                        // when isLocal, it's possible for there to be > 1 subject sharing the same thumbprint
                        // in this case, we only cache the first isLocal subject, the rest we don't cache
                        s_createdCertsBySubject.Add(subjects[0], certificate);
                        s_createdCertsByThumbprint.Add(certificate.Thumbprint, certificate);
                    }
                }
            }

            ResourceResponse response = new ResourceResponse();

            response.Properties.Add(thumbprintKeyName, certificate.Thumbprint);
            response.Properties.Add(isLocalKeyName, isLocal.ToString());

            return(response);
        }
示例#2
0
        protected override void ModifyHost(ServiceHost serviceHost, ResourceRequestContext context)
        {
            // Ensure the service certificate is installed before this endpoint resource is used
            //Create an expired certificate
            CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName      = "WCF Bridge - TcpExpiredServerCertResource",
                ValidityType      = CertificateValidityType.Expired,
                ValidityNotBefore = DateTime.UtcNow - TimeSpan.FromDays(4),
                ValidityNotAfter  = DateTime.UtcNow - TimeSpan.FromDays(2),
                //If you specify multiple subjects, the first one becomes the subject, and all of them become Subject Alt Names.
                //In this case, the certificate subject is  CN=fqdn, OU=..., O=... , and SANs will be  fqdn, hostname, localhost
                //We do this so that a single bridge setup can deal with all the possible addresses that a client might use.
                //If we don't put "localhost' here, a long-running bridge will not be able to receive requests from both fqdn  and  localhost
                //because the certs won't match.
                Subject = s_fqdn,
                SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" }
            };

            X509Certificate2 cert = CertificateResourceHelpers.EnsureCustomCertificateInstalled(context.BridgeConfiguration, certificateCreationSettings, Address);

            serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
                                                                      StoreName.My,
                                                                      X509FindType.FindByThumbprint,
                                                                      cert.Thumbprint);
        }
        // Requests a certificate to be generated by the Bridge based on a user name and not machine name
        public override ResourceResponse Put(ResourceRequestContext context)
        {
            X509Certificate2 certificate;

            string subject;

            if (!context.Properties.TryGetValue(subjectKeyName, out subject) || string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentException("When PUTting to this resource, specify an non-empty 'subject'", "context.Properties");
            }

            // There can be multiple subjects, separated by ,
            string[] subjects = subject.Split(',');

            lock (s_certificateResourceLock)
            {
                if (!s_createdCertsBySubject.TryGetValue(subjects[0], out certificate))
                {
                    CertificateGenerator generator = CertificateResourceHelpers.GetCertificateGeneratorInstance(context.BridgeConfiguration);

                    CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
                    {
                        FriendlyName            = "WCF Bridge - UserCertificateResource",
                        Subject                 = subjects[0],
                        SubjectAlternativeNames = subjects
                    };
                    certificate = generator.CreateUserCertificate(certificateCreationSettings).Certificate;

                    // Cache the certificates
                    s_createdCertsBySubject.Add(subjects[0], certificate);
                    s_createdCertsByThumbprint.Add(certificate.Thumbprint, certificate);

                    // Created certs get put onto the local machine
                    // We ideally don't want this to happen, but until we find a way to have BridgeClient not need elevation for cert installs
                    // we need this to happen so that running locally doesn't require elevation as it messes up our CI and developer builds
                    CertificateManager.InstallCertificateToMyStore(certificate);
                }
            }

            ResourceResponse response = new ResourceResponse();

            response.Properties.Add(thumbprintKeyName, certificate.Thumbprint);

            return(response);
        }
        protected override void ModifyHost(ServiceHost serviceHost, ResourceRequestContext context)
        {
            // Ensure the service certificate is installed before this endpoint resource is used
            //Create a certificate and add to the revocation list
            CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpRevokedServerCertResource",
                ValidityType            = CertificateValidityType.Revoked,
                Subject                 = s_fqdn,
                SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" }
            };

            X509Certificate2 cert = CertificateResourceHelpers.EnsureCustomCertificateInstalled(context.BridgeConfiguration, certificateCreationSettings, Address);

            serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
                                                                      StoreName.My,
                                                                      X509FindType.FindByThumbprint,
                                                                      cert.Thumbprint);
        }
示例#5
0
        protected override void ModifyHost(ServiceHost serviceHost, ResourceRequestContext context)
        {
            // Ensure the service certificate is installed before this endpoint resource is used
            //Create a certificate and add to the revocation list
            CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
            {
                IsValidCert = false,
                Subjects    = new string[] { s_fqdn, s_hostname, "localhost" }
            };

            X509Certificate2 cert = CertificateResourceHelpers.EnsureRevokedCertificateInstalled(context.BridgeConfiguration, certificateCreationSettings, Address);

            CertificateManager.RevokeCertificate(CertificateResourceHelpers.GetCertificateGeneratorInstance(context.BridgeConfiguration), cert.SerialNumber);

            serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
                                                                      StoreName.My,
                                                                      X509FindType.FindByThumbprint,
                                                                      cert.Thumbprint);
        }
        protected override void ModifyHost(ServiceHost serviceHost, ResourceRequestContext context)
        {
            // Ensure the service certificate is installed before this endpoint resource is used
            // Exactly one subject name, which is going to be the CN

            CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpCertificateWithSubjectCanonicalNameLocalhostResource",
                Subject                 = "localhost",
                SubjectAlternativeNames = new string[0],
                ValidityType            = CertificateValidityType.NonAuthoritativeForMachine
            };

            X509Certificate2 cert = CertificateResourceHelpers.EnsureCustomCertificateInstalled(context.BridgeConfiguration, certificateCreationSettings, Address);

            serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
                                                                      StoreName.My,
                                                                      X509FindType.FindByThumbprint,
                                                                      cert.Thumbprint);
        }
示例#7
0
        protected override void ModifyHost(ServiceHost serviceHost, ResourceRequestContext context)
        {
            // Ensure the service certificate is installed before this endpoint resource is used

            // CN=not-real-subject-name means that a cert for "not-real-subject-name" will be installed
            // Per #422 this shouldn't matter as we now check with SAN

            CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpCertificateWithServerAltNameResource",
                Subject                 = "not-real-subject-name",
                SubjectAlternativeNames = new string[] { "not-real-subject-name", "not-real-subject-name.example.com", s_fqdn, s_hostname, "localhost" }
            };

            X509Certificate2 cert = CertificateResourceHelpers.EnsureCustomCertificateInstalled(context.BridgeConfiguration, certificateCreationSettings, Address);

            serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
                                                                      StoreName.My,
                                                                      X509FindType.FindByThumbprint,
                                                                      cert.Thumbprint);
        }
示例#8
0
        private static int Main(string[] args)
        {
            ApplyAppSettings();

            if (args.Length > 0)
            {
                if (string.Compare(args[0], "-Uninstall", true) == 0)
                {
                    UninstallAllCerts();
                    return(0);
                }
                else if (string.Compare(args[0], "-help", true) == 0)
                {
                    Usage();
                    return(0);
                }
                else
                {
                    Usage();
                    return(1);
                }
            }

            UninstallAllCerts();

            CertificateGenerator certificateGenerate = new CertificateGenerator();

            certificateGenerate.CertificatePassword = "******";
            certificateGenerate.CrlServiceUri       = s_fqdn;
            certificateGenerate.ValidityPeriod      = s_ValidatePeriod;

            if (!string.IsNullOrEmpty(s_testserverbase))
            {
                certificateGenerate.CrlUriRelativePath += "/" + s_testserverbase;
            }
            certificateGenerate.CrlUriRelativePath += "/TestHost.svc/Crl";

            //Create and install root and server cert
            CertificateManager.CreateAndInstallLocalMachineCertificates(certificateGenerate);

            //Create and Install expired cert
            CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName      = "WCF Bridge - TcpExpiredServerCertResource",
                ValidityType      = CertificateValidityType.Expired,
                ValidityNotBefore = DateTime.UtcNow - TimeSpan.FromDays(4),
                ValidityNotAfter  = DateTime.UtcNow - TimeSpan.FromDays(2),
                //If you specify multiple subjects, the first one becomes the subject, and all of them become Subject Alt Names.
                //In this case, the certificate subject is  CN=fqdn, OU=..., O=... , and SANs will be  fqdn, hostname, localhost
                //We do this so that a single WCF service setup can deal with all the possible addresses that a client might use.
                Subject = s_fqdn,
                SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" }
            };

            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);


            //Create and Install TcpCertificateWithServerAltName
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpCertificateWithServerAltNameResource",
                Subject                 = "not-real-subject-name",
                SubjectAlternativeNames = new string[] { "not-real-subject-name", "not-real-subject-name.example.com", s_fqdn, s_hostname, "localhost" }
            };
            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);

            //TcpCertificateWithSubjectCanonicalNameDomainName
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpCertificateWithSubjectCanonicalNameDomainNameResource",
                Subject                 = s_hostname,
                SubjectAlternativeNames = new string[0],
                ValidityType            = CertificateValidityType.NonAuthoritativeForMachine
            };
            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);

            //WCF Bridge - TcpCertificateWithSubjectCanonicalNameFqdn
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpCertificateWithSubjectCanonicalNameFqdnResource",
                Subject                 = s_fqdn,
                SubjectAlternativeNames = new string[0],
                ValidityType            = CertificateValidityType.NonAuthoritativeForMachine
            };
            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);

            //TcpCertificateWithSubjectCanonicalNameLocalhost
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpCertificateWithSubjectCanonicalNameLocalhostResource",
                Subject                 = "localhost",
                SubjectAlternativeNames = new string[0],
                ValidityType            = CertificateValidityType.NonAuthoritativeForMachine
            };
            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);

            //TcpRevokedServerCert
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpRevokedServerCertResource",
                ValidityType            = CertificateValidityType.Revoked,
                Subject                 = s_fqdn,
                SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" }
            };
            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);

            //TcpInvalidEkuServerCert
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName            = "WCF Bridge - TcpInvalidEkuServerCert",
                ValidityType            = CertificateValidityType.Valid,
                Subject                 = s_fqdn,
                SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" },
                EKU = new List <Org.BouncyCastle.Asn1.X509.KeyPurposeID> {
                    Org.BouncyCastle.Asn1.X509.KeyPurposeID.IdKPClientAuth
                }
            };
            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);

            //STSMetaData
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName = "WCF Bridge - STSMetaData",
                ValidityType = CertificateValidityType.Valid,
                Subject      = "STSMetaData",
                EKU          = new List <Org.BouncyCastle.Asn1.X509.KeyPurposeID>()
            };
            CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings);

            //Create and install client cert
            certificateCreationSettings = new CertificateCreationSettings()
            {
                FriendlyName = "WCF Bridge - UserCertificateResource",
                Subject      = "WCF Client Certificate",
            };
            X509Certificate2 certificate = certificateGenerate.CreateUserCertificate(certificateCreationSettings).Certificate;

            CertificateManager.AddToStoreIfNeeded(StoreName.My, StoreLocation.LocalMachine, certificate);

            //Create CRL and save it
            File.WriteAllBytes(s_CrlFileLocation, certificateGenerate.CrlEncoded);

            return(0);
        }
示例#9
0
        private static void CreateAndInstallMachineCertificate(CertificateGenerator certificateGenerate, CertificateCreationSettings certificateCreationSettings)
        {
            X509Certificate2 certificate = certificateGenerate.CreateMachineCertificate(certificateCreationSettings).Certificate;

            CertificateManager.AddToStoreIfNeeded(StoreName.My, StoreLocation.LocalMachine, certificate);
        }
        internal static string EnsureNonDefaultCertificateInstalled(BridgeConfiguration configuration, CertificateCreationSettings certificateCreationSettings, string resourceAddress)
        {
            X509Certificate2 cert = CertificateManager.CreateAndInstallNonDefaultMachineCertificates(GetCertificateGeneratorInstance(configuration), certificateCreationSettings, resourceAddress);

            return(cert.Thumbprint);
        }
 internal static X509Certificate2 EnsureRevokedCertificateInstalled(BridgeConfiguration configuration, CertificateCreationSettings certificateCreationSettings, string resourceAddress)
 {
     return(CertificateManager.CreateAndInstallNonDefaultMachineCertificates(GetCertificateGeneratorInstance(configuration), certificateCreationSettings, resourceAddress));
 }