Source file
src/crypto/x509/root_darwin.go
1
2
3
4
5 package x509
6
7 import (
8 macOS "crypto/x509/internal/macos"
9 "errors"
10 "fmt"
11 )
12
13 func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
14 certs := macOS.CFArrayCreateMutable()
15 defer macOS.ReleaseCFArray(certs)
16 leaf, err := macOS.SecCertificateCreateWithData(c.Raw)
17 if err != nil {
18 return nil, errors.New("invalid leaf certificate")
19 }
20 macOS.CFArrayAppendValue(certs, leaf)
21 if opts.Intermediates != nil {
22 for _, lc := range opts.Intermediates.lazyCerts {
23 c, err := lc.getCert()
24 if err != nil {
25 return nil, err
26 }
27 sc, err := macOS.SecCertificateCreateWithData(c.Raw)
28 if err != nil {
29 return nil, err
30 }
31 macOS.CFArrayAppendValue(certs, sc)
32 }
33 }
34
35 policies := macOS.CFArrayCreateMutable()
36 defer macOS.ReleaseCFArray(policies)
37 sslPolicy, err := macOS.SecPolicyCreateSSL(opts.DNSName)
38 if err != nil {
39 return nil, err
40 }
41 macOS.CFArrayAppendValue(policies, sslPolicy)
42
43 trustObj, err := macOS.SecTrustCreateWithCertificates(certs, policies)
44 if err != nil {
45 return nil, err
46 }
47 defer macOS.CFRelease(trustObj)
48
49 if !opts.CurrentTime.IsZero() {
50 dateRef := macOS.TimeToCFDateRef(opts.CurrentTime)
51 defer macOS.CFRelease(dateRef)
52 if err := macOS.SecTrustSetVerifyDate(trustObj, dateRef); err != nil {
53 return nil, err
54 }
55 }
56
57
58
59
60
61
62 if ret, err := macOS.SecTrustEvaluateWithError(trustObj); err != nil {
63 switch ret {
64 case macOS.ErrSecCertificateExpired:
65 return nil, CertificateInvalidError{c, Expired, err.Error()}
66 case macOS.ErrSecHostNameMismatch:
67 return nil, HostnameError{c, opts.DNSName}
68 case macOS.ErrSecNotTrusted:
69 return nil, UnknownAuthorityError{Cert: c}
70 default:
71 return nil, fmt.Errorf("x509: %s", err)
72 }
73 }
74
75 chain := [][]*Certificate{{}}
76 numCerts := macOS.SecTrustGetCertificateCount(trustObj)
77 for i := 0; i < numCerts; i++ {
78 certRef, err := macOS.SecTrustGetCertificateAtIndex(trustObj, i)
79 if err != nil {
80 return nil, err
81 }
82 cert, err := exportCertificate(certRef)
83 if err != nil {
84 return nil, err
85 }
86 chain[0] = append(chain[0], cert)
87 }
88 if len(chain[0]) == 0 {
89
90 return nil, errors.New("x509: macOS certificate verification internal error")
91 }
92
93 if opts.DNSName != "" {
94
95 if err := chain[0][0].VerifyHostname(opts.DNSName); err != nil {
96 return nil, err
97 }
98 }
99
100 keyUsages := opts.KeyUsages
101 if len(keyUsages) == 0 {
102 keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
103 }
104
105
106 for _, usage := range keyUsages {
107 if usage == ExtKeyUsageAny {
108 return chain, nil
109 }
110 }
111
112 if !checkChainForKeyUsage(chain[0], keyUsages) {
113 return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
114 }
115
116 return chain, nil
117 }
118
119
120 func exportCertificate(cert macOS.CFRef) (*Certificate, error) {
121 data, err := macOS.SecCertificateCopyData(cert)
122 if err != nil {
123 return nil, err
124 }
125 return ParseCertificate(data)
126 }
127
128 func loadSystemRoots() (*CertPool, error) {
129 return &CertPool{systemPool: true}, nil
130 }
131
View as plain text