Skip to content

Commit

Permalink
RolesAnywhere-5520: Fix cert selector string parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
13ajay committed Mar 18, 2024
1 parent e7b4399 commit 76f2065
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 22 deletions.
59 changes: 37 additions & 22 deletions cmd/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"io/ioutil"
"math/big"
"regexp"
"strings"

helper "github.com/aws/rolesanywhere-credential-helper/aws_signing_helper"
Expand Down Expand Up @@ -42,6 +43,8 @@ var (
X509_ISSUER_KEY,
X509_SERIAL_KEY,
}

CERT_SELECTOR_KEY_VALUE_REGEX = `^Key=(.+?),Value=(.+?)(?: Key=|$)`
)

type MapEntry struct {
Expand Down Expand Up @@ -84,34 +87,46 @@ func initCredentialsSubCommand(subCmd *cobra.Command) {

// Parses a cert selector string to a map
func getStringMap(s string) (map[string]string, error) {
entries := strings.Split(s, " ")
regex := regexp.MustCompile(CERT_SELECTOR_KEY_VALUE_REGEX)

m := make(map[string]string)
for _, e := range entries {
tokens := strings.SplitN(e, ",", 2)
keyTokens := strings.Split(tokens[0], "=")
if keyTokens[0] != "Key" {
return nil, errors.New("invalid cert selector map key")
}
key := strings.TrimSpace(strings.Join(keyTokens[1:], "="))
for {
match := regex.FindStringSubmatch(s)
if len(match) == 0 {
break
} else {
if len(match) < 3 {
return nil, errors.New("unable to parse cert selector string")
}

isValidKey := false
for _, validKey := range validCertSelectorKeys {
if validKey == key {
isValidKey = true
break
key := match[1]
isValidKey := false
for _, validKey := range validCertSelectorKeys {
if validKey == key {
isValidKey = true
break
}
}
}
if !isValidKey {
return nil, errors.New("cert selector contained invalid key")
}
if !isValidKey {
return nil, errors.New("cert selector contained invalid key")
}
value := match[2]

valueTokens := strings.Split(tokens[1], "=")
if valueTokens[0] != "Value" {
return nil, errors.New("invalid cert selector map value")
m[key] = value

// Remove the matching prefix from the input cert selector string
matchEnd := len(match[0])
if matchEnd != len(s) {
// Since the `Key=` part of the next key-value pair will have been matched, don't include it in the prefix to remove
matchEnd -= 4
}
s = s[matchEnd:]
}
value := strings.TrimSpace(strings.Join(valueTokens[1:], "="))
m[key] = value
}

// There is some part of the cert selector string that couldn't be parsed by the above loop
if len(s) != 0 {
return nil, errors.New("unable to parse cert selector string")
}

return m, nil
Expand Down
2 changes: 2 additions & 0 deletions cmd/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func TestValidSelectorParsing(t *testing.T) {
"file://../tst/selectors/valid-all-attributes-selector.json",
"file://../tst/selectors/valid-some-attributes-selector.json",
"Key=x509Subject,Value=CN=Subject Key=x509Issuer,Value=CN=Issuer Key=x509Serial,Value=15D19632234BF759A32802C0DA88F9E8AFC8702D",
"Key=x509Subject,Value=CN=CN With Spaces Key=x509Issuer,Value=CN=CN With Spaces,OU=OU With Spaces",
"Key=x509Issuer,Value=CN=Issuer",
}
for _, fixture := range fixtures {
Expand All @@ -34,6 +35,7 @@ func TestInvalidSelectorParsing(t *testing.T) {
"laksdjadf",
"Key=laksdjf,Valalsd",
"Key=aljsdf,Value=aljsdfadsf",
"asdf Key=x509Subject,Value=Test",
}
for _, fixture := range fixtures {
_, err := PopulateCertIdentifier(fixture, "MY")
Expand Down

0 comments on commit 76f2065

Please sign in to comment.