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
93 if len(chain[0]) == 0 {
94
95 return nil, errors.New("x509: macos certificate verification internal error")
96 }
97
98 if containsDistrustedSPKIHash(chain[0]) {
99 return nil, CertificateInvalidError{c, NoValidChains, ""}
100 }
101
102 if opts.DNSName != "" {
103
104 if err := chain[0][0].VerifyHostname(opts.DNSName); err != nil {
105 return nil, err
106 }
107 }
108
109 keyUsages := opts.KeyUsages
110 if len(keyUsages) == 0 {
111 keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
112 }
113
114
115 for _, usage := range keyUsages {
116 if usage == ExtKeyUsageAny {
117 return chain, nil
118 }
119 }
120
121 if !checkChainForKeyUsage(chain[0], keyUsages) {
122 return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
123 }
124
125 return chain, nil
126 }
127
128
129 func exportCertificate(cert macos.CFRef) (*Certificate, error) {
130 data, err := macos.SecCertificateCopyData(cert)
131 if err != nil {
132 return nil, err
133 }
134 return ParseCertificate(data)
135 }
136
View as plain text