예제 #1
0
        public void SelfSignedTLSCertTest()
        {
            bool   handshakeOccured = false;
            Server sv = new Server();
            TLSCertificateKeyPair serverCert  = TLSCertificateKeyPair.CreateServerCert("localhost");
            TLSCertificateKeyPair clientCert  = TLSCertificateKeyPair.CreateClientCert();
            KeyCertificatePair    pair        = new KeyCertificatePair(serverCert.CertPEMBytes.ToUTF8String(), serverCert.KeyPEMBytes.ToUTF8String());
            ServerCredentials     credentials = new SslServerCredentials(new[] { pair }, clientCert.CertPEMBytes.ToUTF8String(), true);

            sv.Ports.Add(new ServerPort("localhost", 0, credentials));
            sv.Services.Add(Endorser.BindService(new MockEndorser()).Intercept(new MultalTLSInterceptor(clientCert.CertPEMBytes, (b) => handshakeOccured = b)));
            sv.Start();
            int port = sv.Ports.First().BoundPort;
            ChannelCredentials cred = new SslCredentials(serverCert.CertPEMBytes.ToUTF8String(), new KeyCertificatePair(clientCert.CertPEMBytes.ToUTF8String(), clientCert.KeyPEMBytes.ToUTF8String()));
            Channel            chan = new Channel("localhost", port, cred);
            SignedProposal     prop = new SignedProposal();

            Endorser.EndorserClient cl = new Endorser.EndorserClient(chan);
            cl.ProcessProposal(prop);
            Assert.IsTrue(handshakeOccured, "Handshake didn't occur");
            chan.ShutdownAsync().RunAndUnwrap();
            sv.ShutdownAsync().RunAndUnwrap();
        }
예제 #2
0
        public Endpoint(string url, Properties properties)
        {
            NetworkConfig.ReplaceNettyOptions(properties);

            logger.Trace($"Creating endpoint for url {url}");
            Url = url;
            string cn = null;
            string nt;

            byte[] pemBytes = null;
            var    purl     = Utils.ParseGrpcUrl(url);

            Protocol = purl.Protocol;
            Host     = purl.Host;
            Port     = purl.Port;
            if (properties != null)
            {
                ckp = new TLSCertificateKeyPair(properties);
                if ("grpcs".Equals(Protocol, StringComparison.InvariantCultureIgnoreCase))
                {
                    using (MemoryStream bis = new MemoryStream())
                    {
                        try
                        {
                            if (properties.Contains("pemBytes"))
                            {
                                bis.WriteAllBytes(properties["pemBytes"].ToBytes());
                            }
                            if (properties.Contains("pemFile"))
                            {
                                string   pemFile = properties["pemFile"];
                                Regex    r       = new Regex("[ \t]*,[ \t]*");
                                string[] pems    = r.Split(pemFile);

                                foreach (string pem in pems)
                                {
                                    if (!string.IsNullOrEmpty(pem))
                                    {
                                        try
                                        {
                                            bis.WriteAllBytes(File.ReadAllBytes(Path.GetFullPath(pem)));
                                        }
                                        catch (IOException)
                                        {
                                            throw new ArgumentException($"Failed to read certificate file {Path.GetFullPath(pem)}");
                                        }
                                    }
                                }
                            }

                            bis.Flush();
                            pemBytes = bis.ToArray();
                            logger.Trace($"Endpoint {url} pemBytes: {pemBytes.ToHexString()}");
                            if (pemBytes.Length == 0)
                            {
                                pemBytes = null;
                            }
                        }
                        catch (Exception e)
                        {
                            throw new Exception($"Failed to read CA certificates file {e}");
                        }
                    }

                    if (pemBytes == null)
                    {
                        logger.Warn($"Endpoint {url} is grpcs with no CA certificates");
                    }

                    if (null != pemBytes)
                    {
                        try
                        {
                            cn = properties.Contains("hostnameOverride") ?  properties["hostnameOverride"] : null;
                            bool trustsv = properties.Contains("trustServerCertificate") && (properties["trustServerCertificate"]).Equals("true", StringComparison.InvariantCultureIgnoreCase);
                            if (cn == null && trustsv)
                            {
                                string cnKey = pemBytes.ToUTF8String();
                                CN_CACHE.TryGetValue(cnKey, out cn);
                                if (cn == null)
                                {
                                    X509Certificate2 cert = Certificate.PEMToX509Certificate2(cnKey);
                                    cn = cert.GetNameInfo(X509NameType.DnsName, false);
                                    CN_CACHE.TryAdd(cnKey, cn);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            // Mostly a development env. just log it.
                            logger.Error("Error getting Subject CN from certificate. Try setting it specifically with hostnameOverride property. " + e);
                        }
                    }

                    nt = null;
                    if (properties.Contains("negotiationType"))
                    {
                        nt = properties["negotiationType"];
                    }
                    if (null == nt)
                    {
                        nt = SSLNEGOTIATION;
                        logger.Trace($"Endpoint {url} specific Negotiation type not found use global value: {SSLNEGOTIATION}");
                    }

                    if (!"TLS".Equals(nt, StringComparison.InvariantCultureIgnoreCase) && !"plainText".Equals(nt, StringComparison.InvariantCultureIgnoreCase))
                    {
                        throw new ArgumentException($"Endpoint {url} property of negotiationType has to be either TLS or plainText. value:'{nt}'");
                    }
                }
            }

            try
            {
                List <ChannelOption> options = new List <ChannelOption>();
                if (properties != null)
                {
                    foreach (string str in properties.Keys)
                    {
                        if (str.StartsWith("grpc."))
                        {
                            if (int.TryParse(properties[str], out int value))
                            {
                                options.Add(new ChannelOption(str, value));
                            }
                            else
                            {
                                options.Add(new ChannelOption(str, properties[str]));
                            }
                        }
                    }
                }

                if (Protocol.Equals("grpc", StringComparison.InvariantCultureIgnoreCase))
                {
                    ChannelOptions = options;
                    Credentials    = null;
                }
                else if (Protocol.Equals("grpcs", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (pemBytes == null)
                    {
                        // use root certificate
                        ChannelOptions = options;
                        Credentials    = null;
                    }
                    else
                    {
                        if (ckp != null && ckp.CertPEMBytes != null && ckp.KeyPEMBytes != null)
                        {
                            creds = new SslCredentials(pemBytes.ToUTF8String(), new KeyCertificatePair(ckp.CertPEMBytes.ToUTF8String(), ckp.KeyPEMBytes.ToUTF8String()));
                        }
                        else
                        {
                            creds = new SslCredentials(pemBytes.ToUTF8String());
                        }
                        if (cn != null)
                        {
                            options.Add(new ChannelOption("grpc.ssl_target_name_override", cn));
                        }
                        Credentials    = creds;
                        ChannelOptions = options;
                        logger.Trace($"Endpoint {url} final server pemBytes: {pemBytes.ToHexString()}");
                    }
                }
                else
                {
                    throw new ArgumentException("invalid protocol: " + Protocol);
                }
            }
            catch (Exception e)
            {
                logger.ErrorException($"Endpoint {url}, exception '{e.Message}'", e);
                throw;
            }
        }