// 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); }
internal static string EnsureSslPortCertificateInstalled(BridgeConfiguration configuration) { // Ensure the https certificate is installed before this endpoint resource is used X509Certificate2 cert = CertificateManager.CreateAndInstallLocalMachineCertificates(GetCertificateGeneratorInstance(configuration)); // Ensure http.sys has been told to use this certificate on the https port CertificateManager.InstallSSLPortCertificate(cert.Thumbprint, configuration.BridgeHttpsPort); return(cert.Thumbprint); }
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); }