There doesnt' seem to be an easy to acquire the ExportKeyingMaterial before the RPC is invoked and after the TLS session is established. It looks like the only way to get the EKM and easily invoke the RPC is after the rpc is completed and when the grpc.peeris visible
I know its possible with go and http clients as shown here but what i want to do is use the EKM value for the TLS connection to synthesize a bearer token that is bound to that TLS channel and then invoke the rpc.
The only way i could do that is to dial TLS, get the EKM and then invoke the rpc with that same conn (which is TLS), but set it as if its insecure...that doens't look clean at all
sconn, err := grpc.Dial(*address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
return conn, nil
}))
Any ideas on how i can improve on this?
thansk
package main
import (
"crypto/tls"
"crypto/x509"
"encoding/hex"
"flag"
"fmt"
"net"
"os"
"time"
echo "github.com/salrashid123/example/echo"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/peer"
)
const ()
var (
conn *grpc.ClientConn
)
func main() {
address := flag.String("host", "localhost:50051", "host:port of gRPC server")
serverName := flag.String("servername", "server.domain.com", "servername")
tlsCert := flag.String("tlsCert", "../certs/root-ca.crt", "CACert for server")
flag.Parse()
var err error
rootCAs := x509.NewCertPool()
pem, err := os.ReadFile(*tlsCert)
if err != nil {
fmt.Printf("failed to load root CA certificates error=%v", err)
os.Exit(1)
}
if !rootCAs.AppendCertsFromPEM(pem) {
fmt.Printf("no root CA certs parsed from file ")
os.Exit(1)
}
tlsCfg := &tls.Config{
ServerName: *serverName,
RootCAs: rootCAs,
}
// create connection get its EKM
conn, err := tls.Dial("tcp", *address, tlsCfg)
if err != nil {
fmt.Printf("Error dialing %v\n", err)
return
}
cs := conn.ConnectionState()
sekm, err := cs.ExportKeyingMaterial("EXPORTER-my_label", []byte("mycontext"), 32)
if err != nil {
fmt.Printf("Error getting ekm %v\n", err)
return
}
fmt.Printf("EKM EXPORTER-my_label: %s\n", hex.EncodeToString(sekm))
// now connect to the actual server and try to get the EKM
//ce := credentials.NewTLS(tlsCfg)
sconn, err := grpc.Dial(*address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
return conn, nil
}))
// sconn, err := grpc.Dial(*address, grpc.WithTransportCredentials(ce), grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
// return conn, nil
// }))
//sconn, err := grpc.Dial(*address, grpc.WithTransportCredentials(ce))
if err != nil {
fmt.Printf("did not connect: %v", err)
os.Exit(1)
}
defer sconn.Close()
c := echo.NewEchoServerClient(sconn)
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()
pr := new(peer.Peer)
r, err := c.SayHello(ctx, &echo.EchoRequest{Name: "unary RPC msg "}, grpc.Peer(pr))
if err != nil {
fmt.Printf("could not greet: %v", err)
os.Exit(1)
}
fmt.Println(r.Message)
// switch info := pr.AuthInfo.(type) {
// case credentials.TLSInfo:
// authType := info.AuthType()
// sn := info.State.ServerName
// fmt.Printf("AuthType, ServerName %s, %s\n", authType, sn)
// tlsInfo, ok := pr.AuthInfo.(credentials.TLSInfo)
// if !ok {
// fmt.Printf("ERROR: Could get remote TLS")
// os.Exit(1)
// }
// ekm, err := tlsInfo.State.ExportKeyingMaterial("EXPORTER-my_label", []byte("mycontext"), 32)
// if err != nil {
// fmt.Printf("ERROR: Could getting EKM %v", err)
// os.Exit(1)
// }
// fmt.Printf("EKM EXPORTER-my_label: %s\n", hex.EncodeToString(ekm))
// default:
// fmt.Printf("Unknown AuthInfo type %v", info)
// os.Exit(1)
// }
// fmt.Println("return")
}
for ref:
There doesnt' seem to be an easy to acquire the ExportKeyingMaterial before the RPC is invoked and after the TLS session is established. It looks like the only way to get the EKM and easily invoke the RPC is after the rpc is completed and when the grpc.peeris visible
I know its possible with go and http clients as shown here but what i want to do is use the EKM value for the TLS connection to synthesize a bearer token that is bound to that TLS channel and then invoke the rpc.
The only way i could do that is to dial TLS, get the EKM and then invoke the rpc with that same conn (which is TLS), but set it as if its insecure...that doens't look clean at all
Any ideas on how i can improve on this?
thansk
for ref:
https://github.com/salrashid123/go_ekm_tls
google.golang.org/grpc v1.60.1go version go1.26.2 linux/amd64