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