From f94e37f299305ddffb114b75c4e51bcf8d2f9611 Mon Sep 17 00:00:00 2001 From: Urko Date: Mon, 6 Mar 2023 17:31:30 +0100 Subject: [PATCH] test --- credentials.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 credentials.go diff --git a/credentials.go b/credentials.go new file mode 100644 index 0000000..2ac759d --- /dev/null +++ b/credentials.go @@ -0,0 +1,73 @@ +package credentials + +import ( + "crypto/tls" + "encoding/pem" + "errors" + "fmt" + "os" + "os/exec" + "strings" + + "google.golang.org/grpc/credentials" +) + +func CredentialsFromKeyWithPasswd(certFile, certKey, passwd string) (credentials.TransportCredentials, error) { + if certFile == "" { + return nil, errors.New("certFile cannot be empty") + } + if certKey == "" { + return nil, errors.New("certKey cannot be empty") + } + + bts, err := os.ReadFile(certKey) + if err != nil { + return nil, fmt.Errorf("os.ReadFile certKey: %s", err) + } + + keyBlock, rest := pem.Decode(bts) + if keyBlock == nil { + return nil, errors.New("not valid pem file") + } + if len(rest) > 0 { + return nil, errors.New("rest is not empty") + } + + if !strings.Contains(keyBlock.Type, "ENCRYPTED") { + return nil, fmt.Errorf("certificate should has been encrypted with password") + } + + decriptedKeyPem, err := decryptRSA(certKey, passwd) + if err != nil { + return nil, fmt.Errorf("decryptRSA: %s", err) + } + + bts, err = os.ReadFile(certFile) + if err != nil { + return nil, fmt.Errorf("os.ReadFile certFile: %s", err) + } + cert, err := tls.X509KeyPair(bts, []byte(decriptedKeyPem)) + if err != nil { + return nil, fmt.Errorf("tls.X509KeyPair: %s", err) + } + + return credentials.NewServerTLSFromCert(&cert), nil +} + +func decryptRSA(keyFile, password string) (string, error) { + cmd := exec.Command("openssl", "rsa", "-in", keyFile, "-passin", formatPass(password), "-text") + output_bts, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("cmd.Output: %s", err) + } + + idx := strings.Index(string(output_bts), "-----BEGIN") + return string(output_bts)[idx:], nil +} + +func formatPass(password string) string { + if password == "" { + return "" + } + return "pass:" + password +}