github.com/Venafi/vcert/v5@v5.10.2/pkg/policy/policyUtils.go (about)

     1  package policy
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"strconv"
    10  	"strings"
    11  
    12  	"gopkg.in/yaml.v2"
    13  )
    14  
    15  // TppKeyType represents the Private Key types supported by TPP
    16  var TppKeyType = []string{"RSA", "ECDSA", "ECC"}
    17  
    18  // TppRsaKeySize represents the Key sizes supported by TPP for RSA Private Keys
    19  var TppRsaKeySize = []int{512, 1024, 2048, 3072, 4096}
    20  
    21  // CloudRsaKeySize represents the Key sizes supported by VaaS for RSA Private Keys
    22  var CloudRsaKeySize = []int{1024, 2048, 3072, 4096}
    23  
    24  // TppEllipticCurves represents the curves supported by TPP for ECDSA Private Keys
    25  var TppEllipticCurves = []string{"P256", "P384", "P521"}
    26  
    27  // KeyAlgorithmsToPKIX represents the mapping of RSA and ECDSA/ECC Key Algorithms to the PKIX OIDs
    28  var KeyAlgorithmsToPKIX = map[string]map[string]string{
    29  	"RSA": {
    30  		"1024": "1.3.6.1.4.1.28783.10.1.1.1024",
    31  		"2048": "1.3.6.1.4.1.28783.10.1.1.2048",
    32  		"3072": "1.3.6.1.4.1.28783.10.1.1.3072",
    33  		"4096": "1.3.6.1.4.1.28783.10.1.1.4096",
    34  	},
    35  	"ECC": {
    36  		"P256": "1.3.6.1.4.1.28783.10.2.1.256",
    37  		"P384": "1.3.6.1.4.1.28783.10.2.1.384",
    38  		"P521": "1.3.6.1.4.1.28783.10.2.1.521",
    39  	},
    40  }
    41  
    42  func GetFileType(f string) string {
    43  	extension := filepath.Ext(f)
    44  
    45  	//As yaml extension could be yaml or yml then convert it to just .yaml
    46  	extension = strings.ToLower(extension)
    47  	if extension == ".yml" {
    48  		extension = YamlExtension
    49  	}
    50  
    51  	return extension
    52  }
    53  
    54  func GetParent(p string) string {
    55  	lastIndex := strings.LastIndex(p, "\\")
    56  	parentPath := p[:lastIndex]
    57  	return parentPath
    58  }
    59  
    60  func ValidateTppPolicySpecification(ps *PolicySpecification) error {
    61  
    62  	if ps.Policy != nil {
    63  		err := validatePolicySubject(ps)
    64  		if err != nil {
    65  			return err
    66  		}
    67  
    68  		err = validateKeyPair(ps)
    69  		if err != nil {
    70  			return err
    71  		}
    72  	}
    73  
    74  	err := validateDefaultSubject(ps)
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	err = validateDefaultKeyPairWithPolicySubject(ps)
    80  	if err != nil {
    81  		return err
    82  	}
    83  
    84  	err = validateDefaultKeyPair(ps)
    85  	if err != nil {
    86  		return err
    87  	}
    88  
    89  	if ps.Default != nil && ps.Default.AutoInstalled != nil && ps.Policy != nil && ps.Policy.AutoInstalled != nil {
    90  		if *(ps.Default.AutoInstalled) != *(ps.Policy.AutoInstalled) {
    91  			return fmt.Errorf("default autoInstalled attribute value doesn't match with policy's autoInstalled attribute value")
    92  		}
    93  	}
    94  
    95  	return nil
    96  }
    97  
    98  func validatePolicySubject(ps *PolicySpecification) error {
    99  
   100  	if ps.Policy.Subject == nil {
   101  		return nil
   102  	}
   103  	subject := ps.Policy.Subject
   104  
   105  	if len(subject.Orgs) > 1 {
   106  		return fmt.Errorf("attribute orgs has more than one value")
   107  	}
   108  	if len(subject.Localities) > 1 {
   109  		return fmt.Errorf("attribute localities has more than one value")
   110  	}
   111  	if len(subject.States) > 1 {
   112  		return fmt.Errorf("attribute states has more than one value")
   113  	}
   114  	if len(subject.Countries) > 1 {
   115  		return fmt.Errorf("attribute countries has more than one value")
   116  	}
   117  
   118  	if len(subject.Countries) > 0 {
   119  		if len(subject.Countries[0]) != 2 {
   120  			return fmt.Errorf("number of country's characters, doesn't match to two characters")
   121  		}
   122  	}
   123  
   124  	return nil
   125  }
   126  
   127  func validateKeyPair(ps *PolicySpecification) error {
   128  	if ps.Policy.KeyPair == nil {
   129  		return nil
   130  	}
   131  	keyPair := ps.Policy.KeyPair
   132  
   133  	//validate algorithm
   134  	if len(keyPair.KeyTypes) > 1 {
   135  		return fmt.Errorf("attribute keyTypes has more than one value")
   136  	}
   137  	if len(keyPair.KeyTypes) > 0 && !existStringInArray(keyPair.KeyTypes, TppKeyType) {
   138  		return fmt.Errorf("specified keyTypes doesn't match with the supported ones")
   139  	}
   140  
   141  	//validate key bit strength
   142  	if len(keyPair.RsaKeySizes) > 1 {
   143  		return fmt.Errorf("attribute rsaKeySizes has more than one value")
   144  	}
   145  	if len(keyPair.RsaKeySizes) > 0 && !existIntInArray(keyPair.RsaKeySizes, TppRsaKeySize) {
   146  		return fmt.Errorf("specified rsaKeySizes doesn't match with the supported ones")
   147  	}
   148  
   149  	//validate elliptic curve
   150  	if len(keyPair.EllipticCurves) > 1 {
   151  		return fmt.Errorf("attribute ellipticCurves has more than one value")
   152  	}
   153  	if len(keyPair.EllipticCurves) > 0 && !existStringInArray(keyPair.EllipticCurves, TppEllipticCurves) {
   154  		return fmt.Errorf("specified ellipticCurves doesn't match with the supported ones")
   155  	}
   156  
   157  	return nil
   158  }
   159  
   160  func existStringInArray(userValue []string, supportedValues []string) bool {
   161  	for _, uv := range userValue {
   162  		match := false
   163  		for _, sv := range supportedValues {
   164  			if uv == sv {
   165  				match = true
   166  			}
   167  		}
   168  		if !match {
   169  			return false
   170  		}
   171  	}
   172  	return true
   173  }
   174  
   175  func existIntInArray(userValue []int, supportedValues []int) bool {
   176  	for _, uv := range userValue {
   177  		match := false
   178  		for _, sv := range supportedValues {
   179  			if uv == sv {
   180  				match = true
   181  			}
   182  		}
   183  		if !match {
   184  			return false
   185  		}
   186  	}
   187  
   188  	return true
   189  }
   190  
   191  func validateDefaultSubject(ps *PolicySpecification) error {
   192  
   193  	if ps.Default != nil && ps.Default.Subject != nil {
   194  
   195  		defaultSubject := ps.Default.Subject
   196  
   197  		if ps.Policy != nil && ps.Policy.Subject != nil {
   198  
   199  			policySubject := ps.Policy.Subject
   200  
   201  			if policySubject.Orgs != nil && policySubject.Orgs[0] != "" && defaultSubject.Org != nil && *(defaultSubject.Org) != "" {
   202  				if policySubject.Orgs[0] != *(defaultSubject.Org) {
   203  					return fmt.Errorf("policy default org doesn't match with policy's orgs value")
   204  				}
   205  			}
   206  
   207  			if len(policySubject.OrgUnits) > 0 && len(defaultSubject.OrgUnits) > 0 {
   208  				if !existStringInArray(defaultSubject.OrgUnits, policySubject.OrgUnits) {
   209  					return fmt.Errorf("policy default orgUnits doesn't match with policy's orgUnits value")
   210  				}
   211  			}
   212  
   213  			if policySubject.Localities != nil && policySubject.Localities[0] != "" && defaultSubject.Locality != nil && *(defaultSubject.Locality) != "" {
   214  				if policySubject.Localities[0] != *(defaultSubject.Locality) {
   215  					return fmt.Errorf("policy default locality doesn't match with policy's localities value")
   216  				}
   217  			}
   218  			if policySubject.States != nil && policySubject.States[0] != "" && defaultSubject.State != nil && *(defaultSubject.State) != "" {
   219  				if policySubject.States[0] != *(defaultSubject.State) {
   220  					return fmt.Errorf("policy default state doesn't match with policy's states value")
   221  				}
   222  			}
   223  			if policySubject.Countries != nil && policySubject.Countries[0] != "" && defaultSubject.Country != nil && *(defaultSubject.Country) != "" {
   224  				if policySubject.Countries[0] != *(defaultSubject.Country) {
   225  					return fmt.Errorf("policy default country doesn't match with policy's countries value")
   226  				}
   227  			}
   228  			if defaultSubject.Country != nil && *(defaultSubject.Country) != "" {
   229  				if len(*(defaultSubject.Country)) != 2 {
   230  					return fmt.Errorf("number of default country's characters, doesn't match to two characters")
   231  				}
   232  			}
   233  		} else {
   234  			//there is nothing to validate
   235  			return nil
   236  		}
   237  	}
   238  
   239  	return nil
   240  }
   241  
   242  func validateDefaultKeyPairWithPolicySubject(ps *PolicySpecification) error {
   243  	if ps.Default == nil || ps.Default.KeyPair == nil || ps.Policy == nil || ps.Policy.KeyPair == nil {
   244  		return nil
   245  	}
   246  	defaultKeyPair := ps.Default.KeyPair
   247  	policyKeyPair := ps.Policy.KeyPair
   248  
   249  	if policyKeyPair.KeyTypes != nil && policyKeyPair.KeyTypes[0] != "" && defaultKeyPair.KeyType != nil && *(defaultKeyPair.KeyType) != "" {
   250  		if policyKeyPair.KeyTypes[0] != *(defaultKeyPair.KeyType) {
   251  			return fmt.Errorf("policy default keyType doesn't match with policy's keyType value")
   252  		}
   253  	}
   254  
   255  	if policyKeyPair.RsaKeySizes != nil && policyKeyPair.RsaKeySizes[0] != 0 && defaultKeyPair.RsaKeySize != nil && *(defaultKeyPair.RsaKeySize) != 0 {
   256  		if policyKeyPair.RsaKeySizes[0] != *(defaultKeyPair.RsaKeySize) {
   257  			return fmt.Errorf("policy default rsaKeySize doesn't match with policy's rsaKeySize value")
   258  		}
   259  	}
   260  
   261  	if policyKeyPair.EllipticCurves != nil && policyKeyPair.EllipticCurves[0] != "" && defaultKeyPair.EllipticCurve != nil && *(defaultKeyPair.EllipticCurve) != "" {
   262  		if policyKeyPair.EllipticCurves[0] != *(defaultKeyPair.EllipticCurve) {
   263  			return fmt.Errorf("policy default ellipticCurve doesn't match with policy's ellipticCurve value")
   264  		}
   265  	}
   266  
   267  	if policyKeyPair.ServiceGenerated != nil && defaultKeyPair.ServiceGenerated != nil {
   268  		if *(policyKeyPair.ServiceGenerated) != *(defaultKeyPair.ServiceGenerated) {
   269  			return fmt.Errorf("policy default serviceGenerated generated doesn't match with policy's serviceGenerated value")
   270  		}
   271  	}
   272  
   273  	return nil
   274  }
   275  
   276  func validateDefaultKeyPair(ps *PolicySpecification) error {
   277  
   278  	if ps.Default == nil {
   279  		return nil
   280  	}
   281  
   282  	if ps.Default.KeyPair == nil {
   283  		return nil
   284  	}
   285  
   286  	keyPair := ps.Default.KeyPair
   287  
   288  	if keyPair.KeyType != nil && *(keyPair.KeyType) != "" && !existStringInArray([]string{*(keyPair.KeyType)}, TppKeyType) {
   289  		return fmt.Errorf("specified default keyType doesn't match with the supported ones")
   290  	}
   291  
   292  	//validate key bit strength
   293  	if keyPair.RsaKeySize != nil && *(keyPair.RsaKeySize) > 0 && !existIntInArray([]int{*(keyPair.RsaKeySize)}, TppRsaKeySize) {
   294  		return fmt.Errorf("specified default rsaKeySize doesn't match with the supported ones")
   295  	}
   296  
   297  	//validate elliptic curve
   298  	if keyPair.EllipticCurve != nil && *(keyPair.EllipticCurve) != "" && !existStringInArray([]string{*(keyPair.EllipticCurve)}, TppEllipticCurves) {
   299  		return fmt.Errorf("specified default ellipticCurve doesn't match with the supported ones")
   300  	}
   301  
   302  	return nil
   303  }
   304  
   305  func BuildTppPolicy(ps *PolicySpecification) TppPolicy {
   306  	/*
   307  		"owners": string[],					(permissions only)	prefixed name/universal
   308  		"userAccess": string,					(permissions)	prefixed name/universal
   309  		}
   310  	*/
   311  	var tppPolicy TppPolicy
   312  
   313  	tppPolicy.Contact = ps.Users
   314  	tppPolicy.Approver = ps.Approvers
   315  
   316  	//policy attributes
   317  	if ps.Policy != nil {
   318  		tppPolicy.DomainSuffixWhitelist = ps.Policy.Domains
   319  	}
   320  
   321  	if ps.Policy != nil && ps.Policy.WildcardAllowed != nil {
   322  
   323  		if *(ps.Policy.WildcardAllowed) { //this is true so we revert it to false(0)
   324  			intValZero := 0
   325  			tppPolicy.ProhibitWildcard = &intValZero
   326  		} else {
   327  			intValOne := 1
   328  			tppPolicy.ProhibitWildcard = &intValOne
   329  		}
   330  
   331  	}
   332  
   333  	if ps.Policy != nil && ps.Policy.CertificateAuthority != nil {
   334  		tppPolicy.CertificateAuthority = ps.Policy.CertificateAuthority
   335  	}
   336  
   337  	managementType := TppManagementTypeEnrollment
   338  	if ps.Policy != nil && ps.Policy.AutoInstalled != nil {
   339  		if *(ps.Policy.AutoInstalled) {
   340  			managementType = TppManagementTypeProvisioning
   341  		}
   342  		tppPolicy.ManagementType = createLockedAttribute(managementType, true)
   343  	} else if ps.Default != nil && ps.Default.AutoInstalled != nil {
   344  		if *(ps.Default.AutoInstalled) {
   345  			managementType = TppManagementTypeProvisioning
   346  		}
   347  		tppPolicy.ManagementType = createLockedAttribute(managementType, false)
   348  	}
   349  
   350  	//policy subject attributes
   351  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.Orgs) > 0 && ps.Policy.Subject.Orgs[0] != "" {
   352  		tppPolicy.Organization = createLockedAttribute(ps.Policy.Subject.Orgs[0], true)
   353  	} else if ps.Default != nil && ps.Default.Subject != nil && *(ps.Default.Subject.Org) != "" {
   354  		tppPolicy.Organization = createLockedAttribute(*(ps.Default.Subject.Org), false)
   355  	}
   356  
   357  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.OrgUnits) > 0 && ps.Policy.Subject.OrgUnits[0] != "" {
   358  		tppPolicy.OrganizationalUnit = createLockedArrayAttribute(ps.Policy.Subject.OrgUnits, true)
   359  	} else if ps.Default != nil && ps.Default.Subject != nil && len(ps.Default.Subject.OrgUnits) > 0 && ps.Default.Subject.OrgUnits[0] != "" {
   360  		tppPolicy.OrganizationalUnit = createLockedArrayAttribute(ps.Default.Subject.OrgUnits, false)
   361  	}
   362  
   363  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.Localities) > 0 && ps.Policy.Subject.Localities[0] != "" {
   364  		tppPolicy.City = createLockedAttribute(ps.Policy.Subject.Localities[0], true)
   365  	} else if ps.Default != nil && ps.Default.Subject != nil && (ps.Default.Subject.Locality != nil) && (*(ps.Default.Subject.Locality) != "") {
   366  		tppPolicy.City = createLockedAttribute(*(ps.Default.Subject.Locality), false)
   367  	}
   368  
   369  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.States) > 0 && ps.Policy.Subject.States[0] != "" {
   370  		tppPolicy.State = createLockedAttribute(ps.Policy.Subject.States[0], true)
   371  	} else if ps.Default != nil && ps.Default.Subject != nil && (ps.Default.Subject.State != nil) && (*(ps.Default.Subject.State) != "") {
   372  		tppPolicy.State = createLockedAttribute(*(ps.Default.Subject.State), false)
   373  	}
   374  
   375  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.Countries) > 0 && ps.Policy.Subject.Countries[0] != "" {
   376  		tppPolicy.Country = createLockedAttribute(ps.Policy.Subject.Countries[0], true)
   377  	} else if ps.Default != nil && ps.Default.Subject != nil && (ps.Default.Subject.Country != nil) && (*(ps.Default.Subject.Country) != "") {
   378  		tppPolicy.Country = createLockedAttribute(*(ps.Default.Subject.Country), false)
   379  	}
   380  
   381  	if ps.Policy != nil && ps.Policy.KeyPair != nil && ps.Policy.KeyPair.PkixParameterSet != nil && len(ps.Policy.KeyPair.PkixParameterSet) > 0 {
   382  		tppPolicy.PkixParameterSet = createLockedArrayAttribute(ps.Policy.KeyPair.PkixParameterSet, true)
   383  	}
   384  	if ps.Default != nil && ps.Default.KeyPair != nil && (ps.Default.KeyPair.PkixParameterSetDefault != nil) && (*(ps.Default.KeyPair.PkixParameterSetDefault) != "") {
   385  		tppPolicy.PkixParameterSetDefault = createLockedAttribute(*(ps.Default.KeyPair.PkixParameterSetDefault), false)
   386  	}
   387  
   388  	if ps.Policy != nil && ps.Policy.KeyPair != nil && len(ps.Policy.KeyPair.KeyTypes) > 0 && ps.Policy.KeyPair.KeyTypes[0] != "" {
   389  		tppPolicy.KeyAlgorithm = createLockedAttribute(ps.Policy.KeyPair.KeyTypes[0], true)
   390  	} else if ps.Default != nil && ps.Default.KeyPair != nil && (ps.Default.KeyPair.KeyType != nil) && (*(ps.Default.KeyPair.KeyType) != "") {
   391  		tppPolicy.KeyAlgorithm = createLockedAttribute(*(ps.Default.KeyPair.KeyType), false)
   392  	}
   393  
   394  	if ps.Policy != nil && ps.Policy.KeyPair != nil && len(ps.Policy.KeyPair.RsaKeySizes) > 0 && ps.Policy.KeyPair.RsaKeySizes[0] != 0 {
   395  		rsaKey := ps.Policy.KeyPair.RsaKeySizes[0]
   396  		tppPolicy.KeyBitStrength = createLockedAttribute(strconv.Itoa(rsaKey), true)
   397  	} else if ps.Default != nil && ps.Default.KeyPair != nil && (ps.Default.KeyPair.RsaKeySize != nil) && *(ps.Default.KeyPair.RsaKeySize) != 0 {
   398  		tppPolicy.KeyBitStrength = createLockedAttribute(strconv.Itoa(*(ps.Default.KeyPair.RsaKeySize)), false)
   399  	}
   400  
   401  	if ps.Policy != nil && ps.Policy.KeyPair != nil && len(ps.Policy.KeyPair.EllipticCurves) > 0 && ps.Policy.KeyPair.EllipticCurves[0] != "" {
   402  		tppPolicy.EllipticCurve = createLockedAttribute(ps.Policy.KeyPair.EllipticCurves[0], true)
   403  	} else if ps.Default != nil && ps.Default.KeyPair != nil && (ps.Default.KeyPair.EllipticCurve != nil) && (*(ps.Default.KeyPair.EllipticCurve) != "") {
   404  		tppPolicy.EllipticCurve = createLockedAttribute(*(ps.Default.KeyPair.EllipticCurve), false)
   405  	}
   406  
   407  	if ps.Policy != nil && ps.Policy.KeyPair != nil && ps.Policy.KeyPair.ServiceGenerated != nil {
   408  		strVal := "1"
   409  		if *(ps.Policy.KeyPair.ServiceGenerated) {
   410  			strVal = "0"
   411  		}
   412  		tppPolicy.ManualCsr = createLockedAttribute(strVal, true)
   413  	} else if ps.Default != nil && ps.Default.KeyPair != nil && (ps.Default.KeyPair.ServiceGenerated != nil) {
   414  		strVal := "1"
   415  		if *(ps.Default.KeyPair.ServiceGenerated) {
   416  			strVal = "0"
   417  		}
   418  		tppPolicy.ManualCsr = createLockedAttribute(strVal, false)
   419  	}
   420  
   421  	if ps.Policy != nil && ps.Policy.KeyPair != nil && ps.Policy.KeyPair.ReuseAllowed != nil {
   422  
   423  		var intVal int
   424  		if *(ps.Policy.KeyPair.ReuseAllowed) {
   425  			intVal = 1
   426  		} else {
   427  			intVal = 0
   428  		}
   429  
   430  		tppPolicy.AllowPrivateKeyReuse = &intVal
   431  		tppPolicy.WantRenewal = &intVal
   432  	}
   433  
   434  	if ps.Policy != nil && ps.Policy.SubjectAltNames != nil {
   435  		prohibitedSANType := getProhibitedSanTypes(*(ps.Policy.SubjectAltNames))
   436  		if prohibitedSANType != nil {
   437  			tppPolicy.ProhibitedSANType = prohibitedSANType
   438  		}
   439  	}
   440  
   441  	return tppPolicy
   442  }
   443  
   444  func createLockedAttribute(value string, locked bool) *LockedAttribute {
   445  	lockedAtr := LockedAttribute{
   446  		Value:  value,
   447  		Locked: locked,
   448  	}
   449  	return &lockedAtr
   450  }
   451  
   452  func createLockedArrayAttribute(value []string, locked bool) *LockedArrayAttribute {
   453  	lockedAtr := LockedArrayAttribute{
   454  		Value:  value,
   455  		Locked: locked,
   456  	}
   457  	return &lockedAtr
   458  }
   459  
   460  func getProhibitedSanTypes(sa SubjectAltNames) []string {
   461  
   462  	var prohibitedSanTypes []string
   463  
   464  	if (sa.DnsAllowed != nil) && !*(sa.DnsAllowed) {
   465  		prohibitedSanTypes = append(prohibitedSanTypes, "DNS")
   466  	}
   467  	if (sa.IpAllowed != nil) && !*(sa.IpAllowed) {
   468  		prohibitedSanTypes = append(prohibitedSanTypes, "IP")
   469  	}
   470  
   471  	if (sa.EmailAllowed != nil) && !*(sa.EmailAllowed) {
   472  		prohibitedSanTypes = append(prohibitedSanTypes, "Email")
   473  	}
   474  
   475  	if (sa.UriAllowed != nil) && !*(sa.UriAllowed) {
   476  		prohibitedSanTypes = append(prohibitedSanTypes, "URI")
   477  	}
   478  
   479  	if (sa.UpnAllowed != nil) && !*(sa.UpnAllowed) {
   480  		prohibitedSanTypes = append(prohibitedSanTypes, "UPN")
   481  	}
   482  
   483  	if len(prohibitedSanTypes) == 0 {
   484  		return nil
   485  	}
   486  
   487  	return prohibitedSanTypes
   488  }
   489  
   490  func BuildPolicySpecificationForTPP(checkPolicyResp CheckPolicyResponse) (*PolicySpecification, error) {
   491  
   492  	if checkPolicyResp.Policy == nil {
   493  		return nil, fmt.Errorf("policy is nul")
   494  	}
   495  
   496  	policy := checkPolicyResp.Policy
   497  	var ps PolicySpecification
   498  
   499  	/*ps.Users = tppPolicy.Contact
   500  	ps.Approvers = tppPolicy.Approver*/
   501  
   502  	var p Policy
   503  
   504  	if policy.WhitelistedDomains != nil {
   505  		p.Domains = policy.WhitelistedDomains
   506  	}
   507  
   508  	if policy.CertificateAuthority.Value != "" {
   509  		p.CertificateAuthority = &policy.CertificateAuthority.Value
   510  	}
   511  
   512  	var subject Subject
   513  	shouldCreateSubject := false
   514  	var defaultSubject DefaultSubject
   515  	shouldCreateDefSubject := false
   516  
   517  	var keyPair KeyPair
   518  	shouldCreateKeyPair := false
   519  	var defaultKeyPair DefaultKeyPair
   520  	shouldCreateDefKeyPair := false
   521  
   522  	var def Default
   523  
   524  	p.WildcardAllowed = &policy.WildcardsAllowed
   525  
   526  	if policy.ManagementType.Value != "" {
   527  		boolVal := false
   528  		if policy.ManagementType.Value == TppManagementTypeProvisioning {
   529  			boolVal = true
   530  		}
   531  		if policy.ManagementType.Locked {
   532  			p.AutoInstalled = &boolVal
   533  		} else {
   534  			def.AutoInstalled = &boolVal
   535  		}
   536  	}
   537  
   538  	//resolve subject's attributes
   539  
   540  	//resolve org
   541  	if policy.Subject.Organization.Value != "" {
   542  		if policy.Subject.Organization.Locked {
   543  			shouldCreateSubject = true
   544  			subject.Orgs = []string{policy.Subject.Organization.Value}
   545  		} else {
   546  			shouldCreateDefSubject = true
   547  			defaultSubject.Org = &policy.Subject.Organization.Value
   548  		}
   549  	}
   550  
   551  	//resolve orgUnit
   552  
   553  	if len(policy.Subject.OrganizationalUnit.Value) > 0 {
   554  		if policy.Subject.OrganizationalUnit.Locked {
   555  			shouldCreateSubject = true
   556  			subject.OrgUnits = policy.Subject.OrganizationalUnit.Value
   557  		} else {
   558  			shouldCreateDefSubject = true
   559  			defaultSubject.OrgUnits = policy.Subject.OrganizationalUnit.Value
   560  		}
   561  	}
   562  
   563  	//resolve localities
   564  	if policy.Subject.City.Value != "" {
   565  		if policy.Subject.City.Locked {
   566  			shouldCreateSubject = true
   567  			subject.Localities = []string{policy.Subject.City.Value}
   568  		} else {
   569  			shouldCreateDefSubject = true
   570  			defaultSubject.Locality = &policy.Subject.City.Value
   571  		}
   572  	}
   573  
   574  	//resolve states
   575  
   576  	if policy.Subject.State.Value != "" {
   577  		if policy.Subject.State.Locked {
   578  			shouldCreateSubject = true
   579  			subject.States = []string{policy.Subject.State.Value}
   580  		} else {
   581  			shouldCreateDefSubject = true
   582  			defaultSubject.State = &policy.Subject.State.Value
   583  		}
   584  	}
   585  
   586  	//resolve countries
   587  	if policy.Subject.Country.Value != "" {
   588  		if policy.Subject.Country.Locked {
   589  			shouldCreateSubject = true
   590  			subject.Countries = []string{policy.Subject.Country.Value}
   591  		} else {
   592  			shouldCreateDefSubject = true
   593  			defaultSubject.Country = &policy.Subject.Country.Value
   594  		}
   595  	}
   596  
   597  	//resolve key pair's attributes
   598  
   599  	//resolve keyTypes
   600  	if policy.KeyPairResponse.KeyAlgorithm.Value != "" {
   601  		if policy.KeyPairResponse.KeyAlgorithm.Locked {
   602  			keyPair.KeyTypes = []string{policy.KeyPairResponse.KeyAlgorithm.Value}
   603  		} else {
   604  			shouldCreateDefKeyPair = true
   605  			defaultKeyPair.KeyType = &policy.KeyPairResponse.KeyAlgorithm.Value
   606  		}
   607  	}
   608  
   609  	if strings.ToUpper(policy.KeyPairResponse.KeyAlgorithm.Value) == "RSA" {
   610  		//resolve rsaKeySizes
   611  		if policy.KeyPairResponse.KeySize.Value > 0 {
   612  			if policy.KeyPairResponse.KeySize.Locked {
   613  				keyPair.RsaKeySizes = []int{policy.KeyPairResponse.KeySize.Value}
   614  			} else {
   615  				shouldCreateDefKeyPair = true
   616  				defaultKeyPair.RsaKeySize = &policy.KeyPairResponse.KeySize.Value
   617  			}
   618  		}
   619  	} else {
   620  		//resolve ellipticCurve
   621  		if policy.KeyPairResponse.EllipticCurve.Value != "" {
   622  			if policy.KeyPairResponse.EllipticCurve.Locked {
   623  				keyPair.EllipticCurves = []string{policy.KeyPairResponse.EllipticCurve.Value}
   624  			} else {
   625  				shouldCreateDefKeyPair = true
   626  				defaultKeyPair.EllipticCurve = &policy.KeyPairResponse.EllipticCurve.Value
   627  			}
   628  		}
   629  	}
   630  
   631  	//resolve generationType
   632  	value := policy.CsrGeneration.Value
   633  	if value != "" {
   634  		booleanValue := true
   635  
   636  		//this mean that is a generated csr so ServiceGenerated is false
   637  		if value == UserProvided {
   638  			booleanValue = false
   639  		}
   640  
   641  		if policy.CsrGeneration.Locked {
   642  			keyPair.ServiceGenerated = &booleanValue
   643  		} else {
   644  			shouldCreateDefKeyPair = true
   645  			defaultKeyPair.ServiceGenerated = &booleanValue
   646  		}
   647  	}
   648  
   649  	keyPair.ReuseAllowed = &policy.PrivateKeyReuseAllowed
   650  	shouldCreateKeyPair = true
   651  
   652  	//assign policy's subject and key pair values
   653  	if shouldCreateSubject {
   654  		p.Subject = &subject
   655  	}
   656  	if shouldCreateKeyPair {
   657  		p.KeyPair = &keyPair
   658  	}
   659  	subjectAltNames := resolveSubjectAltNames(*policy)
   660  
   661  	if subjectAltNames != nil {
   662  		p.SubjectAltNames = subjectAltNames
   663  	}
   664  
   665  	//set policy and defaults to policy specification.
   666  	ps.Policy = &p
   667  
   668  	if shouldCreateDefSubject {
   669  		def.Subject = &defaultSubject
   670  	}
   671  	if shouldCreateDefKeyPair {
   672  		def.KeyPair = &defaultKeyPair
   673  	}
   674  
   675  	if shouldCreateDefSubject || shouldCreateDefKeyPair || def.AutoInstalled != nil {
   676  		ps.Default = &def
   677  	}
   678  
   679  	return &ps, nil
   680  
   681  }
   682  
   683  func resolveSubjectAltNames(policy PolicyResponse) *SubjectAltNames {
   684  
   685  	trueVal := true
   686  	falseVal := false
   687  	var subjectAltName SubjectAltNames
   688  
   689  	if policy.SubjAltNameDnsAllowed {
   690  		subjectAltName.DnsAllowed = &trueVal
   691  	} else {
   692  		subjectAltName.DnsAllowed = &falseVal
   693  	}
   694  
   695  	if policy.SubjAltNameIpAllowed {
   696  		subjectAltName.IpAllowed = &trueVal
   697  	} else {
   698  		subjectAltName.IpAllowed = &falseVal
   699  	}
   700  
   701  	if policy.SubjAltNameEmailAllowed {
   702  		subjectAltName.EmailAllowed = &trueVal
   703  	} else {
   704  		subjectAltName.EmailAllowed = &falseVal
   705  	}
   706  
   707  	if policy.SubjAltNameUriAllowed {
   708  		subjectAltName.UriAllowed = &trueVal
   709  	} else {
   710  		subjectAltName.UriAllowed = &falseVal
   711  	}
   712  
   713  	if policy.SubjAltNameUpnAllowed {
   714  		subjectAltName.UpnAllowed = &trueVal
   715  	} else {
   716  		subjectAltName.UpnAllowed = &falseVal
   717  	}
   718  
   719  	return &subjectAltName
   720  }
   721  
   722  func existValueInArray(array []string, value string) bool {
   723  	for _, currentValue := range array {
   724  
   725  		if currentValue == value {
   726  			return true
   727  		}
   728  
   729  	}
   730  
   731  	return false
   732  }
   733  
   734  //////////////////////---------------------Venafi Cloud policy management code-------------//////////////////////////////////////
   735  
   736  func validateDefaultStringCloudValues(array []string, value string) bool {
   737  	if len(array) == 1 {
   738  		if array[0] == AllowAll { // this means that we are allowing everything
   739  			return true
   740  		}
   741  	}
   742  	return existValueInArray(array, value)
   743  }
   744  
   745  func validateDefaultSubjectOrgsCloudValues(defaultValues []string, policyValues []string) bool {
   746  	if len(policyValues) == 1 {
   747  		if policyValues[0] == AllowAll { // this means that we are allowing everything
   748  			return true
   749  		}
   750  	}
   751  	return existStringInArray(defaultValues, policyValues)
   752  }
   753  
   754  func ValidateCloudPolicySpecification(ps *PolicySpecification) error {
   755  
   756  	//validate key type
   757  	if ps.Policy != nil {
   758  		if ps.Policy.KeyPair != nil {
   759  
   760  			//validate key KeyTypes:keyLengths
   761  			if len(ps.Policy.KeyPair.RsaKeySizes) > 0 {
   762  				unSupported := getInvalidCloudRsaKeySizeValue(ps.Policy.KeyPair.RsaKeySizes)
   763  				if unSupported != nil {
   764  					return fmt.Errorf("specified attribute key length value: %s is not supported on VaaS", strconv.Itoa(*(unSupported)))
   765  				}
   766  			}
   767  		}
   768  
   769  		//validate subjectCNRegexes & sanRegexes
   770  		if ps.Policy.SubjectAltNames != nil {
   771  			subjectAltNames := getSubjectAltNames(*(ps.Policy.SubjectAltNames))
   772  			if len(subjectAltNames) > 0 {
   773  				for k, v := range subjectAltNames {
   774  					if k == "upnAllowed" && v {
   775  						return fmt.Errorf("specified subjectAltNames: %s value is true, this value is not allowed ", k)
   776  					}
   777  					if k == "uriAllowed" && v {
   778  						if len(ps.Policy.SubjectAltNames.UriProtocols) == 0 {
   779  							return fmt.Errorf("uriAllowed attribute is true, but uriProtocols is not specified or empty")
   780  						}
   781  					}
   782  				}
   783  			}
   784  		}
   785  
   786  		//if defaults are define validate that them matches with policy values
   787  		if ps.Policy.Subject != nil {
   788  			if ps.Default != nil && ps.Default.Subject != nil && ps.Default.Subject.Org != nil && len(ps.Policy.Subject.Orgs) > 0 {
   789  				exist := validateDefaultStringCloudValues(ps.Policy.Subject.Orgs, *(ps.Default.Subject.Org))
   790  				if !exist {
   791  					return fmt.Errorf("specified default org value: %s  doesn't match with specified policy org", *(ps.Default.Subject.Org))
   792  				}
   793  			}
   794  
   795  			if ps.Default != nil && ps.Default.Subject != nil && len(ps.Default.Subject.OrgUnits) > 0 && len(ps.Policy.Subject.OrgUnits) > 0 {
   796  				exist := validateDefaultSubjectOrgsCloudValues(ps.Default.Subject.OrgUnits, ps.Policy.Subject.OrgUnits)
   797  				if !exist {
   798  					return fmt.Errorf("specified default org unit value: %s  doesn't match with specified policy org unit", *(ps.Default.Subject.Org))
   799  				}
   800  			}
   801  
   802  			if ps.Default != nil && ps.Default.Subject != nil && ps.Default.Subject.Locality != nil && len(ps.Policy.Subject.Localities) > 0 {
   803  				exist := validateDefaultStringCloudValues(ps.Policy.Subject.Localities, *(ps.Default.Subject.Locality))
   804  				if !exist {
   805  					return fmt.Errorf("specified default locality value: %s  doesn't match with specified policy locality", *(ps.Default.Subject.Locality))
   806  				}
   807  			}
   808  
   809  			if ps.Default != nil && ps.Default.Subject != nil && ps.Default.Subject.State != nil && len(ps.Policy.Subject.States) > 0 {
   810  				exist := validateDefaultStringCloudValues(ps.Policy.Subject.States, *(ps.Default.Subject.State))
   811  				if !exist {
   812  					return fmt.Errorf("specified default state value: %s  doesn't match with specified policy state", *(ps.Default.Subject.State))
   813  				}
   814  			}
   815  
   816  			if ps.Default != nil && ps.Default.Subject != nil && ps.Default.Subject.Country != nil && len(ps.Policy.Subject.Countries) > 0 {
   817  				exist := validateDefaultStringCloudValues(ps.Policy.Subject.Countries, *(ps.Default.Subject.Country))
   818  				if !exist {
   819  					return fmt.Errorf("specified default country value: %s  doesn't match with specified policy country", *(ps.Default.Subject.Country))
   820  				}
   821  			}
   822  		}
   823  
   824  		if ps.Policy.KeyPair != nil {
   825  			if ps.Default != nil && ps.Default.KeyPair != nil && ps.Default.KeyPair.KeyType != nil && len(ps.Policy.KeyPair.KeyTypes) > 0 {
   826  				exist := existValueInArray(ps.Policy.KeyPair.KeyTypes, *(ps.Default.KeyPair.KeyType))
   827  				if !exist {
   828  					return fmt.Errorf("specified default key type value: %s  doesn't match with specified policy key type", *(ps.Default.KeyPair.KeyType))
   829  				}
   830  			}
   831  
   832  			if ps.Default != nil && ps.Default.KeyPair != nil && ps.Default.KeyPair.RsaKeySize != nil && len(ps.Policy.KeyPair.RsaKeySizes) > 0 {
   833  				exist := existIntInArray([]int{*(ps.Default.KeyPair.RsaKeySize)}, ps.Policy.KeyPair.RsaKeySizes)
   834  				if !exist {
   835  					return fmt.Errorf("specified default rsa key size value: %s  doesn't match with specified policy rsa key size", strconv.Itoa(*(ps.Default.KeyPair.RsaKeySize)))
   836  				}
   837  			}
   838  		}
   839  	}
   840  
   841  	//now in case that policy is empty but defaults key types and rsa sizes not, we need to validate them
   842  	if ps.Default != nil && ps.Default.KeyPair != nil {
   843  
   844  		if ps.Default.KeyPair.KeyType != nil && *(ps.Default.KeyPair.KeyType) != "" {
   845  			if *(ps.Default.KeyPair.KeyType) != "RSA" && *(ps.Default.KeyPair.KeyType) != "EC" {
   846  				return fmt.Errorf("specified default attribute keyType value is not supported on VaaS")
   847  			}
   848  		}
   849  
   850  		//validate key KeyTypes:keyLengths
   851  		if ps.Default.KeyPair.RsaKeySize != nil && *(ps.Default.KeyPair.RsaKeySize) != 0 {
   852  			unSupported := getInvalidCloudRsaKeySizeValue([]int{*(ps.Default.KeyPair.RsaKeySize)})
   853  			if unSupported != nil {
   854  				return fmt.Errorf("specified attribute key length value: %s is not supported on VaaS", strconv.Itoa(*(unSupported)))
   855  			}
   856  		}
   857  	}
   858  
   859  	return nil
   860  }
   861  
   862  func getInvalidCloudRsaKeySizeValue(specifiedRSAKeys []int) *int {
   863  
   864  	for _, currentUserVal := range specifiedRSAKeys {
   865  		valid := false
   866  		for _, rsaKey := range CloudRsaKeySize {
   867  			if currentUserVal == rsaKey {
   868  				valid = true
   869  				break
   870  			}
   871  		}
   872  		if !valid {
   873  			return &currentUserVal
   874  		}
   875  	}
   876  	return nil
   877  }
   878  
   879  func getSubjectAltNames(names SubjectAltNames) map[string]bool {
   880  
   881  	subjectAltNames := make(map[string]bool)
   882  
   883  	if names.DnsAllowed != nil {
   884  		subjectAltNames["dnsAllowed"] = *(names.DnsAllowed)
   885  	}
   886  
   887  	if names.IpAllowed != nil {
   888  		subjectAltNames["ipAllowed"] = *(names.IpAllowed)
   889  	}
   890  
   891  	if names.EmailAllowed != nil {
   892  		subjectAltNames["emailAllowed"] = *(names.EmailAllowed)
   893  	}
   894  
   895  	if names.UriAllowed != nil {
   896  		subjectAltNames["uriAllowed"] = *(names.UriAllowed)
   897  	}
   898  
   899  	if names.UpnAllowed != nil {
   900  		subjectAltNames["upnAllowed"] = *(names.UpnAllowed)
   901  	}
   902  
   903  	return subjectAltNames
   904  
   905  }
   906  
   907  func BuildCloudCitRequest(ps *PolicySpecification, ca *CADetails) (*CloudPolicyRequest, error) {
   908  	var cloudPolicyRequest CloudPolicyRequest
   909  	var certAuth CertificateAuthorityInfo
   910  	var err error
   911  	var period int
   912  	if ps.Policy != nil && ps.Policy.CertificateAuthority != nil && *(ps.Policy.CertificateAuthority) != "" {
   913  		certAuth, err = GetCertAuthorityInfo(*(ps.Policy.CertificateAuthority))
   914  		if err != nil {
   915  			return nil, err
   916  		}
   917  	} else {
   918  		certAuth, err = GetCertAuthorityInfo(DefaultCA)
   919  		if err != nil {
   920  			return nil, err
   921  		}
   922  	}
   923  
   924  	cloudPolicyRequest.CertificateAuthority = certAuth.CAType
   925  	cloudPolicyRequest.CertificateAuthorityProductOptionId = *(ca.CertificateAuthorityProductOptionId)
   926  
   927  	if ps.Policy != nil && ps.Policy.MaxValidDays != nil {
   928  		period = *(ps.Policy.MaxValidDays)
   929  		if period == 0 {
   930  			period = 365
   931  		}
   932  	} else {
   933  		period = 365
   934  	}
   935  
   936  	product := Product{
   937  		CertificateAuthority: certAuth.CAType,
   938  		ProductName:          certAuth.VendorProductName,
   939  		ValidityPeriod:       fmt.Sprint("P", strconv.Itoa(period), "D"),
   940  	}
   941  
   942  	if certAuth.CAType == CloudDigicertCA {
   943  		alg := "SHA256"
   944  		autoRen := false
   945  		product.HashAlgorithm = &alg
   946  		product.AutoRenew = &autoRen
   947  		product.OrganizationId = ca.CertificateAuthorityOrganizationId
   948  	}
   949  
   950  	if certAuth.CAType == CloudEntrustCA {
   951  		td := TrackingData{
   952  			CertificateAuthority: CloudEntrustCA,
   953  			RequesterName:        CloudRequesterName,
   954  			RequesterEmail:       CloudRequesterEmail,
   955  			RequesterPhone:       CloudRequesterPhone,
   956  		}
   957  		cloudPolicyRequest.TrackingData = &td
   958  	}
   959  
   960  	cloudPolicyRequest.Product = product
   961  
   962  	if ps.Policy != nil && len(ps.Policy.Domains) > 0 {
   963  		regexValues := ConvertToRegex(ps.Policy.Domains, IsWildcardAllowed(*(ps)))
   964  		cloudPolicyRequest.SubjectCNRegexes = regexValues
   965  		if ps.Policy.SubjectAltNames != nil && ps.Policy.SubjectAltNames.DnsAllowed != nil {
   966  			if *(ps.Policy.SubjectAltNames.DnsAllowed) {
   967  				cloudPolicyRequest.SanRegexes = regexValues //in cloud subject CN and SAN have the same values and we use domains as those values
   968  			} else {
   969  				cloudPolicyRequest.SanRegexes = nil
   970  			}
   971  		} else {
   972  			cloudPolicyRequest.SanRegexes = regexValues //in cloud subject CN and SAN have the same values and we use domains as those values
   973  		}
   974  
   975  		if ps.Policy.SubjectAltNames != nil && ps.Policy.SubjectAltNames.EmailAllowed != nil {
   976  			if *(ps.Policy.SubjectAltNames.EmailAllowed) {
   977  				rfc882Regex := ConvertToRfc822Regex(ps.Policy.Domains)
   978  				cloudPolicyRequest.SanRfc822NameRegexes = rfc882Regex
   979  			} else {
   980  				cloudPolicyRequest.SanRfc822NameRegexes = nil
   981  			}
   982  		}
   983  
   984  		if ps.Policy != nil && ps.Policy.SubjectAltNames != nil && len(ps.Policy.SubjectAltNames.UriProtocols) > 0 {
   985  			uriRegex := convertToUriRegex(ps.Policy.SubjectAltNames.UriProtocols, ps.Policy.Domains)
   986  			cloudPolicyRequest.SanUniformResourceIdentifierRegexes = uriRegex
   987  		}
   988  
   989  	} else {
   990  		cloudPolicyRequest.SubjectCNRegexes = []string{".*"}
   991  		cloudPolicyRequest.SanRegexes = []string{".*"}
   992  
   993  		if ps.Policy != nil {
   994  			if ps.Policy.SubjectAltNames != nil && ps.Policy.SubjectAltNames.EmailAllowed != nil {
   995  				if *(ps.Policy.SubjectAltNames.EmailAllowed) {
   996  					cloudPolicyRequest.SanRfc822NameRegexes = []string{".*@.*"}
   997  				}
   998  			}
   999  
  1000  			if ps.Policy.SubjectAltNames != nil && ps.Policy.SubjectAltNames.IpAllowed != nil {
  1001  				if *(ps.Policy.SubjectAltNames.IpAllowed) {
  1002  					cloudPolicyRequest.SanIpAddressRegexes = []string{}
  1003  				}
  1004  			}
  1005  
  1006  			//to be implemented.
  1007  			if ps.Policy != nil && ps.Policy.SubjectAltNames != nil && len(ps.Policy.SubjectAltNames.UriProtocols) > 0 {
  1008  				uriRegex := convertToUriRegex(ps.Policy.SubjectAltNames.UriProtocols, []string{".*"})
  1009  				cloudPolicyRequest.SanUniformResourceIdentifierRegexes = uriRegex
  1010  			}
  1011  
  1012  		}
  1013  	}
  1014  
  1015  	if ps.Policy != nil && ps.Policy.SubjectAltNames != nil && ps.Policy.SubjectAltNames.IpAllowed != nil {
  1016  		if *(ps.Policy.SubjectAltNames.IpAllowed) {
  1017  			if len(ps.Policy.SubjectAltNames.IpConstraints) > 0 {
  1018  				cloudPolicyRequest.SanIpAddressRegexes = getIpRegexes(ps.Policy.SubjectAltNames.IpConstraints)
  1019  			} else {
  1020  				cloudPolicyRequest.SanIpAddressRegexes = []string{
  1021  					ipv4, ipv6,
  1022  				}
  1023  			}
  1024  
  1025  		} else {
  1026  			cloudPolicyRequest.SanIpAddressRegexes = nil
  1027  		}
  1028  	}
  1029  
  1030  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.Orgs) > 0 {
  1031  		if len(ps.Policy.Subject.Orgs) == 1 && ps.Policy.Subject.Orgs[0] == "" {
  1032  			cloudPolicyRequest.SubjectORegexes = nil
  1033  		} else {
  1034  			cloudPolicyRequest.SubjectORegexes = ps.Policy.Subject.Orgs
  1035  		}
  1036  
  1037  	} else {
  1038  		cloudPolicyRequest.SubjectORegexes = []string{".*"}
  1039  	}
  1040  
  1041  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.OrgUnits) > 0 {
  1042  		if len(ps.Policy.Subject.OrgUnits) == 1 && ps.Policy.Subject.OrgUnits[0] == "" {
  1043  			cloudPolicyRequest.SubjectOURegexes = nil
  1044  		} else {
  1045  			cloudPolicyRequest.SubjectOURegexes = ps.Policy.Subject.OrgUnits
  1046  		}
  1047  
  1048  	} else {
  1049  		cloudPolicyRequest.SubjectOURegexes = []string{".*"}
  1050  	}
  1051  
  1052  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.Localities) > 0 {
  1053  		if len(ps.Policy.Subject.Localities) == 1 && ps.Policy.Subject.Localities[0] == "" {
  1054  			cloudPolicyRequest.SubjectLRegexes = nil
  1055  		} else {
  1056  			cloudPolicyRequest.SubjectLRegexes = ps.Policy.Subject.Localities
  1057  		}
  1058  
  1059  	} else {
  1060  		cloudPolicyRequest.SubjectLRegexes = []string{".*"}
  1061  	}
  1062  
  1063  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.States) > 0 {
  1064  		if len(ps.Policy.Subject.States) == 1 && ps.Policy.Subject.States[0] == "" {
  1065  			cloudPolicyRequest.SubjectSTRegexes = nil
  1066  		} else {
  1067  			cloudPolicyRequest.SubjectSTRegexes = ps.Policy.Subject.States
  1068  		}
  1069  	} else {
  1070  		cloudPolicyRequest.SubjectSTRegexes = []string{".*"}
  1071  	}
  1072  
  1073  	if ps.Policy != nil && ps.Policy.Subject != nil && len(ps.Policy.Subject.Countries) > 0 {
  1074  		if len(ps.Policy.Subject.Countries) == 1 && ps.Policy.Subject.Countries[0] == "" {
  1075  			cloudPolicyRequest.SubjectCValues = nil
  1076  		} else {
  1077  			cloudPolicyRequest.SubjectCValues = ps.Policy.Subject.Countries
  1078  		}
  1079  	} else {
  1080  		cloudPolicyRequest.SubjectCValues = []string{".*"}
  1081  	}
  1082  
  1083  	var keyType *KeyType
  1084  	var ecKeyType *KeyType
  1085  	if ps.Policy != nil && ps.Policy.KeyPair != nil && len(ps.Policy.KeyPair.KeyTypes) > 0 {
  1086  		for _, val := range ps.Policy.KeyPair.KeyTypes {
  1087  			if val == "RSA" {
  1088  				keyType = &KeyType{}
  1089  				keyType.KeyType = val
  1090  			} else if val == "EC" {
  1091  				ecKeyType = &KeyType{}
  1092  				ecKeyType.KeyType = val
  1093  			}
  1094  		}
  1095  
  1096  	} else {
  1097  		keyType = &KeyType{}
  1098  		keyType.KeyType = "RSA"
  1099  	}
  1100  
  1101  	if keyType != nil {
  1102  		if ps.Policy != nil && ps.Policy.KeyPair != nil && len(ps.Policy.KeyPair.RsaKeySizes) > 0 {
  1103  			keyType.KeyLengths = ps.Policy.KeyPair.RsaKeySizes
  1104  		} else {
  1105  			// on this case we need to look if there is a default if so then we can use it.
  1106  			if ps.Default != nil && ps.Default.KeyPair != nil && ps.Default.KeyPair.RsaKeySize != nil {
  1107  				keyType.KeyLengths = []int{*(ps.Default.KeyPair.RsaKeySize)}
  1108  			} else {
  1109  				keyType.KeyLengths = []int{2048}
  1110  			}
  1111  
  1112  		}
  1113  	}
  1114  
  1115  	if ecKeyType != nil {
  1116  		if ps.Policy != nil && ps.Policy.KeyPair != nil && len(ps.Policy.KeyPair.EllipticCurves) > 0 {
  1117  			ecKeyType.KeyCurves = ps.Policy.KeyPair.EllipticCurves
  1118  		} else {
  1119  			// on this case we need to look if there is a default if so then we can use it.
  1120  			if ps.Default != nil && ps.Default.KeyPair != nil && ps.Default.KeyPair.EllipticCurve != nil {
  1121  				ecKeyType.KeyCurves = []string{*(ps.Default.KeyPair.EllipticCurve)}
  1122  			} else {
  1123  				ecKeyType.KeyCurves = []string{"P256"}
  1124  			}
  1125  		}
  1126  	}
  1127  
  1128  	var keyTypesArr []KeyType
  1129  
  1130  	if keyType != nil {
  1131  		keyTypesArr = append(keyTypesArr, *(keyType))
  1132  	}
  1133  
  1134  	if ecKeyType != nil {
  1135  		keyTypesArr = append(keyTypesArr, *(ecKeyType))
  1136  	}
  1137  
  1138  	if len(keyTypesArr) > 0 {
  1139  		cloudPolicyRequest.KeyTypes = keyTypesArr
  1140  	}
  1141  
  1142  	if ps.Policy != nil && ps.Policy.KeyPair != nil && ps.Policy.KeyPair.ReuseAllowed != nil {
  1143  		cloudPolicyRequest.KeyReuse = ps.Policy.KeyPair.ReuseAllowed
  1144  	} else {
  1145  		falseValue := false
  1146  		cloudPolicyRequest.KeyReuse = &falseValue
  1147  	}
  1148  
  1149  	//build recommended settings
  1150  
  1151  	var recommendedSettings RecommendedSettings
  1152  	shouldCreateSubjectRS := false
  1153  	shouldCreateKPRS := false
  1154  
  1155  	/*if ps.Default.Domain != nil { ignore for now
  1156  		recommendedSettings.SubjectCNRegexes = []string{*(ps.Default.Domain)}//whan value should be put here.
  1157  		shouldCreateSubjectRS = true
  1158  	}*/
  1159  	if ps.Default != nil && ps.Default.Subject != nil {
  1160  		if ps.Default.Subject.Org != nil {
  1161  			recommendedSettings.SubjectOValue = ps.Default.Subject.Org
  1162  			shouldCreateSubjectRS = true
  1163  		}
  1164  		if ps.Default.Subject.OrgUnits != nil {
  1165  			recommendedSettings.SubjectOUValue = &ps.Default.Subject.OrgUnits[0]
  1166  			shouldCreateSubjectRS = true
  1167  		}
  1168  		if ps.Default.Subject.Locality != nil {
  1169  			recommendedSettings.SubjectLValue = ps.Default.Subject.Locality
  1170  			shouldCreateSubjectRS = true
  1171  		}
  1172  		if ps.Default.Subject.State != nil {
  1173  			recommendedSettings.SubjectSTValue = ps.Default.Subject.State
  1174  			shouldCreateSubjectRS = true
  1175  		}
  1176  
  1177  		if ps.Default.Subject.Country != nil {
  1178  			recommendedSettings.SubjectCValue = ps.Default.Subject.Country
  1179  			shouldCreateSubjectRS = true
  1180  		}
  1181  	}
  1182  
  1183  	var key Key
  1184  	if ps.Default != nil && ps.Default.KeyPair != nil {
  1185  		if ps.Default.KeyPair.KeyType != nil {
  1186  
  1187  			key.Type = *(ps.Default.KeyPair.KeyType)
  1188  			if key.Type == "RSA" {
  1189  				if ps.Default.KeyPair.RsaKeySize != nil {
  1190  					key.Length = *(ps.Default.KeyPair.RsaKeySize)
  1191  				} else {
  1192  					//default
  1193  					key.Length = 2048
  1194  				}
  1195  			} else if key.Type == "EC" {
  1196  				if ps.Default.KeyPair.EllipticCurve != nil && *(ps.Default.KeyPair.EllipticCurve) != "" {
  1197  					key.Curve = *(ps.Default.KeyPair.EllipticCurve)
  1198  				} else {
  1199  					key.Curve = "P256"
  1200  				}
  1201  			}
  1202  
  1203  			shouldCreateKPRS = true
  1204  		}
  1205  	}
  1206  	//SanRegexes is ignored now.
  1207  
  1208  	if shouldCreateKPRS {
  1209  		recommendedSettings.Key = &key
  1210  	}
  1211  
  1212  	if shouldCreateKPRS || shouldCreateSubjectRS {
  1213  		cloudPolicyRequest.RecommendedSettings = &recommendedSettings
  1214  	}
  1215  
  1216  	if ps.Policy != nil && ps.Policy.KeyPair != nil && ps.Policy.KeyPair.ServiceGenerated != nil {
  1217  		cloudPolicyRequest.CsrUploadAllowed = !*(ps.Policy.KeyPair.ServiceGenerated)
  1218  		cloudPolicyRequest.KeyGeneratedByVenafiAllowed = *(ps.Policy.KeyPair.ServiceGenerated)
  1219  	} else {
  1220  		cloudPolicyRequest.CsrUploadAllowed = true
  1221  		cloudPolicyRequest.KeyGeneratedByVenafiAllowed = true
  1222  	}
  1223  
  1224  	return &cloudPolicyRequest, nil
  1225  }
  1226  
  1227  func ConvertToRegex(values []string, wildcardAllowed bool) []string {
  1228  	regexVals := make([]string, 0)
  1229  	for _, current := range values {
  1230  		currentRegex := strings.ReplaceAll(current, ".", "\\.")
  1231  		if wildcardAllowed {
  1232  			currentRegex = fmt.Sprint("[*a-z]{1}[a-z0-9.-]*\\.", currentRegex)
  1233  		} else {
  1234  			currentRegex = fmt.Sprint("[a-z]{1}[a-z0-9.-]*\\.", currentRegex)
  1235  		}
  1236  		regexVals = append(regexVals, currentRegex)
  1237  	}
  1238  	if len(regexVals) > 0 {
  1239  		return regexVals
  1240  	}
  1241  
  1242  	return nil
  1243  }
  1244  
  1245  func getIpRegexes(supportedIps []string) (ipRegexes []string) {
  1246  
  1247  	ipRegexes = make([]string, 0)
  1248  
  1249  	for _, val := range supportedIps {
  1250  
  1251  		if val == "v4" {
  1252  			ipRegexes = append(ipRegexes, ipv4)
  1253  		}
  1254  		if val == "v6" {
  1255  			ipRegexes = append(ipRegexes, ipv6)
  1256  
  1257  		}
  1258  		if val == "v4private" {
  1259  			ipRegexes = append(ipRegexes, v4private)
  1260  
  1261  		}
  1262  		if val == "v6private" {
  1263  			ipRegexes = append(ipRegexes, v6private)
  1264  
  1265  		}
  1266  	}
  1267  
  1268  	return ipRegexes
  1269  }
  1270  
  1271  func ConvertToRfc822Regex(values []string) []string {
  1272  	regexVals := make([]string, 0)
  1273  	for _, current := range values {
  1274  
  1275  		currentRegex := strings.ReplaceAll(current, ".", "\\.")
  1276  		currentRegex = fmt.Sprint(".*@", currentRegex)
  1277  
  1278  		regexVals = append(regexVals, currentRegex)
  1279  	}
  1280  
  1281  	if len(regexVals) > 0 {
  1282  		return regexVals
  1283  	}
  1284  
  1285  	return nil
  1286  }
  1287  
  1288  func convertToUriRegex(protocols, domains []string) []string {
  1289  
  1290  	regexVals := make([]string, 0)
  1291  
  1292  	protocolsS := strings.Join(protocols, "|")
  1293  	protocolsS = fmt.Sprint("(", protocolsS, ")://.*\\.")
  1294  
  1295  	for _, current := range domains {
  1296  
  1297  		currentRegex := strings.ReplaceAll(current, ".", "\\.")
  1298  		currentRegex = fmt.Sprint(protocolsS, currentRegex)
  1299  
  1300  		regexVals = append(regexVals, currentRegex)
  1301  	}
  1302  
  1303  	if len(regexVals) > 0 {
  1304  		return regexVals
  1305  	}
  1306  
  1307  	return nil
  1308  }
  1309  
  1310  func RemoveRegex(values []string) []string {
  1311  	regexVals := make([]string, 0)
  1312  	for _, current := range values {
  1313  
  1314  		current = strings.TrimPrefix(current, "[*a-z]{1}[a-z0-9.-]*\\.")
  1315  		current = strings.TrimPrefix(current, "[a-z]{1}[a-z0-9.-]*\\.")
  1316  		current = strings.TrimPrefix(current, ".*\\.")
  1317  
  1318  		current = strings.ReplaceAll(current, "\\.", ".")
  1319  
  1320  		regexVals = append(regexVals, current)
  1321  	}
  1322  	if len(regexVals) > 0 {
  1323  		return regexVals
  1324  	}
  1325  
  1326  	return nil
  1327  }
  1328  
  1329  func GetApplicationName(zone string) string {
  1330  	data := strings.Split(zone, "\\")
  1331  	if data != nil && data[0] != "" {
  1332  		return data[0]
  1333  	}
  1334  	return ""
  1335  }
  1336  
  1337  func GetCitName(zone string) string {
  1338  	data := strings.Split(zone, "\\")
  1339  	if len(data) == 2 {
  1340  		return data[1]
  1341  	}
  1342  	return ""
  1343  }
  1344  
  1345  func GetCertAuthorityInfo(certificateAuthority string) (CertificateAuthorityInfo, error) {
  1346  
  1347  	var caInfo CertificateAuthorityInfo
  1348  	data := strings.Split(certificateAuthority, "\\")
  1349  
  1350  	if len(data) < 3 {
  1351  		return caInfo, fmt.Errorf("certificate Authority is invalid, please provide a valid value with this structure: ca_type\\ca_account_key\\vendor_product_name")
  1352  	}
  1353  
  1354  	caInfo = CertificateAuthorityInfo{
  1355  		CAType:            data[0],
  1356  		CAAccountKey:      data[1],
  1357  		VendorProductName: data[2],
  1358  	}
  1359  
  1360  	return caInfo, nil
  1361  }
  1362  
  1363  func IsWildcardAllowed(ps PolicySpecification) bool {
  1364  	if ps.Policy != nil && ps.Policy.WildcardAllowed != nil {
  1365  		return *(ps.Policy.WildcardAllowed)
  1366  	}
  1367  	return false
  1368  }
  1369  
  1370  func IsPolicyEmpty(ps *PolicySpecification) bool {
  1371  	if ps.Policy == nil {
  1372  		return true
  1373  	}
  1374  
  1375  	policy := ps.Policy
  1376  
  1377  	if policy.WildcardAllowed != nil {
  1378  		return false
  1379  	}
  1380  	if policy.SubjectAltNames != nil {
  1381  		san := policy.SubjectAltNames
  1382  
  1383  		if san.DnsAllowed != nil {
  1384  			return false
  1385  		}
  1386  
  1387  		if san.UriAllowed != nil {
  1388  			return false
  1389  		}
  1390  
  1391  		if san.EmailAllowed != nil {
  1392  			return false
  1393  		}
  1394  
  1395  		if san.IpAllowed != nil {
  1396  			return false
  1397  		}
  1398  
  1399  		if san.UpnAllowed != nil {
  1400  			return false
  1401  		}
  1402  
  1403  		if len(san.IpConstraints) > 0 {
  1404  			return false
  1405  		}
  1406  
  1407  		if len(san.UriProtocols) > 0 {
  1408  			return false
  1409  		}
  1410  	}
  1411  
  1412  	if policy.CertificateAuthority != nil && *(policy.CertificateAuthority) != "" {
  1413  		return false
  1414  	}
  1415  
  1416  	if policy.MaxValidDays != nil {
  1417  		return false
  1418  	}
  1419  
  1420  	if len(policy.Domains) > 0 {
  1421  		return false
  1422  	}
  1423  
  1424  	if policy.Subject != nil {
  1425  
  1426  		subject := policy.Subject
  1427  
  1428  		if len(subject.OrgUnits) > 0 {
  1429  			return false
  1430  		}
  1431  		if len(subject.Countries) > 0 {
  1432  			return false
  1433  		}
  1434  		if len(subject.States) > 0 {
  1435  			return false
  1436  		}
  1437  		if len(subject.Localities) > 0 {
  1438  			return false
  1439  		}
  1440  		if len(subject.Orgs) > 0 {
  1441  			return false
  1442  		}
  1443  
  1444  	}
  1445  
  1446  	if policy.KeyPair != nil {
  1447  		keyPair := policy.KeyPair
  1448  		if keyPair.ReuseAllowed != nil {
  1449  			return false
  1450  		}
  1451  		if len(keyPair.RsaKeySizes) > 0 {
  1452  			return false
  1453  		}
  1454  		if len(keyPair.KeyTypes) > 0 {
  1455  			return false
  1456  		}
  1457  		if len(keyPair.EllipticCurves) > 0 {
  1458  			return false
  1459  		}
  1460  		if keyPair.ServiceGenerated != nil {
  1461  			return false
  1462  		}
  1463  	}
  1464  
  1465  	return true
  1466  }
  1467  
  1468  func IsDefaultEmpty(ps *PolicySpecification) bool {
  1469  
  1470  	if ps.Default == nil {
  1471  		return true
  1472  	}
  1473  
  1474  	def := ps.Default
  1475  
  1476  	if def.Domain != nil && *(def.Domain) != "" {
  1477  		return false
  1478  	}
  1479  
  1480  	if def.KeyPair != nil {
  1481  		keyPair := def.KeyPair
  1482  
  1483  		if keyPair.ServiceGenerated != nil {
  1484  			return false
  1485  		}
  1486  
  1487  		if keyPair.EllipticCurve != nil && *(keyPair.EllipticCurve) != "" {
  1488  			return false
  1489  		}
  1490  
  1491  		if keyPair.RsaKeySize != nil {
  1492  			return false
  1493  		}
  1494  		if keyPair.KeyType != nil && *(keyPair.KeyType) != "" {
  1495  			return false
  1496  		}
  1497  
  1498  	}
  1499  
  1500  	if def.Subject != nil {
  1501  		subject := def.Subject
  1502  
  1503  		if len(subject.OrgUnits) > 0 {
  1504  			return false
  1505  		}
  1506  
  1507  		if subject.Org != nil && *(subject.Org) != "" {
  1508  			return false
  1509  		}
  1510  
  1511  		if subject.State != nil && *(subject.State) != "" {
  1512  			return false
  1513  		}
  1514  
  1515  		if subject.Country != nil && *(subject.Country) != "" {
  1516  			return false
  1517  		}
  1518  
  1519  		if subject.Locality != nil && *(subject.Locality) != "" {
  1520  			return false
  1521  		}
  1522  
  1523  	}
  1524  
  1525  	return true
  1526  }
  1527  
  1528  func VerifyPolicySpec(bytes []byte, fileExt string) error {
  1529  
  1530  	var err error
  1531  	var policySpecification PolicySpecification
  1532  
  1533  	if fileExt == JsonExtension {
  1534  		err = json.Unmarshal(bytes, &policySpecification)
  1535  		if err != nil {
  1536  			return err
  1537  		}
  1538  	} else if fileExt == YamlExtension {
  1539  		err = yaml.Unmarshal(bytes, &policySpecification)
  1540  		if err != nil {
  1541  			return err
  1542  		}
  1543  	} else {
  1544  		return fmt.Errorf("the specified file is not supported")
  1545  	}
  1546  
  1547  	return nil
  1548  }
  1549  
  1550  func GetFileAndBytes(p string) (*os.File, []byte, error) {
  1551  	file, err := os.Open(p)
  1552  	if err != nil {
  1553  		return nil, nil, err
  1554  	}
  1555  
  1556  	bytes, err := io.ReadAll(file)
  1557  	if err != nil {
  1558  		return nil, nil, err
  1559  	}
  1560  	return file, bytes, nil
  1561  }
  1562  func GetPolicySpec() *PolicySpecification {
  1563  
  1564  	emptyString := ""
  1565  	intVal := 0
  1566  	falseBool := false
  1567  
  1568  	specification := PolicySpecification{
  1569  		Policy: &Policy{
  1570  			CertificateAuthority: &emptyString,
  1571  			Domains:              []string{""},
  1572  			WildcardAllowed:      &falseBool,
  1573  			AutoInstalled:        &falseBool,
  1574  			MaxValidDays:         &intVal,
  1575  			Subject: &Subject{
  1576  				Orgs:       []string{""},
  1577  				OrgUnits:   []string{""},
  1578  				Localities: []string{""},
  1579  				States:     []string{""},
  1580  				Countries:  []string{""},
  1581  			},
  1582  			KeyPair: &KeyPair{
  1583  				KeyTypes:         []string{""},
  1584  				RsaKeySizes:      []int{0},
  1585  				ServiceGenerated: &falseBool,
  1586  				ReuseAllowed:     &falseBool,
  1587  				EllipticCurves:   []string{""},
  1588  			},
  1589  			SubjectAltNames: &SubjectAltNames{
  1590  				DnsAllowed:    &falseBool,
  1591  				IpAllowed:     &falseBool,
  1592  				EmailAllowed:  &falseBool,
  1593  				UriAllowed:    &falseBool,
  1594  				UpnAllowed:    &falseBool,
  1595  				UriProtocols:  []string{""},
  1596  				IpConstraints: []string{""},
  1597  			},
  1598  		},
  1599  		Default: &Default{
  1600  			Domain: &emptyString,
  1601  			Subject: &DefaultSubject{
  1602  				Org:      &emptyString,
  1603  				OrgUnits: []string{""},
  1604  				Locality: &emptyString,
  1605  				State:    &emptyString,
  1606  				Country:  &emptyString,
  1607  			},
  1608  			KeyPair: &DefaultKeyPair{
  1609  				KeyType:          &emptyString,
  1610  				RsaKeySize:       &intVal,
  1611  				EllipticCurve:    &emptyString,
  1612  				ServiceGenerated: &falseBool,
  1613  			},
  1614  		},
  1615  	}
  1616  	return &specification
  1617  }