github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/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, err := macOS.SecCertificateCreateWithData(c.Raw) 16 if err != nil { 17 return nil, errors.New("invalid leaf certificate") 18 } 19 macOS.CFArrayAppendValue(certs, leaf) 20 if opts.Intermediates != nil { 21 for _, lc := range opts.Intermediates.lazyCerts { 22 c, err := lc.getCert() 23 if err != nil { 24 return nil, err 25 } 26 sc, err := macOS.SecCertificateCreateWithData(c.Raw) 27 if err == nil { 28 macOS.CFArrayAppendValue(certs, sc) 29 } 30 } 31 } 32 33 policies := macOS.CFArrayCreateMutable() 34 defer macOS.ReleaseCFArray(policies) 35 sslPolicy, err := macOS.SecPolicyCreateSSL(opts.DNSName) 36 if err != nil { 37 return nil, err 38 } 39 macOS.CFArrayAppendValue(policies, sslPolicy) 40 41 trustObj, err := macOS.SecTrustCreateWithCertificates(certs, policies) 42 if err != nil { 43 return nil, err 44 } 45 defer macOS.CFRelease(trustObj) 46 47 if !opts.CurrentTime.IsZero() { 48 dateRef := macOS.TimeToCFDateRef(opts.CurrentTime) 49 defer macOS.CFRelease(dateRef) 50 if err := macOS.SecTrustSetVerifyDate(trustObj, dateRef); err != nil { 51 return nil, err 52 } 53 } 54 55 // TODO(roland): we may want to allow passing in SCTs via VerifyOptions and 56 // set them via SecTrustSetSignedCertificateTimestamps, since Apple will 57 // always enforce its SCT requirements, and there are still _some_ people 58 // using TLS or OCSP for that. 59 60 if err := macOS.SecTrustEvaluateWithError(trustObj); err != nil { 61 return nil, err 62 } 63 64 chain := [][]*Certificate{{}} 65 numCerts := macOS.SecTrustGetCertificateCount(trustObj) 66 for i := 0; i < numCerts; i++ { 67 certRef, err := macOS.SecTrustGetCertificateAtIndex(trustObj, i) 68 if err != nil { 69 return nil, err 70 } 71 cert, err := exportCertificate(certRef) 72 if err != nil { 73 return nil, err 74 } 75 chain[0] = append(chain[0], cert) 76 } 77 if len(chain[0]) == 0 { 78 // This should _never_ happen, but to be safe 79 return nil, errors.New("x509: macOS certificate verification internal error") 80 } 81 82 if opts.DNSName != "" { 83 // If we have a DNS name, apply our own name verification 84 if err := chain[0][0].VerifyHostname(opts.DNSName); err != nil { 85 return nil, err 86 } 87 } 88 89 keyUsages := opts.KeyUsages 90 if len(keyUsages) == 0 { 91 keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth} 92 } 93 94 // If any key usage is acceptable then we're done. 95 for _, usage := range keyUsages { 96 if usage == ExtKeyUsageAny { 97 return chain, nil 98 } 99 } 100 101 if !checkChainForKeyUsage(chain[0], keyUsages) { 102 return nil, CertificateInvalidError{c, IncompatibleUsage, ""} 103 } 104 105 return chain, nil 106 } 107 108 // exportCertificate returns a *Certificate for a SecCertificateRef. 109 func exportCertificate(cert macOS.CFRef) (*Certificate, error) { 110 data, err := macOS.SecCertificateCopyData(cert) 111 if err != nil { 112 return nil, err 113 } 114 return ParseCertificate(data) 115 } 116 117 func loadSystemRoots() (*CertPool, error) { 118 return &CertPool{systemPool: true}, nil 119 }