From e148c7cde64c59ff45493207f16b7a8ef46487cb Mon Sep 17 00:00:00 2001 From: u5surf Date: Fri, 27 Jul 2018 23:54:20 +0900 Subject: [PATCH 1/6] issue-98 support a pem with pass phrase --- CONFIGURATION.md | 1 + cmd/gaurun_recover/gaurun_recover.go | 1 + gaurun/apns_http2.go | 32 +++++++++++++++++++++++++--- gaurun/client.go | 1 + gaurun/conf.go | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index a8966f2..7b01b2e 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -28,6 +28,7 @@ The configuration for Gaurun has some sections. The example is [here](conf/gauru |enabled |bool |On/Off for push notication to APNs |true | | |pem_cert_path |string|certification file path for APNs | | | |pem_key_path |string|secret key file path for APNs | | | +|pem_key_passphrase |string|secret key file pass phrase for APNs | | | |sandbox |bool |On/Off for sandbox environment |true | | |retry_max |int |maximum retry count for push notication to APNs |1 | | |timeout |int |timeout for push notification to APNs |5 | | diff --git a/cmd/gaurun_recover/gaurun_recover.go b/cmd/gaurun_recover/gaurun_recover.go index c92621b..916f6e2 100644 --- a/cmd/gaurun_recover/gaurun_recover.go +++ b/cmd/gaurun_recover/gaurun_recover.go @@ -138,6 +138,7 @@ func main() { APNSClient, err = gaurun.NewApnsClientHttp2( gaurun.ConfGaurun.Ios.PemCertPath, gaurun.ConfGaurun.Ios.PemKeyPath, + gaurun.ConfGaurun.Ios.PemKeyPassphrase, ) if err != nil { gaurun.LogSetupFatal(err) diff --git a/gaurun/apns_http2.go b/gaurun/apns_http2.go index 6ae6bd6..09cb339 100644 --- a/gaurun/apns_http2.go +++ b/gaurun/apns_http2.go @@ -2,7 +2,10 @@ package gaurun import ( "crypto/tls" + "crypto/x509" "encoding/json" + "encoding/pem" + "io/ioutil" "net" "net/http" "time" @@ -37,13 +40,13 @@ func NewTransportHttp2(cert tls.Certificate) (*http.Transport, error) { return transport, nil } -func NewApnsClientHttp2(certPath, keyPath string) (*http.Client, error) { - cert, err := tls.LoadX509KeyPair(certPath, keyPath) +func NewApnsClientHttp2(certPath, keyPath, keyPassphrase string) (*http.Client, error) { + cert, err := loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase) if err != nil { return nil, err } - transport, err := NewTransportHttp2(cert) + transport, err := NewTransportHttp2(*cert) if err != nil { return nil, err } @@ -54,6 +57,29 @@ func NewApnsClientHttp2(certPath, keyPath string) (*http.Client, error) { }, nil } +func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (*tls.Certificate, error) { + keyPEMBlock, err := ioutil.ReadFile(keyPath) + if err != nil { + return nil, err + } + if keyPassphrase != "" { + pemBlock, _ := pem.Decode(keyPEMBlock) + keyPEMBlock, err = x509.DecryptPEMBlock(pemBlock, []byte(keyPassphrase)) + if err != nil { + return nil, err + } + } + certPEMBlock, err := ioutil.ReadFile(certPath) + if err != nil { + return nil, err + } + cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock) + if err != nil { + return nil, err + } + return &cert, nil +} + func NewApnsServiceHttp2(client *http.Client) *push.Service { var host string if ConfGaurun.Ios.Sandbox { diff --git a/gaurun/client.go b/gaurun/client.go index 8a3a015..811ecab 100644 --- a/gaurun/client.go +++ b/gaurun/client.go @@ -61,6 +61,7 @@ func InitAPNSClient() error { APNSClient, err = NewApnsClientHttp2( ConfGaurun.Ios.PemCertPath, ConfGaurun.Ios.PemKeyPath, + ConfGaurun.Ios.PemKeyPassphrase, ) if err != nil { return err diff --git a/gaurun/conf.go b/gaurun/conf.go index 5a7184e..d6706d0 100644 --- a/gaurun/conf.go +++ b/gaurun/conf.go @@ -41,6 +41,7 @@ type SectionIos struct { Enabled bool `toml:"enabled"` PemCertPath string `toml:"pem_cert_path"` PemKeyPath string `toml:"pem_key_path"` + PemKeyPassphrase string `toml:"pem_key_passphrase"` Sandbox bool `toml:"sandbox"` RetryMax int `toml:"retry_max"` Timeout int `toml:"timeout"` From 3cfc3dce75161fd2303f3425c2ff6a82496d99b0 Mon Sep 17 00:00:00 2001 From: u5surf Date: Mon, 30 Jul 2018 18:50:37 +0900 Subject: [PATCH 2/6] issue-98 fix return type in loadX509KeyPairWithPassword --- gaurun/apns_http2.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gaurun/apns_http2.go b/gaurun/apns_http2.go index 09cb339..6b45756 100644 --- a/gaurun/apns_http2.go +++ b/gaurun/apns_http2.go @@ -46,7 +46,7 @@ func NewApnsClientHttp2(certPath, keyPath, keyPassphrase string) (*http.Client, return nil, err } - transport, err := NewTransportHttp2(*cert) + transport, err := NewTransportHttp2(cert) if err != nil { return nil, err } @@ -57,27 +57,27 @@ func NewApnsClientHttp2(certPath, keyPath, keyPassphrase string) (*http.Client, }, nil } -func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (*tls.Certificate, error) { +func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (tls.Certificate, error) { keyPEMBlock, err := ioutil.ReadFile(keyPath) if err != nil { - return nil, err + return tls.Certificate{}, err } if keyPassphrase != "" { pemBlock, _ := pem.Decode(keyPEMBlock) keyPEMBlock, err = x509.DecryptPEMBlock(pemBlock, []byte(keyPassphrase)) if err != nil { - return nil, err + return tls.Certificate{}, err } } certPEMBlock, err := ioutil.ReadFile(certPath) if err != nil { - return nil, err + return tls.Certificate{}, err } cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock) if err != nil { - return nil, err + return tls.Certificate{}, err } - return &cert, nil + return cert, nil } func NewApnsServiceHttp2(client *http.Client) *push.Service { From 804ea76d33c2891b4431a2a6c4398879ea5fee87 Mon Sep 17 00:00:00 2001 From: u5surf Date: Tue, 31 Jul 2018 23:40:19 +0900 Subject: [PATCH 3/6] issue-98 fix re-encode decrypted pem block --- gaurun/apns_http2.go | 1 + 1 file changed, 1 insertion(+) diff --git a/gaurun/apns_http2.go b/gaurun/apns_http2.go index 6b45756..c044251 100644 --- a/gaurun/apns_http2.go +++ b/gaurun/apns_http2.go @@ -68,6 +68,7 @@ func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (tls.C if err != nil { return tls.Certificate{}, err } + keyPEMBlock = pem.EncodeToMemory(&pem.Block{Type: pemBlock.Type, Bytes: keyPEMBlock}) } certPEMBlock, err := ioutil.ReadFile(certPath) if err != nil { From f0e8ae4b028f69dcaeb8e0b5f3e8bbcf03ef93de Mon Sep 17 00:00:00 2001 From: u5surf Date: Thu, 2 Aug 2018 00:32:07 +0900 Subject: [PATCH 4/6] issue-98 add error message when pem_key_passphrase is not require --- gaurun/apns_http2.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gaurun/apns_http2.go b/gaurun/apns_http2.go index c044251..0579ad5 100644 --- a/gaurun/apns_http2.go +++ b/gaurun/apns_http2.go @@ -5,6 +5,7 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" + "errors" "io/ioutil" "net" "net/http" @@ -64,6 +65,10 @@ func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (tls.C } if keyPassphrase != "" { pemBlock, _ := pem.Decode(keyPEMBlock) + if !x509.IsEncryptedPEMBlock(pemBlock) { + err = errors.New(keyPath + "is not encrypted. passphrase is not required") + return tls.Certificate{}, err + } keyPEMBlock, err = x509.DecryptPEMBlock(pemBlock, []byte(keyPassphrase)) if err != nil { return tls.Certificate{}, err From 5a509b1677f3e7a46fda400ea6f3a7958373ec6c Mon Sep 17 00:00:00 2001 From: u5surf Date: Thu, 2 Aug 2018 18:42:50 +0900 Subject: [PATCH 5/6] issue-98 change fmt.Errorf from errors.New when passphrase is not required --- gaurun/apns_http2.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gaurun/apns_http2.go b/gaurun/apns_http2.go index 0579ad5..adfbaf0 100644 --- a/gaurun/apns_http2.go +++ b/gaurun/apns_http2.go @@ -5,7 +5,7 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" - "errors" + "fmt" "io/ioutil" "net" "net/http" @@ -66,7 +66,7 @@ func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (tls.C if keyPassphrase != "" { pemBlock, _ := pem.Decode(keyPEMBlock) if !x509.IsEncryptedPEMBlock(pemBlock) { - err = errors.New(keyPath + "is not encrypted. passphrase is not required") + err = fmt.Errorf("%s(private-key-pem-file-path) is not encrypted. passphrase is not required",keyPath) return tls.Certificate{}, err } keyPEMBlock, err = x509.DecryptPEMBlock(pemBlock, []byte(keyPassphrase)) From 1df61f2ab640bf069280eb466221d2c739be57ac Mon Sep 17 00:00:00 2001 From: u5surf Date: Fri, 3 Aug 2018 08:07:39 +0900 Subject: [PATCH 6/6] issue-98 fix message and format --- gaurun/apns_http2.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gaurun/apns_http2.go b/gaurun/apns_http2.go index adfbaf0..056d714 100644 --- a/gaurun/apns_http2.go +++ b/gaurun/apns_http2.go @@ -66,7 +66,7 @@ func loadX509KeyPairWithPassword(certPath, keyPath, keyPassphrase string) (tls.C if keyPassphrase != "" { pemBlock, _ := pem.Decode(keyPEMBlock) if !x509.IsEncryptedPEMBlock(pemBlock) { - err = fmt.Errorf("%s(private-key-pem-file-path) is not encrypted. passphrase is not required",keyPath) + err = fmt.Errorf("%s is not encrypted. passphrase is not required", keyPath) return tls.Certificate{}, err } keyPEMBlock, err = x509.DecryptPEMBlock(pemBlock, []byte(keyPassphrase))