nss_decryptor_mac.mm revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2009 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
5#include <Cocoa/Cocoa.h>
6
7#include <dlfcn.h>
8
9#include "base/sys_string_conversions.h"
10
11#include "chrome/browser/importer/nss_decryptor_mac.h"
12#include "chrome/browser/importer/firefox_importer_utils.h"
13
14#include "base/logging.h"
15
16// static
17const wchar_t NSSDecryptor::kNSS3Library[] = L"libnss3.dylib";
18
19// Important!! : On OS X the nss3 libraries are compiled with depedencies
20// on one another, referenced using dyld's @executable_path directive.
21// To make a long story short in order to get the libraries to load, dyld's
22// fallback path needs to be set to the directory containing the libraries.
23// To do so, the process this function runs in must have the
24// DYLD_FALLBACK_LIBRARY_PATH set on startup to said directory.
25bool NSSDecryptor::Init(const std::wstring& dll_path,
26                        const std::wstring& db_path) {
27  if (getenv("DYLD_FALLBACK_LIBRARY_PATH") == NULL) {
28    LOG(ERROR) << "DYLD_FALLBACK_LIBRARY_PATH variable not set";
29    return false;
30  }
31  FilePath dylib_file_path = FilePath::FromWStringHack(dll_path);
32  FilePath nss3_path = dylib_file_path.Append("libnss3.dylib");
33
34  void *nss_3_lib = dlopen(nss3_path.value().c_str(), RTLD_LAZY);
35  if (!nss_3_lib) {
36    LOG(ERROR) << "Failed to load nss3 lib" << dlerror();
37    return false;
38  }
39
40  NSS_Init = (NSSInitFunc)dlsym(nss_3_lib, "NSS_Init");
41  NSS_Shutdown = (NSSShutdownFunc)dlsym(nss_3_lib, "NSS_Shutdown");
42  PK11_GetInternalKeySlot =
43      (PK11GetInternalKeySlotFunc)dlsym(nss_3_lib, "PK11_GetInternalKeySlot");
44  PK11_CheckUserPassword =
45      (PK11CheckUserPasswordFunc)dlsym(nss_3_lib, "PK11_CheckUserPassword");
46  PK11_FreeSlot = (PK11FreeSlotFunc)dlsym(nss_3_lib, "PK11_FreeSlot");
47  PK11_Authenticate =
48      (PK11AuthenticateFunc)dlsym(nss_3_lib, "PK11_Authenticate");
49  PK11SDR_Decrypt = (PK11SDRDecryptFunc)dlsym(nss_3_lib, "PK11SDR_Decrypt");
50  SECITEM_FreeItem = (SECITEMFreeItemFunc)dlsym(nss_3_lib, "SECITEM_FreeItem");
51
52  if (!NSS_Init || !NSS_Shutdown || !PK11_GetInternalKeySlot ||
53      !PK11_CheckUserPassword || !PK11_FreeSlot || !PK11_Authenticate ||
54      !PK11SDR_Decrypt || !SECITEM_FreeItem) {
55    LOG(ERROR) << "NSS3 importer couldn't find entry points";
56    return false;
57  }
58
59  SECStatus result = NSS_Init(base::SysWideToNativeMB(db_path).c_str());
60
61  if (result != SECSuccess) {
62    LOG(ERROR) << "NSS_Init Failed returned: " << result;
63    return false;
64  }
65
66  is_nss_initialized_ = true;
67  return true;
68}
69
70NSSDecryptor::~NSSDecryptor() {
71  if (NSS_Shutdown && is_nss_initialized_) {
72    NSS_Shutdown();
73    is_nss_initialized_ = false;
74  }
75}
76