github.com/Venafi/vcert/v5@v5.10.2/pkg/venafi/cloud/cloudUtil.go (about)

     1  package cloud
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"net/http"
     8  	"regexp"
     9  
    10  	"github.com/Venafi/vcert/v5/pkg/certificate"
    11  	"github.com/Venafi/vcert/v5/pkg/util"
    12  )
    13  
    14  func parseDEKInfo(httpStatusCode int, httpStatus string, body []byte) (*EdgeEncryptionKey, error) {
    15  	switch httpStatusCode {
    16  	case http.StatusOK:
    17  		var res = &EdgeEncryptionKey{}
    18  		err := json.Unmarshal(body, res)
    19  		if err != nil {
    20  			return nil, fmt.Errorf("failed to parse DEK info results: %s, body: %s", err, body)
    21  		}
    22  		return res, nil
    23  	default:
    24  		if body != nil {
    25  			respErrors, err := parseResponseErrors(body)
    26  			if err == nil {
    27  				respError := fmt.Sprintf("unexpected status code on VaaS retrieving DEK's info. Status: %s\n", httpStatus)
    28  				for _, e := range respErrors {
    29  					respError += fmt.Sprintf("Error Code: %d Error: %s\n", e.Code, e.Message)
    30  				}
    31  				return nil, errors.New(respError)
    32  			}
    33  		}
    34  		return nil, fmt.Errorf("unexpected status code on VaaS retrieving DEK's info. Status. Status: %s", httpStatus)
    35  	}
    36  }
    37  
    38  func Load32KeyByte(keyBytes []byte) (*[32]byte, error) {
    39  	key := new([32]byte)
    40  	copy(key[:], keyBytes)
    41  	return key, nil
    42  }
    43  
    44  func getCsrAttributes(c *Connector, req *certificate.Request) (*CsrAttributes, error) {
    45  	zone := c.zone.zone
    46  	policy, err := c.GetPolicyWithRegex(zone)
    47  
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	csrAttr := CsrAttributes{}
    53  	valid := false
    54  
    55  	if req.Subject.CommonName != "" {
    56  		if policy.Policy != nil {
    57  
    58  			valid, err = isValueMatch([]string{req.Subject.CommonName}, policy.Policy.Domains)
    59  			if err != nil {
    60  				return nil, err
    61  			}
    62  
    63  			if !valid {
    64  				return nil, fmt.Errorf("specified CN %s, doesn't match with policy's specified domains %+q", req.Subject.CommonName, policy.Policy.Domains)
    65  			}
    66  		}
    67  		csrAttr.CommonName = &req.Subject.CommonName
    68  	}
    69  
    70  	if len(req.Subject.Organization) > 0 {
    71  		if policy.Policy != nil && policy.Policy.Subject != nil {
    72  			valid, err := isValueMatch(req.Subject.Organization, policy.Policy.Subject.Orgs)
    73  			if err != nil {
    74  				return nil, err
    75  			}
    76  			if !valid {
    77  				return nil, fmt.Errorf("specified organization %s, doesn't match with policy's specified organization %+q", req.Subject.Organization, policy.Policy.Subject.Orgs)
    78  			}
    79  		}
    80  		csrAttr.Organization = &req.Subject.Organization[0]
    81  
    82  	} else if policy.Default != nil && policy.Default.Subject != nil && policy.Default.Subject.Org != nil {
    83  		org := *(policy.Default.Subject.Org)
    84  		csrAttr.Organization = &org
    85  	}
    86  
    87  	if len(req.Subject.OrganizationalUnit) > 0 {
    88  		if policy.Policy != nil && policy.Policy.Subject != nil {
    89  			valid, err := isValueMatch(req.Subject.OrganizationalUnit, policy.Policy.Subject.OrgUnits)
    90  			if err != nil {
    91  				return nil, err
    92  			}
    93  			if !valid {
    94  				return nil, fmt.Errorf("specified org unit  %+q, doesn't match with policy's specified org unit %+q", req.Subject.OrganizationalUnit, policy.Policy.Subject.OrgUnits)
    95  			}
    96  		}
    97  		csrAttr.OrganizationalUnits = req.Subject.OrganizationalUnit
    98  	} else if policy.Default != nil && policy.Default.Subject != nil && policy.Default.Subject.OrgUnits != nil {
    99  		ou := policy.Default.Subject.OrgUnits
   100  		csrAttr.OrganizationalUnits = ou
   101  	}
   102  
   103  	if len(req.Subject.Locality) > 0 {
   104  
   105  		if policy.Policy != nil && policy.Policy.Subject != nil {
   106  			valid, err := isValueMatch(req.Subject.Locality, policy.Policy.Subject.Localities)
   107  			if err != nil {
   108  				return nil, err
   109  			}
   110  			if !valid {
   111  				return nil, fmt.Errorf("specified locality %s, doesn't match with policy's specified localities %+q", req.Subject.Locality[0], policy.Policy.Subject.Localities)
   112  			}
   113  		}
   114  
   115  		csrAttr.Locality = &req.Subject.Locality[0]
   116  	} else if policy.Default != nil && policy.Default.Subject != nil && policy.Default.Subject.Locality != nil {
   117  		locality := *(policy.Default.Subject.Locality)
   118  		csrAttr.Locality = &locality
   119  	}
   120  
   121  	if len(req.Subject.Province) > 0 {
   122  
   123  		if policy.Policy != nil && policy.Policy.Subject != nil {
   124  			valid, err := isValueMatch(req.Subject.Province, policy.Policy.Subject.States)
   125  			if err != nil {
   126  				return nil, err
   127  			}
   128  			if !valid {
   129  				return nil, fmt.Errorf("specified state %s, doesn't match with policy's specified states %+q", req.Subject.Province[0], policy.Policy.Subject.States)
   130  			}
   131  		}
   132  
   133  		csrAttr.State = &req.Subject.Province[0]
   134  	} else if policy.Default != nil && policy.Default.Subject != nil && policy.Default.Subject.State != nil {
   135  		state := *(policy.Default.Subject.State)
   136  		csrAttr.State = &state
   137  	}
   138  
   139  	if len(req.Subject.Country) > 0 {
   140  
   141  		if policy.Policy != nil && policy.Policy.Subject != nil {
   142  			valid, err := isValueMatch(req.Subject.Country, policy.Policy.Subject.Countries)
   143  			if err != nil {
   144  				return nil, err
   145  			}
   146  			if !valid {
   147  				return nil, fmt.Errorf("specified country %s, doesn't match with policy's specified countries %+q", req.Subject.Country[0], policy.Policy.Subject.Countries)
   148  			}
   149  		}
   150  
   151  		csrAttr.Country = &req.Subject.Country[0]
   152  	} else if policy.Default != nil && policy.Default.Subject != nil && policy.Default.Subject.Country != nil {
   153  		country := *(policy.Default.Subject.Country)
   154  		csrAttr.Country = &country
   155  	}
   156  
   157  	if len(req.DNSNames) > 0 {
   158  		sanByType := getSANByType(&csrAttr)
   159  		sanByType.DnsNames = req.DNSNames
   160  	}
   161  
   162  	if len(req.IPAddresses) > 0 {
   163  		sArray := make([]string, 0)
   164  		for _, val := range req.IPAddresses {
   165  			sArray = append(sArray, val.String())
   166  		}
   167  		sanByType := getSANByType(&csrAttr)
   168  		sanByType.IpAddresses = sArray
   169  	}
   170  
   171  	if len(req.EmailAddresses) > 0 {
   172  		sanByType := getSANByType(&csrAttr)
   173  		sanByType.Rfc822Names = req.EmailAddresses
   174  	}
   175  
   176  	if len(req.URIs) > 0 {
   177  		sArray := make([]string, 0)
   178  		for _, val := range req.URIs {
   179  			sArray = append(sArray, val.String())
   180  		}
   181  		sanByType := getSANByType(&csrAttr)
   182  		sanByType.UniformResourceIdentifiers = sArray
   183  	}
   184  
   185  	keyTypeParam := &KeyTypeParameters{}
   186  	if req.KeyType == certificate.KeyTypeRSA {
   187  		keyTypeParam.KeyType = "RSA"
   188  		if req.KeyLength > 0 {
   189  			keyTypeParam.KeyLength = &req.KeyLength
   190  		} else {
   191  			keyTypeParam.KeyLength = util.GetIntRef(2048)
   192  		}
   193  	} else if req.KeyType == certificate.KeyTypeECDSA {
   194  		keyTypeParam.KeyType = "EC"
   195  		if req.KeyCurve.String() != "" {
   196  			keyCurve := req.KeyCurve.String()
   197  			keyTypeParam.KeyCurve = &keyCurve
   198  		} else {
   199  			defaultCurve := certificate.EllipticCurveDefault
   200  			defaultCurveStr := defaultCurve.String()
   201  			keyTypeParam.KeyCurve = &defaultCurveStr
   202  		}
   203  	}
   204  	csrAttr.KeyTypeParameters = keyTypeParam
   205  
   206  	return &csrAttr, nil
   207  }
   208  
   209  func getSANByType(csrAttributes *CsrAttributes) *SubjectAlternativeNamesByType {
   210  	if csrAttributes.SubjectAlternativeNamesByType == nil {
   211  		csrAttributes.SubjectAlternativeNamesByType = &SubjectAlternativeNamesByType{}
   212  	}
   213  	return csrAttributes.SubjectAlternativeNamesByType
   214  }
   215  
   216  // receives a string regex and a string to test
   217  func testRegex(toTest, regex string) (bool, error) {
   218  	compiledRegex, err := regexp.Compile(regex)
   219  	if err != nil {
   220  		return false, err
   221  	}
   222  	return compiledRegex.MatchString(toTest), nil
   223  }
   224  
   225  func isValueMatch(toTest, regexString []string) (bool, error) {
   226  	validCN := true
   227  	var err error
   228  	if len(regexString) > 0 {
   229  		for _, value := range toTest {
   230  			valid := false
   231  			for _, regexVal := range regexString {
   232  				valid, err = testRegex(value, regexVal)
   233  				if err != nil {
   234  					return false, err
   235  				}
   236  				if valid {
   237  					break
   238  				}
   239  			}
   240  			if !valid {
   241  				validCN = false
   242  				break
   243  			}
   244  		}
   245  	} else {
   246  		validCN = true
   247  	}
   248  	return validCN, nil
   249  }