Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traffic Vault: Fix reencrypt utility to uniquely reencrypt ssl keys #7159

Merged
merged 2 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#7048](https://github.com/apache/trafficcontrol/issues/7048) *Traffic Stats* Add configuration value to set the client request timeout for calls to Traffic Ops.
- Updated Apache Tomcat from 9.0.43 to 9.0.67
- [#7125](https://github.com/apache/trafficcontrol/issues/7125) *Docs* Reflect implementation and deprecation notice for `letsencrypt/autorenew` endpoint.
- [#7158](https://github.com/apache/trafficcontrol/issues/7158) *Traffic Vault* Fix the `reencrypt` utility to uniquely reencrypt each version of the SSL Certificates.

## [7.0.0] - 2022-07-19
### Added
Expand Down
35 changes: 21 additions & 14 deletions traffic_ops/app/db/reencrypt/reencrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,49 +160,56 @@ func readKey(keyLocation string) ([]byte, error) {
return key, nil
}

type sslInfo struct {
xmlId string
version string
previousData []byte
newData []byte
}

func reEncryptSslKeys(tx *sql.Tx, previousKey []byte, newKey []byte) error {
rows, err := tx.Query("SELECT deliveryservice, data FROM sslkey")
rows, err := tx.Query("SELECT deliveryservice, version, data FROM sslkey")
if err != nil {
return fmt.Errorf("querying: %w", err)
}
defer rows.Close()

sslKeyMap := map[string][]byte{}
var sslKeyInfos []sslInfo

for rows.Next() {
xmlid := ""
var encryptedSslKeys []byte
if err = rows.Scan(&xmlid, &encryptedSslKeys); err != nil {
sslKeyInfo := sslInfo{}

if err = rows.Scan(&sslKeyInfo.xmlId, &sslKeyInfo.version, &sslKeyInfo.previousData); err != nil {
return fmt.Errorf("getting SSL Keys: %w", err)
}
jsonKeys, err := util.AESDecrypt(encryptedSslKeys, previousKey)
jsonKeys, err := util.AESDecrypt(sslKeyInfo.previousData, previousKey)
if err != nil {
return fmt.Errorf("reading SSL Keys: %w", err)
}

if !bytes.HasPrefix(jsonKeys, []byte("{")) {
return fmt.Errorf("decrypted SSL Key did not have prefix '{' for xmlid %s", xmlid)
return fmt.Errorf("decrypted SSL Key did not have prefix '{' for xmlid %s", sslKeyInfo.xmlId)
}

reencryptedKeys, err := util.AESEncrypt(jsonKeys, newKey)
sslKeyInfo.newData, err = util.AESEncrypt(jsonKeys, newKey)
if err != nil {
return fmt.Errorf("encrypting SSL Keys with new key: %w", err)
}

sslKeyMap[xmlid] = reencryptedKeys
sslKeyInfos = append(sslKeyInfos, sslKeyInfo)
}

for xmlid, reencryptedKeys := range sslKeyMap {
res, err := tx.Exec(`UPDATE sslkey SET data = $1 WHERE deliveryservice = $2`, reencryptedKeys, xmlid)
for _, sslKeyInfo := range sslKeyInfos {
res, err := tx.Exec(`UPDATE sslkey SET data = $1 WHERE deliveryservice = $2 AND version = $3`, sslKeyInfo.newData, sslKeyInfo.xmlId, sslKeyInfo.version)
if err != nil {
return fmt.Errorf("updating SSL Keys for xmlid %s: %w", xmlid, err)
return fmt.Errorf("updating SSL Keys for xmlid %s: %w", sslKeyInfo.xmlId, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("determining rows affected for reencrypting SSL Keys with xmlid %s: %w", xmlid, err)
return fmt.Errorf("determining rows affected for reencrypting SSL Keys with xmlid %s: %w", sslKeyInfo.xmlId, err)
}
if rowsAffected == 0 {
return fmt.Errorf("no rows updated for reencrypting SSL Keys for xmlid %s", xmlid)
return fmt.Errorf("no rows updated for reencrypting SSL Keys for xmlid %s", sslKeyInfo.xmlId)
}
}

Expand Down