decrypt private key if password provided

For #101
This commit is contained in:
Victor Vrantchan
2017-03-21 20:22:04 -04:00
committed by Victor Vrantchan
parent d46cd2e21c
commit 472d416791
6 changed files with 102 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
# v1.0.1 TBD
* Decrypt armored private keys if the `-apns-password` flag is specified by the user. #105
* Improved command queue handling of NotNow and other responses. #96
* Fixed data race in pubsub package. #97
* Fixed bug that would cause PushInfo Token for the device to be replaced by one for the user. #90

View File

@@ -1,6 +1,7 @@
package main
import (
"bytes"
"context"
"crypto/rsa"
"crypto/tls"
@@ -55,8 +56,8 @@ func serve(args []string) error {
flagset := flag.NewFlagSet("serve", flag.ExitOnError)
var (
flServerURL = flagset.String("server-url", "", "public HTTPS url of your server")
flAPNSCertPath = flagset.String("apns-cert", "mdm.p12", "path to APNS certificate")
flAPNSKeyPass = flagset.String("apns-password", "secret", "password for your p12 APNS cert file (if using)")
flAPNSCertPath = flagset.String("apns-cert", "", "path to APNS certificate")
flAPNSKeyPass = flagset.String("apns-password", "", "password for your p12 APNS cert file (if using)")
flAPNSKeyPath = flagset.String("apns-key", "", "path to key file if using .pem push cert")
flTLS = flagset.Bool("tls", true, "use https")
flTLSCert = flagset.String("tls-cert", "", "path to TLS certificate")
@@ -395,13 +396,30 @@ func (c *config) loadPushCerts() {
return
}
pkeyBlock := new(bytes.Buffer)
pemBlock, _ = pem.Decode(pemData)
if pemBlock == nil {
c.err = errors.New("invalid PEM data for privkey")
return
}
c.pushCert.PrivateKey, c.err =
x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
if x509.IsEncryptedPEMBlock(pemBlock) {
b, err := x509.DecryptPEMBlock(pemBlock, []byte(c.APNSPrivateKeyPass))
if err != nil {
c.err = fmt.Errorf("decrypting DES private key %s", err)
return
}
pkeyBlock.Write(b)
} else {
pkeyBlock.Write(pemBlock.Bytes)
}
priv, err := x509.ParsePKCS1PrivateKey(pkeyBlock.Bytes())
if err != nil {
c.err = fmt.Errorf("parsing pkcs1 private key: %s", err)
return
}
c.pushCert.PrivateKey = priv
}
type pushServiceCert struct {

31
serve_test.go Normal file
View File

@@ -0,0 +1,31 @@
package main
import "testing"
func TestLoadPushCerts(t *testing.T) {
keypath := "testdata/ProviderPrivateKey.key"
certpath := "testdata/pushcert.pem"
p12path := "testdata/pushcert.p12"
keysecret := "secret"
cfg := &config{
APNSPrivateKeyPath: keypath,
APNSCertificatePath: certpath,
APNSPrivateKeyPass: keysecret,
}
// test separate key and cert
cfg.loadPushCerts()
if cfg.err != nil {
t.Fatal(cfg.err)
}
// test p12 with secret
cfg.APNSCertificatePath = p12path
cfg.APNSPrivateKeyPath = ""
cfg.loadPushCerts()
if cfg.err != nil {
t.Fatal(cfg.err)
}
}

30
testdata/ProviderPrivateKey.key vendored Normal file
View File

@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,22c0f4c89c7b1fcd
KVnJeaMzHPrL5pHmkB6yAR9N8cvh2FKBfmJuRP61GiSR+PAI1UxsZ+627cnNZc/8
Y2haoxAtW4k5Yl6gIQH8exf4el5yD+Ds4mEUacw7m3RV+WNL32I1+Z+jr55jetzP
nb3t9LQmsP07uigSe/oh0vumVhjxxSE31/iB2BISnEfJDsDYHFFc1XWAxNABG+JP
ttCnIHPXaFLb7jDdZnnsk2rBNsRkOPwJ27hna9b0RyHVmqMb3XZtQs2RtARTVqap
hCFSphMrS20wLqcHyJZ7v0p9MiCp71g58xs4Bl9Vh1FI86AA+AOaosA0Kl8lPa08
ChuJf7ng3mhJ+nKRkPUK4eDtnCsNm3Xd0lQQHqRWcoUJ80Gdhla0CodJnt/BT35y
SP+j2SUJRuAvNpSeGyAcLv3wDwhMgkVTt1errZOL0tFa/ep5YwfFPMBDVNXx+lOd
AHDey8gnoGJFpwoQFdXp6TVZEJjP6kgN8njmAZmbwrFcqMdjg+eMZfAYXUAdy4aT
aMbMGwjyjUgP80iXX5OAgGchpQ+HO5otpbecAMKs6SAqAgTMbKMG2rLgZe+mlkbd
6xnwyrhkQpQHVN97gqWic2cIggyR3UL58mned/5eS3EcNTTxHJO8D7EwmIjkGVxY
fT+tdpJ6iKK6CfjIEZYFgtLafmKMxxDHaplLGnIK8VHiopwUIKxVcji9Pjp+0a1O
q9NSVZXAbt45mL2jV94hhEpt83YyBFdRYBFk5LT7AQg2ipVl51g7fO2SoTiHakzL
MrKfo+bSxDHOWefu9Z380Vmh1Mm0xDU44C8g9Jc4N7euCQtGfX5bnWuueuGwaaXL
lYrqKVuqKdc2y5d8N7KiHEHY0zsfyjFu4+zh/v2zYIBlbuM9ZGiuSlprHvy//wev
kPZDEtHNTeFXBn7qDeTGNlYK+aGQyTFOzasXcUbf3RywjpHOM/uL7rUpA11W+Ip/
/b1h+mcADy90DMBv1xVX3vZVldwAdcqbQR0QTXxgCS1dzVdedG2N7noJVKUfbA4x
tI3NEAaBt7J7eLQm7TawRv6j5G+VB/ZS5B8WVCVbBjwwqbeccJcuzJKLBX0A7c+X
TouVuE7xpq9OK0zsaIwg7WMgKOY9ZMuMNzjKnXcSYcq5o9LHHsB1CHyOGdHkmj/J
AmME2xnyB+GCLWyN8B17hyC4MwkoNDWLnlUzL1Z3lf5jsorx+zORKho+rgg02Blw
hY02jVEcHoO8fup6GXkWtWpq2pljHD6DBg4thqwd2X3tpKBEDCcPYjMNRBmb+EZo
ZZrHMZX999BsgQip+9s6gpg4OxLbkn/wB94D+XoQYCF/rKb3ztlMHWygyjasKbWe
L5DnI4tDaO0CAYP79ixJWd8DnHy7lkDFCWA3ZdDV5brM81biJVr24b0SoV22/nT/
wvTP0wgdRBmBmqFYZojlIWM+Gu09tVqXy8ui5oOGJThXgCyPWPrs9PSIfLyOjfDm
vUy/3yhOfCZmLEFG955P3A92ygojs/EvIrE2oWKVxf0X+T0mIVnBxeWpQ0OOVC1q
51gz/pyLNjbqxP2FUOkF5hLvRupAHhFpzbP4yZcDHUisNyUgjb4kHQ==
-----END RSA PRIVATE KEY-----

BIN
testdata/pushcert.p12 vendored Normal file

Binary file not shown.

18
testdata/pushcert.pem vendored Normal file
View File

@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC9zCCAd+gAwIBAgIJAPQybPTtooGmMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
BAMMB21kbXB1c2gwHhcNMTcwMzIxMjMyNzEwWhcNNDQwODA2MjMyNzEwWjASMRAw
DgYDVQQDDAdtZG1wdXNoMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
43VCT3Xw62hJ1t3HhLNsyJ/wTTaLJfyNu9zwNeNVY+yOxSaj6V5UVEpWiNIfyB+j
J7E+cUdWmEQewwXPaoNsCR4bKBElB1f45UApcrmkoqzruFI4O+yfmLJkN95fO5Sd
009VZPudFf96HdYjNpgg8ofIxAxo9dP+ReU+4QgxevIM2Hg+X+4zabDiLspfGX6Y
A5Iz/R6rFCx8rc+GEWFhkB4JE0cIV/TifP5xlOr0UFTCYQ1KUEM+30s928PFRXM4
tsm/TcM5g0Mi2bNDiVHE0hvzxmJbiL2XjFE3VBK6Dphw9gF1GLe8D2TnZMeIAj3K
JW0sjnkmvBxRvTqTHA4LvwIDAQABo1AwTjAdBgNVHQ4EFgQUJmri9d+KEYhPyDu3
dHsVm7eFWngwHwYDVR0jBBgwFoAUJmri9d+KEYhPyDu3dHsVm7eFWngwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAmRu4hFq4+WN7Vr9FucU+yHYcj0YV
kKfJMUSxDK/bab1DR02gxcYVR+bY/xtlcc/dA0zzzXUj97/BKLpkQCxu1+MtqMPx
bbVJnrSkGDXBXMmwn9C29WDdMjLQwS4WLrkDTEVc8W9kUqZsEBQalneKlV8u5kXi
A9tolc2Kaq2uJxKcsC2Yx1MLqpEm6bqKRlQSPM0G3uWupJBnvIQfXt0n3ErphQhf
m6BuVIs2iVvEo2W+VZ+LwfeN992Yd0DeMqvMAh6Rg/N/SGaxmMeD/Co+LHKCAzW4
JVjDjF01dBDmWTBs+NC9euIoCBej+PjMwXUo229uA19DucZXMIed9Xyoqg==
-----END CERTIFICATE-----