x509_util_mac.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef NET_CERT_X509_UTIL_MAC_H_
  5. #define NET_CERT_X509_UTIL_MAC_H_
  6. #include <Security/Security.h>
  7. namespace net::x509_util {
  8. // CSSM functions are deprecated as of OSX 10.7, but have no replacement.
  9. // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1
  10. #pragma clang diagnostic push
  11. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  12. // Wrapper for a CSSM_DATA_PTR that was obtained via one of the CSSM field
  13. // accessors (such as CSSM_CL_CertGet[First/Next]Value or
  14. // CSSM_CL_CertGet[First/Next]CachedValue).
  15. class CSSMFieldValue {
  16. public:
  17. CSSMFieldValue();
  18. CSSMFieldValue(CSSM_CL_HANDLE cl_handle,
  19. const CSSM_OID* oid,
  20. CSSM_DATA_PTR field);
  21. CSSMFieldValue(const CSSMFieldValue&) = delete;
  22. CSSMFieldValue& operator=(const CSSMFieldValue&) = delete;
  23. ~CSSMFieldValue();
  24. CSSM_OID_PTR oid() const { return oid_; }
  25. CSSM_DATA_PTR field() const { return field_; }
  26. // Returns the field as if it was an arbitrary type - most commonly, by
  27. // interpreting the field as a specific CSSM/CDSA parsed type, such as
  28. // CSSM_X509_SUBJECT_PUBLIC_KEY_INFO or CSSM_X509_ALGORITHM_IDENTIFIER.
  29. // An added check is applied to ensure that the current field is large
  30. // enough to actually contain the requested type.
  31. template <typename T> const T* GetAs() const {
  32. if (!field_ || field_->Length < sizeof(T))
  33. return nullptr;
  34. return reinterpret_cast<const T*>(field_->Data);
  35. }
  36. void Reset(CSSM_CL_HANDLE cl_handle,
  37. CSSM_OID_PTR oid,
  38. CSSM_DATA_PTR field);
  39. private:
  40. CSSM_CL_HANDLE cl_handle_;
  41. CSSM_OID_PTR oid_;
  42. CSSM_DATA_PTR field_;
  43. };
  44. // CSSMCachedCertificate is a container class that is used to wrap the
  45. // CSSM_CL_CertCache APIs and provide safe and efficient access to
  46. // certificate fields in their CSSM form.
  47. //
  48. // To provide efficient access to certificate/CRL fields, CSSM provides an
  49. // API/SPI to "cache" a certificate/CRL. The exact meaning of a cached
  50. // certificate is not defined by CSSM, but is documented to generally be some
  51. // intermediate or parsed form of the certificate. In the case of Apple's
  52. // CSSM CL implementation, the intermediate form is the parsed certificate
  53. // stored in an internal format (which happens to be NSS). By caching the
  54. // certificate, callers that wish to access multiple fields (such as subject,
  55. // issuer, and validity dates) do not need to repeatedly parse the entire
  56. // certificate, nor are they forced to convert all fields from their NSS types
  57. // to their CSSM equivalents. This latter point is especially helpful when
  58. // running on OS X 10.5, as it will fail to convert some fields that reference
  59. // unsupported algorithms, such as ECC.
  60. class CSSMCachedCertificate {
  61. public:
  62. CSSMCachedCertificate();
  63. ~CSSMCachedCertificate();
  64. // Initializes the CSSMCachedCertificate by caching the specified
  65. // |os_cert_handle|. On success, returns noErr.
  66. // Note: Once initialized, the cached certificate should only be accessed
  67. // from a single thread.
  68. OSStatus Init(SecCertificateRef os_cert_handle);
  69. // Fetches the first value for the field associated with |field_oid|.
  70. // If |field_oid| is a valid OID and is present in the current certificate,
  71. // returns CSSM_OK and stores the first value in |field|. If additional
  72. // values are associated with |field_oid|, they are ignored.
  73. OSStatus GetField(const CSSM_OID* field_oid, CSSMFieldValue* field) const;
  74. private:
  75. CSSM_CL_HANDLE cl_handle_;
  76. CSSM_HANDLE cached_cert_handle_;
  77. };
  78. // Compares two OIDs by value.
  79. inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) {
  80. return oid1->Length == oid2->Length &&
  81. (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0);
  82. }
  83. #pragma clang diagnostic pop // "-Wdeprecated-declarations"
  84. } // namespace net::x509_util
  85. #endif // NET_CERT_X509_UTIL_MAC_H_