1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/cssm_init.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <Security/SecBase.h>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/mac/scoped_cftyperef.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/sys_string_conversions.h"
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// When writing crypto code for Mac OS X, you may find the following
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// documentation useful:
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Common Security: CDSA and CSSM, Version 2 (with corrigenda)
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   http://www.opengroup.org/security/cdsa.htm
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - Apple Cryptographic Service Provider Functional Specification
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid* CSSMMalloc(CSSM_SIZE size, void* alloc_ref) {
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return malloc(size);
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid CSSMFree(void* mem_ptr, void* alloc_ref) {
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  free(mem_ptr);
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) {
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return realloc(ptr, size);
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) {
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return calloc(num, size);
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass CSSMInitSingleton {
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static CSSMInitSingleton* GetInstance() {
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return Singleton<CSSMInitSingleton,
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                     LeakySingletonTraits<CSSMInitSingleton> >::get();
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CSSM_CSP_HANDLE csp_handle() const { return csp_handle_; }
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CSSM_CL_HANDLE cl_handle() const { return cl_handle_; }
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CSSM_TP_HANDLE tp_handle() const { return tp_handle_; }
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CSSMInitSingleton()
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      : inited_(false), csp_loaded_(false), cl_loaded_(false),
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        tp_loaded_(false), csp_handle_(NULL), cl_handle_(NULL),
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        tp_handle_(NULL) {
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    static CSSM_VERSION version = {2, 0};
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // TODO(wtc): what should our caller GUID be?
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    static const CSSM_GUID test_guid = {
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 }
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    };
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CSSM_RETURN crtn;
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE;
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid,
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL);
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (crtn) {
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      NOTREACHED();
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return;
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    inited_ = true;
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (crtn) {
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      NOTREACHED();
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return;
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    csp_loaded_ = true;
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    crtn = CSSM_ModuleLoad(
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        &gGuidAppleX509CL, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (crtn) {
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NOTREACHED();
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return;
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    cl_loaded_ = true;
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    crtn = CSSM_ModuleLoad(
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        &gGuidAppleX509TP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (crtn) {
8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NOTREACHED();
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return;
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    tp_loaded_ = true;
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const CSSM_API_MEMORY_FUNCS cssmMemoryFunctions = {
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CSSMMalloc,
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CSSMFree,
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CSSMRealloc,
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CSSMCalloc,
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NULL
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    };
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &cssmMemoryFunctions, 0,
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE,
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             NULL, 0, NULL, &csp_handle_);
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(crtn == CSSM_OK);
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    crtn = CSSM_ModuleAttach(&gGuidAppleX509CL, &version, &cssmMemoryFunctions,
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             0, CSSM_SERVICE_CL, 0, CSSM_KEY_HIERARCHY_NONE,
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             NULL, 0, NULL, &cl_handle_);
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DCHECK(crtn == CSSM_OK);
10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    crtn = CSSM_ModuleAttach(&gGuidAppleX509TP, &version, &cssmMemoryFunctions,
10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             0, CSSM_SERVICE_TP, 0, CSSM_KEY_HIERARCHY_NONE,
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             NULL, 0, NULL, &tp_handle_);
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DCHECK(crtn == CSSM_OK);
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~CSSMInitSingleton() {
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CSSM_RETURN crtn;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (csp_handle_) {
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_);
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(crtn == CSSM_OK);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (cl_handle_) {
12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CSSM_RETURN crtn = CSSM_ModuleDetach(cl_handle_);
12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      DCHECK(crtn == CSSM_OK);
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (tp_handle_) {
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CSSM_RETURN crtn = CSSM_ModuleDetach(tp_handle_);
12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      DCHECK(crtn == CSSM_OK);
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (csp_loaded_) {
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DCHECK(crtn == CSSM_OK);
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (cl_loaded_) {
13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      crtn = CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL);
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      DCHECK(crtn == CSSM_OK);
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (tp_loaded_) {
13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      crtn = CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL);
13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      DCHECK(crtn == CSSM_OK);
13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (inited_) {
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      crtn = CSSM_Terminate();
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DCHECK(crtn == CSSM_OK);
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool inited_;  // True if CSSM_Init has been called successfully.
14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool csp_loaded_;  // True if gGuidAppleCSP has been loaded
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool cl_loaded_;  // True if gGuidAppleX509CL has been loaded.
14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool tp_loaded_;  // True if gGuidAppleX509TP has been loaded.
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CSSM_CSP_HANDLE csp_handle_;
15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CSSM_CL_HANDLE cl_handle_;
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CSSM_TP_HANDLE tp_handle_;
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  friend struct DefaultSingletonTraits<CSSMInitSingleton>;
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto {
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid EnsureCSSMInit() {
16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  CSSMInitSingleton::GetInstance();
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCSSM_CSP_HANDLE GetSharedCSPHandle() {
16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return CSSMInitSingleton::GetInstance()->csp_handle();
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenCSSM_CL_HANDLE GetSharedCLHandle() {
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return CSSMInitSingleton::GetInstance()->cl_handle();
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenCSSM_TP_HANDLE GetSharedTPHandle() {
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return CSSMInitSingleton::GetInstance()->tp_handle();
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid* CSSMMalloc(CSSM_SIZE size) {
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return ::CSSMMalloc(size, NULL);
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid CSSMFree(void* ptr) {
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ::CSSMFree(ptr, NULL);
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid LogCSSMError(const char* fn_name, CSSM_RETURN err) {
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!err)
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::mac::ScopedCFTypeRef<CFStringRef> cfstr(
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      SecCopyErrorMessageString(err, NULL));
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  LOG(ERROR) << fn_name << " returned " << err
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             << " (" << base::SysCFStringRefToUTF8(cfstr) << ")";
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenScopedCSSMData::ScopedCSSMData() {
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  memset(&data_, 0, sizeof(data_));
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenScopedCSSMData::~ScopedCSSMData() {
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (data_.Data) {
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    CSSMFree(data_.Data);
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    data_.Data = NULL;
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace crypto
205