cloudflare/cloudflared
Publicmirrored from https://github.com/cloudflare/cloudflaredAvailable
certutil/certutil.go
58lines · modecode
| 1 | package certutil |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "encoding/pem" |
| 6 | "fmt" |
| 7 | ) |
| 8 | |
| 9 | type namedTunnelToken struct { |
| 10 | ZoneID string `json:"zoneID"` |
| 11 | AccountID string `json:"accountID"` |
| 12 | APIToken string `json:"apiToken"` |
| 13 | } |
| 14 | |
| 15 | type OriginCert struct { |
| 16 | ZoneID string |
| 17 | APIToken string |
| 18 | AccountID string |
| 19 | } |
| 20 | |
| 21 | func DecodeOriginCert(blocks []byte) (*OriginCert, error) { |
| 22 | if len(blocks) == 0 { |
| 23 | return nil, fmt.Errorf("Cannot decode empty certificate") |
| 24 | } |
| 25 | originCert := OriginCert{} |
| 26 | block, rest := pem.Decode(blocks) |
| 27 | for { |
| 28 | if block == nil { |
| 29 | break |
| 30 | } |
| 31 | switch block.Type { |
| 32 | case "PRIVATE KEY", "CERTIFICATE": |
| 33 | // this is for legacy purposes. |
| 34 | break |
| 35 | case "ARGO TUNNEL TOKEN": |
| 36 | if originCert.ZoneID != "" || originCert.APIToken != "" { |
| 37 | return nil, fmt.Errorf("Found multiple tokens in the certificate") |
| 38 | } |
| 39 | // The token is a string, |
| 40 | // Try the newer JSON format |
| 41 | ntt := namedTunnelToken{} |
| 42 | if err := json.Unmarshal(block.Bytes, &ntt); err == nil { |
| 43 | originCert.ZoneID = ntt.ZoneID |
| 44 | originCert.APIToken = ntt.APIToken |
| 45 | originCert.AccountID = ntt.AccountID |
| 46 | } |
| 47 | default: |
| 48 | return nil, fmt.Errorf("Unknown block %s in the certificate", block.Type) |
| 49 | } |
| 50 | block, rest = pem.Decode(rest) |
| 51 | } |
| 52 | |
| 53 | if originCert.ZoneID == "" || originCert.APIToken == "" { |
| 54 | return nil, fmt.Errorf("Missing token in the certificate") |
| 55 | } |
| 56 | |
| 57 | return &originCert, nil |
| 58 | } |
| 59 | |