cloudflare/cloudflared

Public

mirrored fromhttps://github.com/cloudflare/cloudflaredAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
cc1c6d9abc865533e1ebb5a6a387fd3973ff7bc6

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

certutil/certutil.go

94lines · modecode

1package certutil
2
3import (
4 "crypto/x509"
5 "encoding/json"
6 "encoding/pem"
7 "fmt"
8 "strings"
9)
10
11type namedTunnelToken struct {
12 ZoneID string `json:"zoneID"`
13 AccountID string `json:"accountID"`
14 ServiceKey string `json:"serviceKey"`
15}
16
17type OriginCert struct {
18 PrivateKey interface{}
19 Cert *x509.Certificate
20 ZoneID string
21 ServiceKey string
22 AccountID string
23}
24
25func DecodeOriginCert(blocks []byte) (*OriginCert, error) {
26 if len(blocks) == 0 {
27 return nil, fmt.Errorf("Cannot decode empty certificate")
28 }
29 originCert := OriginCert{}
30 block, rest := pem.Decode(blocks)
31 for {
32 if block == nil {
33 break
34 }
35 switch block.Type {
36 case "PRIVATE KEY":
37 if originCert.PrivateKey != nil {
38 return nil, fmt.Errorf("Found multiple private key in the certificate")
39 }
40 // RSA private key
41 privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
42 if err != nil {
43 return nil, fmt.Errorf("Cannot parse private key")
44 }
45 originCert.PrivateKey = privateKey
46 case "CERTIFICATE":
47 if originCert.Cert != nil {
48 return nil, fmt.Errorf("Found multiple certificates in the certificate")
49 }
50 cert, err := x509.ParseCertificates(block.Bytes)
51 if err != nil {
52 return nil, fmt.Errorf("Cannot parse certificate")
53 } else if len(cert) > 1 {
54 return nil, fmt.Errorf("Found multiple certificates in the certificate")
55 }
56 originCert.Cert = cert[0]
57 case "WARP TOKEN", "ARGO TUNNEL TOKEN":
58 if originCert.ZoneID != "" || originCert.ServiceKey != "" {
59 return nil, fmt.Errorf("Found multiple tokens in the certificate")
60 }
61 // The token is a string,
62 // Try the newer JSON format
63 ntt := namedTunnelToken{}
64 if err := json.Unmarshal(block.Bytes, &ntt); err == nil {
65 originCert.ZoneID = ntt.ZoneID
66 originCert.ServiceKey = ntt.ServiceKey
67 originCert.AccountID = ntt.AccountID
68 } else {
69 // Try the older format, where the zoneID and service key are separated by
70 // a new line character
71 token := string(block.Bytes)
72 s := strings.Split(token, "\n")
73 if len(s) != 2 {
74 return nil, fmt.Errorf("Cannot parse token")
75 }
76 originCert.ZoneID = s[0]
77 originCert.ServiceKey = s[1]
78 }
79 default:
80 return nil, fmt.Errorf("Unknown block %s in the certificate", block.Type)
81 }
82 block, rest = pem.Decode(rest)
83 }
84
85 if originCert.PrivateKey == nil {
86 return nil, fmt.Errorf("Missing private key in the certificate")
87 } else if originCert.Cert == nil {
88 return nil, fmt.Errorf("Missing certificate in the certificate")
89 } else if originCert.ZoneID == "" || originCert.ServiceKey == "" {
90 return nil, fmt.Errorf("Missing token in the certificate")
91 }
92
93 return &originCert, nil
94}
95