// 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);
        }
Beispiel #2
0
        private static void CreateAndInstallMachineCertificate(CertificateGenerator certificateGenerate, CertificateCreationSettings certificateCreationSettings)
        {
            X509Certificate2 certificate = certificateGenerate.CreateMachineCertificate(certificateCreationSettings).Certificate;

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