Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: net/cert/internal/trust_store_mac.cc

Issue 2832703002: Allow the TrustStore interface to return matching intermediates, and identify distrusted certs. (Closed)
Patch Set: address comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/internal/trust_store_mac.h" 5 #include "net/cert/internal/trust_store_mac.h"
6 6
7 #include <Security/Security.h> 7 #include <Security/Security.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/mac/foundation_util.h" 10 #include "base/mac/foundation_util.h"
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 trust_settings, is_self_signed, policy_oid); 171 trust_settings, is_self_signed, policy_oid);
172 if (trust != TrustStatus::UNSPECIFIED) 172 if (trust != TrustStatus::UNSPECIFIED)
173 return trust; 173 return trust;
174 } 174 }
175 175
176 // No trust settings, or none of the settings were for the correct policy, or 176 // No trust settings, or none of the settings were for the correct policy, or
177 // had the correct trust result. 177 // had the correct trust result.
178 return TrustStatus::UNSPECIFIED; 178 return TrustStatus::UNSPECIFIED;
179 } 179 }
180 180
181 // Filters an array of SecCertificateRef by trust for |policy_oid|, returning 181 } // namespace
182 // the results as TrustAnchors in |out_anchors|. 182
183 void FilterTrustedCertificates(CFArrayRef matching_items, 183 TrustStoreMac::TrustStoreMac(CFTypeRef policy_oid)
184 const CFStringRef policy_oid, 184 : policy_oid_(base::mac::CFCastStrict<CFStringRef>(policy_oid)) {
185 TrustAnchors* out_anchors) { 185 DCHECK(policy_oid_);
186 }
187
188 TrustStoreMac::~TrustStoreMac() = default;
189
190 void TrustStoreMac::SyncGetIssuersOf(const ParsedCertificate* cert,
191 ParsedCertificateList* issuers) {
192 base::ScopedCFTypeRef<CFDataRef> name_data = GetMacNormalizedIssuer(cert);
193
194 base::ScopedCFTypeRef<CFArrayRef> matching_items =
195 FindMatchingCertificatesForMacNormalizedSubject(name_data);
196 if (!matching_items)
197 return;
198
199 // Convert to ParsedCertificate.
186 for (CFIndex i = 0, item_count = CFArrayGetCount(matching_items); 200 for (CFIndex i = 0, item_count = CFArrayGetCount(matching_items);
187 i < item_count; ++i) { 201 i < item_count; ++i) {
188 SecCertificateRef match_cert_handle = reinterpret_cast<SecCertificateRef>( 202 SecCertificateRef match_cert_handle = reinterpret_cast<SecCertificateRef>(
189 const_cast<void*>(CFArrayGetValueAtIndex(matching_items, i))); 203 const_cast<void*>(CFArrayGetValueAtIndex(matching_items, i)));
190 204
191 if (IsSecCertificateTrustedForPolicy(match_cert_handle, policy_oid) !=
192 TrustStatus::TRUSTED)
193 continue;
194
195 base::ScopedCFTypeRef<CFDataRef> der_data( 205 base::ScopedCFTypeRef<CFDataRef> der_data(
196 SecCertificateCopyData(match_cert_handle)); 206 SecCertificateCopyData(match_cert_handle));
197 if (!der_data) { 207 if (!der_data) {
198 LOG(ERROR) << "SecCertificateCopyData error"; 208 LOG(ERROR) << "SecCertificateCopyData error";
199 continue; 209 continue;
200 } 210 }
201 211
202 CertErrors errors; 212 CertErrors errors;
203 ParseCertificateOptions options; 213 ParseCertificateOptions options;
204 options.allow_invalid_serial_numbers = true; 214 options.allow_invalid_serial_numbers = true;
205 scoped_refptr<ParsedCertificate> anchor_cert = ParsedCertificate::Create( 215 scoped_refptr<ParsedCertificate> anchor_cert = ParsedCertificate::Create(
206 x509_util::CreateCryptoBuffer(CFDataGetBytePtr(der_data.get()), 216 x509_util::CreateCryptoBuffer(CFDataGetBytePtr(der_data.get()),
207 CFDataGetLength(der_data.get())), 217 CFDataGetLength(der_data.get())),
208 options, &errors); 218 options, &errors);
209 if (!anchor_cert) { 219 if (!anchor_cert) {
210 // TODO(crbug.com/634443): return errors better. 220 // TODO(crbug.com/634443): return errors better.
211 LOG(ERROR) << "Error parsing issuer certificate:\n" 221 LOG(ERROR) << "Error parsing issuer certificate:\n"
212 << errors.ToDebugString(); 222 << errors.ToDebugString();
213 continue; 223 continue;
214 } 224 }
215 225
216 out_anchors->push_back(TrustAnchor::CreateFromCertificateNoConstraints( 226 issuers->push_back(std::move(anchor_cert));
217 std::move(anchor_cert)));
218 } 227 }
219 } 228 }
220 229
221 } // namespace 230 void TrustStoreMac::GetTrust(const scoped_refptr<ParsedCertificate>& cert,
231 CertificateTrust* trust) const {
232 // TODO(eroman): Inefficient -- path building will convert between
233 // SecCertificateRef and ParsedCertificate representations multiple times
234 // (when getting the issuers, and again here).
235 base::ScopedCFTypeRef<SecCertificateRef> cert_handle =
236 x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(),
237 cert->der_cert().Length());
222 238
223 TrustStoreMac::TrustStoreMac(CFTypeRef policy_oid) 239 TrustStatus trust_status =
224 : policy_oid_(base::mac::CFCastStrict<CFStringRef>(policy_oid)) { 240 IsSecCertificateTrustedForPolicy(cert_handle, policy_oid_);
225 DCHECK(policy_oid_); 241 switch (trust_status) {
226 } 242 case TrustStatus::TRUSTED:
243 *trust = CertificateTrust::ForTrustAnchor();
244 return;
245 case TrustStatus::DISTRUSTED:
246 *trust = CertificateTrust::ForDistrusted();
247 return;
248 case TrustStatus::UNSPECIFIED:
249 *trust = CertificateTrust::ForUnspecified();
250 return;
251 }
227 252
228 TrustStoreMac::~TrustStoreMac() = default; 253 *trust = CertificateTrust::ForUnspecified();
229 254 return;
230 void TrustStoreMac::FindTrustAnchorsForCert(
231 const scoped_refptr<ParsedCertificate>& cert,
232 TrustAnchors* out_anchors) const {
233 base::ScopedCFTypeRef<CFDataRef> name_data = GetMacNormalizedIssuer(cert);
234
235 FindTrustAnchorsByMacNormalizedSubject(name_data, out_anchors);
236 } 255 }
237 256
238 // static 257 // static
239 base::ScopedCFTypeRef<CFArrayRef> 258 base::ScopedCFTypeRef<CFArrayRef>
240 TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( 259 TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject(
241 CFDataRef name_data) { 260 CFDataRef name_data) {
242 base::ScopedCFTypeRef<CFArrayRef> matching_items; 261 base::ScopedCFTypeRef<CFArrayRef> matching_items;
243 base::ScopedCFTypeRef<CFMutableDictionaryRef> query( 262 base::ScopedCFTypeRef<CFMutableDictionaryRef> query(
244 CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks, 263 CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks,
245 &kCFTypeDictionaryValueCallBacks)); 264 &kCFTypeDictionaryValueCallBacks));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 } 327 }
309 if (err) { 328 if (err) {
310 OSSTATUS_LOG(ERROR, err) << "SecItemCopyMatching error"; 329 OSSTATUS_LOG(ERROR, err) << "SecItemCopyMatching error";
311 return matching_items; 330 return matching_items;
312 } 331 }
313 return matching_items; 332 return matching_items;
314 } 333 }
315 334
316 // static 335 // static
317 base::ScopedCFTypeRef<CFDataRef> TrustStoreMac::GetMacNormalizedIssuer( 336 base::ScopedCFTypeRef<CFDataRef> TrustStoreMac::GetMacNormalizedIssuer(
318 const scoped_refptr<ParsedCertificate>& cert) { 337 const ParsedCertificate* cert) {
319 base::ScopedCFTypeRef<CFDataRef> name_data; 338 base::ScopedCFTypeRef<CFDataRef> name_data;
320 // There does not appear to be any public API to get the normalized version 339 // There does not appear to be any public API to get the normalized version
321 // of a Name without creating a SecCertificate. 340 // of a Name without creating a SecCertificate.
322 base::ScopedCFTypeRef<SecCertificateRef> cert_handle( 341 base::ScopedCFTypeRef<SecCertificateRef> cert_handle(
323 x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(), 342 x509_util::CreateSecCertificateFromBytes(cert->der_cert().UnsafeData(),
324 cert->der_cert().Length())); 343 cert->der_cert().Length()));
325 if (!cert_handle) { 344 if (!cert_handle) {
326 LOG(ERROR) << "CreateOSCertHandleFromBytes"; 345 LOG(ERROR) << "CreateOSCertHandleFromBytes";
327 return name_data; 346 return name_data;
328 } 347 }
329 { 348 {
330 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); 349 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
331 name_data.reset( 350 name_data.reset(
332 SecCertificateCopyNormalizedIssuerContent(cert_handle, nullptr)); 351 SecCertificateCopyNormalizedIssuerContent(cert_handle, nullptr));
333 } 352 }
334 if (!name_data) 353 if (!name_data)
335 LOG(ERROR) << "SecCertificateCopyNormalizedIssuerContent"; 354 LOG(ERROR) << "SecCertificateCopyNormalizedIssuerContent";
336 return name_data; 355 return name_data;
337 } 356 }
338 357
339 void TrustStoreMac::FindTrustAnchorsByMacNormalizedSubject(
340 CFDataRef name_data,
341 TrustAnchors* out_anchors) const {
342 base::ScopedCFTypeRef<CFArrayRef> scoped_matching_items =
343 FindMatchingCertificatesForMacNormalizedSubject(name_data);
344 if (!scoped_matching_items)
345 return;
346
347 FilterTrustedCertificates(scoped_matching_items.get(), policy_oid_,
348 out_anchors);
349 }
350
351 } // namespace net 358 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698