Beispiel #1
2
// Decode and verify an in memory .p12 certificate (DER binary format).
func Decode(p12 []byte, password string) (tls.Certificate, error) {
	// decode an x509.Certificate to verify
	privateKey, cert, err := pkcs12.Decode(p12, password)
	if err != nil {
		return tls.Certificate{}, err
	}
	if err := verify(cert); err != nil {
		return tls.Certificate{}, err
	}

	// wrap in a tls certificate
	return tls.Certificate{
		Certificate: [][]byte{cert.Raw},
		PrivateKey:  privateKey,
		Leaf:        cert,
	}, nil
}
Beispiel #2
1
// ParseCertificatesDER parses a DER encoding of a certificate object and possibly private key,
// either PKCS #7, PKCS #12, or raw x509.
func ParseCertificatesDER(certsDER []byte, password string) (certs []*x509.Certificate, key crypto.Signer, err error) {
	certsDER = bytes.TrimSpace(certsDER)
	pkcs7data, err := pkcs7.ParsePKCS7(certsDER)
	if err != nil {
		var pkcs12data interface{}
		certs = make([]*x509.Certificate, 1)
		pkcs12data, certs[0], err = pkcs12.Decode(certsDER, password)
		if err != nil {
			certs, err = x509.ParseCertificates(certsDER)
			if err != nil {
				return nil, nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed)
			}
		} else {
			key = pkcs12data.(crypto.Signer)
		}
	} else {
		if pkcs7data.ContentInfo != "SignedData" {
			return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.DecodeFailed, errors.New("can only extract certificates from signed data content info"))
		}
		certs = pkcs7data.Content.SignedData.Certificates
	}
	if certs == nil {
		return nil, key, cferr.New(cferr.CertificateError, cferr.DecodeFailed)
	}
	return certs, key, nil
}
Beispiel #3
1
// CreateClient creates HTTP/2 apns client
func CreateClient(certFile string, password string, isSandbox bool) (*Client, error) {
	/* Condition validation: validate certificate's path */
	if len(certFile) == 0 {
		return nil, fmt.Errorf("Invalid certificate's path.")
	}

	/* Condition validation: validate certificate's password */
	if len(password) == 0 {
		return nil, fmt.Errorf("Invalid certificate's password.")
	}

	// Load certificate
	bytes, _ := ioutil.ReadFile(certFile)
	key, cert, err := pkcs12.Decode(bytes, password)

	/* Condition validation: validate the correctness of loading process */
	if err != nil {
		return nil, err
	}

	// Create certificate
	certificate := tls.Certificate{
		Certificate: [][]byte{cert.Raw},
		PrivateKey:  key,
		Leaf:        cert,
	}

	// Define gateway
	var gateway string
	if !isSandbox {
		gateway = Gateway
	} else {
		gateway = SandboxGateway
	}

	// Config TLS
	config := &tls.Config{
		Certificates: []tls.Certificate{certificate},
		ServerName:   gateway,
	}

	// Config transport
	transport := &http2.Transport{
		TLSClientConfig: config,
	}

	// Finalize
	client := Client{
		gateway: gateway,
		client:  &http.Client{Transport: transport},
	}

	return &client, nil
}
Beispiel #4
1
// FromP12Bytes loads a PKCS#12 certificate from an in memory byte array and
// returns a tls.Certificate.
//
// Use "" as the password argument if the PKCS#12 certificate is not password
// protected.
func FromP12Bytes(bytes []byte, password string) (tls.Certificate, error) {
	key, cert, err := pkcs12.Decode(bytes, password)
	if err != nil {
		return tls.Certificate{}, err
	}
	return tls.Certificate{
		Certificate: [][]byte{cert.Raw},
		PrivateKey:  key,
		Leaf:        cert,
	}, nil
}
Beispiel #5
1
func decodePkcs12(pkcs []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) {
	privateKey, certificate, err := pkcs12.Decode(pkcs, password)
	if err != nil {
		return nil, nil, err
	}

	rsaPrivateKey, isRsaKey := privateKey.(*rsa.PrivateKey)
	if !isRsaKey {
		return nil, nil, fmt.Errorf("PKCS#12 certificate must contain an RSA private key")
	}

	return certificate, rsaPrivateKey, nil
}
Beispiel #6
0
// Decode and verify an in memory .p12 certificate (DER binary format).
func Decode(p12 []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) {
	// decode an x509.Certificate to verify
	privateKey, cert, err := pkcs12.Decode(p12, password)
	if err != nil {
		return nil, nil, err
	}
	if err := verify(cert); err != nil {
		return nil, nil, err
	}

	// assert that private key is RSA
	priv, ok := privateKey.(*rsa.PrivateKey)
	if !ok {
		return nil, nil, errors.New("expected RSA private key type")
	}
	return cert, priv, nil
}
Beispiel #7
0
func loadCertificate() (tls.Certificate, error) {
	if *p12File != "" {
		cert := tls.Certificate{}
		b, err := ioutil.ReadFile(*p12File)
		if err != nil {
			return cert, err
		}
		key, cer, err := pkcs12.Decode(b, *p12Password)
		if err != nil {
			return cert, err
		}
		cert.PrivateKey = key
		cert.Certificate = [][]byte{cer.Raw}
		return cert, nil
	} else {
		return tls.LoadX509KeyPair(*cerFile, *keyFile)
	}
}
Beispiel #8
0
func testPfxRoundTrip(t *testing.T, privateKey interface{}) interface{} {
	certificateBytes, err := newCertificate("hostname", privateKey)
	if err != nil {
		t.Fatal(err.Error())
	}

	bytes, err := Encode(certificateBytes, privateKey, "sesame")
	if err != nil {
		t.Fatal(err.Error())
	}

	key, _, err := gopkcs12.Decode(bytes, "sesame")
	if err != nil {
		t.Fatalf(err.Error())
	}

	return key
}
func main() {

	devP := flag.Bool("d", false, "use development push server")

	flag.Parse()
	if flag.NArg() < 1 {
		log.Fatalf("usage: %s [-d] cert.p12", os.Args[0])
	}

	var server string
	if *devP {
		server = "api.development.push.apple.com"
	} else {
		server = "api.push.apple.com"
	}

	d, err := ioutil.ReadFile(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}

	key, cert, err := pkcs12.Decode(d, "")
	if err != nil {
		log.Fatal(err)
	}

	tlsConfig := tls.Config{
		Certificates: []tls.Certificate{{
			Certificate: [][]byte{cert.Raw},
			PrivateKey:  key.(*rsa.PrivateKey),
		}},
	}
	tlsConfig.BuildNameToCertificate()

	client := http.Client{
		Transport: &http2.Transport{
			TLSClientConfig: &tlsConfig,
		},
	}

	scanner := bufio.NewScanner(os.Stdin)

	for scanner.Scan() {
		var notification Notification
		err := json.Unmarshal([]byte(scanner.Text()), &notification)
		if err != nil {
			log.Fatal(err)
		}

		resp, err := client.Post(fmt.Sprintf(
			"https://%s/3/device/%s",
			server,
			url.QueryEscape(notification.Token),
		), "", bytes.NewReader(notification.Payload))

		if err != nil {
			log.Fatal(err)
		}

		defer resp.Body.Close()
		var buf bytes.Buffer
		buf.ReadFrom(resp.Body)

		var rawRes *json.RawMessage
		if len(buf.Bytes()) != 0 {
			rm := json.RawMessage(buf.Bytes())
			rawRes = &rm
		}

		json, err := json.Marshal(struct {
			Status int              `json:"status"`
			Body   *json.RawMessage `json:"body,omitempty"`
		}{resp.StatusCode, rawRes})

		if err != nil {
			log.Fatal(err)
		}

		os.Stdout.Write(json)
		os.Stdout.Write([]byte{'\n'})
	}

	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

}