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 )
11
12 func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
13 certs := macOS.CFArrayCreateMutable()
14 defer macOS.ReleaseCFArray(certs)
15 leaf := macOS.SecCertificateCreateWithData(c.Raw)
16 if leaf == 0 {
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 := macOS.SecCertificateCreateWithData(c.Raw)
27 if sc != 0 {
28 macOS.CFArrayAppendValue(certs, sc)
29 }
30 }
31 }
32
33 policies := macOS.CFArrayCreateMutable()
34 defer macOS.ReleaseCFArray(policies)
35 sslPolicy := macOS.SecPolicyCreateSSL(opts.DNSName)
36 macOS.CFArrayAppendValue(policies, sslPolicy)
37
38 trustObj, err := macOS.SecTrustCreateWithCertificates(certs, policies)
39 if err != nil {
40 return nil, err
41 }
42 defer macOS.CFRelease(trustObj)
43
44 if !opts.CurrentTime.IsZero() {
45 dateRef := macOS.TimeToCFDateRef(opts.CurrentTime)
46 defer macOS.CFRelease(dateRef)
47 if err := macOS.SecTrustSetVerifyDate(trustObj, dateRef); err != nil {
48 return nil, err
49 }
50 }
51
52
53
54
55
56
57 if err := macOS.SecTrustEvaluateWithError(trustObj); err != nil {
58 return nil, err
59 }
60
61 chain := [][]*Certificate{{}}
62 numCerts := macOS.SecTrustGetCertificateCount(trustObj)
63 for i := 0; i < numCerts; i++ {
64 certRef := macOS.SecTrustGetCertificateAtIndex(trustObj, i)
65 cert, err := exportCertificate(certRef)
66 if err != nil {
67 return nil, err
68 }
69 chain[0] = append(chain[0], cert)
70 }
71 if len(chain[0]) == 0 {
72
73 return nil, errors.New("x509: macOS certificate verification internal error")
74 }
75
76 if opts.DNSName != "" {
77
78 if err := chain[0][0].VerifyHostname(opts.DNSName); err != nil {
79 return nil, err
80 }
81 }
82
83 keyUsages := opts.KeyUsages
84 if len(keyUsages) == 0 {
85 keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
86 }
87
88
89 for _, usage := range keyUsages {
90 if usage == ExtKeyUsageAny {
91 return chain, nil
92 }
93 }
94
95 if !checkChainForKeyUsage(chain[0], keyUsages) {
96 return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
97 }
98
99 return chain, nil
100 }
101
102
103 func exportCertificate(cert macOS.CFRef) (*Certificate, error) {
104 data, err := macOS.SecCertificateCopyData(cert)
105 if err != nil {
106 return nil, err
107 }
108 return ParseCertificate(data)
109 }
110
111 func loadSystemRoots() (*CertPool, error) {
112 return &CertPool{systemPool: true}, nil
113 }
114
View as plain text