github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/crypto/x509/root_darwin.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package x509
     6  
     7  import (
     8  	macOS "crypto/x509/internal/macos"
     9  	"errors"
    10  )
    11  
    12  func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
    13  	certs := macOS.CFArrayCreateMutable()
    14  	defer macOS.ReleaseCFArray(certs)
    15  	leaf := macOS.SecCertificateCreateWithData(c.Raw)
    16  	macOS.CFArrayAppendValue(certs, leaf)
    17  	if opts.Intermediates != nil {
    18  		for _, lc := range opts.Intermediates.lazyCerts {
    19  			c, err := lc.getCert()
    20  			if err != nil {
    21  				return nil, err
    22  			}
    23  			sc := macOS.SecCertificateCreateWithData(c.Raw)
    24  			macOS.CFArrayAppendValue(certs, sc)
    25  		}
    26  	}
    27  
    28  	policies := macOS.CFArrayCreateMutable()
    29  	defer macOS.ReleaseCFArray(policies)
    30  	sslPolicy := macOS.SecPolicyCreateSSL(opts.DNSName)
    31  	macOS.CFArrayAppendValue(policies, sslPolicy)
    32  
    33  	trustObj, err := macOS.SecTrustCreateWithCertificates(certs, policies)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	defer macOS.CFRelease(trustObj)
    38  
    39  	if !opts.CurrentTime.IsZero() {
    40  		dateRef := macOS.TimeToCFDateRef(opts.CurrentTime)
    41  		defer macOS.CFRelease(dateRef)
    42  		if err := macOS.SecTrustSetVerifyDate(trustObj, dateRef); err != nil {
    43  			return nil, err
    44  		}
    45  	}
    46  
    47  	// TODO(roland): we may want to allow passing in SCTs via VerifyOptions and
    48  	// set them via SecTrustSetSignedCertificateTimestamps, since Apple will
    49  	// always enforce its SCT requirements, and there are still _some_ people
    50  	// using TLS or OCSP for that.
    51  
    52  	if err := macOS.SecTrustEvaluateWithError(trustObj); err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	chain := [][]*Certificate{{}}
    57  	numCerts := macOS.SecTrustGetCertificateCount(trustObj)
    58  	for i := 0; i < numCerts; i++ {
    59  		certRef := macOS.SecTrustGetCertificateAtIndex(trustObj, i)
    60  		cert, err := exportCertificate(certRef)
    61  		if err != nil {
    62  			return nil, err
    63  		}
    64  		chain[0] = append(chain[0], cert)
    65  	}
    66  	if len(chain[0]) == 0 {
    67  		// This should _never_ happen, but to be safe
    68  		return nil, errors.New("x509: macOS certificate verification internal error")
    69  	}
    70  
    71  	if opts.DNSName != "" {
    72  		// If we have a DNS name, apply our own name verification
    73  		if err := chain[0][0].VerifyHostname(opts.DNSName); err != nil {
    74  			return nil, err
    75  		}
    76  	}
    77  
    78  	keyUsages := opts.KeyUsages
    79  	if len(keyUsages) == 0 {
    80  		keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
    81  	}
    82  
    83  	// If any key usage is acceptable then we're done.
    84  	for _, usage := range keyUsages {
    85  		if usage == ExtKeyUsageAny {
    86  			return chain, nil
    87  		}
    88  	}
    89  
    90  	if !checkChainForKeyUsage(chain[0], keyUsages) {
    91  		return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
    92  	}
    93  
    94  	return chain, nil
    95  }
    96  
    97  // exportCertificate returns a *Certificate for a SecCertificateRef.
    98  func exportCertificate(cert macOS.CFRef) (*Certificate, error) {
    99  	data, err := macOS.SecCertificateCopyData(cert)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  	return ParseCertificate(data)
   104  }
   105  
   106  func loadSystemRoots() (*CertPool, error) {
   107  	return &CertPool{systemPool: true}, nil
   108  }