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 chainRef, err := macOS.SecTrustCopyCertificateChain(trustObj)
77 if err != nil {
78 return nil, err
79 }
80 defer macOS.CFRelease(chainRef)
81 for i := 0; i < macOS.CFArrayGetCount(chainRef); i++ {
82 certRef := macOS.CFArrayGetValueAtIndex(chainRef, i)
83 cert, err := exportCertificate(certRef)
84 if err != nil {
85 return nil, err
86 }
87 chain[0] = append(chain[0], cert)
88 }
89 if len(chain[0]) == 0 {
90
91 return nil, errors.New("x509: macOS certificate verification internal error")
92 }
93
94 if opts.DNSName != "" {
95
96 if err := chain[0][0].VerifyHostname(opts.DNSName); err != nil {
97 return nil, err
98 }
99 }
100
101 keyUsages := opts.KeyUsages
102 if len(keyUsages) == 0 {
103 keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
104 }
105
106
107 for _, usage := range keyUsages {
108 if usage == ExtKeyUsageAny {
109 return chain, nil
110 }
111 }
112
113 if !checkChainForKeyUsage(chain[0], keyUsages) {
114 return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
115 }
116
117 return chain, nil
118 }
119
120
121 func exportCertificate(cert macOS.CFRef) (*Certificate, error) {
122 data, err := macOS.SecCertificateCopyData(cert)
123 if err != nil {
124 return nil, err
125 }
126 return ParseCertificate(data)
127 }
128
129 func loadSystemRoots() (*CertPool, error) {
130 return &CertPool{systemPool: true}, nil
131 }
132
View as plain text