package main import ( "log" "net" "time" "crypto/tls" "crypto/x509" "io/ioutil" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/reflection" ) var ( port = ":5000" ca = "./ca.cer" server_crt = "./server.cer" server_key = "./server_pri.key" client_crt = "./client.cer" client_key = "./client_pri.key" ) type server struct{} func (s *server) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) { return &HelloReply{Message: "Hello " + in.Name}, nil } func main() { go startServer() time.Sleep(time.Second) doClientWork() } func startServer() { // Load the certificates from disk certificate, err := tls.LoadX509KeyPair(server_crt, server_key) if err != nil { log.Panicf("could not load server key pair: %s", err) } // Create a certificate pool from the certificate authority certPool := x509.NewCertPool() ca, err := ioutil.ReadFile(ca) if err != nil { log.Panicf("could not read ca certificate: %s", err) } // Append the client certificates from the CA if ok := certPool.AppendCertsFromPEM(ca); !ok { log.Panic("failed to append client certs") } // Create the channel to listen on lis, err := net.Listen("tcp", port) if err != nil { log.Panicf("could not list on %s: %s", port, err) } // Create the TLS credentials creds := credentials.NewTLS(&tls.Config{ ClientAuth: tls.RequireAndVerifyClientCert, Certificates: []tls.Certificate{certificate}, ClientCAs: certPool, }) // Create the gRPC server with the credentials s := grpc.NewServer(grpc.Creds(creds)) // Register the handler object RegisterGreeterServer(s, &server{}) // Serve and Listen if err := s.Serve(lis); err != nil { log.Panicf("grpc serve error: %s", err) } // Register reflection service on gRPC server. reflection.Register(s) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } func doClientWork() { certificate, err := tls.LoadX509KeyPair(client_crt, client_key) if err != nil { log.Panicf("could not load client key pair: %s", err) } // Create a certificate pool from the certificate authority certPool := x509.NewCertPool() ca, err := ioutil.ReadFile(ca) if err != nil { log.Panicf("could not read ca certificate: %s", err) } // Append the certificates from the CA if ok := certPool.AppendCertsFromPEM(ca); !ok { log.Panic("failed to append ca certs") } creds := credentials.NewTLS(&tls.Config{ ServerName: "server", // NOTE: this is required! Certificates: []tls.Certificate{certificate}, RootCAs: certPool, }) // Create a connection with the TLS credentials conn, err := grpc.Dial("localhost"+port, grpc.WithTransportCredentials(creds)) if err != nil { log.Fatal(err) } defer conn.Close() c := NewGreeterClient(conn) r, err := c.SayHello(context.Background(), &HelloRequest{Name: "gopher"}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("doClientWork: %s", r.Message) }