You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by sh...@apache.org on 2021/10/15 18:02:19 UTC
[trafficcontrol] branch master updated: Added SANs to Cert Page
(#6282)
This is an automated email from the ASF dual-hosted git repository.
shamrick pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 1f56100 Added SANs to Cert Page (#6282)
1f56100 is described below
commit 1f5610066c9191eeba29dcacb25182e6c676c82e
Author: mattjackson220 <33...@users.noreply.github.com>
AuthorDate: Fri Oct 15 12:02:12 2021 -0600
Added SANs to Cert Page (#6282)
* Added SANs to Cert Page
* updated changelog
* updated per comment
---
CHANGELOG.md | 1 +
.../v4/deliveryservices_xmlid_xmlid_sslkeys.rst | 6 +-
lib/go-tc/deliveryservice_ssl_keys.go | 16 ++++-
lib/go-util/str.go | 11 ++++
.../deliveryservice/autorenewcerts.go | 2 +-
.../traffic_ops_golang/deliveryservice/keys.go | 69 ++++++++++++++--------
traffic_ops/traffic_ops_golang/routing/routes.go | 9 ++-
.../FormDeliveryServiceSslKeysController.js | 1 +
.../form.deliveryServiceSslKeys.tpl.html | 6 ++
traffic_portal/app/src/scripts/config.js | 2 +-
10 files changed, 90 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7286bf6..9624e01 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#6034](https://github.com/apache/trafficcontrol/issues/6034) Added new query parameter `cdn` to the `GET /api/x/deliveryserviceserver` Traffic Ops API to filter by CDN name
- Added a new Traffic Monitor configuration option -- `short_hostname_override` -- to traffic_monitor.cfg to allow overriding the system hostname that Traffic Monitor uses.
- A new Traffic Portal server command-line option `-c` to specify a configuration file, and the ability to set `log: null` to log to stdout (consult documentation for details).
+- SANs information to the SSL key endpoint and Traffic Portal page.
### Fixed
- Fixed Traffic Router crs/stats to prevent overflow and to correctly record the time used in averages.
diff --git a/docs/source/api/v4/deliveryservices_xmlid_xmlid_sslkeys.rst b/docs/source/api/v4/deliveryservices_xmlid_xmlid_sslkeys.rst
index efc2cb5..3130a23 100644
--- a/docs/source/api/v4/deliveryservices_xmlid_xmlid_sslkeys.rst
+++ b/docs/source/api/v4/deliveryservices_xmlid_xmlid_sslkeys.rst
@@ -71,6 +71,9 @@ Response Structure
:state: An optional field which, if present, contains the state entered by the user when generating certificate\ [1]_
:version: An integer that defines the "version" of the key - which may be thought of as the sequential generation; that is, the higher the number the more recent the key
:expiration: The expiration date of the certificate for the :term:`Delivery Service` in :rfc:`3339` format
+:sans: The :abbr:`SANs (Subject Alternate Names)` from the SSL certificate.
+
+ .. versionadded:: 4.1
.. code-block:: http
:caption: Response Example
@@ -93,7 +96,8 @@ Response Structure
"country": "US",
"state": "Colorado",
"version": "1",
- "expiration": "2020-08-18T13:53:06Z"
+ "expiration": "2020-08-18T13:53:06Z",
+ "sans": ["*.foober.com", "*.foober2.com"]
}}
``DELETE``
diff --git a/lib/go-tc/deliveryservice_ssl_keys.go b/lib/go-tc/deliveryservice_ssl_keys.go
index ec6dc4c..fd67722 100644
--- a/lib/go-tc/deliveryservice_ssl_keys.go
+++ b/lib/go-tc/deliveryservice_ssl_keys.go
@@ -65,6 +65,20 @@ type DeliveryServiceSSLKeys struct {
Certificate DeliveryServiceSSLKeysCertificate `json:"certificate,omitempty"`
}
+// DeliveryServiceSSLKeysV4 is the representation of a DeliveryServiceSSLKeys in the latest minor version of
+// version 4 of the Traffic Ops API.
+type DeliveryServiceSSLKeysV4 = DeliveryServiceSSLKeysV41
+
+// DeliveryServiceSSLKeysV41 structures contain information about an SSL key
+// certificate pair used by a Delivery Service.
+//
+// "V41" is used because this structure was first introduced in version 4.1 of
+// the Traffic Ops API.
+type DeliveryServiceSSLKeysV41 struct {
+ DeliveryServiceSSLKeysV15
+ Sans []string `json:"sans,omitempty"`
+}
+
// DeliveryServiceSSLKeysV15 structures contain information about an SSL key
// certificate pair used by a Delivery Service.
//
@@ -73,7 +87,7 @@ type DeliveryServiceSSLKeys struct {
//
// This is, ostensibly, an updated version of DeliveryServiceSSLKeys, but
// beware that this may not be completely accurate as the predecessor structure
-// appears to be used in many more contexts than this this structure.
+// appears to be used in many more contexts than this structure.
type DeliveryServiceSSLKeysV15 struct {
DeliveryServiceSSLKeys
Expiration time.Time `json:"expiration,omitempty"`
diff --git a/lib/go-util/str.go b/lib/go-util/str.go
index 842def7..755fc8c 100644
--- a/lib/go-util/str.go
+++ b/lib/go-util/str.go
@@ -49,6 +49,17 @@ func StrInArray(strs []string, s string) bool {
return false
}
+// RemoveStrFromArray removes a specific string from a string slice.
+func RemoveStrFromArray(strs []string, s string) []string {
+ newStrArray := []string{}
+ for _, str := range strs {
+ if str != s {
+ newStrArray = append(newStrArray, str)
+ }
+ }
+ return newStrArray
+}
+
func ContainsStr(a []string, x string) bool {
for _, n := range a {
if x == n {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/autorenewcerts.go b/traffic_ops/traffic_ops_golang/deliveryservice/autorenewcerts.go
index 05327d2..84be21f 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/autorenewcerts.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/autorenewcerts.go
@@ -208,7 +208,7 @@ func RunAutorenewal(existingCerts []ExistingCerts, cfg *config.Config, ctx conte
continue
}
- expiration, err := parseExpirationFromCert([]byte(keyObj.Certificate.Crt))
+ expiration, _, err := parseExpirationAndSansFromCert([]byte(keyObj.Certificate.Crt), keyObj.Hostname)
if err != nil {
log.Errorf("cert autorenewal: %s: %s", ds.XmlId, err.Error())
dsExpInfo.XmlId = ds.XmlId
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/keys.go b/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
index 79fcd69..b4d1502 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
@@ -21,6 +21,7 @@ package deliveryservice
import (
"bytes"
+ "context"
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
@@ -135,8 +136,8 @@ func AddSSLKeys(w http.ResponseWriter, r *http.Request) {
api.WriteResp(w, r, "Successfully added ssl keys for "+*req.DeliveryService)
}
-// GetSSLKeysByXMLIDV15 fetches the deliveryservice ssl keys by the specified xmlID. V15 includes expiration date.
-func GetSSLKeysByXMLIDV15(w http.ResponseWriter, r *http.Request) {
+// GetSSLKeysByXMLID fetches the deliveryservice ssl keys by the specified xmlID. V15 includes expiration date.
+func GetSSLKeysByXMLID(w http.ResponseWriter, r *http.Request) {
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)
@@ -149,67 +150,83 @@ func GetSSLKeysByXMLIDV15(w http.ResponseWriter, r *http.Request) {
}
xmlID := inf.Params["xmlid"]
alerts := tc.Alerts{}
- version := inf.Params["version"]
- decode := inf.Params["decode"]
if userErr, sysErr, errCode := tenant.Check(inf.User, xmlID, inf.Tx.Tx); userErr != nil || sysErr != nil {
userErr = api.LogErr(r, errCode, userErr, sysErr)
alerts.AddNewAlert(tc.ErrorLevel, userErr.Error())
api.WriteAlerts(w, r, errCode, alerts)
return
}
- keyObj, ok, err := inf.Vault.GetDeliveryServiceSSLKeys(xmlID, version, inf.Tx.Tx, r.Context())
+
+ keyObjV4, err := getSslKeys(inf, r.Context())
if err != nil {
- userErr := api.LogErr(r, http.StatusInternalServerError, nil, errors.New("getting ssl keys: "+err.Error()))
+ userErr := api.LogErr(r, http.StatusInternalServerError, nil, err)
alerts.AddNewAlert(tc.ErrorLevel, userErr.Error())
api.WriteAlerts(w, r, http.StatusInternalServerError, alerts)
return
}
- if !ok {
- keyObj = tc.DeliveryServiceSSLKeysV15{}
+
+ var keyObj interface{}
+ if inf.Version.Major < 4 || (inf.Version.Major == 4 && inf.Version.Minor < 1) {
+ keyObj = keyObjV4.DeliveryServiceSSLKeysV15
} else {
+ keyObj = keyObjV4
+ }
+
+ if len(alerts.Alerts) == 0 {
+ api.WriteResp(w, r, keyObj)
+ } else {
+ api.WriteAlertsObj(w, r, http.StatusOK, alerts, keyObj)
+ }
+}
+
+func getSslKeys(inf *api.APIInfo, ctx context.Context) (tc.DeliveryServiceSSLKeysV4, error) {
+ xmlID := inf.Params["xmlid"]
+ version := inf.Params["version"]
+ decode := inf.Params["decode"]
+
+ keyObjFromTv, ok, err := inf.Vault.GetDeliveryServiceSSLKeys(xmlID, version, inf.Tx.Tx, ctx)
+ if err != nil {
+ return tc.DeliveryServiceSSLKeysV4{}, errors.New("getting ssl keys: " + err.Error())
+ }
+ keyObj := tc.DeliveryServiceSSLKeysV4{}
+ if ok {
+ keyObj.DeliveryServiceSSLKeysV15 = keyObjFromTv
parsedCert := keyObj.Certificate
err = Base64DecodeCertificate(&parsedCert)
if err != nil {
- userErr := api.LogErr(r, http.StatusInternalServerError, nil, errors.New("getting SSL keys for XMLID '"+xmlID+"': "+err.Error()))
- alerts.AddNewAlert(tc.ErrorLevel, userErr.Error())
- api.WriteAlerts(w, r, http.StatusInternalServerError, alerts)
- return
+ return tc.DeliveryServiceSSLKeysV4{}, errors.New("getting SSL keys for XMLID '" + xmlID + "': " + err.Error())
}
if decode != "" && decode != "0" { // the Perl version checked the decode string as: if ( $decode )
keyObj.Certificate = parsedCert
}
if keyObj.Certificate.Crt != "" && keyObj.Expiration.IsZero() {
- exp, err := parseExpirationFromCert([]byte(parsedCert.Crt))
+ exp, sans, err := parseExpirationAndSansFromCert([]byte(parsedCert.Crt), keyObj.Hostname)
if err != nil {
- userErr := api.LogErr(r, http.StatusInternalServerError, nil, errors.New(xmlID+": "+err.Error()))
- alerts.AddNewAlert(tc.ErrorLevel, userErr.Error())
- api.WriteAlerts(w, r, http.StatusInternalServerError, alerts)
- return
+ return tc.DeliveryServiceSSLKeysV4{}, errors.New(xmlID + ": " + err.Error())
}
keyObj.Expiration = exp
+ keyObj.Sans = sans
}
}
- if len(alerts.Alerts) == 0 {
- api.WriteResp(w, r, keyObj)
- } else {
- api.WriteAlertsObj(w, r, http.StatusOK, alerts, keyObj)
- }
+ return keyObj, nil
}
-func parseExpirationFromCert(cert []byte) (time.Time, error) {
+func parseExpirationAndSansFromCert(cert []byte, commonName string) (time.Time, []string, error) {
block, _ := pem.Decode(cert)
if block == nil {
- return time.Time{}, errors.New("Error decoding cert to parse expiration")
+ return time.Time{}, []string{}, errors.New("Error decoding cert to parse expiration")
}
x509cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
- return time.Time{}, errors.New("Error parsing cert to get expiration - " + err.Error())
+ return time.Time{}, []string{}, errors.New("Error parsing cert to get expiration - " + err.Error())
}
- return x509cert.NotAfter, nil
+ dnsNames := util.RemoveStrFromArray(x509cert.DNSNames, commonName)
+
+ return x509cert.NotAfter, dnsNames, nil
}
func Base64DecodeCertificate(cert *tc.DeliveryServiceSSLKeysCertificate) error {
diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go
index b8a3fc6..8c3ccf0 100644
--- a/traffic_ops/traffic_ops_golang/routing/routes.go
+++ b/traffic_ops/traffic_ops_golang/routing/routes.go
@@ -130,6 +130,9 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
* 4.x API
*/
+ // SSL Keys
+ {api.Version{Major: 4, Minor: 1}, http.MethodGet, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLID, auth.PrivLevelAdmin, nil, Authenticated, nil, 41357729074},
+
// CDN lock
{api.Version{Major: 4, Minor: 0}, http.MethodGet, `cdn_locks/?$`, cdn_lock.Read, auth.PrivLevelReadOnly, nil, Authenticated, nil, 4134390561},
{api.Version{Major: 4, Minor: 0}, http.MethodPost, `cdn_locks/?$`, cdn_lock.Create, auth.PrivLevelOperations, nil, Authenticated, nil, 4134390562},
@@ -484,7 +487,7 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
{api.Version{Major: 4, Minor: 0}, http.MethodDelete, `deliveryservices/{id}/?$`, api.DeleteHandler(&deliveryservice.TODeliveryService{}), auth.PrivLevelOperations, nil, Authenticated, nil, 4226420743},
{api.Version{Major: 4, Minor: 0}, http.MethodGet, `deliveryservices/{id}/servers/eligible/?$`, deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, nil, Authenticated, nil, 4747615843},
- {api.Version{Major: 4, Minor: 0}, http.MethodGet, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLIDV15, auth.PrivLevelAdmin, nil, Authenticated, nil, 41357729073},
+ {api.Version{Major: 4, Minor: 0}, http.MethodGet, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLID, auth.PrivLevelAdmin, nil, Authenticated, nil, 41357729073},
{api.Version{Major: 4, Minor: 0}, http.MethodPost, `deliveryservices/sslkeys/add$`, deliveryservice.AddSSLKeys, auth.PrivLevelAdmin, nil, Authenticated, nil, 48728785833},
{api.Version{Major: 4, Minor: 0}, http.MethodDelete, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.DeleteSSLKeys, auth.PrivLevelOperations, nil, Authenticated, nil, 49267343},
{api.Version{Major: 4, Minor: 0}, http.MethodPost, `deliveryservices/sslkeys/generate/?$`, deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, nil, Authenticated, nil, 4534390513},
@@ -872,7 +875,7 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
{api.Version{Major: 3, Minor: 0}, http.MethodDelete, `deliveryservices/{id}/?$`, api.DeleteHandler(&deliveryservice.TODeliveryService{}), auth.PrivLevelOperations, nil, Authenticated, nil, 2226420743},
{api.Version{Major: 3, Minor: 0}, http.MethodGet, `deliveryservices/{id}/servers/eligible/?$`, deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, nil, Authenticated, nil, 2747615843},
- {api.Version{Major: 3, Minor: 0}, http.MethodGet, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLIDV15, auth.PrivLevelAdmin, nil, Authenticated, nil, 21357729073},
+ {api.Version{Major: 3, Minor: 0}, http.MethodGet, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLID, auth.PrivLevelAdmin, nil, Authenticated, nil, 21357729073},
{api.Version{Major: 3, Minor: 0}, http.MethodPost, `deliveryservices/sslkeys/add$`, deliveryservice.AddSSLKeys, auth.PrivLevelAdmin, nil, Authenticated, nil, 28728785833},
{api.Version{Major: 3, Minor: 0}, http.MethodDelete, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.DeleteSSLKeys, auth.PrivLevelOperations, nil, Authenticated, nil, 29267343},
{api.Version{Major: 3, Minor: 0}, http.MethodPost, `deliveryservices/sslkeys/generate/?$`, deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, nil, Authenticated, nil, 2534390513},
@@ -1236,7 +1239,7 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
{api.Version{Major: 2, Minor: 0}, http.MethodDelete, `deliveryservices/{id}/?$`, api.DeleteHandler(&deliveryservice.TODeliveryService{}), auth.PrivLevelOperations, nil, Authenticated, nil, 222642074},
{api.Version{Major: 2, Minor: 0}, http.MethodGet, `deliveryservices/{id}/servers/eligible/?$`, deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, nil, Authenticated, nil, 274761584},
- {api.Version{Major: 2, Minor: 0}, http.MethodGet, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLIDV15, auth.PrivLevelAdmin, nil, Authenticated, nil, 2135772907},
+ {api.Version{Major: 2, Minor: 0}, http.MethodGet, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.GetSSLKeysByXMLID, auth.PrivLevelAdmin, nil, Authenticated, nil, 2135772907},
{api.Version{Major: 2, Minor: 0}, http.MethodPost, `deliveryservices/sslkeys/add$`, deliveryservice.AddSSLKeys, auth.PrivLevelAdmin, nil, Authenticated, nil, 2872878583},
{api.Version{Major: 2, Minor: 0}, http.MethodDelete, `deliveryservices/xmlId/{xmlid}/sslkeys$`, deliveryservice.DeleteSSLKeys, auth.PrivLevelOperations, nil, Authenticated, nil, 2926734},
{api.Version{Major: 2, Minor: 0}, http.MethodPost, `deliveryservices/sslkeys/generate/?$`, deliveryservice.GenerateSSLKeys, auth.PrivLevelOperations, nil, Authenticated, nil, 253439051},
diff --git a/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/FormDeliveryServiceSslKeysController.js b/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/FormDeliveryServiceSslKeysController.js
index 59596af..205b303 100644
--- a/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/FormDeliveryServiceSslKeysController.js
+++ b/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/FormDeliveryServiceSslKeysController.js
@@ -65,6 +65,7 @@ var FormDeliveryServiceSslKeysController = function(deliveryService, sslKeys, $s
$scope.navigateToPath = locationUtils.navigateToPath;
$scope.formattedExpiration = $scope.sslKeys.expiration !== undefined ? $filter('date')($scope.sslKeys.expiration, 'MM/dd/yyyy') : undefined;
+ $scope.sans = $scope.sslKeys.sans !== undefined ? sslKeys.sans.join(', ') : ""
$scope.generateKeys = function() {
locationUtils.navigateToPath('/delivery-services/' + deliveryService.id + '/ssl-keys/generate');
diff --git a/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/form.deliveryServiceSslKeys.tpl.html b/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/form.deliveryServiceSslKeys.tpl.html
index 6f0bf3a..4894918 100644
--- a/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/form.deliveryServiceSslKeys.tpl.html
+++ b/traffic_portal/app/src/common/modules/form/deliveryServiceSslKeys/form.deliveryServiceSslKeys.tpl.html
@@ -61,6 +61,12 @@ under the License.
<output name="expiration" class="form-control">{{formattedExpiration}}</output>
</div>
</div>
+ <div class="form-group">
+ <label for="sans" class="control-label col-md-2 col-sm-2 col-xs-12">SANs</label>
+ <div class="col-md-10 col-sm-10 col-xs-12">
+ <output name="sans" class="form-control">{{sans}}</output>
+ </div>
+ </div>
<div class="form-group" ng-class="{'has-error': hasError(dsSslKeyForm.authType), 'has-feedback': hasError(dsSslKeyForm.authType)}">
<label for="authType" class="control-label col-md-2 col-sm-2 col-xs-12">Certificate Source (Self Signed, CA, etc) *</label>
<div class="col-md-10 col-sm-10 col-xs-12">
diff --git a/traffic_portal/app/src/scripts/config.js b/traffic_portal/app/src/scripts/config.js
index 52e5f0c..3973a15 100644
--- a/traffic_portal/app/src/scripts/config.js
+++ b/traffic_portal/app/src/scripts/config.js
@@ -23,4 +23,4 @@
angular.module('config', [])
-.constant('ENV', { api: { root:'/api/4.0/', stable: "/api/3.1/" } });
+.constant('ENV', { api: { root:'/api/4.1/', stable: "/api/3.1/" } });