2020-05-01 20:59:52 +00:00
|
|
|
package certutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"encoding/pem"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
type namedTunnelToken struct {
|
2022-11-14 14:50:17 +00:00
|
|
|
ZoneID string `json:"zoneID"`
|
|
|
|
AccountID string `json:"accountID"`
|
|
|
|
APIToken string `json:"apiToken"`
|
2020-05-01 20:59:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type OriginCert struct {
|
2022-11-14 14:50:17 +00:00
|
|
|
ZoneID string
|
|
|
|
APIToken string
|
|
|
|
AccountID string
|
2020-05-01 20:59:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func DecodeOriginCert(blocks []byte) (*OriginCert, error) {
|
|
|
|
if len(blocks) == 0 {
|
|
|
|
return nil, fmt.Errorf("Cannot decode empty certificate")
|
|
|
|
}
|
|
|
|
originCert := OriginCert{}
|
|
|
|
block, rest := pem.Decode(blocks)
|
|
|
|
for {
|
|
|
|
if block == nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
switch block.Type {
|
2022-11-14 14:50:17 +00:00
|
|
|
case "PRIVATE KEY", "CERTIFICATE":
|
|
|
|
// this is for legacy purposes.
|
|
|
|
break
|
|
|
|
case "ARGO TUNNEL TOKEN":
|
|
|
|
if originCert.ZoneID != "" || originCert.APIToken != "" {
|
2020-05-01 20:59:52 +00:00
|
|
|
return nil, fmt.Errorf("Found multiple tokens in the certificate")
|
|
|
|
}
|
|
|
|
// The token is a string,
|
|
|
|
// Try the newer JSON format
|
|
|
|
ntt := namedTunnelToken{}
|
|
|
|
if err := json.Unmarshal(block.Bytes, &ntt); err == nil {
|
|
|
|
originCert.ZoneID = ntt.ZoneID
|
2022-11-14 14:50:17 +00:00
|
|
|
originCert.APIToken = ntt.APIToken
|
2020-05-01 20:59:52 +00:00
|
|
|
originCert.AccountID = ntt.AccountID
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("Unknown block %s in the certificate", block.Type)
|
|
|
|
}
|
|
|
|
block, rest = pem.Decode(rest)
|
|
|
|
}
|
|
|
|
|
2022-11-14 14:50:17 +00:00
|
|
|
if originCert.ZoneID == "" || originCert.APIToken == "" {
|
2020-05-01 20:59:52 +00:00
|
|
|
return nil, fmt.Errorf("Missing token in the certificate")
|
|
|
|
}
|
|
|
|
|
|
|
|
return &originCert, nil
|
|
|
|
}
|