From 95fbe59fd21065701089be727947e1a6e1832bce Mon Sep 17 00:00:00 2001 From: wangtiga Date: Sat, 11 Nov 2023 22:40:57 +0800 Subject: [PATCH 1/9] support p12 certificate format, add param -cert-type and -pass --- .gitignore | 1 + cmd/grpcurl/grpcurl.go | 39 +++++++++++++++++++++++++++++---- go.mod | 3 ++- go.sum | 7 ++---- grpcurl.go | 49 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 88 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 3a2f7da..1386dbb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ dist/ .idea/ VERSION .tmp/ +*.swp diff --git a/cmd/grpcurl/grpcurl.go b/cmd/grpcurl/grpcurl.go index 6ef517b..6b52117 100644 --- a/cmd/grpcurl/grpcurl.go +++ b/cmd/grpcurl/grpcurl.go @@ -66,7 +66,13 @@ var ( Ignored if -insecure is specified.`)) cert = flags.String("cert", "", prettify(` File containing client certificate (public key), to present to the - server. Not valid with -plaintext option. Must also provide -key option.`)) + server. Not valid with -plaintext option. Must also provide -key option + when use PEM certificate file.`)) + certTypeString = flags.String("cert-type", "", prettify(` + Client certificate file type. (PEM/P12)`)) + certType = grpcurl.CertTypePEM + pass = flags.String("pass", "", prettify(` + Pass phrase for the key`)) key = flags.String("key", "", prettify(` File containing client private key, to present to the server. Not valid with -plaintext option. Must also provide -cert option.`)) @@ -289,6 +295,17 @@ func main() { // default behavior is to use tls usetls := !*plaintext && !*usealts + // converto to CertificateFileType + if len(*certTypeString) == 0 { + certType = grpcurl.CertTypePEM // default PEM + } else if strings.EqualFold(*certTypeString, "PEM") { + certType = grpcurl.CertTypePEM + } else if strings.EqualFold(*certTypeString, "P12") { + certType = grpcurl.CertTypeP12 + } else { + fail(nil, "The -cert-type argument must be PEM or P12.") + } + // Do extra validation on arguments and figure out what user asked us to do. if *connectTimeout < 0 { fail(nil, "The -connect-timeout argument must not be negative.") @@ -314,9 +331,23 @@ func main() { if *key != "" && !usetls { fail(nil, "The -key argument can only be used with TLS.") } - if (*key == "") != (*cert == "") { - fail(nil, "The -cert and -key arguments must be used together and both be present.") + + switch certType { + case grpcurl.CertTypePEM: + if (*key == "") != (*cert == "") { + fail(nil, "The -cert and -key arguments must be used together and both be present when -cert-type is PEM.") + } + case grpcurl.CertTypeP12: + if *key != "" { + fail(nil, "The -key arguments must not be used when -cert-type is P12.") + } + if *cert == "" { + fail(nil, "The -cert arguments must be used when -cert-type is P12.") + } + default: + fail(nil, "Not support cert type %v.", certType) } + if *altsHandshakerServiceAddress != "" && !*usealts { fail(nil, "The -alts-handshaker-service argument must be used with the -alts argument.") } @@ -451,7 +482,7 @@ func main() { } creds = alts.NewClientCreds(clientOptions) } else if usetls { - tlsConf, err := grpcurl.ClientTLSConfig(*insecure, *cacert, *cert, *key) + tlsConf, err := grpcurl.ClientTLSConfigV2(*insecure, *cacert, *cert, *key, certType, *pass) if err != nil { fail(err, "Failed to create TLS config") } diff --git a/go.mod b/go.mod index 2b6dac4..2348612 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,8 @@ go 1.18 require ( github.com/golang/protobuf v1.5.3 github.com/jhump/protoreflect v1.15.3 - google.golang.org/grpc v1.57.1 + golang.org/x/crypto v0.14.0 + google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 ) diff --git a/go.sum b/go.sum index f1bc045..9bd231e 100644 --- a/go.sum +++ b/go.sum @@ -25,7 +25,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -37,20 +36,18 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/grpcurl.go b/grpcurl.go index 6010b3a..1ef06d2 100644 --- a/grpcurl.go +++ b/grpcurl.go @@ -12,6 +12,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/base64" + "encoding/pem" "errors" "fmt" "io/ioutil" @@ -25,6 +26,7 @@ import ( "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/desc/protoprint" "github.com/jhump/protoreflect/dynamic" + "golang.org/x/crypto/pkcs12" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -523,16 +525,40 @@ func ClientTransportCredentials(insecureSkipVerify bool, cacertFile, clientCertF return credentials.NewTLS(tlsConf), nil } +type CertificateType int + +const ( + // The certificate file contains PEM encoded data + CertTypePEM CertificateType = 1 + // The certificate file contains PFX data describing PKCS#12. + CertTypeP12 CertificateType = 2 +) + // ClientTLSConfig builds transport-layer config for a gRPC client using the // given properties. If cacertFile is blank, only standard trusted certs are used to // verify the server certs. If clientCertFile is blank, the client will not use a client // certificate. If clientCertFile is not blank then clientKeyFile must not be blank. func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile string) (*tls.Config, error) { + return ClientTLSConfigV2(insecureSkipVerify, cacertFile, clientCertFile, clientKeyFile, CertTypePEM, "") +} + +// ClientTLSConfigV2 builds transport-layer config for a gRPC client using the +// given properties. Support certificate file both PEM and P12. +func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile string, clientCertType CertificateType, clientPass string) (*tls.Config, error) { var tlsConf tls.Config if clientCertFile != "" { // Load the client certificates from disk - certificate, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile) + var certificate tls.Certificate + var err error + switch clientCertType { + case CertTypeP12: + certificate, err = loadClientCertP12(clientCertFile, clientPass) + case CertTypePEM: + certificate, err = tls.LoadX509KeyPair(clientCertFile, clientKeyFile) + default: + return nil, fmt.Errorf("not support client certificate type: %v", clientCertType) + } if err != nil { return nil, fmt.Errorf("could not load client key pair: %v", err) } @@ -560,6 +586,27 @@ func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, client return &tlsConf, nil } +func loadClientCertP12(pfxFile, pfxPassword string) (tls.Certificate, error) { + b, err := os.ReadFile(pfxFile) + if err != nil { + return tls.Certificate{}, fmt.Errorf("os.ReadFile err: %w", err) + } + pemBlocks, err := pkcs12.ToPEM(b, pfxPassword) + if err != nil { + return tls.Certificate{}, fmt.Errorf("pkcs12.ToPEM err: %w", err) + } + + var pemBytes []byte + for _, block := range pemBlocks { + pemBytes = append(pemBytes, pem.EncodeToMemory(block)...) + } + certificate, err := tls.X509KeyPair(pemBytes, pemBytes) + if err != nil { + return tls.Certificate{}, err + } + return certificate, nil +} + // ServerTransportCredentials builds transport credentials for a gRPC server using the // given properties. If cacertFile is blank, the server will not request client certs // unless requireClientCerts is true. When requireClientCerts is false and cacertFile is From 8060fffba35d1c61014b50eea19b586f39a4ef4b Mon Sep 17 00:00:00 2001 From: wangtiga Date: Thu, 26 Oct 2023 23:27:41 +0800 Subject: [PATCH 2/9] guess cert format --- cmd/grpcurl/grpcurl.go | 50 ++-- go.mod | 18 ++ go.sum | 60 +++++ grpcurl.go | 47 +++- internal/certigo/lib/certs.go | 425 ++++++++++++++++++++++++++++++++++ 5 files changed, 566 insertions(+), 34 deletions(-) create mode 100644 internal/certigo/lib/certs.go diff --git a/cmd/grpcurl/grpcurl.go b/cmd/grpcurl/grpcurl.go index 6b52117..cf5ae0d 100644 --- a/cmd/grpcurl/grpcurl.go +++ b/cmd/grpcurl/grpcurl.go @@ -295,16 +295,16 @@ func main() { // default behavior is to use tls usetls := !*plaintext && !*usealts - // converto to CertificateFileType - if len(*certTypeString) == 0 { - certType = grpcurl.CertTypePEM // default PEM - } else if strings.EqualFold(*certTypeString, "PEM") { - certType = grpcurl.CertTypePEM - } else if strings.EqualFold(*certTypeString, "P12") { - certType = grpcurl.CertTypeP12 - } else { - fail(nil, "The -cert-type argument must be PEM or P12.") - } + //// converto to CertificateFileType + //if len(*certTypeString) == 0 { + // certType = grpcurl.CertTypePEM // default PEM + //} else if strings.EqualFold(*certTypeString, "PEM") { + // certType = grpcurl.CertTypePEM + //} else if strings.EqualFold(*certTypeString, "P12") { + // certType = grpcurl.CertTypeP12 + //} else { + // fail(nil, "The -cert-type argument must be PEM or P12.") + //} // Do extra validation on arguments and figure out what user asked us to do. if *connectTimeout < 0 { @@ -332,21 +332,21 @@ func main() { fail(nil, "The -key argument can only be used with TLS.") } - switch certType { - case grpcurl.CertTypePEM: - if (*key == "") != (*cert == "") { - fail(nil, "The -cert and -key arguments must be used together and both be present when -cert-type is PEM.") - } - case grpcurl.CertTypeP12: - if *key != "" { - fail(nil, "The -key arguments must not be used when -cert-type is P12.") - } - if *cert == "" { - fail(nil, "The -cert arguments must be used when -cert-type is P12.") - } - default: - fail(nil, "Not support cert type %v.", certType) - } + //switch certType { + //case grpcurl.CertTypePEM: + // if (*key == "") != (*cert == "") { + // fail(nil, "The -cert and -key arguments must be used together and both be present when -cert-type is PEM.") + // } + //case grpcurl.CertTypeP12: + // if *key != "" { + // fail(nil, "The -key arguments must not be used when -cert-type is P12.") + // } + // if *cert == "" { + // fail(nil, "The -cert arguments must be used when -cert-type is P12.") + // } + //default: + // fail(nil, "Not support cert type %v.", certType) + //} if *altsHandshakerServiceAddress != "" && !*usealts { fail(nil, "The -alts-handshaker-service argument must be used with the -alts argument.") diff --git a/go.mod b/go.mod index 2348612..e62bec7 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require ( github.com/golang/protobuf v1.5.3 github.com/jhump/protoreflect v1.15.3 + github.com/square/certigo v1.16.0 golang.org/x/crypto v0.14.0 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 @@ -13,6 +14,11 @@ require ( require ( cloud.google.com/go/compute v1.19.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/Masterminds/goutils v1.1.0 // indirect + github.com/Masterminds/semver v1.4.2 // indirect + github.com/Masterminds/sprig v2.22.0+incompatible // indirect + github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect + github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/bufbuild/protocompile v0.6.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -20,13 +26,25 @@ require ( github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f // indirect github.com/envoyproxy/protoc-gen-validate v0.10.1 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/huandu/xstrings v1.2.0 // indirect + github.com/imdario/mergo v0.3.6 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mitchellh/copystructure v1.0.0 // indirect + github.com/mitchellh/reflectwalk v1.0.0 // indirect + github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect + gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect + gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225 // indirect ) diff --git a/go.sum b/go.sum index 9bd231e..549042a 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,16 @@ cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IK cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -17,13 +27,17 @@ github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -35,13 +49,39 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 h1:BhQQWYKJwXPtAhm12d4gQU4LKS9Yov22yOrDc2QA7ho= +github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8/go.mod h1:ntWhh7pzdiiRKBMxUB5iG+Q2gmZBxGxpX1KyK6N8kX8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/square/certigo v1.16.0 h1:8g9UgWssUcOMzeFJF0nSMGjmDVXBk6UTZNOMArxcrxM= +github.com/square/certigo v1.16.0/go.mod h1:v9HqynkvfNbHR0aluXlxutyGsZbUpiNACLkYpHyxRlU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -53,6 +93,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -65,10 +106,21 @@ golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -98,6 +150,14 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225 h1:JBwmEvLfCqgPcIq8MjVMQxsF3LVL4XG/HH0qiG0+IFY= +gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/grpcurl.go b/grpcurl.go index 1ef06d2..d852cdc 100644 --- a/grpcurl.go +++ b/grpcurl.go @@ -22,6 +22,7 @@ import ( "sort" "strings" + "github.com/fullstorydev/grpcurl/internal/certigo/lib" "github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/desc/protoprint" @@ -549,16 +550,29 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile, clientCertFile, clie if clientCertFile != "" { // Load the client certificates from disk - var certificate tls.Certificate - var err error - switch clientCertType { - case CertTypeP12: - certificate, err = loadClientCertP12(clientCertFile, clientPass) - case CertTypePEM: - certificate, err = tls.LoadX509KeyPair(clientCertFile, clientKeyFile) - default: - return nil, fmt.Errorf("not support client certificate type: %v", clientCertType) + clientCertFormat := "" + var pemBuf bytes.Buffer + err := lib.ReadAsPEMEx(clientCertFile, clientCertFormat, clientPass, func(block *pem.Block, format string) error { + return pem.Encode(&pemBuf, block) + }) + if err != nil { + return nil, fmt.Errorf("could not load client cert: %v", err) } + pemBytes := pemBuf.Bytes() + pemKeyBytes := pemBytes + + if clientKeyFile != "" { + var pemKeyBuf bytes.Buffer + err := lib.ReadAsPEMEx(clientKeyFile, clientCertFormat, clientPass, func(block *pem.Block, format string) error { + return pem.Encode(&pemKeyBuf, block) + }) + if err != nil { + return nil, fmt.Errorf("could not load client key: %v", err) + } + pemKeyBytes = pemKeyBuf.Bytes() + } + + certificate, err := tls.X509KeyPair(pemBytes, pemKeyBytes) if err != nil { return nil, fmt.Errorf("could not load client key pair: %v", err) } @@ -586,6 +600,21 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile, clientCertFile, clie return &tlsConf, nil } +func inputFiles(fileNames []string) ([]*os.File, error) { + var files []*os.File + for _, filename := range fileNames { + if filename == "" { + continue + } + rawFile, err := os.Open(filename) + if err != nil { + return nil, fmt.Errorf("unable to open file: %s\n", err) + } + files = append(files, rawFile) + } + return files, nil +} + func loadClientCertP12(pfxFile, pfxPassword string) (tls.Certificate, error) { b, err := os.ReadFile(pfxFile) if err != nil { diff --git a/internal/certigo/lib/certs.go b/internal/certigo/lib/certs.go new file mode 100644 index 0000000..e21e7c1 --- /dev/null +++ b/internal/certigo/lib/certs.go @@ -0,0 +1,425 @@ +/*- + * Copyright 2016 Square Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package lib + +import ( + "bufio" + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/x509" + "encoding/binary" + "encoding/pem" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "reflect" + "strings" + + "github.com/square/certigo/jceks" + "github.com/square/certigo/pkcs7" + "golang.org/x/crypto/pkcs12" +) + +const ( + // nameHeader is the PEM header field for the friendly name/alias of the key in the key store. + nameHeader = "friendlyName" + + // fileHeader is the origin file where the key came from (as in file on disk). + fileHeader = "originFile" +) + +var fileExtToFormat = map[string]string{ + ".pem": "PEM", + ".crt": "PEM", + ".p7b": "PEM", + ".p7c": "PEM", + ".p12": "PKCS12", + ".pfx": "PKCS12", + ".jceks": "JCEKS", + ".jks": "JCEKS", // Only partially supported + ".der": "DER", +} + +var badSignatureAlgorithms = [...]x509.SignatureAlgorithm{ + x509.MD2WithRSA, + x509.MD5WithRSA, + x509.SHA1WithRSA, + x509.DSAWithSHA1, + x509.ECDSAWithSHA1, +} + +func errorFromErrors(errs []error) error { + if len(errs) == 0 { + return nil + } + if len(errs) == 1 { + return errs[0] + } + buffer := new(bytes.Buffer) + buffer.WriteString("encountered multiple errors:\n") + for _, err := range errs { + buffer.WriteString("* ") + buffer.WriteString(strings.TrimSuffix(err.Error(), "\n")) + buffer.WriteString("\n") + } + return errors.New(buffer.String()) +} + +// ReadAsPEMFromFiles will read PEM blocks from the given set of inputs. Input +// data may be in plain-text PEM files, DER-encoded certificates or PKCS7 +// envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to PEM +// blocks and passed to the callback. +func ReadAsPEMFromFiles(files []*os.File, format string, password func(string) string, callback func(*pem.Block, string) error) error { + var errs []error + for _, file := range files { + reader := bufio.NewReaderSize(file, 4) + format, err := formatForFile(reader, file.Name(), format) + if err != nil { + return fmt.Errorf("unable to guess file type for file %s", file.Name()) + } + + err = readCertsFromStream(reader, file.Name(), format, password, callback) + if err != nil { + errs = append(errs, err) + } + } + return errorFromErrors(errs) +} + +func ReadAsPEMEx(filename string, format string, password string, callback func(*pem.Block, string) error) error { + rawFile, err := os.Open(filename) + if err != nil { + return fmt.Errorf("unable to open file: %s\n", err) + } + defer rawFile.Close() + passwordFunc := func(promet string) string { + return password + } + return ReadAsPEM([]io.Reader{rawFile}, format, passwordFunc, callback) +} + +// ReadAsPEM will read PEM blocks from the given set of inputs. Input data may +// be in plain-text PEM files, DER-encoded certificates or PKCS7 envelopes, or +// PKCS12/JCEKS keystores. All inputs will be converted to PEM blocks and +// passed to the callback. +func ReadAsPEM(readers []io.Reader, format string, password func(string) string, callback func(*pem.Block, string) error) error { + errs := []error{} + for _, r := range readers { + reader := bufio.NewReaderSize(r, 4) + format, err := formatForFile(reader, "", format) + if err != nil { + return fmt.Errorf("unable to guess format for input stream") + } + + err = readCertsFromStream(reader, "", format, password, callback) + if err != nil { + errs = append(errs, err) + } + } + return errorFromErrors(errs) +} + +// ReadAsX509FromFiles will read X.509 certificates from the given set of +// inputs. Input data may be in plain-text PEM files, DER-encoded certificates +// or PKCS7 envelopes, or PKCS12/JCEKS keystores. All inputs will be converted +// to X.509 certificates (private keys are skipped) and passed to the callback. +func ReadAsX509FromFiles(files []*os.File, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error { + errs := []error{} + for _, file := range files { + reader := bufio.NewReaderSize(file, 4) + format, err := formatForFile(reader, file.Name(), format) + if err != nil { + return fmt.Errorf("unable to guess file type for file %s, try adding --format flag", file.Name()) + } + + err = readCertsFromStream(reader, file.Name(), format, password, pemToX509(callback)) + if err != nil { + errs = append(errs, err) + } + } + return errorFromErrors(errs) +} + +// ReadAsX509 will read X.509 certificates from the given set of inputs. Input +// data may be in plain-text PEM files, DER-encoded certificates or PKCS7 +// envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to X.509 +// certificates (private keys are skipped) and passed to the callback. +func ReadAsX509(readers []io.Reader, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error { + errs := []error{} + for _, r := range readers { + reader := bufio.NewReaderSize(r, 4) + format, err := formatForFile(reader, "", format) + if err != nil { + return fmt.Errorf("unable to guess format for input stream") + } + + err = readCertsFromStream(reader, "", format, password, pemToX509(callback)) + if err != nil { + errs = append(errs, err) + } + } + return errorFromErrors(errs) +} + +func pemToX509(callback func(*x509.Certificate, string, error) error) func(*pem.Block, string) error { + return func(block *pem.Block, format string) error { + switch block.Type { + case "CERTIFICATE": + cert, err := x509.ParseCertificate(block.Bytes) + return callback(cert, format, err) + case "PKCS7": + certs, err := pkcs7.ExtractCertificates(block.Bytes) + if err == nil { + for _, cert := range certs { + return callback(cert, format, nil) + } + } else { + return callback(nil, format, err) + } + case "CERTIFICATE REQUEST": + fmt.Println("warning: certificate requests are not supported") + } + return nil + } +} + +func ReadCertsFromStream(reader io.Reader, filename string, format string, password string, callback func(*pem.Block, string) error) error { + passwordFunc := func(promet string) string { + return password + } + return readCertsFromStream(reader, filename, format, passwordFunc, callback) +} + +// readCertsFromStream takes some input and converts it to PEM blocks. +func readCertsFromStream(reader io.Reader, filename string, format string, password func(string) string, callback func(*pem.Block, string) error) error { + headers := map[string]string{} + if filename != "" && filename != os.Stdin.Name() { + headers[fileHeader] = filename + } + + format = strings.TrimSpace(format) + switch format { + case "PEM": + scanner := pemScanner(reader) + for scanner.Scan() { + block, _ := pem.Decode(scanner.Bytes()) + block.Headers = mergeHeaders(block.Headers, headers) + err := callback(block, format) + if err != nil { + return err + } + } + return nil + case "DER": + data, err := ioutil.ReadAll(reader) + if err != nil { + return fmt.Errorf("unable to read input: %s\n", err) + } + x509Certs, err0 := x509.ParseCertificates(data) + if err0 == nil { + for _, cert := range x509Certs { + err := callback(EncodeX509ToPEM(cert, headers), format) + if err != nil { + return err + } + } + return nil + } + p7bBlocks, err1 := pkcs7.ParseSignedData(data) + if err1 == nil { + for _, block := range p7bBlocks { + err := callback(pkcs7ToPem(block, headers), format) + if err != nil { + return err + } + } + return nil + } + return fmt.Errorf("unable to parse certificates from DER data\n* X.509 parser gave: %s\n* PKCS7 parser gave: %s\n", err0, err1) + case "PKCS12": + data, err := ioutil.ReadAll(reader) + if err != nil { + return fmt.Errorf("unable to read input: %s\n", err) + } + blocks, err := pkcs12.ToPEM(data, password("")) + if err != nil || len(blocks) == 0 { + return fmt.Errorf("keystore appears to be empty or password was incorrect\n") + } + for _, block := range blocks { + block.Headers = mergeHeaders(block.Headers, headers) + err := callback(block, format) + if err != nil { + return err + } + } + return nil + case "JCEKS": + keyStore, err := jceks.LoadFromReader(reader, []byte(password(""))) + if err != nil { + return fmt.Errorf("unable to parse keystore: %s\n", err) + } + for _, alias := range keyStore.ListCerts() { + cert, _ := keyStore.GetCert(alias) + err := callback(EncodeX509ToPEM(cert, mergeHeaders(headers, map[string]string{nameHeader: alias})), format) + if err != nil { + return err + } + } + for _, alias := range keyStore.ListPrivateKeys() { + key, certs, err := keyStore.GetPrivateKeyAndCerts(alias, []byte(password(alias))) + if err != nil { + return fmt.Errorf("unable to parse keystore: %s\n", err) + } + + mergedHeaders := mergeHeaders(headers, map[string]string{nameHeader: alias}) + + block, err := keyToPem(key, mergedHeaders) + if err != nil { + return fmt.Errorf("problem reading key: %s\n", err) + } + + if err := callback(block, format); err != nil { + return err + } + + for _, cert := range certs { + if err = callback(EncodeX509ToPEM(cert, mergedHeaders), format); err != nil { + return err + } + } + } + return nil + } + return fmt.Errorf("unknown file type '%s'\n", format) +} + +func mergeHeaders(baseHeaders, extraHeaders map[string]string) (headers map[string]string) { + headers = map[string]string{} + for k, v := range baseHeaders { + headers[k] = v + } + for k, v := range extraHeaders { + headers[k] = v + } + return +} + +// EncodeX509ToPEM converts an X.509 certificate into a PEM block for output. +func EncodeX509ToPEM(cert *x509.Certificate, headers map[string]string) *pem.Block { + return &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert.Raw, + Headers: headers, + } +} + +// Convert a PKCS7 envelope into a PEM block for output. +func pkcs7ToPem(block *pkcs7.SignedDataEnvelope, headers map[string]string) *pem.Block { + return &pem.Block{ + Type: "PKCS7", + Bytes: block.Raw, + Headers: headers, + } +} + +// Convert a key into one or more PEM blocks for output. +func keyToPem(key crypto.PrivateKey, headers map[string]string) (*pem.Block, error) { + switch k := key.(type) { + case *rsa.PrivateKey: + return &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(k), + Headers: headers, + }, nil + case *ecdsa.PrivateKey: + raw, err := x509.MarshalECPrivateKey(k) + if err != nil { + return nil, fmt.Errorf("error marshaling key: %s\n", reflect.TypeOf(key)) + } + return &pem.Block{ + Type: "EC PRIVATE KEY", + Bytes: raw, + Headers: headers, + }, nil + } + return nil, fmt.Errorf("unknown key type: %s\n", reflect.TypeOf(key)) +} + +// formatForFile returns the file format (either from flags or +// based on file extension). +func formatForFile(file *bufio.Reader, filename, format string) (string, error) { + // First, honor --format flag we got from user + if format != "" { + return format, nil + } + + // Second, attempt to guess based on extension + guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))] + if ok { + return guess, nil + } + + // Third, attempt to guess based on first 4 bytes of input + data, err := file.Peek(4) + if err != nil { + return "", fmt.Errorf("unable to read file: %s\n", err) + } + + // Heuristics for guessing -- best effort. + magic := binary.BigEndian.Uint32(data) + if magic == 0xCECECECE || magic == 0xFEEDFEED { + // JCEKS/JKS files always start with this prefix + return "JCEKS", nil + } + if magic == 0x2D2D2D2D || magic == 0x434f4e4e { + // Starts with '----' or 'CONN' (what s_client prints...) + return "PEM", nil + } + if magic&0xFFFF0000 == 0x30820000 { + // Looks like the input is DER-encoded, so it's either PKCS12 or X.509. + if magic&0x0000FF00 == 0x0300 { + // Probably X.509 + return "DER", nil + } + return "PKCS12", nil + } + + return "", fmt.Errorf("unable to guess file format") +} + +// pemScanner will return a bufio.Scanner that splits the input +// from the given reader into PEM blocks. +func pemScanner(reader io.Reader) *bufio.Scanner { + scanner := bufio.NewScanner(reader) + + scanner.Split(func(data []byte, atEOF bool) (int, []byte, error) { + block, rest := pem.Decode(data) + if block != nil { + size := len(data) - len(rest) + return size, data[:size], nil + } + + return 0, nil, nil + }) + + return scanner +} From 6f4f86da79025f5e8d9f394e95e7db1778a10415 Mon Sep 17 00:00:00 2001 From: wangtiga Date: Thu, 9 Nov 2023 23:29:44 +0800 Subject: [PATCH 3/9] tidy code not finished yet --- cmd/grpcurl/grpcurl.go | 100 +++++++--- grpcurl.go | 68 +------ internal/certigo/lib/certs.go | 361 +++++++++++++++++++++++++--------- 3 files changed, 335 insertions(+), 194 deletions(-) diff --git a/cmd/grpcurl/grpcurl.go b/cmd/grpcurl/grpcurl.go index cf5ae0d..6b0fbcf 100644 --- a/cmd/grpcurl/grpcurl.go +++ b/cmd/grpcurl/grpcurl.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "github.com/fullstorydev/grpcurl/internal/certigo/lib" "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/grpcreflect" "google.golang.org/grpc" @@ -64,18 +65,21 @@ var ( cacert = flags.String("cacert", "", prettify(` File containing trusted root certificates for verifying the server. Ignored if -insecure is specified.`)) + pCACertFormat = flags.String("cacert-format", string(lib.CertKeyFormatPEM), prettify(` + cacert Format of given input (PEM, DER; heuristic if missing).`)) cert = flags.String("cert", "", prettify(` File containing client certificate (public key), to present to the server. Not valid with -plaintext option. Must also provide -key option - when use PEM certificate file.`)) - certTypeString = flags.String("cert-type", "", prettify(` - Client certificate file type. (PEM/P12)`)) - certType = grpcurl.CertTypePEM - pass = flags.String("pass", "", prettify(` + when use PEM/DER certificate file.`)) + pCertFormat = flags.String("cert-format", string(lib.CertKeyFormatPEM), prettify(` + cert Format of given input (PEM, DER, PKCS12; heuristic if missing).`)) + pass = flags.String("pass", "", prettify(` Pass phrase for the key`)) key = flags.String("key", "", prettify(` File containing client private key, to present to the server. Not valid with -plaintext option. Must also provide -cert option.`)) + pKeyFormat = flags.String("key-format", string(lib.CertKeyFormatPEM), prettify(` + key Format of given input (PEM, DER; heuristic if missing).`)) // ALTS Options usealts = flags.Bool("alts", false, prettify(` @@ -294,17 +298,9 @@ func main() { // default behavior is to use tls usetls := !*plaintext && !*usealts - - //// converto to CertificateFileType - //if len(*certTypeString) == 0 { - // certType = grpcurl.CertTypePEM // default PEM - //} else if strings.EqualFold(*certTypeString, "PEM") { - // certType = grpcurl.CertTypePEM - //} else if strings.EqualFold(*certTypeString, "P12") { - // certType = grpcurl.CertTypeP12 - //} else { - // fail(nil, "The -cert-type argument must be PEM or P12.") - //} + cacertFormat := lib.NewCertificateKeyFormat(*pCACertFormat) + certFormat := lib.NewCertificateKeyFormat(*pCertFormat) + keyFormat := lib.NewCertificateKeyFormat(*pKeyFormat) // Do extra validation on arguments and figure out what user asked us to do. if *connectTimeout < 0 { @@ -332,21 +328,61 @@ func main() { fail(nil, "The -key argument can only be used with TLS.") } - //switch certType { - //case grpcurl.CertTypePEM: - // if (*key == "") != (*cert == "") { - // fail(nil, "The -cert and -key arguments must be used together and both be present when -cert-type is PEM.") - // } - //case grpcurl.CertTypeP12: - // if *key != "" { - // fail(nil, "The -key arguments must not be used when -cert-type is P12.") - // } - // if *cert == "" { - // fail(nil, "The -cert arguments must be used when -cert-type is P12.") - // } - //default: - // fail(nil, "Not support cert type %v.", certType) - //} + if usetls { + if *cacert != "" { + if cacertFormat.IsNone() { + guessFormat, err := lib.GuessFormatForFile(*cacert, "") + if err != nil { + fail(nil, "Fail to guess file format of -key err: %s", err) + } + cacertFormat.Set(guessFormat) + } + switch cacertFormat { + case lib.CertKeyFormatPEM, lib.CertKeyFormatDER: + // do nothing + default: + fail(nil, "The -cacert-format %s not support.", keyFormat) + } + } + if *cert != "" { + if certFormat.IsNone() { + guessFormat, err := lib.GuessFormatForFile(*cert, "") + if err != nil { + fail(nil, "Fail to guess file format of -cert err: %s", err) + } + certFormat.Set(guessFormat) + } + + switch certFormat { + case lib.CertKeyFormatPEM, lib.CertKeyFormatDER: + if *cert == "" || *key == "" { + fail(nil, "The -cert and -key arguments must be used together and both be present.") + } + case lib.CertKeyFormatPKCS12: + // do nothing + default: + fail(nil, "The -cert-format %s not support.", certFormat) + } + } + if *key != "" { + if keyFormat.IsNone() { + guessFormat, err := lib.GuessFormatForFile(*key, "") + if err != nil { + fail(nil, "Fail to guess file format of -key err: %s", err) + } + keyFormat.Set(guessFormat) + } + switch keyFormat { + case lib.CertKeyFormatPEM, lib.CertKeyFormatDER: + if *cert == "" || *key == "" { + fail(nil, "The -cert and -key arguments must be used together and both be present.") + } + default: + fail(nil, "The -key-format %s not support.", keyFormat) + } + } + + } if *altsHandshakerServiceAddress != "" && !*usealts { fail(nil, "The -alts-handshaker-service argument must be used with the -alts argument.") @@ -482,7 +518,7 @@ func main() { } creds = alts.NewClientCreds(clientOptions) } else if usetls { - tlsConf, err := grpcurl.ClientTLSConfigV2(*insecure, *cacert, *cert, *key, certType, *pass) + tlsConf, err := lib.ClientTLSConfigV2(*insecure, *cacert, cacertFormat, *cert, certFormat, *key, keyFormat, *pass) if err != nil { fail(err, "Failed to create TLS config") } diff --git a/grpcurl.go b/grpcurl.go index d852cdc..d0ee535 100644 --- a/grpcurl.go +++ b/grpcurl.go @@ -526,78 +526,12 @@ func ClientTransportCredentials(insecureSkipVerify bool, cacertFile, clientCertF return credentials.NewTLS(tlsConf), nil } -type CertificateType int - -const ( - // The certificate file contains PEM encoded data - CertTypePEM CertificateType = 1 - // The certificate file contains PFX data describing PKCS#12. - CertTypeP12 CertificateType = 2 -) - // ClientTLSConfig builds transport-layer config for a gRPC client using the // given properties. If cacertFile is blank, only standard trusted certs are used to // verify the server certs. If clientCertFile is blank, the client will not use a client // certificate. If clientCertFile is not blank then clientKeyFile must not be blank. func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile string) (*tls.Config, error) { - return ClientTLSConfigV2(insecureSkipVerify, cacertFile, clientCertFile, clientKeyFile, CertTypePEM, "") -} - -// ClientTLSConfigV2 builds transport-layer config for a gRPC client using the -// given properties. Support certificate file both PEM and P12. -func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile, clientCertFile, clientKeyFile string, clientCertType CertificateType, clientPass string) (*tls.Config, error) { - var tlsConf tls.Config - - if clientCertFile != "" { - // Load the client certificates from disk - clientCertFormat := "" - var pemBuf bytes.Buffer - err := lib.ReadAsPEMEx(clientCertFile, clientCertFormat, clientPass, func(block *pem.Block, format string) error { - return pem.Encode(&pemBuf, block) - }) - if err != nil { - return nil, fmt.Errorf("could not load client cert: %v", err) - } - pemBytes := pemBuf.Bytes() - pemKeyBytes := pemBytes - - if clientKeyFile != "" { - var pemKeyBuf bytes.Buffer - err := lib.ReadAsPEMEx(clientKeyFile, clientCertFormat, clientPass, func(block *pem.Block, format string) error { - return pem.Encode(&pemKeyBuf, block) - }) - if err != nil { - return nil, fmt.Errorf("could not load client key: %v", err) - } - pemKeyBytes = pemKeyBuf.Bytes() - } - - certificate, err := tls.X509KeyPair(pemBytes, pemKeyBytes) - if err != nil { - return nil, fmt.Errorf("could not load client key pair: %v", err) - } - tlsConf.Certificates = []tls.Certificate{certificate} - } - - if insecureSkipVerify { - tlsConf.InsecureSkipVerify = true - } else if cacertFile != "" { - // Create a certificate pool from the certificate authority - certPool := x509.NewCertPool() - ca, err := ioutil.ReadFile(cacertFile) - if err != nil { - return nil, fmt.Errorf("could not read ca certificate: %v", err) - } - - // Append the certificates from the CA - if ok := certPool.AppendCertsFromPEM(ca); !ok { - return nil, errors.New("failed to append ca certs") - } - - tlsConf.RootCAs = certPool - } - - return &tlsConf, nil + return lib.ClientTLSConfigV2(insecureSkipVerify, cacertFile, lib.CertKeyFormatPEM, clientCertFile, lib.CertKeyFormatPEM, clientKeyFile, lib.CertKeyFormatPEM, "") } func inputFiles(fileNames []string) ([]*os.File, error) { diff --git a/internal/certigo/lib/certs.go b/internal/certigo/lib/certs.go index e21e7c1..e7284af 100644 --- a/internal/certigo/lib/certs.go +++ b/internal/certigo/lib/certs.go @@ -22,6 +22,7 @@ import ( "crypto" "crypto/ecdsa" "crypto/rsa" + "crypto/tls" "crypto/x509" "encoding/binary" "encoding/pem" @@ -50,6 +51,7 @@ const ( var fileExtToFormat = map[string]string{ ".pem": "PEM", ".crt": "PEM", + ".cer": "PEM", ".p7b": "PEM", ".p7c": "PEM", ".p12": "PKCS12", @@ -84,28 +86,166 @@ func errorFromErrors(errs []error) error { return errors.New(buffer.String()) } -// ReadAsPEMFromFiles will read PEM blocks from the given set of inputs. Input -// data may be in plain-text PEM files, DER-encoded certificates or PKCS7 -// envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to PEM -// blocks and passed to the callback. -func ReadAsPEMFromFiles(files []*os.File, format string, password func(string) string, callback func(*pem.Block, string) error) error { - var errs []error - for _, file := range files { - reader := bufio.NewReaderSize(file, 4) - format, err := formatForFile(reader, file.Name(), format) - if err != nil { - return fmt.Errorf("unable to guess file type for file %s", file.Name()) - } - - err = readCertsFromStream(reader, file.Name(), format, password, callback) - if err != nil { - errs = append(errs, err) - } +func NewCertificateKeyFormat(fileFormat string) CertificateKeyFormat { + fileFormat = strings.ToUpper(fileFormat) + switch fileFormat { + case "": + return CertKeyFormatNONE + case "PEM": + return CertKeyFormatPEM + case "DER": + return CertKeyFormatDER + case "PKCS12", "P12": + return CertKeyFormatPKCS12 + default: + return CertKeyFormatNONE } - return errorFromErrors(errs) } -func ReadAsPEMEx(filename string, format string, password string, callback func(*pem.Block, string) error) error { +type CertificateKeyFormat string + +const ( + CertKeyFormatNONE CertificateKeyFormat = "" + // The file contains plain-text PEM data + CertKeyFormatPEM CertificateKeyFormat = "PEM" + // The file contains X.509 DER encoded data + CertKeyFormatDER CertificateKeyFormat = "DER" + // The file contains JCEKS keystores + CertKeyFormatJCEKS CertificateKeyFormat = "JCEKS" + // The file contains PFX data describing PKCS#12 + CertKeyFormatPKCS12 CertificateKeyFormat = "PKCS12" +) + +func (f *CertificateKeyFormat) Set(fileFormat string) { + *f = NewCertificateKeyFormat(fileFormat) +} + +func (f CertificateKeyFormat) IsNone() bool { + return f == CertKeyFormatNONE +} + +func (f *CertificateKeyFormat) SetPEM() { + *f = CertKeyFormatPEM +} + +func (f CertificateKeyFormat) IsPEM() bool { + return f == CertKeyFormatPEM +} + +func (f CertificateKeyFormat) IsDER() bool { + return f == CertKeyFormatDER +} + +func (f CertificateKeyFormat) IsPKCS12() bool { + return f == CertKeyFormatPKCS12 +} + +// ClientTLSConfigV2 builds transport-layer config for a gRPC client using the +// given properties. Support certificate file both PEM and P12. +func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat CertificateKeyFormat, clientCertFile string, certFormat CertificateKeyFormat, clientKeyFile string, keyFormat CertificateKeyFormat, clientPass string) (*tls.Config, error) { + var tlsConf tls.Config + + if clientCertFile != "" { + // Load the client certificates + pemCertBytes, err := readAsPEMEx2(clientCertFile, string(certFormat), clientPass) + if err != nil { + return nil, fmt.Errorf("could not load client cert: %v", err) + } + pemKeyBytes := pemCertBytes // allow clientCertFile include both certificate and key file (JCEKS/PKCS12/PEM) + + // Load the client key + if clientKeyFile != "" { + pemBytes, err := readAsPEMEx2(clientKeyFile, string(keyFormat), clientPass) + if err != nil { + return nil, fmt.Errorf("could not load client key: %v", err) + } + pemKeyBytes = pemBytes + } + + // Load tls.Certificate + certificate, err := tls.X509KeyPair(pemCertBytes, pemKeyBytes) + if err != nil { + return nil, fmt.Errorf("could not load client key pair: %v", err) + } + tlsConf.Certificates = []tls.Certificate{certificate} + } + + if insecureSkipVerify { + tlsConf.InsecureSkipVerify = true + } else if cacertFile != "" { + // Create a certificate pool from the certificate authority + certPool := x509.NewCertPool() + pemCACertBytes, err := readAsPEMEx2(cacertFile, string(cacertFormat), "") + if err != nil { + return nil, fmt.Errorf("could not load cacert : %v", err) + } + + // Append the certificates from the CA + if ok := certPool.AppendCertsFromPEM(pemCACertBytes); !ok { + return nil, errors.New("failed to append ca certs") + } + + tlsConf.RootCAs = certPool + } + + return &tlsConf, nil +} + +func GuessFormatForFile(filename, format string) (string, error) { + // Second, attempt to guess based on extension + guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))] + if ok { + return guess, nil + } + + file, err := os.Open(filename) + if err != nil { + return "", fmt.Errorf("unable to open file: %s\n", err) + } + defer file.Close() + reader := bufio.NewReaderSize(file, 4) + + // Third, attempt to guess based on first 4 bytes of input + data, err := reader.Peek(4) + if err != nil { + return "", fmt.Errorf("unable to read file: %s\n", err) + } + + // Heuristics for guessing -- best effort. + magic := binary.BigEndian.Uint32(data) + if magic == 0xCECECECE || magic == 0xFEEDFEED { + // JCEKS/JKS files always start with this prefix + return "JCEKS", nil + } + if magic == 0x2D2D2D2D || magic == 0x434f4e4e { + // Starts with '----' or 'CONN' (what s_client prints...) + // TODO start with 'Certificate' + return "PEM", nil + } + if magic&0xFFFF0000 == 0x30820000 { + // Looks like the input is DER-encoded, so it's either PKCS12 or X.509. + if magic&0x0000FF00 == 0x0300 { + // Probably X.509 + return "DER", nil + } + return "PKCS12", nil + } + + return "", nil +} + +func readAsPEMEx2(filename string, format string, password string) ([]byte, error) { + var pembuf bytes.Buffer + err := readAsPEMEx(filename, format, "", func(block *pem.Block, format string) error { + return pem.Encode(&pembuf, block) + }) + if err != nil { + return nil, fmt.Errorf("could not load client cert: %v", err) + } + return pembuf.Bytes(), nil +} + +func readAsPEMEx(filename string, format string, password string, callback func(*pem.Block, string) error) error { rawFile, err := os.Open(filename) if err != nil { return fmt.Errorf("unable to open file: %s\n", err) @@ -114,9 +254,39 @@ func ReadAsPEMEx(filename string, format string, password string, callback func( passwordFunc := func(promet string) string { return password } - return ReadAsPEM([]io.Reader{rawFile}, format, passwordFunc, callback) + + reader := bufio.NewReaderSize(rawFile, 4) + format, err = formatForFile(reader, "", format) + if err != nil { + return fmt.Errorf("unable to guess format for input stream") + } + + return readCertsFromStream(reader, "", format, passwordFunc, callback) } +// // ReadAsPEMFromFiles will read PEM blocks from the given set of inputs. Input +// // data may be in plain-text PEM files, DER-encoded certificates or PKCS7 +// // envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to PEM +// // blocks and passed to the callback. +// +// func ReadAsPEMFromFiles(files []*os.File, format string, password func(string) string, callback func(*pem.Block, string) error) error { +// var errs []error +// for _, file := range files { +// reader := bufio.NewReaderSize(file, 4) +// format, err := formatForFile(reader, file.Name(), format) +// if err != nil { +// return fmt.Errorf("unable to guess file type for file %s", file.Name()) +// } +// +// err = readCertsFromStream(reader, file.Name(), format, password, callback) +// if err != nil { +// errs = append(errs, err) +// } +// } +// return errorFromErrors(errs) +// } +// + // ReadAsPEM will read PEM blocks from the given set of inputs. Input data may // be in plain-text PEM files, DER-encoded certificates or PKCS7 envelopes, or // PKCS12/JCEKS keystores. All inputs will be converted to PEM blocks and @@ -138,76 +308,76 @@ func ReadAsPEM(readers []io.Reader, format string, password func(string) string, return errorFromErrors(errs) } -// ReadAsX509FromFiles will read X.509 certificates from the given set of -// inputs. Input data may be in plain-text PEM files, DER-encoded certificates -// or PKCS7 envelopes, or PKCS12/JCEKS keystores. All inputs will be converted -// to X.509 certificates (private keys are skipped) and passed to the callback. -func ReadAsX509FromFiles(files []*os.File, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error { - errs := []error{} - for _, file := range files { - reader := bufio.NewReaderSize(file, 4) - format, err := formatForFile(reader, file.Name(), format) - if err != nil { - return fmt.Errorf("unable to guess file type for file %s, try adding --format flag", file.Name()) - } - - err = readCertsFromStream(reader, file.Name(), format, password, pemToX509(callback)) - if err != nil { - errs = append(errs, err) - } - } - return errorFromErrors(errs) -} - -// ReadAsX509 will read X.509 certificates from the given set of inputs. Input -// data may be in plain-text PEM files, DER-encoded certificates or PKCS7 -// envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to X.509 -// certificates (private keys are skipped) and passed to the callback. -func ReadAsX509(readers []io.Reader, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error { - errs := []error{} - for _, r := range readers { - reader := bufio.NewReaderSize(r, 4) - format, err := formatForFile(reader, "", format) - if err != nil { - return fmt.Errorf("unable to guess format for input stream") - } - - err = readCertsFromStream(reader, "", format, password, pemToX509(callback)) - if err != nil { - errs = append(errs, err) - } - } - return errorFromErrors(errs) -} - -func pemToX509(callback func(*x509.Certificate, string, error) error) func(*pem.Block, string) error { - return func(block *pem.Block, format string) error { - switch block.Type { - case "CERTIFICATE": - cert, err := x509.ParseCertificate(block.Bytes) - return callback(cert, format, err) - case "PKCS7": - certs, err := pkcs7.ExtractCertificates(block.Bytes) - if err == nil { - for _, cert := range certs { - return callback(cert, format, nil) - } - } else { - return callback(nil, format, err) - } - case "CERTIFICATE REQUEST": - fmt.Println("warning: certificate requests are not supported") - } - return nil - } -} - -func ReadCertsFromStream(reader io.Reader, filename string, format string, password string, callback func(*pem.Block, string) error) error { - passwordFunc := func(promet string) string { - return password - } - return readCertsFromStream(reader, filename, format, passwordFunc, callback) -} +//// ReadAsX509FromFiles will read X.509 certificates from the given set of +//// inputs. Input data may be in plain-text PEM files, DER-encoded certificates +//// or PKCS7 envelopes, or PKCS12/JCEKS keystores. All inputs will be converted +//// to X.509 certificates (private keys are skipped) and passed to the callback. +//func ReadAsX509FromFiles(files []*os.File, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error { +// errs := []error{} +// for _, file := range files { +// reader := bufio.NewReaderSize(file, 4) +// format, err := formatForFile(reader, file.Name(), format) +// if err != nil { +// return fmt.Errorf("unable to guess file type for file %s, try adding --format flag", file.Name()) +// } +// +// err = readCertsFromStream(reader, file.Name(), format, password, pemToX509(callback)) +// if err != nil { +// errs = append(errs, err) +// } +// } +// return errorFromErrors(errs) +//} +// +//// ReadAsX509 will read X.509 certificates from the given set of inputs. Input +//// data may be in plain-text PEM files, DER-encoded certificates or PKCS7 +//// envelopes, or PKCS12/JCEKS keystores. All inputs will be converted to X.509 +//// certificates (private keys are skipped) and passed to the callback. +//func ReadAsX509(readers []io.Reader, format string, password func(string) string, callback func(*x509.Certificate, string, error) error) error { +// errs := []error{} +// for _, r := range readers { +// reader := bufio.NewReaderSize(r, 4) +// format, err := formatForFile(reader, "", format) +// if err != nil { +// return fmt.Errorf("unable to guess format for input stream") +// } +// +// err = readCertsFromStream(reader, "", format, password, pemToX509(callback)) +// if err != nil { +// errs = append(errs, err) +// } +// } +// return errorFromErrors(errs) +//} +// +//func pemToX509(callback func(*x509.Certificate, string, error) error) func(*pem.Block, string) error { +// return func(block *pem.Block, format string) error { +// switch block.Type { +// case "CERTIFICATE": +// cert, err := x509.ParseCertificate(block.Bytes) +// return callback(cert, format, err) +// case "PKCS7": +// certs, err := pkcs7.ExtractCertificates(block.Bytes) +// if err == nil { +// for _, cert := range certs { +// return callback(cert, format, nil) +// } +// } else { +// return callback(nil, format, err) +// } +// case "CERTIFICATE REQUEST": +// fmt.Println("warning: certificate requests are not supported") +// } +// return nil +// } +//} +// +//func ReadCertsFromStream(reader io.Reader, filename string, format string, password string, callback func(*pem.Block, string) error) error { +// passwordFunc := func(promet string) string { +// return password +// } +// return readCertsFromStream(reader, filename, format, passwordFunc, callback) +//} // readCertsFromStream takes some input and converts it to PEM blocks. func readCertsFromStream(reader io.Reader, filename string, format string, password func(string) string, callback func(*pem.Block, string) error) error { @@ -237,7 +407,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw x509Certs, err0 := x509.ParseCertificates(data) if err0 == nil { for _, cert := range x509Certs { - err := callback(EncodeX509ToPEM(cert, headers), format) + err := callback(encodeX509ToPEM(cert, headers), format) if err != nil { return err } @@ -279,7 +449,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw } for _, alias := range keyStore.ListCerts() { cert, _ := keyStore.GetCert(alias) - err := callback(EncodeX509ToPEM(cert, mergeHeaders(headers, map[string]string{nameHeader: alias})), format) + err := callback(encodeX509ToPEM(cert, mergeHeaders(headers, map[string]string{nameHeader: alias})), format) if err != nil { return err } @@ -302,7 +472,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw } for _, cert := range certs { - if err = callback(EncodeX509ToPEM(cert, mergedHeaders), format); err != nil { + if err = callback(encodeX509ToPEM(cert, mergedHeaders), format); err != nil { return err } } @@ -323,8 +493,8 @@ func mergeHeaders(baseHeaders, extraHeaders map[string]string) (headers map[stri return } -// EncodeX509ToPEM converts an X.509 certificate into a PEM block for output. -func EncodeX509ToPEM(cert *x509.Certificate, headers map[string]string) *pem.Block { +// encodeX509ToPEM converts an X.509 certificate into a PEM block for output. +func encodeX509ToPEM(cert *x509.Certificate, headers map[string]string) *pem.Block { return &pem.Block{ Type: "CERTIFICATE", Bytes: cert.Raw, @@ -392,6 +562,7 @@ func formatForFile(file *bufio.Reader, filename, format string) (string, error) } if magic == 0x2D2D2D2D || magic == 0x434f4e4e { // Starts with '----' or 'CONN' (what s_client prints...) + // TODO start with 'Certificate' return "PEM", nil } if magic&0xFFFF0000 == 0x30820000 { From 0ade6c177a02c81850a9dcb72f1a503b6fbeb6be Mon Sep 17 00:00:00 2001 From: wangtiga Date: Sat, 11 Nov 2023 21:27:59 +0800 Subject: [PATCH 4/9] add unit test for cert PKCS12 DER PEM --- cmd/grpcurl/grpcurl.go | 62 ++--- internal/certigo/lib/cert_key_format.go | 45 ++++ internal/certigo/lib/certs.go | 328 ++++++++++------------- internal/certigo/lib/certs_test.go | 64 +++++ internal/certigo/lib/tls/ca.crl | 16 ++ internal/certigo/lib/tls/ca.crt | 28 ++ internal/certigo/lib/tls/ca.der | Bin 0 -> 1246 bytes internal/certigo/lib/tls/ca.key | 51 ++++ internal/certigo/lib/tls/client.cer | 101 +++++++ internal/certigo/lib/tls/client.crt | 25 ++ internal/certigo/lib/tls/client.csr | 16 ++ internal/certigo/lib/tls/client.der | Bin 0 -> 1078 bytes internal/certigo/lib/tls/client.guess | 101 +++++++ internal/certigo/lib/tls/client.key | 27 ++ internal/certigo/lib/tls/client.pfx | Bin 0 -> 3973 bytes internal/certigo/lib/tls/client_pass.pfx | Bin 0 -> 3973 bytes internal/certigo/lib/tls/gen.sh | 18 ++ 17 files changed, 655 insertions(+), 227 deletions(-) create mode 100644 internal/certigo/lib/cert_key_format.go create mode 100644 internal/certigo/lib/certs_test.go create mode 100644 internal/certigo/lib/tls/ca.crl create mode 100644 internal/certigo/lib/tls/ca.crt create mode 100644 internal/certigo/lib/tls/ca.der create mode 100644 internal/certigo/lib/tls/ca.key create mode 100644 internal/certigo/lib/tls/client.cer create mode 100644 internal/certigo/lib/tls/client.crt create mode 100644 internal/certigo/lib/tls/client.csr create mode 100644 internal/certigo/lib/tls/client.der create mode 100644 internal/certigo/lib/tls/client.guess create mode 100644 internal/certigo/lib/tls/client.key create mode 100644 internal/certigo/lib/tls/client.pfx create mode 100644 internal/certigo/lib/tls/client_pass.pfx create mode 100755 internal/certigo/lib/tls/gen.sh diff --git a/cmd/grpcurl/grpcurl.go b/cmd/grpcurl/grpcurl.go index 6b0fbcf..ca7bbc4 100644 --- a/cmd/grpcurl/grpcurl.go +++ b/cmd/grpcurl/grpcurl.go @@ -73,13 +73,11 @@ var ( when use PEM/DER certificate file.`)) pCertFormat = flags.String("cert-format", string(lib.CertKeyFormatPEM), prettify(` cert Format of given input (PEM, DER, PKCS12; heuristic if missing).`)) - pass = flags.String("pass", "", prettify(` - Pass phrase for the key`)) + certPass = flags.String("pass", "", prettify(` + Pass phrase for the PKCS12 cert`)) key = flags.String("key", "", prettify(` File containing client private key, to present to the server. Not valid with -plaintext option. Must also provide -cert option.`)) - pKeyFormat = flags.String("key-format", string(lib.CertKeyFormatPEM), prettify(` - key Format of given input (PEM, DER; heuristic if missing).`)) // ALTS Options usealts = flags.Bool("alts", false, prettify(` @@ -300,7 +298,7 @@ func main() { usetls := !*plaintext && !*usealts cacertFormat := lib.NewCertificateKeyFormat(*pCACertFormat) certFormat := lib.NewCertificateKeyFormat(*pCertFormat) - keyFormat := lib.NewCertificateKeyFormat(*pKeyFormat) + keyFormat := lib.CertKeyFormatPEM // Do extra validation on arguments and figure out what user asked us to do. if *connectTimeout < 0 { @@ -330,55 +328,45 @@ func main() { if usetls { if *cacert != "" { - if cacertFormat.IsNone() { - guessFormat, err := lib.GuessFormatForFile(*cacert, "") - if err != nil { - fail(nil, "Fail to guess file format of -key err: %s", err) - } - cacertFormat.Set(guessFormat) + guessFormat, err := lib.GuessFormatForFile(*cacert, cacertFormat) + if err != nil { + fail(nil, "Fail to guess file format of -key err: %s", err) } - switch cacertFormat { + switch guessFormat { case lib.CertKeyFormatPEM, lib.CertKeyFormatDER: - // do nothing + cacertFormat = guessFormat default: - fail(nil, "The -cacert-format %s not support.", keyFormat) + fail(nil, "The -cacert-format %s not support.", cacertFormat) } } if *cert != "" { - if certFormat.IsNone() { - guessFormat, err := lib.GuessFormatForFile(*cert, "") - if err != nil { - fail(nil, "Fail to guess file format of -cert err: %s", err) - } - certFormat.Set(guessFormat) + guessFormat, err := lib.GuessFormatForFile(*cert, certFormat) + if err != nil { + fail(nil, "Fail to guess file format of -cert err: %s", err) } - switch certFormat { + switch guessFormat { case lib.CertKeyFormatPEM, lib.CertKeyFormatDER: if *cert == "" || *key == "" { fail(nil, "The -cert and -key arguments must be used together and both be present.") } + certFormat = guessFormat case lib.CertKeyFormatPKCS12: - // do nothing + certFormat = guessFormat default: fail(nil, "The -cert-format %s not support.", certFormat) } } - if *key != "" { - if keyFormat.IsNone() { - guessFormat, err := lib.GuessFormatForFile(*key, "") - if err != nil { - fail(nil, "Fail to guess file format of -key err: %s", err) - } - keyFormat.Set(guessFormat) - } - switch keyFormat { - case lib.CertKeyFormatPEM, lib.CertKeyFormatDER: - if *cert == "" || *key == "" { - fail(nil, "The -cert and -key arguments must be used together and both be present.") - } + if *certPass != "" { + switch certFormat { + case lib.CertKeyFormatPKCS12: default: - fail(nil, "The -key-format %s not support.", keyFormat) + fail(nil, "The -pass argument is only supported when -cert-type is PKCS12.") + } + } + if *key != "" { + if *cert == "" || *key == "" { + fail(nil, "The -cert and -key arguments must be used together and both be present.") } } @@ -518,7 +506,7 @@ func main() { } creds = alts.NewClientCreds(clientOptions) } else if usetls { - tlsConf, err := lib.ClientTLSConfigV2(*insecure, *cacert, cacertFormat, *cert, certFormat, *key, keyFormat, *pass) + tlsConf, err := lib.ClientTLSConfigV2(*insecure, *cacert, cacertFormat, *cert, certFormat, *key, keyFormat, *certPass) if err != nil { fail(err, "Failed to create TLS config") } diff --git a/internal/certigo/lib/cert_key_format.go b/internal/certigo/lib/cert_key_format.go new file mode 100644 index 0000000..b6f038e --- /dev/null +++ b/internal/certigo/lib/cert_key_format.go @@ -0,0 +1,45 @@ +package lib + +import ( + "strings" +) + +func NewCertificateKeyFormat(fileFormat string) CertificateKeyFormat { + fileFormat = strings.ToUpper(fileFormat) + switch fileFormat { + case "": + return CertKeyFormatNONE + case "PEM": + return CertKeyFormatPEM + case "DER": + return CertKeyFormatDER + case "JCEKS": + return CertKeyFormatJCEKS + case "PKCS12", "P12": + return CertKeyFormatPKCS12 + default: + return CertKeyFormatNONE + } +} + +type CertificateKeyFormat string + +const ( + CertKeyFormatNONE CertificateKeyFormat = "" + // The file contains plain-text PEM data + CertKeyFormatPEM CertificateKeyFormat = "PEM" + // The file contains X.509 DER encoded data + CertKeyFormatDER CertificateKeyFormat = "DER" + // The file contains JCEKS keystores + CertKeyFormatJCEKS CertificateKeyFormat = "JCEKS" + // The file contains PFX data describing PKCS#12 + CertKeyFormatPKCS12 CertificateKeyFormat = "PKCS12" +) + +func (f *CertificateKeyFormat) Set(fileFormat string) { + *f = NewCertificateKeyFormat(fileFormat) +} + +func (f CertificateKeyFormat) IsNone() bool { + return f == CertKeyFormatNONE +} diff --git a/internal/certigo/lib/certs.go b/internal/certigo/lib/certs.go index e7284af..81d47ac 100644 --- a/internal/certigo/lib/certs.go +++ b/internal/certigo/lib/certs.go @@ -48,97 +48,42 @@ const ( fileHeader = "originFile" ) -var fileExtToFormat = map[string]string{ - ".pem": "PEM", - ".crt": "PEM", - ".cer": "PEM", - ".p7b": "PEM", - ".p7c": "PEM", - ".p12": "PKCS12", - ".pfx": "PKCS12", - ".jceks": "JCEKS", - ".jks": "JCEKS", // Only partially supported - ".der": "DER", +var fileExtToFormat = map[string]CertificateKeyFormat{ + ".pem": CertKeyFormatPEM, + ".crt": CertKeyFormatPEM, + ".p7b": CertKeyFormatPEM, + ".p7c": CertKeyFormatPEM, + ".p12": CertKeyFormatPKCS12, + ".pfx": CertKeyFormatPKCS12, + ".jceks": CertKeyFormatJCEKS, + ".jks": CertKeyFormatJCEKS, // Only partially supported + ".der": CertKeyFormatDER, } -var badSignatureAlgorithms = [...]x509.SignatureAlgorithm{ - x509.MD2WithRSA, - x509.MD5WithRSA, - x509.SHA1WithRSA, - x509.DSAWithSHA1, - x509.ECDSAWithSHA1, -} +//var badSignatureAlgorithms = [...]x509.SignatureAlgorithm{ +// x509.MD2WithRSA, +// x509.MD5WithRSA, +// x509.SHA1WithRSA, +// x509.DSAWithSHA1, +// x509.ECDSAWithSHA1, +//} -func errorFromErrors(errs []error) error { - if len(errs) == 0 { - return nil - } - if len(errs) == 1 { - return errs[0] - } - buffer := new(bytes.Buffer) - buffer.WriteString("encountered multiple errors:\n") - for _, err := range errs { - buffer.WriteString("* ") - buffer.WriteString(strings.TrimSuffix(err.Error(), "\n")) - buffer.WriteString("\n") - } - return errors.New(buffer.String()) -} - -func NewCertificateKeyFormat(fileFormat string) CertificateKeyFormat { - fileFormat = strings.ToUpper(fileFormat) - switch fileFormat { - case "": - return CertKeyFormatNONE - case "PEM": - return CertKeyFormatPEM - case "DER": - return CertKeyFormatDER - case "PKCS12", "P12": - return CertKeyFormatPKCS12 - default: - return CertKeyFormatNONE - } -} - -type CertificateKeyFormat string - -const ( - CertKeyFormatNONE CertificateKeyFormat = "" - // The file contains plain-text PEM data - CertKeyFormatPEM CertificateKeyFormat = "PEM" - // The file contains X.509 DER encoded data - CertKeyFormatDER CertificateKeyFormat = "DER" - // The file contains JCEKS keystores - CertKeyFormatJCEKS CertificateKeyFormat = "JCEKS" - // The file contains PFX data describing PKCS#12 - CertKeyFormatPKCS12 CertificateKeyFormat = "PKCS12" -) - -func (f *CertificateKeyFormat) Set(fileFormat string) { - *f = NewCertificateKeyFormat(fileFormat) -} - -func (f CertificateKeyFormat) IsNone() bool { - return f == CertKeyFormatNONE -} - -func (f *CertificateKeyFormat) SetPEM() { - *f = CertKeyFormatPEM -} - -func (f CertificateKeyFormat) IsPEM() bool { - return f == CertKeyFormatPEM -} - -func (f CertificateKeyFormat) IsDER() bool { - return f == CertKeyFormatDER -} - -func (f CertificateKeyFormat) IsPKCS12() bool { - return f == CertKeyFormatPKCS12 -} +//func errorFromErrors(errs []error) error { +// if len(errs) == 0 { +// return nil +// } +// if len(errs) == 1 { +// return errs[0] +// } +// buffer := new(bytes.Buffer) +// buffer.WriteString("encountered multiple errors:\n") +// for _, err := range errs { +// buffer.WriteString("* ") +// buffer.WriteString(strings.TrimSuffix(err.Error(), "\n")) +// buffer.WriteString("\n") +// } +// return errors.New(buffer.String()) +//} // ClientTLSConfigV2 builds transport-layer config for a gRPC client using the // given properties. Support certificate file both PEM and P12. @@ -147,7 +92,7 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat if clientCertFile != "" { // Load the client certificates - pemCertBytes, err := readAsPEMEx2(clientCertFile, string(certFormat), clientPass) + pemCertBytes, err := readAsPEMEx(clientCertFile, certFormat, clientPass) if err != nil { return nil, fmt.Errorf("could not load client cert: %v", err) } @@ -155,7 +100,7 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat // Load the client key if clientKeyFile != "" { - pemBytes, err := readAsPEMEx2(clientKeyFile, string(keyFormat), clientPass) + pemBytes, err := readAsPEMEx(clientKeyFile, keyFormat, clientPass) if err != nil { return nil, fmt.Errorf("could not load client key: %v", err) } @@ -174,13 +119,12 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat tlsConf.InsecureSkipVerify = true } else if cacertFile != "" { // Create a certificate pool from the certificate authority - certPool := x509.NewCertPool() - pemCACertBytes, err := readAsPEMEx2(cacertFile, string(cacertFormat), "") + pemCACertBytes, err := readAsPEMEx(cacertFile, cacertFormat, "") if err != nil { return nil, fmt.Errorf("could not load cacert : %v", err) } - // Append the certificates from the CA + certPool := x509.NewCertPool() if ok := certPool.AppendCertsFromPEM(pemCACertBytes); !ok { return nil, errors.New("failed to append ca certs") } @@ -191,7 +135,12 @@ func ClientTLSConfigV2(insecureSkipVerify bool, cacertFile string, cacertFormat return &tlsConf, nil } -func GuessFormatForFile(filename, format string) (string, error) { +func GuessFormatForFile(filename string, format CertificateKeyFormat) (CertificateKeyFormat, error) { + // First, honor --format flag we got from user + if !format.IsNone() { + return format, nil + } + // Second, attempt to guess based on extension guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))] if ok { @@ -200,7 +149,7 @@ func GuessFormatForFile(filename, format string) (string, error) { file, err := os.Open(filename) if err != nil { - return "", fmt.Errorf("unable to open file: %s\n", err) + return CertKeyFormatNONE, fmt.Errorf("unable to open file: %s\n", err) } defer file.Close() reader := bufio.NewReaderSize(file, 4) @@ -208,60 +157,60 @@ func GuessFormatForFile(filename, format string) (string, error) { // Third, attempt to guess based on first 4 bytes of input data, err := reader.Peek(4) if err != nil { - return "", fmt.Errorf("unable to read file: %s\n", err) + return CertKeyFormatNONE, fmt.Errorf("unable to read file: %s\n", err) } // Heuristics for guessing -- best effort. magic := binary.BigEndian.Uint32(data) + fmt.Printf(" magic 0x%0x\n", magic) if magic == 0xCECECECE || magic == 0xFEEDFEED { // JCEKS/JKS files always start with this prefix - return "JCEKS", nil + return CertKeyFormatJCEKS, nil } - if magic == 0x2D2D2D2D || magic == 0x434f4e4e { - // Starts with '----' or 'CONN' (what s_client prints...) - // TODO start with 'Certificate' - return "PEM", nil + if magic == 0x2D2D2D2D { + // Starts with '----' + return CertKeyFormatPEM, nil + } + if magic == 0x434f4e4e { + // Starts with 'CONN' (what s_client prints...) + return CertKeyFormatPEM, nil + } + if magic == 0x43657274 { + // Starts with 'Cert' (what openssl x509 -text -in tls/client.crt prints...) + return CertKeyFormatPEM, nil } if magic&0xFFFF0000 == 0x30820000 { // Looks like the input is DER-encoded, so it's either PKCS12 or X.509. if magic&0x0000FF00 == 0x0300 { // Probably X.509 - return "DER", nil + return CertKeyFormatDER, nil } - return "PKCS12", nil + return CertKeyFormatPKCS12, nil } - return "", nil + return CertKeyFormatNONE, fmt.Errorf("unable to guess format for %v magic 0x%0x", filename, magic) } -func readAsPEMEx2(filename string, format string, password string) ([]byte, error) { +func readAsPEMEx(filename string, format CertificateKeyFormat, password string) ([]byte, error) { var pembuf bytes.Buffer - err := readAsPEMEx(filename, format, "", func(block *pem.Block, format string) error { + pembufFunc := func(block *pem.Block, format CertificateKeyFormat) error { return pem.Encode(&pembuf, block) - }) - if err != nil { - return nil, fmt.Errorf("could not load client cert: %v", err) } - return pembuf.Bytes(), nil -} - -func readAsPEMEx(filename string, format string, password string, callback func(*pem.Block, string) error) error { - rawFile, err := os.Open(filename) - if err != nil { - return fmt.Errorf("unable to open file: %s\n", err) - } - defer rawFile.Close() passwordFunc := func(promet string) string { return password } - reader := bufio.NewReaderSize(rawFile, 4) - format, err = formatForFile(reader, "", format) + rawFile, err := os.Open(filename) if err != nil { - return fmt.Errorf("unable to guess format for input stream") + return nil, fmt.Errorf("unable to open file: %s\n", err) } + defer rawFile.Close() - return readCertsFromStream(reader, "", format, passwordFunc, callback) + err = readCertsFromStream(rawFile, "", format, passwordFunc, pembufFunc) + if err != nil { + return nil, fmt.Errorf("could not read file: %s\n", err) + } + return pembuf.Bytes(), nil } // // ReadAsPEMFromFiles will read PEM blocks from the given set of inputs. Input @@ -287,26 +236,26 @@ func readAsPEMEx(filename string, format string, password string, callback func( // } // -// ReadAsPEM will read PEM blocks from the given set of inputs. Input data may -// be in plain-text PEM files, DER-encoded certificates or PKCS7 envelopes, or -// PKCS12/JCEKS keystores. All inputs will be converted to PEM blocks and -// passed to the callback. -func ReadAsPEM(readers []io.Reader, format string, password func(string) string, callback func(*pem.Block, string) error) error { - errs := []error{} - for _, r := range readers { - reader := bufio.NewReaderSize(r, 4) - format, err := formatForFile(reader, "", format) - if err != nil { - return fmt.Errorf("unable to guess format for input stream") - } - - err = readCertsFromStream(reader, "", format, password, callback) - if err != nil { - errs = append(errs, err) - } - } - return errorFromErrors(errs) -} +//// ReadAsPEM will read PEM blocks from the given set of inputs. Input data may +//// be in plain-text PEM files, DER-encoded certificates or PKCS7 envelopes, or +//// PKCS12/JCEKS keystores. All inputs will be converted to PEM blocks and +//// passed to the callback. +//func ReadAsPEM(readers []io.Reader, format string, password func(string) string, callback func(*pem.Block, string) error) error { +// errs := []error{} +// for _, r := range readers { +// reader := bufio.NewReaderSize(r, 4) +// format, err := formatForFile(reader, "", format) +// if err != nil { +// return fmt.Errorf("unable to guess format for input stream") +// } +// +// err = readCertsFromStream(reader, "", format, password, callback) +// if err != nil { +// errs = append(errs, err) +// } +// } +// return errorFromErrors(errs) +//} //// ReadAsX509FromFiles will read X.509 certificates from the given set of //// inputs. Input data may be in plain-text PEM files, DER-encoded certificates @@ -380,15 +329,14 @@ func ReadAsPEM(readers []io.Reader, format string, password func(string) string, //} // readCertsFromStream takes some input and converts it to PEM blocks. -func readCertsFromStream(reader io.Reader, filename string, format string, password func(string) string, callback func(*pem.Block, string) error) error { +func readCertsFromStream(reader io.Reader, filename string, format CertificateKeyFormat, password func(string) string, callback func(*pem.Block, CertificateKeyFormat) error) error { headers := map[string]string{} if filename != "" && filename != os.Stdin.Name() { headers[fileHeader] = filename } - format = strings.TrimSpace(format) switch format { - case "PEM": + case CertKeyFormatPEM: scanner := pemScanner(reader) for scanner.Scan() { block, _ := pem.Decode(scanner.Bytes()) @@ -399,7 +347,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw } } return nil - case "DER": + case CertKeyFormatDER: data, err := ioutil.ReadAll(reader) if err != nil { return fmt.Errorf("unable to read input: %s\n", err) @@ -407,6 +355,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw x509Certs, err0 := x509.ParseCertificates(data) if err0 == nil { for _, cert := range x509Certs { + fmt.Printf("cert cn: %v\n", cert.Issuer.CommonName) err := callback(encodeX509ToPEM(cert, headers), format) if err != nil { return err @@ -425,7 +374,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw return nil } return fmt.Errorf("unable to parse certificates from DER data\n* X.509 parser gave: %s\n* PKCS7 parser gave: %s\n", err0, err1) - case "PKCS12": + case CertKeyFormatPKCS12: data, err := ioutil.ReadAll(reader) if err != nil { return fmt.Errorf("unable to read input: %s\n", err) @@ -442,7 +391,7 @@ func readCertsFromStream(reader io.Reader, filename string, format string, passw } } return nil - case "JCEKS": + case CertKeyFormatJCEKS: keyStore, err := jceks.LoadFromReader(reader, []byte(password(""))) if err != nil { return fmt.Errorf("unable to parse keystore: %s\n", err) @@ -534,48 +483,47 @@ func keyToPem(key crypto.PrivateKey, headers map[string]string) (*pem.Block, err return nil, fmt.Errorf("unknown key type: %s\n", reflect.TypeOf(key)) } -// formatForFile returns the file format (either from flags or -// based on file extension). -func formatForFile(file *bufio.Reader, filename, format string) (string, error) { - // First, honor --format flag we got from user - if format != "" { - return format, nil - } - - // Second, attempt to guess based on extension - guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))] - if ok { - return guess, nil - } - - // Third, attempt to guess based on first 4 bytes of input - data, err := file.Peek(4) - if err != nil { - return "", fmt.Errorf("unable to read file: %s\n", err) - } - - // Heuristics for guessing -- best effort. - magic := binary.BigEndian.Uint32(data) - if magic == 0xCECECECE || magic == 0xFEEDFEED { - // JCEKS/JKS files always start with this prefix - return "JCEKS", nil - } - if magic == 0x2D2D2D2D || magic == 0x434f4e4e { - // Starts with '----' or 'CONN' (what s_client prints...) - // TODO start with 'Certificate' - return "PEM", nil - } - if magic&0xFFFF0000 == 0x30820000 { - // Looks like the input is DER-encoded, so it's either PKCS12 or X.509. - if magic&0x0000FF00 == 0x0300 { - // Probably X.509 - return "DER", nil - } - return "PKCS12", nil - } - - return "", fmt.Errorf("unable to guess file format") -} +//// formatForFile returns the file format (either from flags or +//// based on file extension). +//func formatForFile(file *bufio.Reader, filename, format string) (string, error) { +// // First, honor --format flag we got from user +// if format != "" { +// return format, nil +// } +// +// // Second, attempt to guess based on extension +// guess, ok := fileExtToFormat[strings.ToLower(filepath.Ext(filename))] +// if ok { +// return string(guess), nil +// } +// +// // Third, attempt to guess based on first 4 bytes of input +// data, err := file.Peek(4) +// if err != nil { +// return "", fmt.Errorf("unable to read file: %s\n", err) +// } +// +// // Heuristics for guessing -- best effort. +// magic := binary.BigEndian.Uint32(data) +// if magic == 0xCECECECE || magic == 0xFEEDFEED { +// // JCEKS/JKS files always start with this prefix +// return "JCEKS", nil +// } +// if magic == 0x2D2D2D2D || magic == 0x434f4e4e { +// // Starts with '----' or 'CONN' (what s_client prints...) +// return "PEM", nil +// } +// if magic&0xFFFF0000 == 0x30820000 { +// // Looks like the input is DER-encoded, so it's either PKCS12 or X.509. +// if magic&0x0000FF00 == 0x0300 { +// // Probably X.509 +// return "DER", nil +// } +// return "PKCS12", nil +// } +// +// return "", fmt.Errorf("unable to guess file format") +//} // pemScanner will return a bufio.Scanner that splits the input // from the given reader into PEM blocks. diff --git a/internal/certigo/lib/certs_test.go b/internal/certigo/lib/certs_test.go new file mode 100644 index 0000000..1676b9c --- /dev/null +++ b/internal/certigo/lib/certs_test.go @@ -0,0 +1,64 @@ +package lib + +import ( + "testing" +) + +func TestClientTLSConfig(t *testing.T) { + derfmt := CertKeyFormatDER + pemfmt := CertKeyFormatPEM + pfxfmt := CertKeyFormatPKCS12 + testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.crt", pemfmt, "tls/client.key", pemfmt, "") + testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.der", derfmt, "tls/client.key", pemfmt, "") + testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.pfx", pfxfmt, "tls/client.key", pemfmt, "") + testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client_pass.pfx", pfxfmt, "", pemfmt, "pfxpassword") + testTLSConfig(t, false, "tls/ca.der", derfmt, "tls/client.pfx", pfxfmt, "", pemfmt, "") + //testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.crt", pemfmt, "tls/client.key.pass", pemfmt, "123456") // not support + //testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client_pass.pfx", pfxfmt, "", pemfmt, "invalidpwd") // invalid + //testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.der", derfmt, "tls/client.key.der", derfmt, "") key can not be der +} + +func testTLSConfig( + t *testing.T, + insecure bool, + cacert string, + cacertFormat CertificateKeyFormat, + cert string, + certFormat CertificateKeyFormat, + key string, + keyFormat CertificateKeyFormat, + pass string, +) { + tlsConf, err := ClientTLSConfigV2(insecure, cacert, cacertFormat, cert, certFormat, key, keyFormat, pass) + if err != nil { + t.Fatalf("Failed to create TLS config err: %v", err) + } + if tlsConf == nil || tlsConf.Certificates == nil || tlsConf.RootCAs == nil { + t.Fatal("Failed to create TLS config tlsConf is nil") + } + +} + +func TestGuessFormat(t *testing.T) { + guessFormat(t, "tls/client.crt", CertKeyFormatPEM) + guessFormat(t, "tls/client.cer", CertKeyFormatPEM) + guessFormat(t, "tls/client.key", CertKeyFormatPEM) + guessFormat(t, "tls/client.pfx", CertKeyFormatPKCS12) + guessFormat(t, "tls/client.der", CertKeyFormatDER) + forceFormat(t, "tls/client.guess", CertKeyFormatPEM, CertKeyFormatPEM) +} + +func guessFormat(t *testing.T, filename string, formatExpected CertificateKeyFormat) { + forceFormat(t, filename, formatExpected, CertKeyFormatNONE) +} + +func forceFormat(t *testing.T, filename string, formatExpected, formatForce CertificateKeyFormat) { + guessFormat, err := GuessFormatForFile(filename, formatForce) + if err != nil { + t.Fatalf("failed to guess file err: %v", err) + } + if guessFormat != formatExpected { + t.Fatalf("failed to guess file %v format: %v expected: %v", filename, guessFormat, formatExpected) + } + t.Logf("format %v filename %v", guessFormat, filename) +} diff --git a/internal/certigo/lib/tls/ca.crl b/internal/certigo/lib/tls/ca.crl new file mode 100644 index 0000000..6f75589 --- /dev/null +++ b/internal/certigo/lib/tls/ca.crl @@ -0,0 +1,16 @@ +-----BEGIN X509 CRL----- +MIICfDBmAgEBMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNVBAMTAmNhFw0yMzEwMjQy +MzM5MThaFw0zNTA0MjQyMzM5MTZaMACgIzAhMB8GA1UdIwQYMBaAFAoT7NARRdDN +KQdlVkLUqtOsbJ54MA0GCSqGSIb3DQEBCwUAA4ICAQAdG+TDH5K5Y8xdB+kw9iIW +6icXq47ilbI/TRJbAq9BrmvPZXUI630fXojNijDgRqoSkgtbI+0wQuMqBFLJ0+VK +La4WTucsoYOQz89EJikB6z3m3BFNrubsxLjvNuW3i+ebi3ydH4VE2P7QgRjrW10K +M69pozzYM7CzNkQFmmXUcjcg/EPu4UiN2VQK6WXTTDBae1nGsAiZnsLyHNuFiK/G +9vVtoCDNc26GGaRb33Rh/1hS7hXqUCBQb1EdTNunZzVhAC9JfPdAKWlW35NWyrMz +/llYq3RMvouALXpOtRudi2G+ULto9iZdPGH9WiiVWpYx+Mdl1ab/yf/OzmsU8c1L +GHuh6Lx2Ed2Bz2y58Xk8di5IbER9GyVIecP3NbnL/Xrf0SKyw5WH/BTU66cwZgb6 +aUPjqm+U3TUrNXGnh2FKy77CVUTnQV75GU1V+aFsmyplQUOjIHpTP+sAad88tIsg +AMDcezxBVydZV6Zfl+52pGR2aByd8FYZi27Y0ggh8CyMlrmYTKYRP10RbIHwcaKN +bH6CpxGvQDGXRvn6D7BY9qEVt1v2oQzIW11Gm6ldlWDYzLUG0YaID4RrJ3KP2wfX +0fbpbA35kBL+coZ8iLsH79qR8p90IYdhM4QNwfWfptwPcxxW4y5AfNgFD7hao6Wg +N1Hgooy5gkyxxwNUBlRXOg== +-----END X509 CRL----- diff --git a/internal/certigo/lib/tls/ca.crt b/internal/certigo/lib/tls/ca.crt new file mode 100644 index 0000000..491dfad --- /dev/null +++ b/internal/certigo/lib/tls/ca.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIE2jCCAsKgAwIBAgIBATANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJjYTAe +Fw0yMzEwMjQyMzI5MThaFw0zNTA0MjQyMzM5MTZaMA0xCzAJBgNVBAMTAmNhMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm+lCc8AxpzKpx65+fJIb/kX+ +2wmRKjwZ107lsJRhKlEGZEyN6ncgIoDhsaZKBqcBtE8C4QqxWsocKLlb0irP1rnP +nfvUxglA0JFnHElq6KqfsW0aXcNe4DUU9iS2p69uvG/1aAEyUH5DMP0EpncJCLKp +1tw7lehQdNNFUtOdiMpfo88iiP+ECHdPEz3ZRmy9rjzXvWwd72AbH0x2/n7BE3SI +Q4njXDzFt1DZo/d2WssV1/Lghop5vQqeuUQS905Oc+VtKZ+OB52bTrqWsjvc+m8b +/bIUDTsKbR2Gm+/cTjLsjN5GgjAt0kVCS+N1iXSuvlJ/PfeQadk3XugPq20IWdF+ +VlcWe45qrrEjmpBaqrHOKW1DzNjW2yRNmXTz7R3IncnzdFc6pGbpTLtHQ+qnWJ4c +5xCw7SOHdVWFgTBTWd/NMIbDQRwNWcJheFQKTGKwaEJ2uP/s7PNJkcyPH1LNzgfv +MH93zbSw1KNyO36Vslc4cd/lrgtY+b/oMsr49dOn52iNKcJQospcgRJR3S2vkdKx +6i+SFyHSTjP35W04eDRLvK6JNcs3S6yrnyc5bAasvk1gOaosru4/ffEWxXNtQxmi +4FiGUpEpzdCySy3rmnrvEuos269jC79ecS80QzEi825BcMtgStjo0sFfddLiZhx+ +C0wMPv4e95M8YI1cc08CAwEAAaNFMEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB +/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAoT7NARRdDNKQdlVkLUqtOsbJ54MA0GCSqG +SIb3DQEBCwUAA4ICAQBMFWBTyqLqK3ZMOXDupvyMGkjbGP3G4IbVd3e5gjya0qJ9 +w7HhaUT+W/WjfvZ/AjMp3oweSqa1v2hpRQ9nh7odxRuOtOqiE85TCQDBmxyILWN4 +uDWmUFMD5P0rOxwICLLaPy1TCFU/9PlYfO6OT0gj4FNtwK0Z2P7vl920WOpPaKfk +caTH9c1ZovZKCDgrJxWFk+XJdLQX5xTMPZdjPwZxvZnPp1RU2ZyUJKb5uBC6slMU +fPMpmYwd7kt03IyqMepqDRYFI79Va9d6J+E3+yeCbvsgVaZhKX1crHDK2MqkV+TG +E1q+r3VpxCD4efqWaUJDHE9YSbDG8pCT6yM+H4hooSJfTgTKS6Ip/PhEtaM5D02j +vnLwQkf+kB96bJ6ks5RolIsPgH9Y7lZ95sz4xoBT906AjemW+Z76wiMovrOeqa7g +eXy8sSQIxAVhg+oQOS9z2ryt/H/g3AJnMdpcRz+/yd0hFRvFiIY3oUwaaAprcLD/ +a3X5+YKv1LFB9UohigroCofh0RtDXSX83cuP472Ant50qXk7D3WhdLzHLc1hgpPx +5jedrwzBh5VMW/fqhjqz2kCvS50ed+t83/kO9VGwyviiyipmw0VebDp3nCKmD1cx +VqL063NkQC83ijAG+GdeWYydqAqPikxcJnWunfbLFcr73lHjjLA64d+CE+rZOQ== +-----END CERTIFICATE----- diff --git a/internal/certigo/lib/tls/ca.der b/internal/certigo/lib/tls/ca.der new file mode 100644 index 0000000000000000000000000000000000000000..b64fce383c3197018dcffa202dda31ea30d1f4ad GIT binary patch literal 1246 zcmV<41R?t{f&|(yf&#*z0|Eg80s#Rq4F(A+hDe6@4FLfQ1pqJ&F$*vW1_M-@${Z-UThc1e*16A}`_#q>K+utA z97$^Es-LlK8ePL);58KXB(|roZoF^xXaO=%enT+*1g3Wh2(qcx+&h)%P;}EpQq!G? z%3q_;B8dNl2zO5tJ=sQVy{hGycK&|B6Lg3}iQ`;6#kWw|qxW`N%N5u1 z;D(BMy$YVWL=yK-PIKjLDW8r9otsX&ma;qC`fnTkvJ?$F3T+*RoA2CCGVF}rMuIRc z(nUf`<8_I2uD()#J@=4l**9M3536kmSU$eqdabXPj0X6a13M?>nTSe_i`5U}kdhjmqjfiP29-_0R0>RD zuxLVdxc}_z^GT7+j~`Oa&Ij)>e|OEau+*b+JARe2S2%Is<*o}@`M>Bg%J}uur{`#m zDZ)^q%3OgGQQa-Ck!H1Ox*D0R}J<1_Mxq>{J(xQFCvEgY% z{#*5p-Xs6_Hq{sEmS)%qz2skSz z6@`=K$#k?A=M>C6mt#K$alM((r&LtgoRlP{`M40evQrd%^C_8(9qvnX+>EL*>S_%Z z1tY&zYu9=w;Wzsyf^PdDRi&8p8CQgD893vsjlF8e7vzF2*d?pgX$1DFLTusY%2 If)nc5Imvf3kpKVy literal 0 HcmV?d00001 diff --git a/internal/certigo/lib/tls/ca.key b/internal/certigo/lib/tls/ca.key new file mode 100644 index 0000000..0c68f59 --- /dev/null +++ b/internal/certigo/lib/tls/ca.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/internal/certigo/lib/tls/client.cer b/internal/certigo/lib/tls/client.cer new file mode 100644 index 0000000..f240b35 --- /dev/null +++ b/internal/certigo/lib/tls/client.cer @@ -0,0 +1,101 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 1c:c0:06:ac:3b:23:e6:29:6a:a1:79:67:5e:e7:c1:98 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=ca + Validity + Not Before: Oct 24 23:29:18 2023 GMT + Not After : Oct 24 23:39:18 2033 GMT + Subject: CN=client + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d1:ec:d0:8f:11:4f:bb:52:15:ff:81:69:98:4d: + 16:fa:3b:93:3b:cb:65:20:14:cb:92:b9:aa:07:fc: + 0b:92:85:a8:ef:66:ff:e9:70:57:f8:b0:4f:cb:dc: + a4:18:b3:e6:ee:3e:2d:2a:e6:fe:7f:0d:8d:05:47: + b0:2b:b0:1d:6c:77:dd:1a:fb:f0:ac:a2:49:a4:6f: + 77:ec:b6:f1:da:e6:3b:90:08:eb:2d:8a:be:4d:57: + ff:da:fa:c2:5c:a2:67:68:f3:4e:2f:cd:b1:20:09: + fa:7c:7f:62:cb:1b:98:90:1c:58:74:d5:27:68:a9: + 98:20:39:e8:b1:53:55:7f:64:38:e5:68:ef:b3:2e: + 51:e3:2e:2a:56:1e:93:c9:ff:16:9c:a0:46:b4:86: + b9:a5:f4:d8:7f:72:ec:15:7e:8a:98:59:ee:e7:76: + 0f:57:85:3e:80:d2:79:0a:b3:15:4d:5e:38:c8:60: + 3f:10:62:12:6c:a6:97:4a:da:93:44:93:8c:2f:8a: + dd:0a:26:41:fb:2b:80:dc:93:2b:18:99:56:27:21: + cf:24:df:21:0e:a9:a6:21:41:cd:d9:0b:19:62:4a: + 03:b5:ad:a7:be:bd:1e:80:b5:da:e1:0e:e7:28:5d: + 41:cf:f2:30:6e:6f:7f:7f:ac:11:5a:44:1d:87:87: + 6f:cb + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Data Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Subject Key Identifier: + 86:F9:9A:9A:8E:0B:23:62:72:65:A0:BB:6A:03:4F:A6:AB:50:78:B3 + X509v3 Authority Key Identifier: + keyid:0A:13:EC:D0:11:45:D0:CD:29:07:65:56:42:D4:AA:D3:AC:6C:9E:78 + + X509v3 Subject Alternative Name: + DNS:client.com + Signature Algorithm: sha256WithRSAEncryption + 32:4b:c5:cb:ed:61:4f:f3:98:cc:4b:5d:3e:5e:73:ea:8d:0f: + 20:3c:42:c9:c2:f0:4c:7b:a4:3a:e2:7c:60:ba:a0:41:66:c4: + 62:4f:88:26:4e:9f:28:08:dc:28:67:2f:39:04:fc:9b:2d:74: + d6:57:2b:0f:05:5f:96:85:77:26:11:bd:39:1b:e1:30:7c:ec: + 40:ea:45:2a:3d:d7:2d:95:c5:25:75:09:59:f9:99:0a:9e:81: + bd:2a:f6:87:e7:d4:c3:0f:cf:eb:19:dc:53:96:81:5b:bc:36: + 94:8f:21:fb:8c:5f:13:b1:5e:28:2e:9b:6a:99:d6:3d:16:f8: + b7:96:77:24:99:af:7e:93:06:84:a1:45:fc:22:50:af:cb:9f: + 34:02:92:4c:f4:98:66:ab:d8:27:e2:68:84:e4:cb:f9:af:90: + f2:b0:1f:ae:cc:70:a5:ff:bf:e9:1e:81:bb:d1:1b:5a:a7:fb: + 50:f7:ab:ae:ff:0d:d9:69:c6:76:d6:15:2e:b9:0b:e5:d7:84: + 5a:ae:95:01:d1:e1:cb:8d:b7:ee:58:34:65:89:7e:b2:2b:3b: + cf:ef:b7:78:93:28:19:6b:a6:58:40:18:8b:c1:4d:cc:f7:ef: + 38:06:9a:52:e3:85:6a:ff:9b:09:09:36:f6:a2:d3:e0:c4:b6: + ca:79:90:49:a1:70:08:13:ca:b8:88:16:ad:c2:eb:5f:be:5b: + 25:be:1b:56:7d:b9:78:63:66:41:9a:db:b9:4e:e2:5a:14:28: + 1b:ee:cf:14:52:ed:ff:56:ff:9b:98:06:93:cb:b6:92:77:52: + 81:eb:31:6d:3e:6d:23:d9:c3:ff:38:24:24:66:96:7b:58:dc: + 70:a7:b2:f6:a3:f1:b7:f2:99:84:2a:28:65:ba:65:5f:dd:be: + 04:09:78:e4:42:8b:54:2e:9c:29:16:7f:7f:b5:e9:f6:53:c5: + 26:a0:f5:d9:17:4e:69:b6:ac:2f:73:36:cc:f0:09:37:af:03: + c3:21:5d:87:75:86:1a:72:a1:a0:07:90:34:1d:01:d8:05:37: + 0a:4c:ac:0d:10:b5:85:71:59:b7:96:94:e4:7c:9f:d8:60:7d: + 1e:28:24:58:c9:21:1d:f1:d6:29:f2:5f:25:c6:a4:10:47:11: + 1a:7f:fb:a4:8e:bd:a9:49:1a:9c:8d:7d:2c:83:b3:0c:89:ca: + 12:0c:ed:69:37:0f:d0:0b:a0:2c:1c:67:d0:63:3a:b6:8e:b8: + 21:af:fb:b3:54:19:6d:3c:b6:e1:e2:a3:d5:4f:f8:56:65:4c: + d4:c2:13:9e:e7:31:91:c9:13:b1:f5:14:c8:70:db:7d:d1:cf: + de:46:bd:63:6c:f9:d6:99 +-----BEGIN CERTIFICATE----- +MIIEMjCCAhqgAwIBAgIQHMAGrDsj5ilqoXlnXufBmDANBgkqhkiG9w0BAQsFADAN +MQswCQYDVQQDEwJjYTAeFw0yMzEwMjQyMzI5MThaFw0zMzEwMjQyMzM5MThaMBEx +DzANBgNVBAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANHs0I8RT7tSFf+BaZhNFvo7kzvLZSAUy5K5qgf8C5KFqO9m/+lwV/iwT8vcpBiz +5u4+LSrm/n8NjQVHsCuwHWx33Rr78KyiSaRvd+y28drmO5AI6y2Kvk1X/9r6wlyi +Z2jzTi/NsSAJ+nx/YssbmJAcWHTVJ2ipmCA56LFTVX9kOOVo77MuUeMuKlYek8n/ +FpygRrSGuaX02H9y7BV+iphZ7ud2D1eFPoDSeQqzFU1eOMhgPxBiEmyml0rak0ST +jC+K3QomQfsrgNyTKxiZVichzyTfIQ6ppiFBzdkLGWJKA7Wtp769HoC12uEO5yhd +Qc/yMG5vf3+sEVpEHYeHb8sCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCA7gwHQYD +VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSG+ZqajgsjYnJl +oLtqA0+mq1B4szAfBgNVHSMEGDAWgBQKE+zQEUXQzSkHZVZC1KrTrGyeeDAVBgNV +HREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAyS8XL7WFP85jM +S10+XnPqjQ8gPELJwvBMe6Q64nxguqBBZsRiT4gmTp8oCNwoZy85BPybLXTWVysP +BV+WhXcmEb05G+EwfOxA6kUqPdctlcUldQlZ+ZkKnoG9KvaH59TDD8/rGdxTloFb +vDaUjyH7jF8TsV4oLptqmdY9Fvi3lnckma9+kwaEoUX8IlCvy580ApJM9Jhmq9gn +4miE5Mv5r5DysB+uzHCl/7/pHoG70Rtap/tQ96uu/w3ZacZ21hUuuQvl14RarpUB +0eHLjbfuWDRliX6yKzvP77d4kygZa6ZYQBiLwU3M9+84BppS44Vq/5sJCTb2otPg +xLbKeZBJoXAIE8q4iBatwutfvlslvhtWfbl4Y2ZBmtu5TuJaFCgb7s8UUu3/Vv+b +mAaTy7aSd1KB6zFtPm0j2cP/OCQkZpZ7WNxwp7L2o/G38pmEKihlumVf3b4ECXjk +QotULpwpFn9/ten2U8UmoPXZF05ptqwvczbM8Ak3rwPDIV2HdYYacqGgB5A0HQHY +BTcKTKwNELWFcVm3lpTkfJ/YYH0eKCRYySEd8dYp8l8lxqQQRxEaf/ukjr2pSRqc +jX0sg7MMicoSDO1pNw/QC6AsHGfQYzq2jrghr/uzVBltPLbh4qPVT/hWZUzUwhOe +5zGRyROx9RTIcNt90c/eRr1jbPnWmQ== +-----END CERTIFICATE----- diff --git a/internal/certigo/lib/tls/client.crt b/internal/certigo/lib/tls/client.crt new file mode 100644 index 0000000..79b7a12 --- /dev/null +++ b/internal/certigo/lib/tls/client.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEMjCCAhqgAwIBAgIQHMAGrDsj5ilqoXlnXufBmDANBgkqhkiG9w0BAQsFADAN +MQswCQYDVQQDEwJjYTAeFw0yMzEwMjQyMzI5MThaFw0zMzEwMjQyMzM5MThaMBEx +DzANBgNVBAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANHs0I8RT7tSFf+BaZhNFvo7kzvLZSAUy5K5qgf8C5KFqO9m/+lwV/iwT8vcpBiz +5u4+LSrm/n8NjQVHsCuwHWx33Rr78KyiSaRvd+y28drmO5AI6y2Kvk1X/9r6wlyi +Z2jzTi/NsSAJ+nx/YssbmJAcWHTVJ2ipmCA56LFTVX9kOOVo77MuUeMuKlYek8n/ +FpygRrSGuaX02H9y7BV+iphZ7ud2D1eFPoDSeQqzFU1eOMhgPxBiEmyml0rak0ST +jC+K3QomQfsrgNyTKxiZVichzyTfIQ6ppiFBzdkLGWJKA7Wtp769HoC12uEO5yhd +Qc/yMG5vf3+sEVpEHYeHb8sCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCA7gwHQYD +VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSG+ZqajgsjYnJl +oLtqA0+mq1B4szAfBgNVHSMEGDAWgBQKE+zQEUXQzSkHZVZC1KrTrGyeeDAVBgNV +HREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAyS8XL7WFP85jM +S10+XnPqjQ8gPELJwvBMe6Q64nxguqBBZsRiT4gmTp8oCNwoZy85BPybLXTWVysP +BV+WhXcmEb05G+EwfOxA6kUqPdctlcUldQlZ+ZkKnoG9KvaH59TDD8/rGdxTloFb +vDaUjyH7jF8TsV4oLptqmdY9Fvi3lnckma9+kwaEoUX8IlCvy580ApJM9Jhmq9gn +4miE5Mv5r5DysB+uzHCl/7/pHoG70Rtap/tQ96uu/w3ZacZ21hUuuQvl14RarpUB +0eHLjbfuWDRliX6yKzvP77d4kygZa6ZYQBiLwU3M9+84BppS44Vq/5sJCTb2otPg +xLbKeZBJoXAIE8q4iBatwutfvlslvhtWfbl4Y2ZBmtu5TuJaFCgb7s8UUu3/Vv+b +mAaTy7aSd1KB6zFtPm0j2cP/OCQkZpZ7WNxwp7L2o/G38pmEKihlumVf3b4ECXjk +QotULpwpFn9/ten2U8UmoPXZF05ptqwvczbM8Ak3rwPDIV2HdYYacqGgB5A0HQHY +BTcKTKwNELWFcVm3lpTkfJ/YYH0eKCRYySEd8dYp8l8lxqQQRxEaf/ukjr2pSRqc +jX0sg7MMicoSDO1pNw/QC6AsHGfQYzq2jrghr/uzVBltPLbh4qPVT/hWZUzUwhOe +5zGRyROx9RTIcNt90c/eRr1jbPnWmQ== +-----END CERTIFICATE----- diff --git a/internal/certigo/lib/tls/client.csr b/internal/certigo/lib/tls/client.csr new file mode 100644 index 0000000..eddc94e --- /dev/null +++ b/internal/certigo/lib/tls/client.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICfjCCAWYCAQAwETEPMA0GA1UEAxMGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA0ezQjxFPu1IV/4FpmE0W+juTO8tlIBTLkrmqB/wLkoWo +72b/6XBX+LBPy9ykGLPm7j4tKub+fw2NBUewK7AdbHfdGvvwrKJJpG937Lbx2uY7 +kAjrLYq+TVf/2vrCXKJnaPNOL82xIAn6fH9iyxuYkBxYdNUnaKmYIDnosVNVf2Q4 +5Wjvsy5R4y4qVh6Tyf8WnKBGtIa5pfTYf3LsFX6KmFnu53YPV4U+gNJ5CrMVTV44 +yGA/EGISbKaXStqTRJOML4rdCiZB+yuA3JMrGJlWJyHPJN8hDqmmIUHN2QsZYkoD +ta2nvr0egLXa4Q7nKF1Bz/Iwbm9/f6wRWkQdh4dvywIDAQABoCgwJgYJKoZIhvcN +AQkOMRkwFzAVBgNVHREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4IB +AQCk6+YAX3TIhnqV8cUjt++viZrc/DFBAaDhD0NcmKE1SjPwd32UzDDXaunNwWQ8 +htz0dP0x0qSWFQjrUkYbFmUVt4La5kbsNoNNGFJqtVaDbCRI5ye8pg2TUvLkADM2 +daSKMwabNqSAgbW+w1kMk+v9F6A4TFb7Z8/DoRWtWmJS/uR3PkvGOy7skV26+f+t +FCty+DD/2NUe98chXPi2xu9aQld4ZLyWw5KDQqcyS4Gr1fOQQQWENqSM4T76yhuu +LAzpD7sKoqa7u5LsWVr6iQLIhKLU6BHxjZqV7SmGZranIZ0hqWfuRKs04dq/fTXK +GoVHc0Bd9JlPzp0faSgj55jg +-----END CERTIFICATE REQUEST----- diff --git a/internal/certigo/lib/tls/client.der b/internal/certigo/lib/tls/client.der new file mode 100644 index 0000000000000000000000000000000000000000..89ab33f9b5b463eee3f4320484d00fe1dccdf67c GIT binary patch literal 1078 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 literal 0 HcmV?d00001 diff --git a/internal/certigo/lib/tls/gen.sh b/internal/certigo/lib/tls/gen.sh new file mode 100755 index 0000000..a09c529 --- /dev/null +++ b/internal/certigo/lib/tls/gen.sh @@ -0,0 +1,18 @@ + +set -ex + +# generate der and pkcs12 file +openssl x509 -outform der -in tls/ca.crt -out tls/ca.der +openssl x509 -outform der -in tls/client.crt -out tls/client.der +openssl pkcs12 -export \ + -in tls/client.crt \ + -inkey tls/client.key \ + -certfile tls/ca.crt \ + -out tls/client.pfx \ + -password pass: +openssl pkcs12 -export \ + -in tls/client.crt \ + -inkey tls/client.key \ + -certfile tls/ca.crt \ + -out tls/client_pass.pfx \ + -password pass:pfxpassword From a0139c02ba5d02666328e1aeb7dc06ef8cddf2ea Mon Sep 17 00:00:00 2001 From: wangtiga Date: Sat, 11 Nov 2023 21:34:42 +0800 Subject: [PATCH 5/9] add testfile tls/testcert.pem tls/testkey.pem --- internal/certigo/lib/certs.go | 2 - internal/certigo/lib/certs_test.go | 26 +++--- internal/certigo/lib/tls/ca.crl | 16 ---- internal/certigo/lib/tls/ca.crt | 28 ------- internal/certigo/lib/tls/ca.der | Bin 1246 -> 0 bytes internal/certigo/lib/tls/ca.key | 51 ------------ internal/certigo/lib/tls/client.cer | 101 ----------------------- internal/certigo/lib/tls/client.crt | 25 ------ internal/certigo/lib/tls/client.csr | 16 ---- internal/certigo/lib/tls/client.der | Bin 1078 -> 0 bytes internal/certigo/lib/tls/client.guess | 101 ----------------------- internal/certigo/lib/tls/client.key | 27 ------ internal/certigo/lib/tls/client.pfx | Bin 3973 -> 0 bytes internal/certigo/lib/tls/client_pass.pfx | Bin 3973 -> 0 bytes internal/certigo/lib/tls/gen.sh | 18 ---- internal/testing/tls/ca.der | Bin 0 -> 1246 bytes internal/testing/tls/client.cer | 98 ++++++++++++++++++++++ internal/testing/tls/client.der | Bin 0 -> 1054 bytes internal/testing/tls/client.guess | 98 ++++++++++++++++++++++ internal/testing/tls/client.pfx | Bin 0 -> 3949 bytes internal/testing/tls/client_pass.pfx | Bin 0 -> 3949 bytes internal/testing/tls/testcert.pem | 24 ++++++ internal/testing/tls/testkey.pem | 28 +++++++ mk-test-files.sh | 20 +++++ 24 files changed, 280 insertions(+), 399 deletions(-) delete mode 100644 internal/certigo/lib/tls/ca.crl delete mode 100644 internal/certigo/lib/tls/ca.crt delete mode 100644 internal/certigo/lib/tls/ca.der delete mode 100644 internal/certigo/lib/tls/ca.key delete mode 100644 internal/certigo/lib/tls/client.cer delete mode 100644 internal/certigo/lib/tls/client.crt delete mode 100644 internal/certigo/lib/tls/client.csr delete mode 100644 internal/certigo/lib/tls/client.der delete mode 100644 internal/certigo/lib/tls/client.guess delete mode 100644 internal/certigo/lib/tls/client.key delete mode 100644 internal/certigo/lib/tls/client.pfx delete mode 100644 internal/certigo/lib/tls/client_pass.pfx delete mode 100755 internal/certigo/lib/tls/gen.sh create mode 100644 internal/testing/tls/ca.der create mode 100644 internal/testing/tls/client.cer create mode 100644 internal/testing/tls/client.der create mode 100644 internal/testing/tls/client.guess create mode 100644 internal/testing/tls/client.pfx create mode 100644 internal/testing/tls/client_pass.pfx create mode 100644 internal/testing/tls/testcert.pem create mode 100644 internal/testing/tls/testkey.pem diff --git a/internal/certigo/lib/certs.go b/internal/certigo/lib/certs.go index 81d47ac..6732059 100644 --- a/internal/certigo/lib/certs.go +++ b/internal/certigo/lib/certs.go @@ -162,7 +162,6 @@ func GuessFormatForFile(filename string, format CertificateKeyFormat) (Certifica // Heuristics for guessing -- best effort. magic := binary.BigEndian.Uint32(data) - fmt.Printf(" magic 0x%0x\n", magic) if magic == 0xCECECECE || magic == 0xFEEDFEED { // JCEKS/JKS files always start with this prefix return CertKeyFormatJCEKS, nil @@ -355,7 +354,6 @@ func readCertsFromStream(reader io.Reader, filename string, format CertificateKe x509Certs, err0 := x509.ParseCertificates(data) if err0 == nil { for _, cert := range x509Certs { - fmt.Printf("cert cn: %v\n", cert.Issuer.CommonName) err := callback(encodeX509ToPEM(cert, headers), format) if err != nil { return err diff --git a/internal/certigo/lib/certs_test.go b/internal/certigo/lib/certs_test.go index 1676b9c..008c96a 100644 --- a/internal/certigo/lib/certs_test.go +++ b/internal/certigo/lib/certs_test.go @@ -8,14 +8,12 @@ func TestClientTLSConfig(t *testing.T) { derfmt := CertKeyFormatDER pemfmt := CertKeyFormatPEM pfxfmt := CertKeyFormatPKCS12 - testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.crt", pemfmt, "tls/client.key", pemfmt, "") - testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.der", derfmt, "tls/client.key", pemfmt, "") - testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.pfx", pfxfmt, "tls/client.key", pemfmt, "") - testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client_pass.pfx", pfxfmt, "", pemfmt, "pfxpassword") - testTLSConfig(t, false, "tls/ca.der", derfmt, "tls/client.pfx", pfxfmt, "", pemfmt, "") - //testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.crt", pemfmt, "tls/client.key.pass", pemfmt, "123456") // not support - //testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client_pass.pfx", pfxfmt, "", pemfmt, "invalidpwd") // invalid - //testTLSConfig(t, false, "tls/ca.crt", pemfmt, "tls/client.der", derfmt, "tls/client.key.der", derfmt, "") key can not be der + testTLSConfig(t, false, "../../testing/tls/ca.crt", pemfmt, "../../testing/tls/client.crt", pemfmt, "../../testing/tls/client.key", pemfmt, "") + testTLSConfig(t, false, "../../testing/tls/ca.crt", pemfmt, "../../testing/tls/client.der", derfmt, "../../testing/tls/client.key", pemfmt, "") + testTLSConfig(t, false, "../../testing/tls/ca.crt", pemfmt, "../../testing/tls/client.pfx", pfxfmt, "../../testing/tls/client.key", pemfmt, "") + testTLSConfig(t, false, "../../testing/tls/ca.crt", pemfmt, "../../testing/tls/client_pass.pfx", pfxfmt, "", pemfmt, "pfxpassword") + testTLSConfig(t, false, "../../testing/tls/ca.der", derfmt, "../../testing/tls/client.pfx", pfxfmt, "", pemfmt, "") + testTLSConfig(t, false, "../../testing/tls/ca.crt", pemfmt, "../../testing/tls/testcert.pem", pemfmt, "../../testing/tls/testkey.pem", pemfmt, "") } func testTLSConfig( @@ -40,12 +38,12 @@ func testTLSConfig( } func TestGuessFormat(t *testing.T) { - guessFormat(t, "tls/client.crt", CertKeyFormatPEM) - guessFormat(t, "tls/client.cer", CertKeyFormatPEM) - guessFormat(t, "tls/client.key", CertKeyFormatPEM) - guessFormat(t, "tls/client.pfx", CertKeyFormatPKCS12) - guessFormat(t, "tls/client.der", CertKeyFormatDER) - forceFormat(t, "tls/client.guess", CertKeyFormatPEM, CertKeyFormatPEM) + guessFormat(t, "../../testing/tls/client.crt", CertKeyFormatPEM) + guessFormat(t, "../../testing/tls/client.cer", CertKeyFormatPEM) + guessFormat(t, "../../testing/tls/client.key", CertKeyFormatPEM) + guessFormat(t, "../../testing/tls/client.pfx", CertKeyFormatPKCS12) + guessFormat(t, "../../testing/tls/client.der", CertKeyFormatDER) + forceFormat(t, "../../testing/tls/client.guess", CertKeyFormatPEM, CertKeyFormatPEM) } func guessFormat(t *testing.T, filename string, formatExpected CertificateKeyFormat) { diff --git a/internal/certigo/lib/tls/ca.crl b/internal/certigo/lib/tls/ca.crl deleted file mode 100644 index 6f75589..0000000 --- a/internal/certigo/lib/tls/ca.crl +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN X509 CRL----- -MIICfDBmAgEBMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNVBAMTAmNhFw0yMzEwMjQy -MzM5MThaFw0zNTA0MjQyMzM5MTZaMACgIzAhMB8GA1UdIwQYMBaAFAoT7NARRdDN -KQdlVkLUqtOsbJ54MA0GCSqGSIb3DQEBCwUAA4ICAQAdG+TDH5K5Y8xdB+kw9iIW -6icXq47ilbI/TRJbAq9BrmvPZXUI630fXojNijDgRqoSkgtbI+0wQuMqBFLJ0+VK -La4WTucsoYOQz89EJikB6z3m3BFNrubsxLjvNuW3i+ebi3ydH4VE2P7QgRjrW10K -M69pozzYM7CzNkQFmmXUcjcg/EPu4UiN2VQK6WXTTDBae1nGsAiZnsLyHNuFiK/G -9vVtoCDNc26GGaRb33Rh/1hS7hXqUCBQb1EdTNunZzVhAC9JfPdAKWlW35NWyrMz -/llYq3RMvouALXpOtRudi2G+ULto9iZdPGH9WiiVWpYx+Mdl1ab/yf/OzmsU8c1L -GHuh6Lx2Ed2Bz2y58Xk8di5IbER9GyVIecP3NbnL/Xrf0SKyw5WH/BTU66cwZgb6 -aUPjqm+U3TUrNXGnh2FKy77CVUTnQV75GU1V+aFsmyplQUOjIHpTP+sAad88tIsg -AMDcezxBVydZV6Zfl+52pGR2aByd8FYZi27Y0ggh8CyMlrmYTKYRP10RbIHwcaKN -bH6CpxGvQDGXRvn6D7BY9qEVt1v2oQzIW11Gm6ldlWDYzLUG0YaID4RrJ3KP2wfX -0fbpbA35kBL+coZ8iLsH79qR8p90IYdhM4QNwfWfptwPcxxW4y5AfNgFD7hao6Wg -N1Hgooy5gkyxxwNUBlRXOg== ------END X509 CRL----- diff --git a/internal/certigo/lib/tls/ca.crt b/internal/certigo/lib/tls/ca.crt deleted file mode 100644 index 491dfad..0000000 --- a/internal/certigo/lib/tls/ca.crt +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIE2jCCAsKgAwIBAgIBATANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDEwJjYTAe -Fw0yMzEwMjQyMzI5MThaFw0zNTA0MjQyMzM5MTZaMA0xCzAJBgNVBAMTAmNhMIIC -IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm+lCc8AxpzKpx65+fJIb/kX+ -2wmRKjwZ107lsJRhKlEGZEyN6ncgIoDhsaZKBqcBtE8C4QqxWsocKLlb0irP1rnP -nfvUxglA0JFnHElq6KqfsW0aXcNe4DUU9iS2p69uvG/1aAEyUH5DMP0EpncJCLKp -1tw7lehQdNNFUtOdiMpfo88iiP+ECHdPEz3ZRmy9rjzXvWwd72AbH0x2/n7BE3SI -Q4njXDzFt1DZo/d2WssV1/Lghop5vQqeuUQS905Oc+VtKZ+OB52bTrqWsjvc+m8b -/bIUDTsKbR2Gm+/cTjLsjN5GgjAt0kVCS+N1iXSuvlJ/PfeQadk3XugPq20IWdF+ -VlcWe45qrrEjmpBaqrHOKW1DzNjW2yRNmXTz7R3IncnzdFc6pGbpTLtHQ+qnWJ4c -5xCw7SOHdVWFgTBTWd/NMIbDQRwNWcJheFQKTGKwaEJ2uP/s7PNJkcyPH1LNzgfv -MH93zbSw1KNyO36Vslc4cd/lrgtY+b/oMsr49dOn52iNKcJQospcgRJR3S2vkdKx -6i+SFyHSTjP35W04eDRLvK6JNcs3S6yrnyc5bAasvk1gOaosru4/ffEWxXNtQxmi -4FiGUpEpzdCySy3rmnrvEuos269jC79ecS80QzEi825BcMtgStjo0sFfddLiZhx+ -C0wMPv4e95M8YI1cc08CAwEAAaNFMEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB -/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAoT7NARRdDNKQdlVkLUqtOsbJ54MA0GCSqG -SIb3DQEBCwUAA4ICAQBMFWBTyqLqK3ZMOXDupvyMGkjbGP3G4IbVd3e5gjya0qJ9 -w7HhaUT+W/WjfvZ/AjMp3oweSqa1v2hpRQ9nh7odxRuOtOqiE85TCQDBmxyILWN4 -uDWmUFMD5P0rOxwICLLaPy1TCFU/9PlYfO6OT0gj4FNtwK0Z2P7vl920WOpPaKfk -caTH9c1ZovZKCDgrJxWFk+XJdLQX5xTMPZdjPwZxvZnPp1RU2ZyUJKb5uBC6slMU -fPMpmYwd7kt03IyqMepqDRYFI79Va9d6J+E3+yeCbvsgVaZhKX1crHDK2MqkV+TG -E1q+r3VpxCD4efqWaUJDHE9YSbDG8pCT6yM+H4hooSJfTgTKS6Ip/PhEtaM5D02j -vnLwQkf+kB96bJ6ks5RolIsPgH9Y7lZ95sz4xoBT906AjemW+Z76wiMovrOeqa7g -eXy8sSQIxAVhg+oQOS9z2ryt/H/g3AJnMdpcRz+/yd0hFRvFiIY3oUwaaAprcLD/ -a3X5+YKv1LFB9UohigroCofh0RtDXSX83cuP472Ant50qXk7D3WhdLzHLc1hgpPx -5jedrwzBh5VMW/fqhjqz2kCvS50ed+t83/kO9VGwyviiyipmw0VebDp3nCKmD1cx -VqL063NkQC83ijAG+GdeWYydqAqPikxcJnWunfbLFcr73lHjjLA64d+CE+rZOQ== ------END CERTIFICATE----- diff --git a/internal/certigo/lib/tls/ca.der b/internal/certigo/lib/tls/ca.der deleted file mode 100644 index b64fce383c3197018dcffa202dda31ea30d1f4ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1246 zcmV<41R?t{f&|(yf&#*z0|Eg80s#Rq4F(A+hDe6@4FLfQ1pqJ&F$*vW1_M-@${Z-UThc1e*16A}`_#q>K+utA z97$^Es-LlK8ePL);58KXB(|roZoF^xXaO=%enT+*1g3Wh2(qcx+&h)%P;}EpQq!G? z%3q_;B8dNl2zO5tJ=sQVy{hGycK&|B6Lg3}iQ`;6#kWw|qxW`N%N5u1 z;D(BMy$YVWL=yK-PIKjLDW8r9otsX&ma;qC`fnTkvJ?$F3T+*RoA2CCGVF}rMuIRc z(nUf`<8_I2uD()#J@=4l**9M3536kmSU$eqdabXPj0X6a13M?>nTSe_i`5U}kdhjmqjfiP29-_0R0>RD zuxLVdxc}_z^GT7+j~`Oa&Ij)>e|OEau+*b+JARe2S2%Is<*o}@`M>Bg%J}uur{`#m zDZ)^q%3OgGQQa-Ck!H1Ox*D0R}J<1_Mxq>{J(xQFCvEgY% z{#*5p-Xs6_Hq{sEmS)%qz2skSz z6@`=K$#k?A=M>C6mt#K$alM((r&LtgoRlP{`M40evQrd%^C_8(9qvnX+>EL*>S_%Z z1tY&zYu9=w;Wzsyf^PdDRi&8p8CQgD893vsjlF8e7vzF2*d?pgX$1DFLTusY%2 If)nc5Imvf3kpKVy diff --git a/internal/certigo/lib/tls/ca.key b/internal/certigo/lib/tls/ca.key deleted file mode 100644 index 0c68f59..0000000 --- a/internal/certigo/lib/tls/ca.key +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- diff --git a/internal/certigo/lib/tls/client.cer b/internal/certigo/lib/tls/client.cer deleted file mode 100644 index f240b35..0000000 --- a/internal/certigo/lib/tls/client.cer +++ /dev/null @@ -1,101 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 1c:c0:06:ac:3b:23:e6:29:6a:a1:79:67:5e:e7:c1:98 - Signature Algorithm: sha256WithRSAEncryption - Issuer: CN=ca - Validity - Not Before: Oct 24 23:29:18 2023 GMT - Not After : Oct 24 23:39:18 2033 GMT - Subject: CN=client - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:d1:ec:d0:8f:11:4f:bb:52:15:ff:81:69:98:4d: - 16:fa:3b:93:3b:cb:65:20:14:cb:92:b9:aa:07:fc: - 0b:92:85:a8:ef:66:ff:e9:70:57:f8:b0:4f:cb:dc: - a4:18:b3:e6:ee:3e:2d:2a:e6:fe:7f:0d:8d:05:47: - b0:2b:b0:1d:6c:77:dd:1a:fb:f0:ac:a2:49:a4:6f: - 77:ec:b6:f1:da:e6:3b:90:08:eb:2d:8a:be:4d:57: - ff:da:fa:c2:5c:a2:67:68:f3:4e:2f:cd:b1:20:09: - fa:7c:7f:62:cb:1b:98:90:1c:58:74:d5:27:68:a9: - 98:20:39:e8:b1:53:55:7f:64:38:e5:68:ef:b3:2e: - 51:e3:2e:2a:56:1e:93:c9:ff:16:9c:a0:46:b4:86: - b9:a5:f4:d8:7f:72:ec:15:7e:8a:98:59:ee:e7:76: - 0f:57:85:3e:80:d2:79:0a:b3:15:4d:5e:38:c8:60: - 3f:10:62:12:6c:a6:97:4a:da:93:44:93:8c:2f:8a: - dd:0a:26:41:fb:2b:80:dc:93:2b:18:99:56:27:21: - cf:24:df:21:0e:a9:a6:21:41:cd:d9:0b:19:62:4a: - 03:b5:ad:a7:be:bd:1e:80:b5:da:e1:0e:e7:28:5d: - 41:cf:f2:30:6e:6f:7f:7f:ac:11:5a:44:1d:87:87: - 6f:cb - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Digital Signature, Key Encipherment, Data Encipherment, Key Agreement - X509v3 Extended Key Usage: - TLS Web Server Authentication, TLS Web Client Authentication - X509v3 Subject Key Identifier: - 86:F9:9A:9A:8E:0B:23:62:72:65:A0:BB:6A:03:4F:A6:AB:50:78:B3 - X509v3 Authority Key Identifier: - keyid:0A:13:EC:D0:11:45:D0:CD:29:07:65:56:42:D4:AA:D3:AC:6C:9E:78 - - X509v3 Subject Alternative Name: - DNS:client.com - Signature Algorithm: sha256WithRSAEncryption - 32:4b:c5:cb:ed:61:4f:f3:98:cc:4b:5d:3e:5e:73:ea:8d:0f: - 20:3c:42:c9:c2:f0:4c:7b:a4:3a:e2:7c:60:ba:a0:41:66:c4: - 62:4f:88:26:4e:9f:28:08:dc:28:67:2f:39:04:fc:9b:2d:74: - d6:57:2b:0f:05:5f:96:85:77:26:11:bd:39:1b:e1:30:7c:ec: - 40:ea:45:2a:3d:d7:2d:95:c5:25:75:09:59:f9:99:0a:9e:81: - bd:2a:f6:87:e7:d4:c3:0f:cf:eb:19:dc:53:96:81:5b:bc:36: - 94:8f:21:fb:8c:5f:13:b1:5e:28:2e:9b:6a:99:d6:3d:16:f8: - b7:96:77:24:99:af:7e:93:06:84:a1:45:fc:22:50:af:cb:9f: - 34:02:92:4c:f4:98:66:ab:d8:27:e2:68:84:e4:cb:f9:af:90: - f2:b0:1f:ae:cc:70:a5:ff:bf:e9:1e:81:bb:d1:1b:5a:a7:fb: - 50:f7:ab:ae:ff:0d:d9:69:c6:76:d6:15:2e:b9:0b:e5:d7:84: - 5a:ae:95:01:d1:e1:cb:8d:b7:ee:58:34:65:89:7e:b2:2b:3b: - cf:ef:b7:78:93:28:19:6b:a6:58:40:18:8b:c1:4d:cc:f7:ef: - 38:06:9a:52:e3:85:6a:ff:9b:09:09:36:f6:a2:d3:e0:c4:b6: - ca:79:90:49:a1:70:08:13:ca:b8:88:16:ad:c2:eb:5f:be:5b: - 25:be:1b:56:7d:b9:78:63:66:41:9a:db:b9:4e:e2:5a:14:28: - 1b:ee:cf:14:52:ed:ff:56:ff:9b:98:06:93:cb:b6:92:77:52: - 81:eb:31:6d:3e:6d:23:d9:c3:ff:38:24:24:66:96:7b:58:dc: - 70:a7:b2:f6:a3:f1:b7:f2:99:84:2a:28:65:ba:65:5f:dd:be: - 04:09:78:e4:42:8b:54:2e:9c:29:16:7f:7f:b5:e9:f6:53:c5: - 26:a0:f5:d9:17:4e:69:b6:ac:2f:73:36:cc:f0:09:37:af:03: - c3:21:5d:87:75:86:1a:72:a1:a0:07:90:34:1d:01:d8:05:37: - 0a:4c:ac:0d:10:b5:85:71:59:b7:96:94:e4:7c:9f:d8:60:7d: - 1e:28:24:58:c9:21:1d:f1:d6:29:f2:5f:25:c6:a4:10:47:11: - 1a:7f:fb:a4:8e:bd:a9:49:1a:9c:8d:7d:2c:83:b3:0c:89:ca: - 12:0c:ed:69:37:0f:d0:0b:a0:2c:1c:67:d0:63:3a:b6:8e:b8: - 21:af:fb:b3:54:19:6d:3c:b6:e1:e2:a3:d5:4f:f8:56:65:4c: - d4:c2:13:9e:e7:31:91:c9:13:b1:f5:14:c8:70:db:7d:d1:cf: - de:46:bd:63:6c:f9:d6:99 ------BEGIN CERTIFICATE----- -MIIEMjCCAhqgAwIBAgIQHMAGrDsj5ilqoXlnXufBmDANBgkqhkiG9w0BAQsFADAN -MQswCQYDVQQDEwJjYTAeFw0yMzEwMjQyMzI5MThaFw0zMzEwMjQyMzM5MThaMBEx -DzANBgNVBAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANHs0I8RT7tSFf+BaZhNFvo7kzvLZSAUy5K5qgf8C5KFqO9m/+lwV/iwT8vcpBiz -5u4+LSrm/n8NjQVHsCuwHWx33Rr78KyiSaRvd+y28drmO5AI6y2Kvk1X/9r6wlyi -Z2jzTi/NsSAJ+nx/YssbmJAcWHTVJ2ipmCA56LFTVX9kOOVo77MuUeMuKlYek8n/ -FpygRrSGuaX02H9y7BV+iphZ7ud2D1eFPoDSeQqzFU1eOMhgPxBiEmyml0rak0ST -jC+K3QomQfsrgNyTKxiZVichzyTfIQ6ppiFBzdkLGWJKA7Wtp769HoC12uEO5yhd -Qc/yMG5vf3+sEVpEHYeHb8sCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCA7gwHQYD -VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSG+ZqajgsjYnJl -oLtqA0+mq1B4szAfBgNVHSMEGDAWgBQKE+zQEUXQzSkHZVZC1KrTrGyeeDAVBgNV -HREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAyS8XL7WFP85jM -S10+XnPqjQ8gPELJwvBMe6Q64nxguqBBZsRiT4gmTp8oCNwoZy85BPybLXTWVysP -BV+WhXcmEb05G+EwfOxA6kUqPdctlcUldQlZ+ZkKnoG9KvaH59TDD8/rGdxTloFb -vDaUjyH7jF8TsV4oLptqmdY9Fvi3lnckma9+kwaEoUX8IlCvy580ApJM9Jhmq9gn -4miE5Mv5r5DysB+uzHCl/7/pHoG70Rtap/tQ96uu/w3ZacZ21hUuuQvl14RarpUB -0eHLjbfuWDRliX6yKzvP77d4kygZa6ZYQBiLwU3M9+84BppS44Vq/5sJCTb2otPg -xLbKeZBJoXAIE8q4iBatwutfvlslvhtWfbl4Y2ZBmtu5TuJaFCgb7s8UUu3/Vv+b -mAaTy7aSd1KB6zFtPm0j2cP/OCQkZpZ7WNxwp7L2o/G38pmEKihlumVf3b4ECXjk -QotULpwpFn9/ten2U8UmoPXZF05ptqwvczbM8Ak3rwPDIV2HdYYacqGgB5A0HQHY -BTcKTKwNELWFcVm3lpTkfJ/YYH0eKCRYySEd8dYp8l8lxqQQRxEaf/ukjr2pSRqc -jX0sg7MMicoSDO1pNw/QC6AsHGfQYzq2jrghr/uzVBltPLbh4qPVT/hWZUzUwhOe -5zGRyROx9RTIcNt90c/eRr1jbPnWmQ== ------END CERTIFICATE----- diff --git a/internal/certigo/lib/tls/client.crt b/internal/certigo/lib/tls/client.crt deleted file mode 100644 index 79b7a12..0000000 --- a/internal/certigo/lib/tls/client.crt +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEMjCCAhqgAwIBAgIQHMAGrDsj5ilqoXlnXufBmDANBgkqhkiG9w0BAQsFADAN -MQswCQYDVQQDEwJjYTAeFw0yMzEwMjQyMzI5MThaFw0zMzEwMjQyMzM5MThaMBEx -DzANBgNVBAMTBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANHs0I8RT7tSFf+BaZhNFvo7kzvLZSAUy5K5qgf8C5KFqO9m/+lwV/iwT8vcpBiz -5u4+LSrm/n8NjQVHsCuwHWx33Rr78KyiSaRvd+y28drmO5AI6y2Kvk1X/9r6wlyi -Z2jzTi/NsSAJ+nx/YssbmJAcWHTVJ2ipmCA56LFTVX9kOOVo77MuUeMuKlYek8n/ -FpygRrSGuaX02H9y7BV+iphZ7ud2D1eFPoDSeQqzFU1eOMhgPxBiEmyml0rak0ST -jC+K3QomQfsrgNyTKxiZVichzyTfIQ6ppiFBzdkLGWJKA7Wtp769HoC12uEO5yhd -Qc/yMG5vf3+sEVpEHYeHb8sCAwEAAaOBiTCBhjAOBgNVHQ8BAf8EBAMCA7gwHQYD -VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSG+ZqajgsjYnJl -oLtqA0+mq1B4szAfBgNVHSMEGDAWgBQKE+zQEUXQzSkHZVZC1KrTrGyeeDAVBgNV -HREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAyS8XL7WFP85jM -S10+XnPqjQ8gPELJwvBMe6Q64nxguqBBZsRiT4gmTp8oCNwoZy85BPybLXTWVysP -BV+WhXcmEb05G+EwfOxA6kUqPdctlcUldQlZ+ZkKnoG9KvaH59TDD8/rGdxTloFb -vDaUjyH7jF8TsV4oLptqmdY9Fvi3lnckma9+kwaEoUX8IlCvy580ApJM9Jhmq9gn -4miE5Mv5r5DysB+uzHCl/7/pHoG70Rtap/tQ96uu/w3ZacZ21hUuuQvl14RarpUB -0eHLjbfuWDRliX6yKzvP77d4kygZa6ZYQBiLwU3M9+84BppS44Vq/5sJCTb2otPg -xLbKeZBJoXAIE8q4iBatwutfvlslvhtWfbl4Y2ZBmtu5TuJaFCgb7s8UUu3/Vv+b -mAaTy7aSd1KB6zFtPm0j2cP/OCQkZpZ7WNxwp7L2o/G38pmEKihlumVf3b4ECXjk -QotULpwpFn9/ten2U8UmoPXZF05ptqwvczbM8Ak3rwPDIV2HdYYacqGgB5A0HQHY -BTcKTKwNELWFcVm3lpTkfJ/YYH0eKCRYySEd8dYp8l8lxqQQRxEaf/ukjr2pSRqc -jX0sg7MMicoSDO1pNw/QC6AsHGfQYzq2jrghr/uzVBltPLbh4qPVT/hWZUzUwhOe -5zGRyROx9RTIcNt90c/eRr1jbPnWmQ== ------END CERTIFICATE----- diff --git a/internal/certigo/lib/tls/client.csr b/internal/certigo/lib/tls/client.csr deleted file mode 100644 index eddc94e..0000000 --- a/internal/certigo/lib/tls/client.csr +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICfjCCAWYCAQAwETEPMA0GA1UEAxMGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA0ezQjxFPu1IV/4FpmE0W+juTO8tlIBTLkrmqB/wLkoWo -72b/6XBX+LBPy9ykGLPm7j4tKub+fw2NBUewK7AdbHfdGvvwrKJJpG937Lbx2uY7 -kAjrLYq+TVf/2vrCXKJnaPNOL82xIAn6fH9iyxuYkBxYdNUnaKmYIDnosVNVf2Q4 -5Wjvsy5R4y4qVh6Tyf8WnKBGtIa5pfTYf3LsFX6KmFnu53YPV4U+gNJ5CrMVTV44 -yGA/EGISbKaXStqTRJOML4rdCiZB+yuA3JMrGJlWJyHPJN8hDqmmIUHN2QsZYkoD -ta2nvr0egLXa4Q7nKF1Bz/Iwbm9/f6wRWkQdh4dvywIDAQABoCgwJgYJKoZIhvcN -AQkOMRkwFzAVBgNVHREEDjAMggpjbGllbnQuY29tMA0GCSqGSIb3DQEBCwUAA4IB -AQCk6+YAX3TIhnqV8cUjt++viZrc/DFBAaDhD0NcmKE1SjPwd32UzDDXaunNwWQ8 -htz0dP0x0qSWFQjrUkYbFmUVt4La5kbsNoNNGFJqtVaDbCRI5ye8pg2TUvLkADM2 -daSKMwabNqSAgbW+w1kMk+v9F6A4TFb7Z8/DoRWtWmJS/uR3PkvGOy7skV26+f+t -FCty+DD/2NUe98chXPi2xu9aQld4ZLyWw5KDQqcyS4Gr1fOQQQWENqSM4T76yhuu -LAzpD7sKoqa7u5LsWVr6iQLIhKLU6BHxjZqV7SmGZranIZ0hqWfuRKs04dq/fTXK -GoVHc0Bd9JlPzp0faSgj55jg ------END CERTIFICATE REQUEST----- diff --git a/internal/certigo/lib/tls/client.der b/internal/certigo/lib/tls/client.der deleted file mode 100644 index 89ab33f9b5b463eee3f4320484d00fe1dccdf67c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1078 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 diff --git a/internal/certigo/lib/tls/gen.sh b/internal/certigo/lib/tls/gen.sh deleted file mode 100755 index a09c529..0000000 --- a/internal/certigo/lib/tls/gen.sh +++ /dev/null @@ -1,18 +0,0 @@ - -set -ex - -# generate der and pkcs12 file -openssl x509 -outform der -in tls/ca.crt -out tls/ca.der -openssl x509 -outform der -in tls/client.crt -out tls/client.der -openssl pkcs12 -export \ - -in tls/client.crt \ - -inkey tls/client.key \ - -certfile tls/ca.crt \ - -out tls/client.pfx \ - -password pass: -openssl pkcs12 -export \ - -in tls/client.crt \ - -inkey tls/client.key \ - -certfile tls/ca.crt \ - -out tls/client_pass.pfx \ - -password pass:pfxpassword diff --git a/internal/testing/tls/ca.der b/internal/testing/tls/ca.der new file mode 100644 index 0000000000000000000000000000000000000000..55fa2e6a76796d59b1933cdbcd0f02034c56497f GIT binary patch literal 1246 zcmV<41R?t{f&|(yf&#*z0|Eg80s#Rq4F(A+hDe6@4FLfQ1pqJ&F$*vW1_MQMiJYhOOJlUI^H1YB^z2e6joRKr zCf8MGhf#3yggdl-BtdS1J0LKW7(mTot$Z-LjBdc%f4rFWsET_rps+cr+?ycQwt05TK$lM-B>W}P{q|{z40hQy=&dA<*H5IYPWQ|8H>aBI z`_L)es{y44WAIq|iRh|iff)7ry;XY@Y@1j&``Dgua}0pfyd7zt)2&7u4{s-hdz|1q zb}6=7TKN;;<{A5kK6)piL{&z%<=2Zx3L8vC=U$r*deS>z_GPjG+ZmjItK4fXBQG_o zhIXWG8)hyu90L$w#Ry0LL&^~|GP4F;j53c?`>LDFU6_*R2yOpcP!ZX-DRqTt7 zuex1J;26J3hWgR`P&h|`)RC{5RSKcAZni?s=`>epAd1tloR4?E)L~$pLAe4e4H`y; z9|h)Mk`5cnR{#en8L5wcYLrDZ5h151021|uYP$Naiz*rgO~_1g}Hzh(v+v z=RRU7WsbZQPro&IzBTQ03rMobFz zyaXo!tL#@~t~1%V(t8~Ug`Z*?c)44*JPG=(?-?OPj$5NTC@@f!b6-7rL*4ISi;CP= zG7jU6&YTt;coHms{;k_x`?zQ?0|Em900E;#Fhej71_M!H1Ox*D0R}J<1_MzD@%fG6u{aT#v=6)rmtg)j{U2`Yw2 zhW8Bt0Sg5H1A+np082LG{G#;W6~-U!hhTH&g9mH=sKyl{qD-!Od=BO^+f1+Ph}dw9 zVc(J)L1UT4n;|C0n?$2MzP_QjN;Y%!t{k*E9g&a4D}MQ*zKM<)*E0Didq(Gks|$rOxcZJXw9CMR0;mlgUv|B>U&9+4|p_l&%KqYhyBnP>oE*y5x<9K=cf^zG#Z zAf$OH+5z5cLE!yfiIw54zqq~_?GW3a&`r1K-7fd;+L@?3T->Ke`R~dFl|mrUe_wB= zGcR)rIe4yzvV_<5y?S1Au;1h^T$UBODK~xq==n}$aW7?;5L-^0n=OS!XeyGWjHnzl zT29F*YJQ_T{2&|RniwNC>GbQtPyv;Fo${3FPWJHrlhs6nh72vGe*f5pu90^pJ7Gli ze9C7g0B&F$IupyxQ@Ewv8l_F8J+VZWVat(*hb?@}#2xgJ1P5DbeEZC6_`n+Zuv`z) zTE(pYw{~eR-nRc)@lUjtHv#xbuQvsuw-9h>woqKx$ZD)rgee{hVd?5)%v$b71U^KyHw* IaK4g!Zi@CO=>Px# literal 0 HcmV?d00001 diff --git a/internal/testing/tls/client.cer b/internal/testing/tls/client.cer new file mode 100644 index 0000000..d5b0d1a --- /dev/null +++ b/internal/testing/tls/client.cer @@ -0,0 +1,98 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + fb:74:28:21:75:d8:66:1b:0a:85:23:ee:49:63:e7:f0 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=ca + Validity + Not Before: Aug 25 15:45:53 2017 GMT + Not After : Aug 25 15:45:52 2027 GMT + Subject: CN=client + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b5:27:11:0f:3a:c6:72:7f:cf:3c:de:d9:4f:04: + 46:a3:a2:dc:84:0a:da:d8:31:9e:3c:16:c6:04:99: + 0d:57:bc:a3:e8:1f:77:9b:ef:e1:2f:ee:d4:41:54: + 0b:a9:c8:1f:3b:5d:0e:4f:53:fa:0d:a8:0b:69:a3: + fe:96:0f:92:46:9c:a4:95:b3:e1:00:30:44:97:9b: + 31:05:d3:84:fd:84:af:2e:49:dd:1c:54:41:24:77: + 4b:5b:54:da:57:6d:63:1b:8a:f1:e7:c7:95:69:f2: + 8d:a6:23:1d:2c:56:b8:06:b0:95:b7:b7:e7:18:6c: + d4:e9:dd:b3:93:76:6c:fb:2c:a6:e2:40:dd:88:c7: + 4c:07:fb:6f:ec:3d:76:1a:71:9b:20:6c:8d:18:76: + 8f:4a:9e:ac:a4:3e:6d:93:a8:16:02:2f:59:33:84: + 69:6f:68:0a:2d:8d:d0:c8:9b:b3:a0:9d:a1:82:15: + ee:02:6c:ae:10:64:1e:2e:17:0d:de:33:e3:e6:2c: + 6d:13:b1:a1:fd:09:3f:d9:46:b1:36:d6:20:5f:83: + 4a:ea:82:92:99:28:c7:2a:61:07:ed:5d:d2:ea:96: + 29:2e:57:af:45:fb:42:fc:e3:14:5f:79:5a:81:d4: + 4e:23:d1:1c:01:19:65:bc:13:06:38:58:72:b7:54: + 4d:b9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Data Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Subject Key Identifier: + CB:3E:FD:01:7F:64:96:91:BB:C5:AF:BD:C6:8C:0B:B8:C6:98:FC:31 + X509v3 Authority Key Identifier: + keyid:CD:05:2E:EB:98:07:0B:80:27:EB:68:71:19:6E:FB:15:2E:3B:0E:85 + + Signature Algorithm: sha256WithRSAEncryption + 74:80:f0:ec:f3:a4:63:cb:f3:b6:fa:5f:10:c9:a6:1f:c2:69: + b2:4c:c3:e3:35:5a:8a:81:53:f5:ba:e8:a4:58:4a:cd:e6:14: + c0:97:0b:43:23:d1:6e:88:c1:41:a9:e0:5d:7a:24:fc:21:0b: + f3:10:44:0f:62:ee:bd:90:05:f6:5d:80:56:04:c5:83:6b:ce: + 5c:a3:97:c9:ce:d0:33:57:b6:33:54:bd:5b:ca:1c:5d:da:38: + 0c:d7:8b:ac:cb:1e:8f:6f:39:21:60:a0:4d:7a:cb:a3:1e:3e: + f0:43:4b:ab:fb:ce:4a:a7:ae:87:a8:a0:ae:34:2b:db:8f:4c: + ef:e7:c3:c7:45:69:28:8d:13:e0:c9:3a:5b:2d:d5:d7:08:e5: + 89:5e:9e:b6:5d:f7:5d:2f:50:5f:ec:d2:42:5b:94:13:c8:7a: + 07:a0:eb:0e:7a:83:da:8d:be:0e:3a:64:1e:87:3a:af:6f:d1: + 4f:00:75:45:04:fa:d4:e7:75:e7:d4:25:11:03:34:de:05:0d: + 93:fc:e2:b8:9f:1e:84:75:08:31:3f:df:95:56:ea:c1:43:d3: + 76:60:13:3d:54:42:66:7d:02:bc:2d:fe:7f:f8:42:47:7b:97: + 2d:3b:2d:57:9b:80:37:03:9d:b3:67:59:06:8d:fb:d6:52:d1: + 89:51:29:c9:e5:a8:61:32:6e:83:c7:ad:f0:93:ba:18:34:24: + d7:9c:fb:a9:69:5b:48:35:6c:a0:36:54:bf:75:0b:16:b9:b1: + da:59:21:70:07:df:d0:c0:ad:3b:e3:e1:ff:e0:4a:43:ab:d1: + c2:30:c9:7c:c8:f3:24:b4:e9:af:eb:d1:f2:6a:3b:b7:32:f1: + ac:87:3f:c3:2c:d6:5f:f6:86:29:3b:e9:5b:53:c5:f5:db:86: + 7a:5e:27:c4:ce:d3:22:06:55:0f:5b:be:4a:62:ff:57:e0:24: + db:29:37:44:e3:94:1a:44:c8:8e:65:77:07:e0:71:35:fe:24: + 3d:20:e1:a0:ec:2a:65:32:53:1c:1e:0f:a5:43:b0:a9:5d:08: + ed:51:48:c2:12:99:23:f0:10:2c:f1:82:c3:a1:d2:e7:8e:28: + 2c:e7:af:fc:ef:9f:b7:71:56:6e:d3:e7:58:fb:d7:8d:b7:f1: + 08:ab:38:da:17:01:31:ef:68:5b:2f:28:64:d8:87:92:fb:ee: + d0:96:82:43:85:8a:a5:ab:e9:e0:e7:85:25:f7:9e:c0:f1:ee: + d3:b1:25:47:94:b6:55:19:7c:3c:ca:a8:f2:c7:13:b0:59:a1: + 71:ea:6b:c5:cc:6a:dc:06:db:c2:80:ad:87:c0:48:98:43:da: + 97:27:95:4f:91:da:38:db +-----BEGIN CERTIFICATE----- +MIIEGjCCAgKgAwIBAgIRAPt0KCF12GYbCoUj7klj5/AwDQYJKoZIhvcNAQELBQAw +DTELMAkGA1UEAxMCY2EwHhcNMTcwODI1MTU0NTUzWhcNMjcwODI1MTU0NTUyWjAR +MQ8wDQYDVQQDEwZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC1JxEPOsZyf8883tlPBEajotyECtrYMZ48FsYEmQ1XvKPoH3eb7+Ev7tRBVAup +yB87XQ5PU/oNqAtpo/6WD5JGnKSVs+EAMESXmzEF04T9hK8uSd0cVEEkd0tbVNpX +bWMbivHnx5Vp8o2mIx0sVrgGsJW3t+cYbNTp3bOTdmz7LKbiQN2Ix0wH+2/sPXYa +cZsgbI0Ydo9KnqykPm2TqBYCL1kzhGlvaAotjdDIm7OgnaGCFe4CbK4QZB4uFw3e +M+PmLG0TsaH9CT/ZRrE21iBfg0rqgpKZKMcqYQftXdLqlikuV69F+0L84xRfeVqB +1E4j0RwBGWW8EwY4WHK3VE25AgMBAAGjcTBvMA4GA1UdDwEB/wQEAwIDuDAdBgNV +HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFMs+/QF/ZJaRu8Wv +vcaMC7jGmPwxMB8GA1UdIwQYMBaAFM0FLuuYBwuAJ+tocRlu+xUuOw6FMA0GCSqG +SIb3DQEBCwUAA4ICAQB0gPDs86Rjy/O2+l8QyaYfwmmyTMPjNVqKgVP1uuikWErN +5hTAlwtDI9FuiMFBqeBdeiT8IQvzEEQPYu69kAX2XYBWBMWDa85co5fJztAzV7Yz +VL1byhxd2jgM14usyx6PbzkhYKBNesujHj7wQ0ur+85Kp66HqKCuNCvbj0zv58PH +RWkojRPgyTpbLdXXCOWJXp62XfddL1Bf7NJCW5QTyHoHoOsOeoPajb4OOmQehzqv +b9FPAHVFBPrU53Xn1CURAzTeBQ2T/OK4nx6EdQgxP9+VVurBQ9N2YBM9VEJmfQK8 +Lf5/+EJHe5ctOy1Xm4A3A52zZ1kGjfvWUtGJUSnJ5ahhMm6Dx63wk7oYNCTXnPup +aVtINWygNlS/dQsWubHaWSFwB9/QwK074+H/4EpDq9HCMMl8yPMktOmv69Hyaju3 +MvGshz/DLNZf9oYpO+lbU8X124Z6XifEztMiBlUPW75KYv9X4CTbKTdE45QaRMiO +ZXcH4HE1/iQ9IOGg7CplMlMcHg+lQ7CpXQjtUUjCEpkj8BAs8YLDodLnjigs56/8 +75+3cVZu0+dY+9eNt/EIqzjaFwEx72hbLyhk2IeS++7QloJDhYqlq+ng54Ul957A +8e7TsSVHlLZVGXw8yqjyxxOwWaFx6mvFzGrcBtvCgK2HwEiYQ9qXJ5VPkdo42w== +-----END CERTIFICATE----- diff --git a/internal/testing/tls/client.der b/internal/testing/tls/client.der new file mode 100644 index 0000000000000000000000000000000000000000..dcac0fc58119e0c5acc80b621fb020d99171dff5 GIT binary patch literal 1054 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 F{ulD`Yr_Bl literal 0 HcmV?d00001 diff --git a/internal/testing/tls/client_pass.pfx b/internal/testing/tls/client_pass.pfx new file mode 100644 index 0000000000000000000000000000000000000000..92d92c7fd96c831408fac89cd869f9421c625a00 GIT binary patch literal 3949 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 H0s;sCyP0*~ literal 0 HcmV?d00001 diff --git a/internal/testing/tls/testcert.pem b/internal/testing/tls/testcert.pem new file mode 100644 index 0000000..1804f11 --- /dev/null +++ b/internal/testing/tls/testcert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIUb9rMtZakmrPUSehrVFATTotK2JAwDQYJKoZIhvcNAQEL +BQAwgZYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdHZW9yZ2lhMRAwDgYDVQQHDAdB +dGxhbnRhMRIwEAYDVQQKDAlGdWxsU3RvcnkxFDASBgNVBAsMC0VuZ2luZWVyaW5n +MRMwEQYDVQQDDApTY290dCBCbHVtMSQwIgYJKoZIhvcNAQkBFhVkcmFnb25zaW50 +aEBnbWFpbC5jb20wHhcNMjMxMTAyMTYzMDI2WhcNMjQxMTAxMTYzMDI2WjCBljEL +MAkGA1UEBhMCVVMxEDAOBgNVBAgMB0dlb3JnaWExEDAOBgNVBAcMB0F0bGFudGEx +EjAQBgNVBAoMCUZ1bGxTdG9yeTEUMBIGA1UECwwLRW5naW5lZXJpbmcxEzARBgNV +BAMMClNjb3R0IEJsdW0xJDAiBgkqhkiG9w0BCQEWFWRyYWdvbnNpbnRoQGdtYWls +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKWAjgrJW+83dAYb +N8aQpVSxbbqxfhokavnulLtko5l0TBnZKAJROKHYEKF84wEYMAudqsfUkEq6AxEg +z9ob3MqpyFORLO1aysgw4uzOzmp/D95dcbY49soQfxQKA19UvMSr8ERBdoULjaR7 +oNCnf2j2cNkZT/yBN68FcTLLoGH+CH+KZovUhzjswew9Q51l9Wq2QxENFreKaxQE +kwA8i+hxd2VoVIrDRL1i7UMQOYfjgPaVWPPilvuH+/eyuHuVW84ziqHzLM78ZMHB +XJB3g4H1irj1bfPt54L7kqymv1paYaOUpSHqBcIE8+NlvOSnW2LeRqDdAN3tcq7N +IvsYRvECAwEAAaNTMFEwHQYDVR0OBBYEFEtQbQRGQjJJgKwYhIHbnCihExdxMB8G +A1UdIwQYMBaAFEtQbQRGQjJJgKwYhIHbnCihExdxMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggEBAIw/P+VNIv75FghOYuEiCIGf63A1vjoMmNOJ7xI2 +t9dmW54/1MHqC3KlQYyOzTBCbOuEASfLT05mq16aIh834gIVB3upYFsBkB5bBpRg +LnNTYHSnnpB5k/jikLapgJk/cyRXPQkxCdtH4TwB813iOvou/BSrIIvUYh0vFmGW +cLe3abB+zCg8gwbOf4pvLGp37ogtTQo2gkcPI2CrKEnpxs4J5AabkCLuk+2XyClP +9ow3eZAqTUsMOsKbHLGMBOnMthRbpN8UWGWTm8yYo296Kt1Gs1PbBw+xHC84KLsq +unwlChN+nOKOW4sPIMb9rjkPGMgOgu4rQmqeoGf295fbFIs= +-----END CERTIFICATE----- diff --git a/internal/testing/tls/testkey.pem b/internal/testing/tls/testkey.pem new file mode 100644 index 0000000..b8b7cba --- /dev/null +++ b/internal/testing/tls/testkey.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClgI4KyVvvN3QG +GzfGkKVUsW26sX4aJGr57pS7ZKOZdEwZ2SgCUTih2BChfOMBGDALnarH1JBKugMR +IM/aG9zKqchTkSztWsrIMOLszs5qfw/eXXG2OPbKEH8UCgNfVLzEq/BEQXaFC42k +e6DQp39o9nDZGU/8gTevBXEyy6Bh/gh/imaL1Ic47MHsPUOdZfVqtkMRDRa3imsU +BJMAPIvocXdlaFSKw0S9Yu1DEDmH44D2lVjz4pb7h/v3srh7lVvOM4qh8yzO/GTB +wVyQd4OB9Yq49W3z7eeC+5Kspr9aWmGjlKUh6gXCBPPjZbzkp1ti3kag3QDd7XKu +zSL7GEbxAgMBAAECggEAEh4xLpgdkuIQtwxqvjeeideEqi/9HJKJDYRjTuJ1EHsN +S7UcrqhCmWEkbPFVjoyd0d+4TvkDtNKJPGpJpthvAta0YgWeE/vhACpt5Tu8mCcB +zzeOl8LDrZpBtyljdh+6LJOgEXDTLzx1DKEmGUGE7rIv52xgd8WTmXrwif2FuMRf +7o3hJe7KxUZ3ZtOPzHvyy+L2mghrqkMp0kEIb7XfoCYPHWHHElvunZBndQUTC6g5 +MIbMfB5nBilniZtk3YxNIeMgDxj2iOX6SPYUiTmJrVPuT9zuhdX88rhJKtC18Nqt +aF1L2c6+DBNT9toPsaXZH9tu7NKasf0RhwEtNU+4SwKBgQDc8eeIhsrhhmleXd8e +AUQZdrc0GYdXMJpbyxXFkaVpv0K30rwXj0ON7Mtvb9twihGOQB9jS3syKvPkRW2o +2rYNE4sASy+Z9Vi7UbTPT7fozwpymC714+sT31rVTy0QbxDLuj/IcR+65r0kd7xF +tV9IaPH+UiEN/J0ib7Q3nWggPwKBgQC/wrzWJAMAzwhQy3lwalje5xsa2V7Ud0L7 +RTEA5P1ix7Fn+dVGKmcTn6c+i7vyKQDkpSfMRQ0z3+ycwP2yu4ng6UkTRzlECKHI +MpwL92bQNXBhDSjLbH+K8pn7ZQIxdYhpgPjwD+o3D0F1GmnOr+nUFFx5ZZHOyNgn +bHo7+MzMzwKBgQCJxKkrv2kIQUi4l+4FBqMRAa5w5S44Fs1ZSYP04sFy89jFSLkS +M7na6HldrjD1tpIF0kQAJVPXT2Muxn//VwlHlBULhNZUuOCwRN1qm3nAyEDqfaxi +lNDDXnWEJs+hvK+LaUJWWPuBDlmIQMT77oFQZGfovgtwbkEI9QA54YPI/wKBgF13 +xiN6mhwizaLUCvVIYNkFPKjxms9k8jkXmLMe6oLjYw2TMOlqcaOXBiXuZkW6xryr +46IlZjIKy4H8b6xWzPXbv8qtxLPsoS67vGP4yxxhb81eZKwCzogjh/qJWXBSIZOL +UctxdnAv92/k1/3usMK2yfxCDbgFHZbZwRrKQsjxAoGAX/ZzFLVjtJAX0M0iYJ8i +NoJeqNpK7CtnBPcIWFFMamQ1OPOWHtVV32OlD5IfKXTNYhLMLVHzHLEl4fkjUoFN +u+TkCymZqISPUPLJF8PxT9J0uYxvFNpSTDhYK7QacO5TnboYDjjSodg/9PChclBp +Gwo7hmAwa/JiWuOh/yvo2f4= +-----END PRIVATE KEY----- diff --git a/mk-test-files.sh b/mk-test-files.sh index 51db6f4..95fba5b 100755 --- a/mk-test-files.sh +++ b/mk-test-files.sh @@ -55,3 +55,23 @@ cs sign wrong-client --years 10 --CA wrong-ca # Create expired cert cs request-cert --common-name expired --ip 127.0.0.1 --domain localhost cs sign expired --years 0 --CA ca + +# Create DER PKCS12 file +openssl x509 -outform der -in tls/ca.crt -out tls/ca.der +openssl x509 -outform der -in tls/client.crt -out tls/client.der +openssl x509 -outform der -in tls/client.crt -out tls/client.der +openssl x509 -text -in tls/client.crt > tls/client.cer +sed '1s/^/invalidGuess/' tls/client.cer > tls/client.guess +openssl pkcs12 -export \ + -in tls/client.crt \ + -inkey tls/client.key \ + -certfile tls/ca.crt \ + -out tls/client.pfx \ + -password pass: +openssl pkcs12 -export \ + -in tls/client.crt \ + -inkey tls/client.key \ + -certfile tls/ca.crt \ + -out tls/client_pass.pfx \ + -password pass:pfxpassword + From 99e57ce792a0a2555c2b10d9f42a8951c72e8189 Mon Sep 17 00:00:00 2001 From: wangtiga Date: Sat, 18 Nov 2023 00:04:19 +0800 Subject: [PATCH 6/9] tidy code --- go.mod | 17 ----------------- go.sum | 22 ++-------------------- mk-test-files.sh | 38 +++++++++++++++++++------------------- 3 files changed, 21 insertions(+), 56 deletions(-) diff --git a/go.mod b/go.mod index e62bec7..8d0925e 100644 --- a/go.mod +++ b/go.mod @@ -14,11 +14,6 @@ require ( require ( cloud.google.com/go/compute v1.19.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - github.com/Masterminds/goutils v1.1.0 // indirect - github.com/Masterminds/semver v1.4.2 // indirect - github.com/Masterminds/sprig v2.22.0+incompatible // indirect - github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect - github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/bufbuild/protocompile v0.6.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -26,25 +21,13 @@ require ( github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f // indirect github.com/envoyproxy/protoc-gen-validate v0.10.1 // indirect - github.com/fatih/color v1.13.0 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/huandu/xstrings v1.2.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect - github.com/mitchellh/copystructure v1.0.0 // indirect - github.com/mitchellh/reflectwalk v1.0.0 // indirect - github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect - gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect - gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225 // indirect ) diff --git a/go.sum b/go.sum index 549042a..966786a 100644 --- a/go.sum +++ b/go.sum @@ -4,15 +4,10 @@ cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IK cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= @@ -36,7 +31,6 @@ github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -51,24 +45,16 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 h1:BhQQWYKJwXPtAhm12d4gQU4LKS9Yov22yOrDc2QA7ho= github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8/go.mod h1:ntWhh7pzdiiRKBMxUB5iG+Q2gmZBxGxpX1KyK6N8kX8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -116,8 +102,6 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -144,15 +128,13 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go. google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= -google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225 h1:JBwmEvLfCqgPcIq8MjVMQxsF3LVL4XG/HH0qiG0+IFY= gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/mk-test-files.sh b/mk-test-files.sh index 95fba5b..b934af0 100755 --- a/mk-test-files.sh +++ b/mk-test-files.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -e +set -ex cd "$(dirname $0)" @@ -56,22 +56,22 @@ cs sign wrong-client --years 10 --CA wrong-ca cs request-cert --common-name expired --ip 127.0.0.1 --domain localhost cs sign expired --years 0 --CA ca -# Create DER PKCS12 file -openssl x509 -outform der -in tls/ca.crt -out tls/ca.der -openssl x509 -outform der -in tls/client.crt -out tls/client.der -openssl x509 -outform der -in tls/client.crt -out tls/client.der -openssl x509 -text -in tls/client.crt > tls/client.cer -sed '1s/^/invalidGuess/' tls/client.cer > tls/client.guess -openssl pkcs12 -export \ - -in tls/client.crt \ - -inkey tls/client.key \ - -certfile tls/ca.crt \ - -out tls/client.pfx \ - -password pass: -openssl pkcs12 -export \ - -in tls/client.crt \ - -inkey tls/client.key \ - -certfile tls/ca.crt \ - -out tls/client_pass.pfx \ - -password pass:pfxpassword +## Create DER PKCS12 file +#openssl x509 -outform der -in testing/tls/ca.crt -out testing/tls/ca.der +#openssl x509 -outform der -in testing/tls/client.crt -out testing/tls/client.der +#openssl x509 -outform der -in testing/tls/client.crt -out testing/tls/client.der +#openssl x509 -text -in testing/tls/client.crt > testing/tls/client.cer +#sed '1s/^/invalidGuess/' testing/tls/client.cer > testing/tls/client.guess +#openssl pkcs12 -export \ +# -in testing/tls/client.crt \ +# -inkey testing/tls/client.key \ +# -certfile testing/tls/ca.crt \ +# -out testing/tls/client.pfx \ +# -password pass: +#openssl pkcs12 -export \ +# -in testing/tls/client.crt \ +# -inkey testing/tls/client.key \ +# -certfile testing/tls/ca.crt \ +# -out testing/tls/client_pass.pfx \ +# -password pass:pfxpassword From f5e721338a320ba8d88a12df81b1a78bade70583 Mon Sep 17 00:00:00 2001 From: wangtiga Date: Sat, 18 Nov 2023 00:07:58 +0800 Subject: [PATCH 7/9] tidy code --- go.mod | 2 +- go.sum | 4 ++-- mk-test-files.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 8d0925e..d8f3ce0 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/jhump/protoreflect v1.15.3 github.com/square/certigo v1.16.0 golang.org/x/crypto v0.14.0 - google.golang.org/grpc v1.57.0 + google.golang.org/grpc v1.57.1 google.golang.org/protobuf v1.31.0 ) diff --git a/go.sum b/go.sum index 966786a..d097d2b 100644 --- a/go.sum +++ b/go.sum @@ -128,8 +128,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go. google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= +google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= diff --git a/mk-test-files.sh b/mk-test-files.sh index b934af0..ba40a69 100755 --- a/mk-test-files.sh +++ b/mk-test-files.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -ex +set -e cd "$(dirname $0)" From bba2985273e0e67cc4a6cbd37acd12e803a960d8 Mon Sep 17 00:00:00 2001 From: wangtiga Date: Sun, 10 Dec 2023 00:59:52 +0800 Subject: [PATCH 8/9] tidy code --- go.mod | 6 +++--- go.sum | 12 +++++------ grpcurl.go | 38 ----------------------------------- internal/certigo/lib/certs.go | 28 +++++++++++++------------- 4 files changed, 23 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index d8f3ce0..79b6f1c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/golang/protobuf v1.5.3 github.com/jhump/protoreflect v1.15.3 github.com/square/certigo v1.16.0 - golang.org/x/crypto v0.14.0 + golang.org/x/crypto v0.16.0 google.golang.org/grpc v1.57.1 google.golang.org/protobuf v1.31.0 ) @@ -24,8 +24,8 @@ require ( golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect diff --git a/go.sum b/go.sum index d097d2b..b1c9d26 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -99,14 +99,14 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/grpcurl.go b/grpcurl.go index d0ee535..5ac07be 100644 --- a/grpcurl.go +++ b/grpcurl.go @@ -12,7 +12,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/base64" - "encoding/pem" "errors" "fmt" "io/ioutil" @@ -27,7 +26,6 @@ import ( "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/desc/protoprint" "github.com/jhump/protoreflect/dynamic" - "golang.org/x/crypto/pkcs12" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -534,42 +532,6 @@ func ClientTLSConfig(insecureSkipVerify bool, cacertFile, clientCertFile, client return lib.ClientTLSConfigV2(insecureSkipVerify, cacertFile, lib.CertKeyFormatPEM, clientCertFile, lib.CertKeyFormatPEM, clientKeyFile, lib.CertKeyFormatPEM, "") } -func inputFiles(fileNames []string) ([]*os.File, error) { - var files []*os.File - for _, filename := range fileNames { - if filename == "" { - continue - } - rawFile, err := os.Open(filename) - if err != nil { - return nil, fmt.Errorf("unable to open file: %s\n", err) - } - files = append(files, rawFile) - } - return files, nil -} - -func loadClientCertP12(pfxFile, pfxPassword string) (tls.Certificate, error) { - b, err := os.ReadFile(pfxFile) - if err != nil { - return tls.Certificate{}, fmt.Errorf("os.ReadFile err: %w", err) - } - pemBlocks, err := pkcs12.ToPEM(b, pfxPassword) - if err != nil { - return tls.Certificate{}, fmt.Errorf("pkcs12.ToPEM err: %w", err) - } - - var pemBytes []byte - for _, block := range pemBlocks { - pemBytes = append(pemBytes, pem.EncodeToMemory(block)...) - } - certificate, err := tls.X509KeyPair(pemBytes, pemBytes) - if err != nil { - return tls.Certificate{}, err - } - return certificate, nil -} - // ServerTransportCredentials builds transport credentials for a gRPC server using the // given properties. If cacertFile is blank, the server will not request client certs // unless requireClientCerts is true. When requireClientCerts is false and cacertFile is diff --git a/internal/certigo/lib/certs.go b/internal/certigo/lib/certs.go index 6732059..b6dcde4 100644 --- a/internal/certigo/lib/certs.go +++ b/internal/certigo/lib/certs.go @@ -149,7 +149,7 @@ func GuessFormatForFile(filename string, format CertificateKeyFormat) (Certifica file, err := os.Open(filename) if err != nil { - return CertKeyFormatNONE, fmt.Errorf("unable to open file: %s\n", err) + return CertKeyFormatNONE, fmt.Errorf("unable to open file: %v", err) } defer file.Close() reader := bufio.NewReaderSize(file, 4) @@ -157,7 +157,7 @@ func GuessFormatForFile(filename string, format CertificateKeyFormat) (Certifica // Third, attempt to guess based on first 4 bytes of input data, err := reader.Peek(4) if err != nil { - return CertKeyFormatNONE, fmt.Errorf("unable to read file: %s\n", err) + return CertKeyFormatNONE, fmt.Errorf("unable to read file: %v", err) } // Heuristics for guessing -- best effort. @@ -201,13 +201,13 @@ func readAsPEMEx(filename string, format CertificateKeyFormat, password string) rawFile, err := os.Open(filename) if err != nil { - return nil, fmt.Errorf("unable to open file: %s\n", err) + return nil, fmt.Errorf("unable to open file: %v", err) } defer rawFile.Close() err = readCertsFromStream(rawFile, "", format, passwordFunc, pembufFunc) if err != nil { - return nil, fmt.Errorf("could not read file: %s\n", err) + return nil, fmt.Errorf("could not read file: %v", err) } return pembuf.Bytes(), nil } @@ -349,7 +349,7 @@ func readCertsFromStream(reader io.Reader, filename string, format CertificateKe case CertKeyFormatDER: data, err := ioutil.ReadAll(reader) if err != nil { - return fmt.Errorf("unable to read input: %s\n", err) + return fmt.Errorf("unable to read input: %v", err) } x509Certs, err0 := x509.ParseCertificates(data) if err0 == nil { @@ -371,15 +371,15 @@ func readCertsFromStream(reader io.Reader, filename string, format CertificateKe } return nil } - return fmt.Errorf("unable to parse certificates from DER data\n* X.509 parser gave: %s\n* PKCS7 parser gave: %s\n", err0, err1) + return fmt.Errorf("unable to parse certificates from DER data X.509 parser gave: [%v] PKCS7 parser gave: [%v]", err0, err1) case CertKeyFormatPKCS12: data, err := ioutil.ReadAll(reader) if err != nil { - return fmt.Errorf("unable to read input: %s\n", err) + return fmt.Errorf("unable to read input: %v", err) } blocks, err := pkcs12.ToPEM(data, password("")) if err != nil || len(blocks) == 0 { - return fmt.Errorf("keystore appears to be empty or password was incorrect\n") + return fmt.Errorf("keystore appears to be empty or password was incorrect") } for _, block := range blocks { block.Headers = mergeHeaders(block.Headers, headers) @@ -392,7 +392,7 @@ func readCertsFromStream(reader io.Reader, filename string, format CertificateKe case CertKeyFormatJCEKS: keyStore, err := jceks.LoadFromReader(reader, []byte(password(""))) if err != nil { - return fmt.Errorf("unable to parse keystore: %s\n", err) + return fmt.Errorf("unable to parse keystore: %v", err) } for _, alias := range keyStore.ListCerts() { cert, _ := keyStore.GetCert(alias) @@ -404,14 +404,14 @@ func readCertsFromStream(reader io.Reader, filename string, format CertificateKe for _, alias := range keyStore.ListPrivateKeys() { key, certs, err := keyStore.GetPrivateKeyAndCerts(alias, []byte(password(alias))) if err != nil { - return fmt.Errorf("unable to parse keystore: %s\n", err) + return fmt.Errorf("unable to parse keystore: %v", err) } mergedHeaders := mergeHeaders(headers, map[string]string{nameHeader: alias}) block, err := keyToPem(key, mergedHeaders) if err != nil { - return fmt.Errorf("problem reading key: %s\n", err) + return fmt.Errorf("problem reading key: %v", err) } if err := callback(block, format); err != nil { @@ -426,7 +426,7 @@ func readCertsFromStream(reader io.Reader, filename string, format CertificateKe } return nil } - return fmt.Errorf("unknown file type '%s'\n", format) + return fmt.Errorf("unknown file type '%s'", format) } func mergeHeaders(baseHeaders, extraHeaders map[string]string) (headers map[string]string) { @@ -470,7 +470,7 @@ func keyToPem(key crypto.PrivateKey, headers map[string]string) (*pem.Block, err case *ecdsa.PrivateKey: raw, err := x509.MarshalECPrivateKey(k) if err != nil { - return nil, fmt.Errorf("error marshaling key: %s\n", reflect.TypeOf(key)) + return nil, fmt.Errorf("error marshaling key: %s", reflect.TypeOf(key)) } return &pem.Block{ Type: "EC PRIVATE KEY", @@ -478,7 +478,7 @@ func keyToPem(key crypto.PrivateKey, headers map[string]string) (*pem.Block, err Headers: headers, }, nil } - return nil, fmt.Errorf("unknown key type: %s\n", reflect.TypeOf(key)) + return nil, fmt.Errorf("unknown key type: %s", reflect.TypeOf(key)) } //// formatForFile returns the file format (either from flags or From 559de6389d378d0266c48ab7974b5a175b3ae911 Mon Sep 17 00:00:00 2001 From: wangtiga Date: Sun, 17 Dec 2023 21:56:37 +0800 Subject: [PATCH 9/9] build success in cimg/go:1.20 --- go.sum | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go.sum b/go.sum index b1c9d26..f54437e 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,7 @@ github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byA github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -46,6 +47,7 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= @@ -59,6 +61,7 @@ github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8/go.mod h1:n github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/square/certigo v1.16.0 h1:8g9UgWssUcOMzeFJF0nSMGjmDVXBk6UTZNOMArxcrxM= github.com/square/certigo v1.16.0/go.mod h1:v9HqynkvfNbHR0aluXlxutyGsZbUpiNACLkYpHyxRlU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -74,6 +77,7 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=