This is an automated email from the ASF dual-hosted git repository.

rob pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit eaffeb59a74b16ecc1e8c3af14102d48548c4b9d
Author: Rawlin Peters <rawlin_pet...@comcast.com>
AuthorDate: Tue Sep 18 16:44:41 2018 -0600

    Finish up DS SSL keys endpoints in TO Go
    
    Finish out the '-wip' DS sslkeys endpoints and fix up what was already
    there.
---
 lib/go-tc/deliveryservice_ssl_keys.go              |   2 +-
 .../deliveryservice/deliveryservicesv13.go         |   4 +-
 .../traffic_ops_golang/deliveryservice/keys.go     | 220 ++++++++--------
 .../deliveryservice/keys_test.go                   | 284 ++++++++++-----------
 .../traffic_ops_golang/deliveryservice/sslkeys.go  |   4 +-
 traffic_ops/traffic_ops_golang/riaksvc/dsutil.go   |  78 +-----
 traffic_ops/traffic_ops_golang/routes.go           |  11 +-
 7 files changed, 267 insertions(+), 336 deletions(-)

diff --git a/lib/go-tc/deliveryservice_ssl_keys.go 
b/lib/go-tc/deliveryservice_ssl_keys.go
index 0bfb15c..bab764a 100644
--- a/lib/go-tc/deliveryservice_ssl_keys.go
+++ b/lib/go-tc/deliveryservice_ssl_keys.go
@@ -44,7 +44,7 @@ type DeliveryServiceSSLKeysCertificate struct {
 // DeliveryServiceSSLKeys ...
 type DeliveryServiceSSLKeys struct {
        CDN             string                            `json:"cdn,omitempty"`
-       DeliveryService string                            
`json:"DeliveryService,omitempty"`
+       DeliveryService string                            
`json:"deliveryservice,omitempty"`
        BusinessUnit    string                            
`json:"businessUnit,omitempty"`
        City            string                            
`json:"city,omitempty"`
        Organization    string                            
`json:"organization,omitempty"`
diff --git 
a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
index 649afb1..3e2a64f 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
@@ -652,7 +652,7 @@ func updateSSLKeys(ds *tc.DeliveryServiceNullable, hostName 
string, tx *sql.Tx,
        if ds.XMLID == nil {
                return errors.New("delivery services has no XMLID!")
        }
-       key, ok, err := riaksvc.GetDeliveryServiceSSLKeysObjTx(*ds.XMLID, 
"latest", tx, cfg.RiakAuthOptions)
+       key, ok, err := riaksvc.GetDeliveryServiceSSLKeysObj(*ds.XMLID, 
riaksvc.DSSSLKeyVersionLatest, tx, cfg.RiakAuthOptions)
        if err != nil {
                return errors.New("getting SSL key: " + err.Error())
        }
@@ -661,7 +661,7 @@ func updateSSLKeys(ds *tc.DeliveryServiceNullable, hostName 
string, tx *sql.Tx,
        }
        key.DeliveryService = *ds.XMLID
        key.Hostname = hostName
-       if err := riaksvc.PutDeliveryServiceSSLKeysObjTx(key, tx, 
cfg.RiakAuthOptions); err != nil {
+       if err := riaksvc.PutDeliveryServiceSSLKeysObj(key, tx, 
cfg.RiakAuthOptions); err != nil {
                return errors.New("putting updated SSL key: " + err.Error())
        }
        return nil
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/keys.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
index aac39dc..830ec07 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
@@ -27,7 +27,6 @@ import (
        "encoding/json"
        "encoding/pem"
        "errors"
-       "fmt"
        "net/http"
        "strings"
 
@@ -37,6 +36,10 @@ import (
        "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
 )
 
+const (
+       PemCertEndMarker = "-----END CERTIFICATE-----"
+)
+
 // AddSSLKeys adds the given ssl keys to the given delivery service.
 func AddSSLKeys(w http.ResponseWriter, r *http.Request) {
        inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
@@ -46,7 +49,7 @@ func AddSSLKeys(w http.ResponseWriter, r *http.Request) {
        }
        defer inf.Close()
        if !inf.Config.RiakEnabled {
-               api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
nil, errors.New("adding Riak SSL keys for delivery service:: riak is not 
configured"))
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
nil, errors.New("adding SSL keys to Riak for delivery service: Riak is not 
configured"))
                return
        }
        keysObj := tc.DeliveryServiceSSLKeys{}
@@ -58,22 +61,28 @@ func AddSSLKeys(w http.ResponseWriter, r *http.Request) {
                api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
                return
        }
-       certChain, err := verifyAndEncodeCertificate(keysObj.Certificate.Crt, 
"")
+       certChain, err := verifyCertificate(keysObj.Certificate.Crt, "")
        if err != nil {
                api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, 
errors.New("verifying certificate: "+err.Error()), nil)
                return
        }
        keysObj.Certificate.Crt = certChain
+       base64EncodeCertificate(&keysObj.Certificate)
+       if err := riaksvc.PutDeliveryServiceSSLKeysObj(keysObj, inf.Tx.Tx, 
inf.Config.RiakAuthOptions); err != nil {
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, nil, 
errors.New("putting SSL keys in Riak for delivery service 
'"+keysObj.DeliveryService+"': "+err.Error()))
+               return
+       }
+       keysObj.Version = riaksvc.DSSSLKeyVersionLatest
        if err := riaksvc.PutDeliveryServiceSSLKeysObj(keysObj, inf.Tx.Tx, 
inf.Config.RiakAuthOptions); err != nil {
-               api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, nil, 
errors.New("putting Riak SSL keys for delivery service 
'"+keysObj.DeliveryService+"': "+err.Error()))
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, nil, 
errors.New("putting latest SSL keys in Riak for delivery service 
'"+keysObj.DeliveryService+"': "+err.Error()))
                return
        }
-       api.WriteRespRaw(w, r, keysObj)
+       api.WriteResp(w, r, "Successfully added ssl keys for 
"+keysObj.DeliveryService)
 }
 
 // GetSSLKeysByHostName fetches the ssl keys for a deliveryservice specified 
by the fully qualified hostname
 func GetSSLKeysByHostName(w http.ResponseWriter, r *http.Request) {
-       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"hostName"}, 
nil)
+       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"hostname"}, 
nil)
        if userErr != nil || sysErr != nil {
                api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
                return
@@ -81,12 +90,11 @@ func GetSSLKeysByHostName(w http.ResponseWriter, r 
*http.Request) {
        defer inf.Close()
 
        if inf.Config.RiakEnabled == false {
-               api.HandleErr(w, r, inf.Tx.Tx, http.StatusServiceUnavailable, 
errors.New("The RIAK service is unavailable"), errors.New("getting Riak SSL 
keys by host name: riak is not configured"))
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusServiceUnavailable, 
errors.New("the Riak service is unavailable"), errors.New("getting SSL keys 
from Riak by host name: Riak is not configured"))
                return
        }
 
-       version := inf.Params["version"]
-       hostName := inf.Params["hostName"]
+       hostName := inf.Params["hostname"]
        domainName := ""
        hostRegex := ""
        strArr := strings.Split(hostName, ".")
@@ -96,7 +104,7 @@ func GetSSLKeysByHostName(w http.ResponseWriter, r 
*http.Request) {
                        domainName += strArr[i] + "."
                }
                domainName += strArr[ln-1]
-               hostRegex = ".*\\." + strArr[1] + "\\..*"
+               hostRegex = `.*\.` + strArr[1] + `\..*`
        }
 
        // lookup the cdnID
@@ -120,36 +128,28 @@ func GetSSLKeysByHostName(w http.ResponseWriter, r 
*http.Request) {
                return
        }
 
-       if userErr, sysErr, errCode := tenant.Check(inf.User, xmlID, 
inf.Tx.Tx); userErr != nil || sysErr != nil {
-               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-               return
-       }
-       keyObj, ok, err := riaksvc.GetDeliveryServiceSSLKeysObj(xmlID, version, 
inf.Tx.Tx, inf.Config.RiakAuthOptions)
-       if err != nil {
-               api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
nil, errors.New("getting ssl keys: "+err.Error()))
-               return
-       }
-       if !ok {
-               api.WriteRespAlert(w, r, tc.InfoLevel, "no object found for the 
specified key")
-               return
-       }
-       api.WriteResp(w, r, keyObj)
+       getSSLKeysByXMLIDHelper(xmlID, inf, w, r)
 }
 
 // GetSSLKeysByXMLID fetches the deliveryservice ssl keys by the specified 
xmlID.
 func GetSSLKeysByXMLID(w http.ResponseWriter, r *http.Request) {
-       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"xmlID"}, nil)
+       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"xmlid"}, nil)
        if userErr != nil || sysErr != nil {
                api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
                return
        }
        defer inf.Close()
        if inf.Config.RiakEnabled == false {
-               api.HandleErr(w, r, inf.Tx.Tx, http.StatusServiceUnavailable, 
errors.New("The RIAK service is unavailable"), errors.New("getting Riak SSL 
keys by xml id: riak is not configured"))
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusServiceUnavailable, 
errors.New("the Riak service is unavailable"), errors.New("getting SSL keys 
from Riak by xml id: Riak is not configured"))
                return
        }
+       xmlID := inf.Params["xmlid"]
+       getSSLKeysByXMLIDHelper(xmlID, inf, w, r)
+}
+
+func getSSLKeysByXMLIDHelper(xmlID string, inf *api.APIInfo, w 
http.ResponseWriter, r *http.Request) {
        version := inf.Params["version"]
-       xmlID := inf.Params["xmlID"]
+       decode := inf.Params["decode"]
        if userErr, sysErr, errCode := tenant.Check(inf.User, xmlID, 
inf.Tx.Tx); userErr != nil || sysErr != nil {
                api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
                return
@@ -160,29 +160,65 @@ func GetSSLKeysByXMLID(w http.ResponseWriter, r 
*http.Request) {
                return
        }
        if !ok {
-               api.WriteRespAlert(w, r, tc.InfoLevel, "no object found for the 
specified key")
+               api.WriteRespAlertObj(w, r, tc.InfoLevel, "no object found for 
the specified key", struct{}{}) // empty response object because Perl
                return
        }
+       if decode != "" && decode != "0" { // the Perl version checked the 
decode string as: if ( $decode )
+               err = base64DecodeCertificate(&keyObj.Certificate)
+               if err != nil {
+                       api.HandleErr(w, r, inf.Tx.Tx, 
http.StatusInternalServerError, nil, errors.New("getting SSL keys for XMLID 
'"+xmlID+"': "+err.Error()))
+                       return
+               }
+       }
        api.WriteResp(w, r, keyObj)
 }
 
+func base64DecodeCertificate(cert *tc.DeliveryServiceSSLKeysCertificate) error 
{
+       csrDec, err := base64.StdEncoding.DecodeString(cert.CSR)
+       if err != nil {
+               return errors.New("base64 decoding csr: " + err.Error())
+       }
+       cert.CSR = string(csrDec)
+       crtDec, err := base64.StdEncoding.DecodeString(cert.Crt)
+       if err != nil {
+               return errors.New("base64 decoding crt: " + err.Error())
+       }
+       cert.Crt = string(crtDec)
+       keyDec, err := base64.StdEncoding.DecodeString(cert.Key)
+       if err != nil {
+               return errors.New("base64 decoding key: " + err.Error())
+       }
+       cert.Key = string(keyDec)
+       return nil
+}
+
+func base64EncodeCertificate(cert *tc.DeliveryServiceSSLKeysCertificate) {
+       cert.CSR = base64.StdEncoding.EncodeToString([]byte(cert.CSR))
+       cert.Crt = base64.StdEncoding.EncodeToString([]byte(cert.Crt))
+       cert.Key = base64.StdEncoding.EncodeToString([]byte(cert.Key))
+}
+
 func DeleteSSLKeys(w http.ResponseWriter, r *http.Request) {
-       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"name"}, nil)
+       inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"xmlid"}, nil)
        if userErr != nil || sysErr != nil {
                api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
                return
        }
        defer inf.Close()
        if inf.Config.RiakEnabled == false {
-               api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
userErr, errors.New("deliveryservice.DeleteSSLKeys: Riak is not configured!"))
+               api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
userErr, errors.New("deliveryservice.DeleteSSLKeys: Riak is not configured"))
+               return
+       }
+       xmlID := inf.Params["xmlid"]
+       if userErr, sysErr, errCode := tenant.Check(inf.User, xmlID, 
inf.Tx.Tx); userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
                return
        }
-       ds := tc.DeliveryServiceName(inf.Params["name"])
-       if err := riaksvc.DeleteDSSSLKeys(inf.Tx.Tx, 
inf.Config.RiakAuthOptions, ds, inf.Params["version"]); err != nil {
+       if err := riaksvc.DeleteDSSSLKeys(inf.Tx.Tx, 
inf.Config.RiakAuthOptions, xmlID, inf.Params["version"]); err != nil {
                api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
userErr, errors.New("deliveryservice.DeleteSSLKeys: deleting SSL keys: 
"+err.Error()))
                return
        }
-       api.WriteResp(w, r, "Successfully deleted ssl keys for "+string(ds))
+       api.WriteResp(w, r, "Successfully deleted ssl keys for "+xmlID)
 }
 
 // returns the cdn_id found by domainname.
@@ -216,86 +252,64 @@ WHERE r.pattern = $2
 }
 
 // verify the server certificate chain and return the
-// certificate and its chain in the proper order. Returns a  verified,
-// ordered, and base64 encoded certificate and CA chain.
-func verifyAndEncodeCertificate(certificate string, rootCA string) (string, 
error) {
-       var pemEncodedChain string
-       var b64crt string
+// certificate and its chain in the proper order. Returns a verified
+// and ordered certificate and CA chain.
+func verifyCertificate(certificate string, rootCA string) (string, error) {
+       // decode, verify, and order certs for storage
+       certs := strings.SplitAfter(certificate, PemCertEndMarker)
+       if len(certs) <= 1 {
+               return "", errors.New("no certificate chain to verify")
+       }
 
-       // strip newlines from encoded crt and decode it from base64.
-       crtArr := strings.Split(certificate, "\\n")
-       for i := 0; i < len(crtArr); i++ {
-               b64crt += crtArr[i]
+       // decode and verify the server certificate
+       block, _ := pem.Decode([]byte(certs[0]))
+       if block == nil {
+               return "", errors.New("could not decode pem-encoded server 
certificate")
        }
-       pemCerts := make([]byte, base64.StdEncoding.EncodedLen(len(b64crt)))
-       _, err := base64.StdEncoding.Decode(pemCerts, []byte(b64crt))
+       cert, err := x509.ParseCertificate(block.Bytes)
        if err != nil {
-               return "", fmt.Errorf("could not base64 decode the certificate 
%v", err)
+               return "", errors.New("could not parse the server certificate: 
" + err.Error())
+       }
+       if !(cert.KeyUsage&x509.KeyUsageKeyEncipherment > 0) {
+               return "", errors.New("no key encipherment usage for the server 
certificate")
+       }
+       bundle := ""
+       for i := 0; i < len(certs)-1; i++ {
+               bundle += certs[i]
        }
 
-       // decode, verify, and order certs for storgae
-       var bundle string
-       certs := strings.SplitAfter(string(pemCerts), "-----END 
CERTIFICATE-----")
-       if len(certs) > 1 {
-               // decode and verify the server certificate
-               block, _ := pem.Decode([]byte(certs[0]))
-               cert, err := x509.ParseCertificate(block.Bytes)
-               if err != nil {
-                       return "", fmt.Errorf("could not parse the server 
certificate %v", err)
-               }
-               if !(cert.KeyUsage&x509.KeyUsageKeyEncipherment > 0) {
-                       return "", fmt.Errorf("no key encipherment usage for 
the server certificate")
-               }
-               for i := 0; i < len(certs)-1; i++ {
-                       bundle += certs[i]
-               }
-
-               var opts x509.VerifyOptions
+       intermediatePool := x509.NewCertPool()
+       if !intermediatePool.AppendCertsFromPEM([]byte(bundle)) {
+               return "", errors.New("certificate CA bundle is empty")
+       }
 
+       opts := x509.VerifyOptions{
+               Intermediates: intermediatePool,
+       }
+       if rootCA != "" {
+               // verify the certificate chain.
                rootPool := x509.NewCertPool()
-               if rootCA != "" {
-                       if !rootPool.AppendCertsFromPEM([]byte(rootCA)) {
-                               return "", fmt.Errorf("root  CA certificate is 
empty, %v", err)
-                       }
-               }
-
-               intermediatePool := x509.NewCertPool()
-               if !intermediatePool.AppendCertsFromPEM([]byte(bundle)) {
-                       return "", fmt.Errorf("certificate CA bundle is empty, 
%v", err)
-               }
-
-               if rootCA != "" {
-                       // verify the certificate chain.
-                       opts = x509.VerifyOptions{
-                               Intermediates: intermediatePool,
-                               Roots:         rootPool,
-                       }
-               } else {
-                       opts = x509.VerifyOptions{
-                               Intermediates: intermediatePool,
-                       }
+               if !rootPool.AppendCertsFromPEM([]byte(rootCA)) {
+                       return "", errors.New("unable to parse root CA 
certificate")
                }
+               opts.Roots = rootPool
+       }
 
-               chain, err := cert.Verify(opts)
-               if err != nil {
-                       return "", fmt.Errorf("could verify the certificate 
chain %v", err)
-               }
-               if len(chain) > 0 {
-                       for _, link := range chain[0] {
-                               // Only print non-self signed elements of the 
chain
-                               if link.AuthorityKeyId != nil && 
!bytes.Equal(link.AuthorityKeyId, link.SubjectKeyId) {
-                                       block := &pem.Block{Type: 
"CERTIFICATE", Bytes: link.Raw}
-                                       pemEncodedChain += 
string(pem.EncodeToMemory(block))
-                               }
-                       }
-               } else {
-                       return "", fmt.Errorf("Can't find valid chain for cert 
in file in request")
+       chain, err := cert.Verify(opts)
+       if err != nil {
+               return "", errors.New("could not verify the certificate chain: 
" + err.Error())
+       }
+       if len(chain) < 1 {
+               return "", errors.New("can't find valid chain for cert in file 
in request")
+       }
+       pemEncodedChain := ""
+       for _, link := range chain[0] {
+               // Only print non-self signed elements of the chain
+               if link.AuthorityKeyId != nil && 
!bytes.Equal(link.AuthorityKeyId, link.SubjectKeyId) {
+                       block := &pem.Block{Type: "CERTIFICATE", Bytes: 
link.Raw}
+                       pemEncodedChain += string(pem.EncodeToMemory(block))
                }
-       } else {
-               return "", fmt.Errorf("ERROR: no certificate chain to verify")
        }
 
-       base64EncodedStr := 
base64.StdEncoding.EncodeToString([]byte(pemEncodedChain))
-
-       return base64EncodedStr, nil
+       return pemEncodedChain, nil
 }
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/keys_test.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/keys_test.go
index 8c92aa9..14b30a3 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/keys_test.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/keys_test.go
@@ -20,153 +20,143 @@ package deliveryservice
  */
 
 import (
-       "encoding/base64"
        "strings"
        "testing"
 )
 
 const (
-       BadData = "This is bad data and it is not base64 encoded"
+       BadData = "This is bad data and it is not pem encoded"
 
        SelfSigneCertOnly = `
-LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURrakNDQW5vQ0NRQ2Z3ZDIxOUpLcFVEQU5C
-Z2txaGtpRzl3MEJBUXNGQURDQmlqRUxNQWtHQTFVRUJoTUMKVlZNeEVUQVBCZ05WQkFnTUNFTnZi
-Rzl5WVdSdk1ROHdEUVlEVlFRSERBWkVaVzUyWlhJeEVEQU9CZ05WQkFvTQpCME52YldOaGMzUXhE
-akFNQmdOVkJBc01CWFpwY0dWeU1SVXdFd1lEVlFRRERBeDNkM2N1ZEdWemRDNXZjbWN4CkhqQWNC
-Z2txaGtpRzl3MEJDUUVXRDIxcFkydGxlVUIwWlhOMExtOXlaekFlRncweE56RXhNVFl4TmpNNU1U
-TmEKRncweU56RXhNVFF4TmpNNU1UTmFNSUdLTVFzd0NRWURWUVFHRXdKVlV6RVJNQThHQTFVRUNB
-d0lRMjlzYjNKaApaRzh4RHpBTkJnTlZCQWNNQmtSbGJuWmxjakVRTUE0R0ExVUVDZ3dIUTI5dFky
-RnpkREVPTUF3R0ExVUVDd3dGCmRtbHdaWEl4RlRBVEJnTlZCQU1NREhkM2R5NTBaWE4wTG05eVp6
-RWVNQndHQ1NxR1NJYjNEUUVKQVJZUGJXbGoKYTJWNVFIUmxjM1F1YjNKbk1JSUJJakFOQmdrcWhr
-aUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBNm02agppQU1KcExNeFpoSVVFOURyUHZuaTA2
-TmViTFJhaDFSUzgrUjNKM1BOMVhDY2d3d1VaaWZaQnBQZ2FTYXBGWGJ2ClpkamxyZlpGcGtBZmdG
-UVhseUdhZTZCVStuNEN3TmxEZGdvMVhiRWM4cW9HSWRzN2FZSEVrclFadFp5aCtYRlkKMkJSdlM2
-Y2JHR0VjMngwdzVJa1hhMTM2V0NKY0x0QnpkVDdGQVZRSlZodTl4UFBuWGs4aWdUWmc2dEZ0MjdF
-YgplYkhDVWVEQXJHVVJGaUZXZFhtOGRHQ1BVVkNaeFNDdnh1WGxJMTVkZGdmcDlHYkZYeENVUDVW
-UjlQajZCdHFlCjdReW1GUk9zSWtscEN3NDZlYTBBODdpa1ZNYWRQQzIxVHViZmF5VUFNUTh4bDYw
-aW94NVk4OWc0WEZyRWdreWQKV3hobVBXclZwVlFyUERXS2d3SURBUUFCTUEwR0NTcUdTSWIzRFFF
-QkN3VUFBNElCQVFDWlpXNnJsbi9LYkdWbgpVWis3RFY5UFVCNHIyNUI5d3JSQUx5OHJRdzNVQWVQ
-SFJxWmlBT1ZOV3hycjM5Njd6ZFBNYzhkMWtZY2t0K2NHCkcxUFU1QmNiVVZuUzJxRTBUa2Z2cWo2
-citPaWNrcnU2dEtmWERhcU1PRXRmTmFud1Q5dURaQ1RlT2FpU0hCengKRnBQLzlURDA1Z0VZYmQx
-VzRSUnpUNi9TN3lMWTB1WWhWQUhGZGwyZTd6T2podHk0aURQRjA0ZmQrWHlaKzNXUwpJeFNnYU1y
-VHAwMG1hRnRicFBuaFRheElHek1ZdG9kaTZGYVVjT21CZk1scFJHS3lrc04wWjNlSjZSNm5oTWIz
-ClJHSjludUdMS3ZxUzV1OUJnZ2NEd28xcXYyazhNY2RTZzZwbEs2WG9kTHlNZEJWVEI2Szdod1N6
-MXVWcDNtWDEKSFZHRTQrb3UKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=`
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnoCCQCfwd219JKpUDANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMC
+VVMxETAPBgNVBAgMCENvbG9yYWRvMQ8wDQYDVQQHDAZEZW52ZXIxEDAOBgNVBAoM
+B0NvbWNhc3QxDjAMBgNVBAsMBXZpcGVyMRUwEwYDVQQDDAx3d3cudGVzdC5vcmcx
+HjAcBgkqhkiG9w0BCQEWD21pY2tleUB0ZXN0Lm9yZzAeFw0xNzExMTYxNjM5MTNa
+Fw0yNzExMTQxNjM5MTNaMIGKMQswCQYDVQQGEwJVUzERMA8GA1UECAwIQ29sb3Jh
+ZG8xDzANBgNVBAcMBkRlbnZlcjEQMA4GA1UECgwHQ29tY2FzdDEOMAwGA1UECwwF
+dmlwZXIxFTATBgNVBAMMDHd3dy50ZXN0Lm9yZzEeMBwGCSqGSIb3DQEJARYPbWlj
+a2V5QHRlc3Qub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6m6j
+iAMJpLMxZhIUE9DrPvni06NebLRah1RS8+R3J3PN1XCcgwwUZifZBpPgaSapFXbv
+ZdjlrfZFpkAfgFQXlyGae6BU+n4CwNlDdgo1XbEc8qoGIds7aYHEkrQZtZyh+XFY
+2BRvS6cbGGEc2x0w5IkXa136WCJcLtBzdT7FAVQJVhu9xPPnXk8igTZg6tFt27Eb
+ebHCUeDArGURFiFWdXm8dGCPUVCZxSCvxuXlI15ddgfp9GbFXxCUP5VR9Pj6Btqe
+7QymFROsIklpCw46ea0A87ikVMadPC21TubfayUAMQ8xl60iox5Y89g4XFrEgkyd
+WxhmPWrVpVQrPDWKgwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCZZW6rln/KbGVn
+UZ+7DV9PUB4r25B9wrRALy8rQw3UAePHRqZiAOVNWxrr3967zdPMc8d1kYckt+cG
+G1PU5BcbUVnS2qE0Tkfvqj6r+Oickru6tKfXDaqMOEtfNanwT9uDZCTeOaiSHBzx
+FpP/9TD05gEYbd1W4RRzT6/S7yLY0uYhVAHFdl2e7zOjhty4iDPF04fd+XyZ+3WS
+IxSgaMrTp00maFtbpPnhTaxIGzMYtodi6FaUcOmBfMlpRGKyksN0Z3eJ6R6nhMb3
+RGJ9nuGLKvqS5u9BggcDwo1qv2k8McdSg6plK6XodLyMdBVTB6K7hwSz1uVp3mX1
+HVGE4+ou
+-----END CERTIFICATE-----
+`
        GoodTLSKeys = `
-LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUYzRENDQThTZ0F3SUJBZ0lDRUFBd0RRWUpL
-b1pJaHZjTkFRRUxCUUF3Z1l3eEN6QUpCZ05WQkFZVEFsVlQKTVJFd0R3WURWUVFJREFoRGIyeHZj
-bUZrYnpFa01DSUdBMVVFQ2d3YlNYQmpaRzRnUTJWeWRHbG1hV05oZEdVZwpRWFYwYUc5eWFYUjVN
-U1F3SWdZRFZRUUxEQnRKY0dOa2JpQkRaWEowYVdacFkyRjBaU0JCZFhSb2IzSnBkSGt4CkhqQWNC
-Z05WQkFNTUZVbHdZMlJ1SUVsdWRHVnliV1ZrYVdGMFpTQkRRVEFlRncweE56RXhNVFl5TURVd01U
-bGEKRncweU5qQXlNREl5TURVd01UbGFNSEF4Q3pBSkJnTlZCQVlUQWxWVE1SRXdEd1lEVlFRSURB
-aERiMnh2Y21GawpiekVQTUEwR0ExVUVCd3dHUkdWdWRtVnlNUTh3RFFZRFZRUUtEQVpKY0dOa2Jp
-QXhFakFRQmdOVkJBc01DVWx3ClkyUnVJR1JsZGpFWU1CWUdBMVVFQXd3UGQzZDNMbVY0WVcxd2JH
-VXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEIKQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBMWg5Zlh3
-SjE3UVlOTVhNNWpFZ0hlY1Z4V20rQ05QUWJpMk8wYUxtNQpsYUV1b2N0bC94bmNsRGdrT2NWNTBz
-SWdVUlNuYVJYSENNYTkzemI5NXhRZWZUSXZSRi8xa1U5ZTY4bW1Gano4CmZyQWRPYU05MFRkVWYx
-eXYyNlczN25UOUR4MjZDQWlTd0FMWFZkeCs0b1Bvck5IdjIweDNxUGJzKzNjRHVuQWYKL1hWWis2
-dHhuOVZzZzAwb2RIWm9mcVpibUdUdkcveWJRY0dQalJQYVdZSGFMYWZqcERCM3dQc0REdTBMMGJY
-VApITlE4Vld6S3drOFVRdHpndEt4WEFFMlp3TFNkUVdzV0VLSEZGTmthT3F3ZnEyMVVZdmN0NHEy
-cnE5MXREbmJhCmZxTWpOTnNxVmtYZFIyNFdjUDhtZ1YxY3NWTkx1WmhtUWFCTlo2dytoR2l0aVFJ
-REFRQUJvNElCWVRDQ0FWMHcKQ1FZRFZSMFRCQUl3QURBUkJnbGdoa2dCaHZoQ0FRRUVCQU1DQmtB
-d013WUpZSVpJQVliNFFnRU5CQ1lXSkU5dwpaVzVUVTB3Z1IyVnVaWEpoZEdWa0lGTmxjblpsY2lC
-RFpYSjBhV1pwWTJGMFpUQWRCZ05WSFE0RUZnUVVpWmVaCjVVbXdGRjFWQ2dwd1hmM2crcTFGUzZN
-d2djTUdBMVVkSXdTQnV6Q0J1SUFVSVY3aXF0Myt4WWExRngvbll6eGQKMWh4dk53MmhnWnVrZ1pn
-d2daVXhDekFKQmdOVkJBWVRBbFZUTVJFd0R3WURWUVFJREFoRGIyeHZjbUZrYnpFUApNQTBHQTFV
-RUJ3d0dSR1Z1ZG1WeU1TUXdJZ1lEVlFRS0RCdEpjR05rYmlCRFpYSjBhV1pwWTJGMFpTQkJkWFJv
-CmIzSnBkSGt4SkRBaUJnTlZCQXNNRzBsd1kyUnVJRU5sY25ScFptbGpZWFJsSUdGMWRHaHZjbWww
-ZVRFV01CUUcKQTFVRUF3d05TWEJqWkc0Z1VtOXZkQ0JEUVlJQ0VBQXdEZ1lEVlIwUEFRSC9CQVFE
-QWdXZ01CTUdBMVVkSlFRTQpNQW9HQ0NzR0FRVUZCd01CTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElD
-QVFCSFgrWW1PNlRMYk1UWkJ5dXdyZ2lICnV5N3JQenBYVFhTSnZVTSt1cHhTZW5ybXo4SDVmQnp5
-cExmS0UxTk9LNThScjI1T3lBZDFJcWdHMUlkKzh5Y2cKYXRldGpJMXBvYU5DWnZLUFJyNDh3amNU
-VnNmZ3g3SFhXMGZ5a0kwS1QyMzlPazR1c0VNM3VxbWJrbjdBbm5mNwpkYnk4Qkt6NHA5bjF5ZTdl
-SHBpcHUxQTVXeGpCUWVEeW1sUHcvQ005RTB2NUYvaGdpV3hXK2U4bDV1N2g0M2JQCjFCTk82UEpY
-Si9HT05pUWg0YmNMMFI3NjN0TklLR1ZOWUhTZmZXNzF2eW9ZNnJlWGRLQk5uazkxT2dqRndIVE4K
-QUxKdHI5ank1eHk5dktBVFk3Z1RoVldEaFcvdWl2OExVSUN4eFpXbkN1Y0t2aGdCMmJMV2FIeElP
-cjlZeWphWApoRVZkSGdUVlhQbDVjTVhCdytVWkxuM3Z3NUVRSHVNRkFJV1IyWk5JaHJFdmphUG9u
-NXFhRXZlUUNEc2RhMzl3CnJUcjNsaGV5QkdNaFRubUE0d05WK2xOU0xJbUFjMm83OGFldGUwY1Rz
-SjYxOXNuR09EVW85UU8yWVovazd2UFMKbUhlSzBWclp2bkU4dWtsRkpVVERheUxvRCtTbnN4enRS
-SVR2ay9FdVJheTJQMWZHMS9xWm43UVVJZytaTTRhVgpTOHZQcmZJOXJ3dThDUmd4bVRUdFg1Wk1l
-ejg5Znk2RmxWRElUalZOaFJyVkljMm0zeEwwM0FTVGI2TmFua0pvCkVuK01MUXBDRlZLeVF5OU43
-MlJaTno2OEtpUEgvZnJhQWRxNG1MNU5BY1I0UC82R2c3U24rcWpuZi80bDQzeloKKzd1enFqd2hk
-dFUvWUhKOWo4L2Nvdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJU
-SUZJQ0FURS0tLS0tCk1JSUdCVENDQSsyZ0F3SUJBZ0lDRUFBd0RRWUpLb1pJaHZjTkFRRUxCUUF3
-Z1pVeEN6QUpCZ05WQkFZVEFsVlQKTVJFd0R3WURWUVFJREFoRGIyeHZjbUZrYnpFUE1BMEdBMVVF
-Qnd3R1JHVnVkbVZ5TVNRd0lnWURWUVFLREJ0SgpjR05rYmlCRFpYSjBhV1pwWTJGMFpTQkJkWFJv
-YjNKcGRIa3hKREFpQmdOVkJBc01HMGx3WTJSdUlFTmxjblJwClptbGpZWFJsSUdGMWRHaHZjbWww
-ZVRFV01CUUdBMVVFQXd3TlNYQmpaRzRnVW05dmRDQkRRVEFlRncweE56RXgKTVRZeU1ETTRNVFZh
-RncweU56RXhNVFF5TURNNE1UVmFNSUdNTVFzd0NRWURWUVFHRXdKVlV6RVJNQThHQTFVRQpDQXdJ
-UTI5c2IzSmhaRzh4SkRBaUJnTlZCQW9NRzBsd1kyUnVJRU5sY25ScFptbGpZWFJsSUVGMWRHaHZj
-bWwwCmVURWtNQ0lHQTFVRUN3d2JTWEJqWkc0Z1EyVnlkR2xtYVdOaGRHVWdRWFYwYUc5eWFYUjVN
-UjR3SEFZRFZRUUQKREJWSmNHTmtiaUJKYm5SbGNtMWxaR2xoZEdVZ1EwRXdnZ0lpTUEwR0NTcUdT
-SWIzRFFFQkFRVUFBNElDRHdBdwpnZ0lLQW9JQ0FRREtreFE5aGRNdFN3Zk5FQnFHUEFLenU3Q1Bo
-SCt4dTNrTDRlK3JKMDlFQisrZnhHOTA1bXdNClltOHMxR0MvaTFWMWhQYk9rK3pMV1hjY1podEM0
-OUJ0dHNEQlZSbWFndDRxNmVlRDEyQXh6VkJveldqNFluRnkKWkUwNENpWmxBSU4zcU40VG5OVC9P
-M2l5dm1qNThRRElGVk81MVlOU3JyN2oyZFFSTHBveVM2czg3a3B3OUE2VAoyNEwxcExrbUZ1QWdD
-TE1GUEc1SFpXeVpTU3RwWE96T2M3TElUWlFYUXp1bndMYXpOOVo0QXo4ellDOWlsTzZWCnROTk5j
-K1k3TXBGclRhRUZGU3NNMitSRWV4dVB0Q090VC9aRWNPd1A4ODRUNkFDY1VTVHY4NmlFL0VGT1Bn
-WmgKdlRLMkQwTnphdDNaVHNjNU4ydnZOMGVabTZDT25WQXZZTndyVFdHNHYzWVV0THIvUEVvRm05
-bXRQZFNBK1RzaQpMa0dGUmp3QW9BbmhWaWVGQUZ1bFFuc3diWkFhSlJjL3hTN0JKdnRzLzNKOWk3
-bDFvcHF1MEVibTZMOGpMZUh2CnAvb3AxVEQ4TElRa2NwN0dkc1hrNExZSDZWb3BhTk9pOHlvYUVm
-S1d3clhoeEJkQ2hISGxZQ2NmZWN5RDhPMzkKOGV1b0dRMHppL2VhQ3IzTUhZVTErYTIrNVRSUGR6
-SHgvbC8zVjF3eFg5aG1PR2Nyd1RDdGNZUnpSanphMlVsRQpVYWNtd0JxR3lmYTFHbi9pT3RvOXlx
-dFJ2V2xQR3E5ekpOUXpOQko2aVdSN2d5YjB0ODIwanBkdG1GeU5CNVB2CkpjZUh5VnlpeC83c0JV
-QjVHd01PMGlHbkxQcFk5SXg4N25ZUDNpdE4zamtxYWhUclQ3dEh1d0lEQVFBQm8yWXcKWkRBZEJn
-TlZIUTRFRmdRVUlWN2lxdDMreFlhMUZ4L25ZenhkMWh4dk53MHdId1lEVlIwakJCZ3dGb0FVV2Nk
-SQpCUjZ0M044dzd5VXQvVE9mWHdtdWJBZ3dFZ1lEVlIwVEFRSC9CQWd3QmdFQi93SUJBREFPQmdO
-VkhROEJBZjhFCkJBTUNBWVl3RFFZSktvWklodmNOQVFFTEJRQURnZ0lCQUtiZDhuS0ExaGx4Q1Rj
-elRnOVBIU2RxSFZFWVdxUkQKZHpyb09uejBLY0lnSkY0bmNSYU4zbm5hNzR3SW0zbkpEL1d1d2RG
-OGRWYnBENFlhZVpLaFFnbVhtWWdnVkgwbAo4SUlrZEMzcVlOVERqNHhoZzdxWkMzcHpLdU5JZzd5
-SHYzQXhyL3JiOUJ2cFVKeGJLby9hbG4vRzZQcmJOb1F4CjR4YjZ4bEs2V2NZT1JCL1VnekY2aktN
-NUNCWGFVdDJRUW1XdHM3TWdub056WjRreHNZYnV3ajNyT1B6SElnUlkKWXdKdCtraDV0bHloSFBr
-Z2p3VVRiTWcvTXYvb21melozK1hNQkQyWjY5ZU5kOVJIRTlYUzZBZE1LdERpcHJoZwpUTHUrOXRP
-Vmx5ZFFqWmszS3NxRnY1Ny8xVHdLcnQ5SkZqWGsvUFBRYWxYb1Azb3lrb2l2aWFjZDRNeWlCbWFX
-Cmk1V2J0Y3hHUDV2d2FObjI2N09HbGliZlFtUWdBMVZJZ0RxZnRyUXdlNlQvWndPS1hxRnFiNTZn
-cWRXNFZkT1UKNWJHTjB1TFhlbXJpdU5Rb2xUcFZtaE51MGJOSTVXQ2lZN2MzMFhOMk01ZWJjQldE
-SE9yNERPQ2crbW1YK3RKVApHaTFqdmZtQTZMT1lueVE4eEFWMDgwdVZlMzVOUTEwZTlteTZMdVhN
-aVE3dWJ2SFVTNU53YVFDRnBMREl2YmhmCjJYVmM0Nk5kMFYvYm9sTTIzQVFSbHp1bzBJU3NEU2VX
-U1FWTSt1UVorcExlOUc1bjJNeHFGZDg0VnU0ODlhdWMKMDJJOWNIaU5haFd5WFB0dm52TVd3SW1J
-QjMwQ1loaDVCeUdXbmVEbzNkNVpqMkhBQTZGd082N0xsSWhTZTdxegpheER0Y000bk8zUUgKLS0t
-LS1FTkQgQ0VSVElGSUNBVEUtLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJR0Vq
-Q0NBL3FnQXdJQkFnSUpBTDJWMWhuTFd1emdNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1JR1ZNUXN3Q1FZ
-RApWUVFHRXdKVlV6RVJNQThHQTFVRUNBd0lRMjlzYjNKaFpHOHhEekFOQmdOVkJBY01Ca1JsYm5a
-bGNqRWtNQ0lHCkExVUVDZ3diU1hCalpHNGdRMlZ5ZEdsbWFXTmhkR1VnUVhWMGFHOXlhWFI1TVNR
-d0lnWURWUVFMREJ0SmNHTmsKYmlCRFpYSjBhV1pwWTJGMFpTQmhkWFJvYjNKcGRIa3hGakFVQmdO
-VkJBTU1EVWx3WTJSdUlGSnZiM1FnUTBFdwpIaGNOTVRjeE1URTJNakF4T1RJMFdoY05NamN4TVRF
-ME1qQXhPVEkwV2pDQmxURUxNQWtHQTFVRUJoTUNWVk14CkVUQVBCZ05WQkFnTUNFTnZiRzl5WVdS
-dk1ROHdEUVlEVlFRSERBWkVaVzUyWlhJeEpEQWlCZ05WQkFvTUcwbHcKWTJSdUlFTmxjblJwWm1s
-allYUmxJRUYxZEdodmNtbDBlVEVrTUNJR0ExVUVDd3diU1hCalpHNGdRMlZ5ZEdsbQphV05oZEdV
-Z1lYVjBhRzl5YVhSNU1SWXdGQVlEVlFRRERBMUpjR05rYmlCU2IyOTBJRU5CTUlJQ0lqQU5CZ2tx
-CmhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBMkhzTGtubTl3eDFWMzN6dHRNV24xc0ZF
-SnlMTk1lZVcKaEEwZHdlS0NocURWdzVsQXlJaWQwbHFqbmpJRWl2bEFNOHpkMk5BUFpUSEZHOUJU
-M3VuZHVOY0RjV3VSZ2gzMwptbHlzc0VoYXJXdEU2VTdsenc4Uk1HV2t5V1FrSjJFMFN4akUvVm1L
-UWpIMy80QWs4U2hoVFpGS0VadXdlUmRnCmoyMThxVWVtc09WK0VOVHNuR1V4b0FQcHI1Y0dHbzRp
-Z2ZPOXRwSTFnN1BXbmtZclZGdHdzUG95MkNLeHFoL0kKM0Y2N0VacTJ5Uk9CeTlnQmhDNUZ1Wmh1
-dmdwdHZTYWtOUXkvdys5YnVSZmZzaGI2OXdMc2JxUWF5aGpsTHFjUQpYa2NoNHk2Y0c4WWxnK2hy
-cXptRzN2RzRxMDNZRno4UHVNZC91TnhlSlFBYlpKL3NYaDdqVlFOSml0Z2k2b095CmoxeFZ6TktV
-cWIxTXgyNURoQnkxMjUvbDh3R0Jkc0NSVVlSNnI3ME5BWlJuZGprUUtWNGwzdFRRNCtvMnJkamQK
-Qy8yU2syL2JIVmJ5dE1xNEl6KzFzT3NJVVYzTGErUitEV2NMQTZVb25wRW9jTmI4YnQ1YnU0SmhS
-RHJuSndQaQo0alJhSCtLZ3hwQlRJbFozYUZuU3MwSTN3a1BPZ0EzRHJJNkxXeGd0M0JmUHVLOURQ
-bWExcmM0QjFjd1NRVE5rCnl5VVkyYm9Yc25MTU1QZWJGM2Rqd2J0WUVkcUFhaXh4enpRQ1ZZbGhm
-Q0VRanFjZVNkNlRKMlNkekg0STNKN3gKT3NMejFMai85MmFEZWVxNzdxL2M5RmlkbmZOZTc1ekI3
-Z1hOL2JUdGI1NVpjVFRPOFhBRXZlZ3hjcnc1Q25PMQpNbkZ3NnhEZisrVUNBd0VBQWFOak1HRXdI
-UVlEVlIwT0JCWUVGRm5IU0FVZXJkemZNTzhsTGYwem4xOEpybXdJCk1COEdBMVVkSXdRWU1CYUFG
-Rm5IU0FVZXJkemZNTzhsTGYwem4xOEpybXdJTUE4R0ExVWRFd0VCL3dRRk1BTUIKQWY4d0RnWURW
-UjBQQVFIL0JBUURBZ0dHTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElDQVFCK2FZV1poKy9nQ21GeQpv
-STU4MkFDNSs1NGM3eGVMUm10UVBtRnBBQTJZNGlUU2VHeWp2Mmc1TTlhZ1E0SXh3dWU1RGx1UWxz
-RGNEc0p3CmxzWFZIeUFsQ2Y2bkRiSk9wZjVtNml4ZnZCRitRekVlWGpVRzc0aVNDV3JBcFlGbXNO
-c0NybHNNL0VQSm9ncXUKN2NnR3ZId1dZTmpQenV3b1UwQVdITzlGZ0liRHozTWMxNVpsSElRMlQv
-aXh4eUJmcElQYzVEOTFrNHUvWldTYgpoTzZsc00xaUVBdnY5VG9VWGtLdHRDUTBmTjM0QndZWDQ3
-QXhDNzF0U3Q5L1ZLSURJRVhqenFKSnBiSmRCR1NtCld1aVpIV3dCelZ3N2s1eStTK3dNNXZaL09N
-dzB0aEwrSTUzem1reEdFZjN0TUg0UE9lS3ZYL3UxOW4wVEZrLzEKOTZjenRWbVRCNlc2N21iOXpa
-OHlTZUp0RDl1WEU0NHljeGs5M2dUbmFya0lHZFRmOFhvbkNWbGtIR3BiNlRXTQo1RTdhV0NvVmJx
-UVJrRjFycVB6YThoUkpHSDFFR2ttZGJrdXlVTUxtUTFGSks5Zi94RkljcmRCR3BNbHh5T29MCk1T
-ZUZlYWdvU0xOcTV4emp1Y0YvNm1rQVVKOFVaQXhyU0dtYURFYVN0MS9xSlJIb3ZIY3QyYjVGV1pM
-dVJ0MGcKZkRzR29LVDhJRnVhcFNzbUZFSW52RDBXS1hEU1BsVThyVHkxWkJEbENxcDNlTkg0dENm
-TGFoazd2TEEwSmJmNwpVTHJ0RG5yTmZqeFVZRmNGMFJjYXVSMWRsclFRUkFzMzFRT3pYK0pPcjRn
-VUc3eVhhM2o2NG54Mkc1TXBMZ1NvCk9FVWpmYWtLNzErVi9IYlF0NDc3elI0azdjUmJpQT09Ci0t
-LS0tRU5EIENFUlRJRklDQVRFLS0tLS0K`
-
+-----BEGIN CERTIFICATE-----
+MIIF3DCCA8SgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVT
+MREwDwYDVQQIDAhDb2xvcmFkbzEkMCIGA1UECgwbSXBjZG4gQ2VydGlmaWNhdGUg
+QXV0aG9yaXR5MSQwIgYDVQQLDBtJcGNkbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkx
+HjAcBgNVBAMMFUlwY2RuIEludGVybWVkaWF0ZSBDQTAeFw0xNzExMTYyMDUwMTla
+Fw0yNjAyMDIyMDUwMTlaMHAxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhDb2xvcmFk
+bzEPMA0GA1UEBwwGRGVudmVyMQ8wDQYDVQQKDAZJcGNkbiAxEjAQBgNVBAsMCUlw
+Y2RuIGRldjEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA1h9fXwJ17QYNMXM5jEgHecVxWm+CNPQbi2O0aLm5
+laEuoctl/xnclDgkOcV50sIgURSnaRXHCMa93zb95xQefTIvRF/1kU9e68mmFjz8
+frAdOaM90TdUf1yv26W37nT9Dx26CAiSwALXVdx+4oPorNHv20x3qPbs+3cDunAf
+/XVZ+6txn9Vsg00odHZofqZbmGTvG/ybQcGPjRPaWYHaLafjpDB3wPsDDu0L0bXT
+HNQ8VWzKwk8UQtzgtKxXAE2ZwLSdQWsWEKHFFNkaOqwfq21UYvct4q2rq91tDnba
+fqMjNNsqVkXdR24WcP8mgV1csVNLuZhmQaBNZ6w+hGitiQIDAQABo4IBYTCCAV0w
+CQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9w
+ZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUiZeZ
+5UmwFF1VCgpwXf3g+q1FS6MwgcMGA1UdIwSBuzCBuIAUIV7iqt3+xYa1Fx/nYzxd
+1hxvNw2hgZukgZgwgZUxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhDb2xvcmFkbzEP
+MA0GA1UEBwwGRGVudmVyMSQwIgYDVQQKDBtJcGNkbiBDZXJ0aWZpY2F0ZSBBdXRo
+b3JpdHkxJDAiBgNVBAsMG0lwY2RuIENlcnRpZmljYXRlIGF1dGhvcml0eTEWMBQG
+A1UEAwwNSXBjZG4gUm9vdCBDQYICEAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQM
+MAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQBHX+YmO6TLbMTZByuwrgiH
+uy7rPzpXTXSJvUM+upxSenrmz8H5fBzypLfKE1NOK58Rr25OyAd1IqgG1Id+8ycg
+atetjI1poaNCZvKPRr48wjcTVsfgx7HXW0fykI0KT239Ok4usEM3uqmbkn7Annf7
+dby8BKz4p9n1ye7eHpipu1A5WxjBQeDymlPw/CM9E0v5F/hgiWxW+e8l5u7h43bP
+1BNO6PJXJ/GONiQh4bcL0R763tNIKGVNYHSffW71vyoY6reXdKBNnk91OgjFwHTN
+ALJtr9jy5xy9vKATY7gThVWDhW/uiv8LUICxxZWnCucKvhgB2bLWaHxIOr9YyjaX
+hEVdHgTVXPl5cMXBw+UZLn3vw5EQHuMFAIWR2ZNIhrEvjaPon5qaEveQCDsda39w
+rTr3lheyBGMhTnmA4wNV+lNSLImAc2o78aete0cTsJ619snGODUo9QO2YZ/k7vPS
+mHeK0VrZvnE8uklFJUTDayLoD+SnsxztRITvk/EuRay2P1fG1/qZn7QUIg+ZM4aV
+S8vPrfI9rwu8CRgxmTTtX5ZMez89fy6FlVDITjVNhRrVIc2m3xL03ASTb6NankJo
+En+MLQpCFVKyQy9N72RZNz68KiPH/fraAdq4mL5NAcR4P/6Gg7Sn+qjnf/4l43zZ
++7uzqjwhdtU/YHJ9j8/cow==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGBTCCA+2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAlVT
+MREwDwYDVQQIDAhDb2xvcmFkbzEPMA0GA1UEBwwGRGVudmVyMSQwIgYDVQQKDBtJ
+cGNkbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxJDAiBgNVBAsMG0lwY2RuIENlcnRp
+ZmljYXRlIGF1dGhvcml0eTEWMBQGA1UEAwwNSXBjZG4gUm9vdCBDQTAeFw0xNzEx
+MTYyMDM4MTVaFw0yNzExMTQyMDM4MTVaMIGMMQswCQYDVQQGEwJVUzERMA8GA1UE
+CAwIQ29sb3JhZG8xJDAiBgNVBAoMG0lwY2RuIENlcnRpZmljYXRlIEF1dGhvcml0
+eTEkMCIGA1UECwwbSXBjZG4gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR4wHAYDVQQD
+DBVJcGNkbiBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDKkxQ9hdMtSwfNEBqGPAKzu7CPhH+xu3kL4e+rJ09EB++fxG905mwM
+Ym8s1GC/i1V1hPbOk+zLWXccZhtC49BttsDBVRmagt4q6eeD12AxzVBozWj4YnFy
+ZE04CiZlAIN3qN4TnNT/O3iyvmj58QDIFVO51YNSrr7j2dQRLpoyS6s87kpw9A6T
+24L1pLkmFuAgCLMFPG5HZWyZSStpXOzOc7LITZQXQzunwLazN9Z4Az8zYC9ilO6V
+tNNNc+Y7MpFrTaEFFSsM2+REexuPtCOtT/ZEcOwP884T6ACcUSTv86iE/EFOPgZh
+vTK2D0Nzat3ZTsc5N2vvN0eZm6COnVAvYNwrTWG4v3YUtLr/PEoFm9mtPdSA+Tsi
+LkGFRjwAoAnhVieFAFulQnswbZAaJRc/xS7BJvts/3J9i7l1opqu0Ebm6L8jLeHv
+p/op1TD8LIQkcp7GdsXk4LYH6VopaNOi8yoaEfKWwrXhxBdChHHlYCcfecyD8O39
+8euoGQ0zi/eaCr3MHYU1+a2+5TRPdzHx/l/3V1wxX9hmOGcrwTCtcYRzRjza2UlE
+UacmwBqGyfa1Gn/iOto9yqtRvWlPGq9zJNQzNBJ6iWR7gyb0t820jpdtmFyNB5Pv
+JceHyVyix/7sBUB5GwMO0iGnLPpY9Ix87nYP3itN3jkqahTrT7tHuwIDAQABo2Yw
+ZDAdBgNVHQ4EFgQUIV7iqt3+xYa1Fx/nYzxd1hxvNw0wHwYDVR0jBBgwFoAUWcdI
+BR6t3N8w7yUt/TOfXwmubAgwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
+BAMCAYYwDQYJKoZIhvcNAQELBQADggIBAKbd8nKA1hlxCTczTg9PHSdqHVEYWqRD
+dzroOnz0KcIgJF4ncRaN3nna74wIm3nJD/WuwdF8dVbpD4YaeZKhQgmXmYggVH0l
+8IIkdC3qYNTDj4xhg7qZC3pzKuNIg7yHv3Axr/rb9BvpUJxbKo/aln/G6PrbNoQx
+4xb6xlK6WcYORB/UgzF6jKM5CBXaUt2QQmWts7MgnoNzZ4kxsYbuwj3rOPzHIgRY
+YwJt+kh5tlyhHPkgjwUTbMg/Mv/omfzZ3+XMBD2Z69eNd9RHE9XS6AdMKtDiprhg
+TLu+9tOVlydQjZk3KsqFv57/1TwKrt9JFjXk/PPQalXoP3oykoiviacd4MyiBmaW
+i5WbtcxGP5vwaNn267OGlibfQmQgA1VIgDqftrQwe6T/ZwOKXqFqb56gqdW4VdOU
+5bGN0uLXemriuNQolTpVmhNu0bNI5WCiY7c30XN2M5ebcBWDHOr4DOCg+mmX+tJT
+Gi1jvfmA6LOYnyQ8xAV080uVe35NQ10e9my6LuXMiQ7ubvHUS5NwaQCFpLDIvbhf
+2XVc46Nd0V/bolM23AQRlzuo0ISsDSeWSQVM+uQZ+pLe9G5n2MxqFd84Vu489auc
+02I9cHiNahWyXPtvnvMWwImIB30CYhh5ByGWneDo3d5Zj2HAA6FwO67LlIhSe7qz
+axDtcM4nO3QH
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGEjCCA/qgAwIBAgIJAL2V1hnLWuzgMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD
+VQQGEwJVUzERMA8GA1UECAwIQ29sb3JhZG8xDzANBgNVBAcMBkRlbnZlcjEkMCIG
+A1UECgwbSXBjZG4gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSQwIgYDVQQLDBtJcGNk
+biBDZXJ0aWZpY2F0ZSBhdXRob3JpdHkxFjAUBgNVBAMMDUlwY2RuIFJvb3QgQ0Ew
+HhcNMTcxMTE2MjAxOTI0WhcNMjcxMTE0MjAxOTI0WjCBlTELMAkGA1UEBhMCVVMx
+ETAPBgNVBAgMCENvbG9yYWRvMQ8wDQYDVQQHDAZEZW52ZXIxJDAiBgNVBAoMG0lw
+Y2RuIENlcnRpZmljYXRlIEF1dGhvcml0eTEkMCIGA1UECwwbSXBjZG4gQ2VydGlm
+aWNhdGUgYXV0aG9yaXR5MRYwFAYDVQQDDA1JcGNkbiBSb290IENBMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2HsLknm9wx1V33zttMWn1sFEJyLNMeeW
+hA0dweKChqDVw5lAyIid0lqjnjIEivlAM8zd2NAPZTHFG9BT3unduNcDcWuRgh33
+mlyssEharWtE6U7lzw8RMGWkyWQkJ2E0SxjE/VmKQjH3/4Ak8ShhTZFKEZuweRdg
+j218qUemsOV+ENTsnGUxoAPpr5cGGo4igfO9tpI1g7PWnkYrVFtwsPoy2CKxqh/I
+3F67EZq2yROBy9gBhC5FuZhuvgptvSakNQy/w+9buRffshb69wLsbqQayhjlLqcQ
+Xkch4y6cG8Ylg+hrqzmG3vG4q03YFz8PuMd/uNxeJQAbZJ/sXh7jVQNJitgi6oOy
+j1xVzNKUqb1Mx25DhBy125/l8wGBdsCRUYR6r70NAZRndjkQKV4l3tTQ4+o2rdjd
+C/2Sk2/bHVbytMq4Iz+1sOsIUV3La+R+DWcLA6UonpEocNb8bt5bu4JhRDrnJwPi
+4jRaH+KgxpBTIlZ3aFnSs0I3wkPOgA3DrI6LWxgt3BfPuK9DPma1rc4B1cwSQTNk
+yyUY2boXsnLMMPebF3djwbtYEdqAaixxzzQCVYlhfCEQjqceSd6TJ2SdzH4I3J7x
+OsLz1Lj/92aDeeq77q/c9FidnfNe75zB7gXN/bTtb55ZcTTO8XAEvegxcrw5CnO1
+MnFw6xDf++UCAwEAAaNjMGEwHQYDVR0OBBYEFFnHSAUerdzfMO8lLf0zn18JrmwI
+MB8GA1UdIwQYMBaAFFnHSAUerdzfMO8lLf0zn18JrmwIMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQB+aYWZh+/gCmFy
+oI582AC5+54c7xeLRmtQPmFpAA2Y4iTSeGyjv2g5M9agQ4Ixwue5DluQlsDcDsJw
+lsXVHyAlCf6nDbJOpf5m6ixfvBF+QzEeXjUG74iSCWrApYFmsNsCrlsM/EPJogqu
+7cgGvHwWYNjPzuwoU0AWHO9FgIbDz3Mc15ZlHIQ2T/ixxyBfpIPc5D91k4u/ZWSb
+hO6lsM1iEAvv9ToUXkKttCQ0fN34BwYX47AxC71tSt9/VKIDIEXjzqJJpbJdBGSm
+WuiZHWwBzVw7k5y+S+wM5vZ/OMw0thL+I53zmkxGEf3tMH4POeKvX/u19n0TFk/1
+96cztVmTB6W67mb9zZ8ySeJtD9uXE44ycxk93gTnarkIGdTf8XonCVlkHGpb6TWM
+5E7aWCoVbqQRkF1rqPza8hRJGH1EGkmdbkuyUMLmQ1FJK9f/xFIcrdBGpMlxyOoL
+MSeFeagoSLNq5xzjucF/6mkAUJ8UZAxrSGmaDEaSt1/qJRHovHct2b5FWZLuRt0g
+fDsGoKT8IFuapSsmFEInvD0WKXDSPlU8rTy1ZBDlCqp3eNH4tCfLahk7vLA0Jbf7
+ULrtDnrNfjxUYFcF0RcauR1dlrQQRAs31QOzX+JOr4gUG7yXa3j64nx2G5MpLgSo
+OEUjfakK71+V/HbQt477zR4k7cRbiA==
+-----END CERTIFICATE-----
+`
        rootCA = `
 -----BEGIN CERTIFICATE-----
 MIIGEjCCA/qgAwIBAgIJAL2V1hnLWuzgMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD
@@ -209,32 +199,26 @@ OEUjfakK71+V/HbQt477zR4k7cRbiA==
 func TestVerifyAndEncodeCertificate(t *testing.T) {
 
        // should fail bad base64 data
-       dat, err := verifyAndEncodeCertificate(BadData, "")
+       dat, err := verifyCertificate(BadData, "")
        if err == nil {
                t.Errorf("Unexpected result, there should have been a base64 
decoding failure")
        }
 
        // should fail, can't verify self signed cert
-       dat, err = verifyAndEncodeCertificate(SelfSigneCertOnly, rootCA)
+       dat, err = verifyCertificate(SelfSigneCertOnly, rootCA)
        if err == nil {
                t.Errorf("Unexpected result, a certificate verification error 
should have occured")
        }
 
        // should pass
-       dat, err = verifyAndEncodeCertificate(GoodTLSKeys, rootCA)
+       dat, err = verifyCertificate(GoodTLSKeys, rootCA)
        if err != nil {
                t.Errorf("Test failure: %s", err)
        }
 
-       pemCerts := make([]byte, base64.StdEncoding.EncodedLen(len(dat)))
-       _, err = base64.StdEncoding.Decode(pemCerts, []byte(dat))
-       if err != nil {
-               t.Errorf("Test failure: bad retrun value from 
verifyAndEncodeCertificate(): %v", err)
-       }
-
-       certs := strings.SplitAfter(string(pemCerts), "-----END 
CERTIFICATE-----")
+       certs := strings.SplitAfter(dat, PemCertEndMarker)
        length := len(certs) - 1
        if length != 2 {
-               t.Errorf("Test failure: expected 2 certs from 
verifyAndEncodeCertificate(), got: %d ", length)
+               t.Errorf("Test failure: expected 2 certs from 
verifyCertificate(), got: %d ", length)
        }
 }
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/sslkeys.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/sslkeys.go
index d313608..16b87cf 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/sslkeys.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/sslkeys.go
@@ -75,12 +75,12 @@ func generatePutRiakKeys(req tc.DeliveryServiceSSLKeysReq, 
tx *sql.Tx, cfg *conf
                }
                dsSSLKeys.Certificate = 
tc.DeliveryServiceSSLKeysCertificate{Crt: string(crt), Key: string(key), CSR: 
string(csr)}
        }
-       if err := riaksvc.PutDeliveryServiceSSLKeysObjTx(dsSSLKeys, tx, 
cfg.RiakAuthOptions); err != nil {
+       if err := riaksvc.PutDeliveryServiceSSLKeysObj(dsSSLKeys, tx, 
cfg.RiakAuthOptions); err != nil {
                return errors.New("putting riak keys: " + err.Error())
        }
 
        dsSSLKeys.Version = riaksvc.DSSSLKeyVersionLatest
-       if err := riaksvc.PutDeliveryServiceSSLKeysObjTx(dsSSLKeys, tx, 
cfg.RiakAuthOptions); err != nil {
+       if err := riaksvc.PutDeliveryServiceSSLKeysObj(dsSSLKeys, tx, 
cfg.RiakAuthOptions); err != nil {
                return errors.New("putting latest riak keys: " + err.Error())
        }
        return nil
diff --git a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go 
b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
index 24f3d57..1ad1b57 100644
--- a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
+++ b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
@@ -56,35 +56,6 @@ func GetDeliveryServiceSSLKeysObj(xmlID string, version 
string, tx *sql.Tx, auth
                        return nil // not found
                }
                if err := json.Unmarshal(ro[0].Value, &key); err != nil {
-                       return errors.New("unmarshalling Riak result: " + 
err.Error())
-               }
-               found = true
-               return nil
-       })
-       if err != nil {
-               return key, false, err
-       }
-       return key, found, nil
-}
-
-func GetDeliveryServiceSSLKeysObjTx(xmlID string, version string, tx *sql.Tx, 
authOpts *riak.AuthOptions) (tc.DeliveryServiceSSLKeys, bool, error) {
-       key := tc.DeliveryServiceSSLKeys{}
-       if version == "" {
-               xmlID += "-latest"
-       } else {
-               xmlID += "-" + version
-       }
-       found := false
-       err := WithClusterTx(tx, authOpts, func(cluster StorageCluster) error {
-               // get the deliveryservice ssl keys by xmlID and version
-               ro, err := FetchObjectValues(xmlID, 
DeliveryServiceSSLKeysBucket, cluster)
-               if err != nil {
-                       return err
-               }
-               if len(ro) == 0 {
-                       return nil // not found
-               }
-               if err := json.Unmarshal(ro[0].Value, &key); err != nil {
                        log.Errorf("failed at unmarshaling sslkey response: 
%s\n", err)
                        return errors.New("unmarshalling Riak result: " + 
err.Error())
                }
@@ -118,27 +89,6 @@ func PutDeliveryServiceSSLKeysObj(key 
tc.DeliveryServiceSSLKeys, tx *sql.Tx, aut
        return err
 }
 
-func PutDeliveryServiceSSLKeysObjTx(key tc.DeliveryServiceSSLKeys, tx *sql.Tx, 
authOpts *riak.AuthOptions) error {
-       keyJSON, err := json.Marshal(&key)
-       if err != nil {
-               return errors.New("marshalling key: " + err.Error())
-       }
-       err = WithClusterTx(tx, authOpts, func(cluster StorageCluster) error {
-               obj := &riak.Object{
-                       ContentType:     "text/json",
-                       Charset:         "utf-8",
-                       ContentEncoding: "utf-8",
-                       Key:             MakeDSSSLKeyKey(key.DeliveryService, 
string(key.Version)),
-                       Value:           []byte(keyJSON),
-               }
-               if err = SaveObject(obj, DeliveryServiceSSLKeysBucket, 
cluster); err != nil {
-                       return errors.New("saving Riak object: " + err.Error())
-               }
-               return nil
-       })
-       return err
-}
-
 func Ping(tx *sql.Tx, authOpts *riak.AuthOptions) (tc.RiakPingResp, error) {
        servers, err := GetRiakServers(tx)
        if err != nil {
@@ -235,28 +185,14 @@ func GetBucketKey(tx *sql.Tx, authOpts *riak.AuthOptions, 
bucket string, key str
        return val, found, nil
 }
 
-func DeleteDSSSLKeys(tx *sql.Tx, authOpts *riak.AuthOptions, ds 
tc.DeliveryServiceName, version string) error {
-       if version == "" {
-               version = "latest"
-       }
-       key := string(ds) + "-" + version
-
-       cluster, err := GetRiakClusterTx(tx, authOpts)
-       if err != nil {
-               return errors.New("getting riak cluster: " + err.Error())
-       }
-       if err = cluster.Start(); err != nil {
-               return errors.New("starting riak cluster: " + err.Error())
-       }
-       defer func() {
-               if err := cluster.Stop(); err != nil {
-                       log.Errorln("stopping Riak cluster: " + err.Error())
+func DeleteDSSSLKeys(tx *sql.Tx, authOpts *riak.AuthOptions, xmlID string, 
version string) error {
+       err := WithClusterTx(tx, authOpts, func(cluster StorageCluster) error {
+               if err := DeleteObject(MakeDSSSLKeyKey(xmlID, version), 
DeliveryServiceSSLKeysBucket, cluster); err != nil {
+                       return errors.New("deleting SSL keys: " + err.Error())
                }
-       }()
-       if err := DeleteObject(key, DeliveryServiceSSLKeysBucket, cluster); err 
!= nil {
-               return errors.New("deleting SSL keys: " + err.Error())
-       }
-       return nil
+               return nil
+       })
+       return err
 }
 
 // GetURLSigConfigFileName returns the filename of the Apache Traffic Server 
URLSig config file
diff --git a/traffic_ops/traffic_ops_golang/routes.go 
b/traffic_ops/traffic_ops_golang/routes.go
index f9c2c84..72e7d05 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -361,13 +361,6 @@ func Routes(d ServerData) ([]Route, []RawRoute, 
http.Handler, error) {
                {1.1, http.MethodPut, `cdns/{id}/snapshot/?$`, 
crconfig.SnapshotHandler, auth.PrivLevelOperations, Authenticated, nil},
                {1.1, http.MethodPut, `snapshot/{cdn}/?$`, 
crconfig.SnapshotHandler, auth.PrivLevelOperations, Authenticated, nil},
 
-               //SSLKeys deliveryservice endpoints here that are marked  
marked as '-wip' need to have tenancy checks added
-
-               {1.3, http.MethodGet, 
`deliveryservices-wip/xmlId/{xmlID}/sslkeys$`, 
deliveryservice.GetSSLKeysByXMLID, auth.PrivLevelAdmin, Authenticated, nil},
-               {1.3, http.MethodGet, 
`deliveryservices-wip/hostname/{hostName}/sslkeys$`, 
deliveryservice.GetSSLKeysByHostName, auth.PrivLevelAdmin, Authenticated, nil},
-               {1.3, http.MethodPost, 
`deliveryservices-wip/hostname/{hostName}/sslkeys/add$`, 
deliveryservice.AddSSLKeys, auth.PrivLevelAdmin, Authenticated, nil},
-               {1.3, http.MethodGet, 
`deliveryservices/xmlId/{name}/sslkeys/delete$`, deliveryservice.DeleteSSLKeys, 
auth.PrivLevelAdmin, Authenticated, nil},
-
                ////DeliveryServices
                {1.3, http.MethodGet, `deliveryservices/?(\.json)?$`, 
api.ReadHandler(deliveryservice.GetTypeV13Factory()), auth.PrivLevelReadOnly, 
Authenticated, nil},
                {1.1, http.MethodGet, `deliveryservices/?(\.json)?$`, 
api.ReadHandler(deliveryservice.GetTypeV12Factory()), auth.PrivLevelReadOnly, 
Authenticated, nil},
@@ -381,6 +374,10 @@ func Routes(d ServerData) ([]Route, []RawRoute, 
http.Handler, error) {
                {1.1, http.MethodDelete, `deliveryservices/{id}/?(\.json)?$`, 
api.DeleteHandler(deliveryservice.GetTypeV12Factory()), 
auth.PrivLevelOperations, Authenticated, nil},
                {1.1, http.MethodGet, 
`deliveryservices/{id}/servers/eligible/?(\.json)?$`, 
deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, Authenticated, nil},
 
+               {1.1, http.MethodGet, 
`deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLID, 
auth.PrivLevelAdmin, Authenticated, nil},
+               {1.1, http.MethodGet, 
`deliveryservices/hostname/{hostname}/sslkeys$`, 
deliveryservice.GetSSLKeysByHostName, auth.PrivLevelAdmin, Authenticated, nil},
+               {1.1, http.MethodPost, `deliveryservices/sslkeys/add$`, 
deliveryservice.AddSSLKeys, auth.PrivLevelAdmin, Authenticated, nil},
+               {1.1, http.MethodGet, 
`deliveryservices/xmlId/{xmlid}/sslkeys/delete$`, 
deliveryservice.DeleteSSLKeys, auth.PrivLevelOperations, Authenticated, nil},
                {1.1, http.MethodPost, 
`deliveryservices/sslkeys/generate/?(\.json)?$`, 
deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, Authenticated, nil},
                {1.1, http.MethodPost, 
`deliveryservices/xmlId/{name}/urlkeys/copyFromXmlId/{copy-name}/?(\.json)?$`, 
deliveryservice.CopyURLKeys, auth.PrivLevelOperations, Authenticated, nil},
                {1.1, http.MethodPost, 
`deliveryservices/xmlId/{name}/urlkeys/generate/?(\.json)?$`, 
deliveryservice.GenerateURLKeys, auth.PrivLevelOperations, Authenticated, nil},

Reply via email to