Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
chore: organized code
  • Loading branch information
nimish-ks committed Feb 14, 2024
commit 87fd13224feafd3b9a14d70442723ff5310d904b
39 changes: 39 additions & 0 deletions phase/crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,45 @@ func DecryptAsymmetric(ciphertextString, privateKeyHex, publicKeyHex string) (st
return plaintext, nil
}

// decryptSecret decrypts a secret's key, value, and optional comment using asymmetric decryption.
func DecryptSecret(secret map[string]interface{}, privateKeyHex, publicKeyHex string) (decryptedKey string, decryptedValue string, decryptedComment string, err error) {
// Decrypt the key
key, ok := secret["key"].(string)
if !ok {
err = fmt.Errorf("key is not a string")
return
}
decryptedKey, err = DecryptAsymmetric(key, privateKeyHex, publicKeyHex)
if err != nil {
log.Printf("Failed to decrypt key: %v\n", err)
return
}

// Decrypt the value
value, ok := secret["value"].(string)
if !ok {
err = fmt.Errorf("value is not a string")
return
}
decryptedValue, err = DecryptAsymmetric(value, privateKeyHex, publicKeyHex)
if err != nil {
log.Printf("Failed to decrypt value: %v\n", err)
return
}

// Decrypt the comment if it exists
comment, ok := secret["comment"].(string)
if ok && comment != "" {
decryptedComment, err = DecryptAsymmetric(comment, privateKeyHex, publicKeyHex)
if err != nil {
log.Printf("Failed to decrypt comment: %v\n", err)
err = nil
}
}

return decryptedKey, decryptedValue, decryptedComment, nil
}

// Decrypt decrypts the provided ciphertext using the Phase encryption mechanism.
func DecryptWrappedKeyShare(Keyshare1 string, Keyshare0 string, AppToken string, Keyshare1UnwrapKey string, PssUserPublicKey string, Host string) (string, error) {
// Fetch the wrapped key share using the app token and host
Expand Down
56 changes: 56 additions & 0 deletions phase/misc/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package misc

import (
"regexp"
)

const (
Version = "1.0"
PhVersion = "v1"
PhaseCloudAPIHost = "https://console.phase.dev"
)

var (
VerifySSL = false
PhaseDebug = false
)

var (

// Compiled regex patterns
PssUserPattern = regexp.MustCompile(`^pss_user:v(\d+):([a-fA-F0-9]{64}):([a-fA-F0-9]{64}):([a-fA-F0-9]{64}):([a-fA-F0-9]{64})$`)
PssServicePattern = regexp.MustCompile(`^pss_service:v(\d+):([a-fA-F0-9]{64}):([a-fA-F0-9]{64}):([a-fA-F0-9]{64}):([a-fA-F0-9]{64})$`)
CrossEnvPattern = regexp.MustCompile(`\$\{(.+?)\.(.+?)\}`)
LocalRefPattern = regexp.MustCompile(`\$\{([^.]+?)\}`)
)


type Environment struct {
ID string `json:"id"`
Name string `json:"name"`
EnvType string `json:"env_type"`
}

type EnvironmentKey struct {
ID string `json:"id"`
Environment Environment `json:"environment"`
IdentityKey string `json:"identity_key"`
WrappedSeed string `json:"wrapped_seed"`
WrappedSalt string `json:"wrapped_salt"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
DeletedAt *string `json:"deleted_at"`
User *string `json:"user"`
}

type App struct {
ID string `json:"id"`
Name string `json:"name"`
Encryption string `json:"encryption"`
EnvironmentKeys []EnvironmentKey `json:"environment_keys"`
}

type AppKeyResponse struct {
WrappedKeyShare string `json:"wrapped_key_share"`
Apps []App `json:"apps"`
}
50 changes: 50 additions & 0 deletions phase/misc/misc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package misc

import (
"fmt"
"strings"
)

// phaseGetContext finds the matching application and environment, returning their IDs and the public key.
func PhaseGetContext(userData AppKeyResponse, appName, envName string) (string, string, string, error) {
for _, app := range userData.Apps {
if app.Name == appName {
for _, envKey := range app.EnvironmentKeys {
if envKey.Environment.Name == envName {
return app.ID, envKey.Environment.ID, envKey.IdentityKey, nil
}
}
}
}
return "", "", "", fmt.Errorf("matching context not found")
}

func FindEnvironmentKey(userData AppKeyResponse, envName, appName string) (*EnvironmentKey, error) {
for _, app := range userData.Apps {
if appName == "" || app.Name == appName {
for _, envKey := range app.EnvironmentKeys {
if envKey.Environment.Name == envName {
return &envKey, nil // Note the address-of operator (&) before envKey
}
}
}
}
return nil, fmt.Errorf("environment key not found")
}

// normalizeTag replaces underscores with spaces and converts the string to lower case.
func normalizeTag(tag string) string {
return strings.ToLower(strings.Replace(tag, "_", " ", -1))
}

// tagMatches checks if the user-provided tag partially matches any of the secret tags.
func TagMatches(secretTags []string, userTag string) bool {
normalizedUserTag := normalizeTag(userTag)
for _, tag := range secretTags {
normalizedSecretTag := normalizeTag(tag)
if strings.Contains(normalizedSecretTag, normalizedUserTag) {
return true
}
}
return false
}
16 changes: 4 additions & 12 deletions phase/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ import (
"os/user"
"runtime"
"strings"
)

var (
verifySSL = os.Getenv("PHASE_VERIFY_SSL") != "false"
phaseDebug = os.Getenv("PHASE_DEBUG") == "true"
"github.com/phasehq/golang-sdk/phase/misc"
)

func ConstructHTTPHeaders(appToken string) http.Header {
Expand All @@ -28,11 +25,10 @@ func ConstructHTTPHeaders(appToken string) http.Header {
return headers
}


func GetUserAgent() string {
details := []string{}

cliVersion := "phase-golang-sdk/v1.0.0"
cliVersion := "phase-golang-sdk/" + misc.Version
details = append(details, cliVersion)

osType := runtime.GOOS
Expand All @@ -52,10 +48,9 @@ func GetUserAgent() string {
return strings.Join(details, " ")
}


func createHTTPClient() *http.Client {
client := &http.Client{}
if !verifySSL {
if !misc.VerifySSL {
client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
Expand All @@ -81,7 +76,6 @@ func handleHTTPResponse(resp *http.Response) error {
return nil
}


func FetchPhaseUser(appToken, host string) (*http.Response, error) {
client := createHTTPClient()
url := fmt.Sprintf("%s/service/secrets/tokens/", host)
Expand Down Expand Up @@ -128,7 +122,6 @@ type AppKeyResponse struct {
} `json:"apps"`
}


func FetchAppKey(appToken, host string) (string, error) {
client := createHTTPClient()
url := fmt.Sprintf("%s/service/secrets/tokens/", host)
Expand Down Expand Up @@ -161,8 +154,7 @@ func FetchWrappedKeyShare(appToken, host string) (string, error) {
client := &http.Client{}

// Check if SSL verification should be skipped
verifySSL := os.Getenv("PHASE_VERIFY_SSL") != "false"
if !verifySSL {
if !misc.VerifySSL {
client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
Expand Down
Loading