From 5700a661554f91e391f9fb28377ecb5dc61a28f0 Mon Sep 17 00:00:00 2001 From: becitsthere Date: Fri, 3 Feb 2023 14:47:05 -0800 Subject: [PATCH] NVSHAS-7597: Update user token's base64 encoding --- controller/rest/auth.go | 4 +-- share/auth/auth.go | 4 +-- share/utils/utils.go | 56 ++++++++++++++++++++++++++++++++++----- share/utils/utils_test.go | 11 +++++++- 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/controller/rest/auth.go b/controller/rest/auth.go index 30fd6210d..3555e7d31 100644 --- a/controller/rest/auth.go +++ b/controller/rest/auth.go @@ -1167,7 +1167,7 @@ func jwtValidateToken(encryptedToken, secret string, rsaPublicKey *rsa.PublicKey var publicKey *rsa.PublicKey if secret == "" { - tokenString = utils.DecryptPasswordRaw(encryptedToken) + tokenString = utils.DecryptUserToken(encryptedToken) } else { tokenString = utils.DecryptSensitive(encryptedToken, []byte(secret)) } @@ -1275,7 +1275,7 @@ func jwtGenerateToken(user *share.CLUSUser, roles access.DomainRole, remote, mai c.StandardClaims.IssuedAt = now.Add(_halfHourBefore).Unix() // so that token won't be invalidated among controllers because of system time diff & iat token := jwt.NewWithClaims(jwt.SigningMethodRS256, c) tokenString, _ := token.SignedString(jwtPrivateKey) - return id, utils.EncryptPasswordRaw(tokenString), &c + return id, utils.EncryptUserToken(tokenString), &c } func jwtGenFedJoinToken(masterCluster *api.RESTFedMasterClusterInfo, duration time.Duration) []byte { diff --git a/share/auth/auth.go b/share/auth/auth.go index b902e318e..874a21243 100644 --- a/share/auth/auth.go +++ b/share/auth/auth.go @@ -156,11 +156,11 @@ func (a *remoteAuth) OIDCDiscover(issuer string) (string, string, string, string func (a *remoteAuth) generateState() string { s := fmt.Sprintf("%d", time.Now().Unix()) - return utils.EncryptPasswordRaw(s) + return utils.EncryptURLSafe(s) } func (a *remoteAuth) verifyState(state string) error { - if tsStr := utils.DecryptPasswordRaw(state); tsStr == "" { + if tsStr := utils.DecryptURLSafe(state); tsStr == "" { return errors.New("Invalid state: wrong encryption") } else if ts, err := strconv.ParseInt(tsStr, 10, 64); err != nil { return errors.New("Invalid state: wrong format") diff --git a/share/utils/utils.go b/share/utils/utils.go index ed7c2fa30..a8d11dc82 100644 --- a/share/utils/utils.go +++ b/share/utils/utils.go @@ -865,7 +865,7 @@ func DecryptFromBase64(encryptionKey []byte, b64 string) (string, error) { } } -func EncryptToRawBase64(key, text []byte) (string, error) { +func EncryptToRawStdBase64(key, text []byte) (string, error) { if ciphertext, err := Encrypt(key, text); err == nil { return base64.RawStdEncoding.EncodeToString(ciphertext), nil } else { @@ -873,7 +873,7 @@ func EncryptToRawBase64(key, text []byte) (string, error) { } } -func DecryptFromRawBase64(key []byte, b64 string) (string, error) { +func DecryptFromRawStdBase64(key []byte, b64 string) (string, error) { text, err := base64.RawStdEncoding.DecodeString(b64) if err != nil { return "", err @@ -886,6 +886,27 @@ func DecryptFromRawBase64(key []byte, b64 string) (string, error) { } } +func EncryptToRawURLBase64(key, text []byte) (string, error) { + if ciphertext, err := Encrypt(key, text); err == nil { + return base64.RawURLEncoding.EncodeToString(ciphertext), nil + } else { + return "", err + } +} + +func DecryptFromRawURLBase64(key []byte, b64 string) (string, error) { + text, err := base64.RawURLEncoding.DecodeString(b64) + if err != nil { + return "", err + } + + if text, err = Decrypt(key, text); err == nil { + return string(text), nil + } else { + return "", err + } +} + func getPasswordSymKey() []byte { return passwordSymKey } @@ -936,21 +957,44 @@ func EncryptSensitive(data string, key []byte) string { return encrypted } -func DecryptPasswordRaw(encrypted string) string { +func DecryptUserToken(encrypted string) string { + if encrypted == "" { + return "" + } + + encrypted = strings.ReplaceAll(encrypted, "_", "/") + token, _ := DecryptFromRawStdBase64(getPasswordSymKey(), encrypted) + return token +} + +// User token cannot have / in it and cannot have - as the first char. +func EncryptUserToken(token string) string { + if token == "" { + return "" + } + + // Std base64 encoding has + and /, instead of - and _ (url encoding) + // token can be part of kv key, so we replace / with _ + encrypted, _ := EncryptToRawStdBase64(getPasswordSymKey(), []byte(token)) + encrypted = strings.ReplaceAll(encrypted, "/", "_") + return encrypted +} + +func DecryptURLSafe(encrypted string) string { if encrypted == "" { return "" } - password, _ := DecryptFromRawBase64(getPasswordSymKey(), encrypted) + password, _ := DecryptFromRawURLBase64(getPasswordSymKey(), encrypted) return password } -func EncryptPasswordRaw(password string) string { +func EncryptURLSafe(password string) string { if password == "" { return "" } - encrypted, _ := EncryptToRawBase64(getPasswordSymKey(), []byte(password)) + encrypted, _ := EncryptToRawURLBase64(getPasswordSymKey(), []byte(password)) return encrypted } diff --git a/share/utils/utils_test.go b/share/utils/utils_test.go index 08a8c8a4a..b2b7015fc 100644 --- a/share/utils/utils_test.go +++ b/share/utils/utils_test.go @@ -184,6 +184,15 @@ func TestPlatformEnv(t *testing.T) { } } +func TestBase64Encrypt(t *testing.T) { + token := "123456" + encrypt := EncryptUserToken(token) + decrypt := DecryptUserToken(encrypt) + if decrypt != token { + t.Errorf("Token encrypt error: token=%v decrypt=%v\n", token, decrypt) + } +} + func TestPasswordEncrypt(t *testing.T) { password := "123456" encrypt := EncryptPassword(password) @@ -242,7 +251,7 @@ func TestBytesDisplay(t *testing.T) { } num = 44356 - if str := DisplayBytes(num); str != "43 KB" { + if str := DisplayBytes(num); str != "43 KB" { t.Errorf("(%v) and (%v) is not equal\n", num, str) }