2017-11-10 152 views
0

我设法让SunPKCS11与Windows下的Firefox ESR 52.0一起使用,但我无法在MacOS中加载它。我已经尝试了几种不同的配置,并通过PKCS11直接加载,但没有任何工作,任何人都可以给我一些指针?MacOS的SunPKCS11提供商适用于Firefox

pkcs11.cfg配置如下:

name = FirefoxKeyStore 
library = "/Applications/Firefox.app/Contents/MacOS/fixed-for-java-runtime/libsoftokn3.dylib" 
attributes = compatibility 
nssArgs = "configdir='/Users/helloworld/Library/Application Support/Firefox/Profiles/wasdwasd.default-1453211557245' certPrefix='' keyPrefix='' secmod='secmod.db' flags='readOnly' " 
slot = 2 

然后在Java中,我试图加载它是这样的:

FileInputStream fis = new FileInputStream("pkcs11.cfg"); 
Provider provider = new SunPKCS11(fis); 
Security.addProvider(provider); 

然而,这立即使我有以下错误:

sunpkcs11: Initializing PKCS#11 library /Applications/Firefox.app/Contents/MacOS/fixed-for-java-runtime/libsoftokn3.dylib 
sunpkcs11: Multi-threaded initialization failed: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DEVICE_ERROR 
Exception in thread "main" java.security.ProviderException: Initialization failed 
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:376) 
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:107) 

您可能会问为什么我要加载奇怪文件夹中的.dylib,这是beca使用我在MacOS中使用install_name_tool@executable_path更改为@loader_path,以便获得库依赖性(因为我试图在Eclipse中而不是从Firefox本身运行它)。

我也尝试使用这里建议的解决方案:How to finalize SunPKCS11 Provider after it is initialized?,这是一个不行的...我得到同样的错误。这里提到

除了尝试各种不同的配置设置:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/PKCS11/Module_Specs#Softoken_Specific_Parameters

EDIT1

我试图通过@FaithReaper提到的方法,但它仍然抛出了同样的错误。我尝试将槽值更改为0,1-1,结果相同。看起来像加载下层PKCS11对象时出现问题。

Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DEVICE_ERROR 
at sun.security.pkcs11.wrapper.PKCS11.C_Initialize(Native Method) 
at sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.C_Initialize(PKCS11.java:1545) 
at sun.security.pkcs11.wrapper.PKCS11.getInstance(PKCS11.java:157) 
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:330) 

我不知道这是否会帮助,但我跑在Firefox的配置文件modutil并倾倒这个信息:

modutil -dbdir "/Users/eto/Library/Application Support/Firefox/Profiles/ew2g332o.default-1453211557245" -rawlist 

library= name="NSS Internal PKCS #11 Module" 
parameters="configdir=/Users/eto/Library/Application Support/Firefox/Profiles/ew2g332o.default-1453211557245 certPrefix= keyPrefix= secmod=secmod.db flags=readOnly " 
NSS="Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})" 

Listing of PKCS #11 Modules

  1. NSS Internal PKCS #11 Module uri: pkcs11:library-manufacturer=Mozilla%20Foundation;library-description=NSS%20Internal%20Crypto%20Services;library-version=3.33 slots: 2 slots attached status: loaded

    slot: NSS Internal Cryptographic Services token: NSS Generic Crypto Services uri: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

    slot: NSS User Private Key and Certificate Services token: NSS Certificate DB uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

回答

0

首先,我注意到你的不同方式插入/添加Provider与我。你能尝试以这种方式添加Provider吗? (也可能是irrelavent)

Provider p = new SunPKCS11(new ByteArrayInputStream(config.getBytes())); 
Security.insertProviderAt(p, 1); 
KeyStore.Builder builder = null; 
builder = KeyStore.Builder.newInstance("PKCS11", p, 
    new KeyStore.CallbackHandlerProtection(new UtilTarjetas().new CustomCallbackHandler())); 
cardKeyStore = builder.getKeyStore(); 

然后,也许你可以在这里尝试的办法:

https://github.com/avocado-framework/avocado/issues/1112

即:

apahim commented on 7 Apr 2016

@will-Do, nss folks were able to track this issue down and seems like they are going to consider a change in NSS_InitContext() , which should include a SECMOD_RestartModules(PR_FALSE) after a fork() . Anyway, they also provided a better workaround than the one I provided you. If you set the environment variable NSS_STRICT_NOFORK to DISABLED then the code is expected to work. It worked for me and I'd like to check if it works for you as well. Looking forward to see your results.

此外,一些消息来源表明,它可能是令牌或插槽问题。您可以尝试将槽位索引更改为0-1

+0

首先,感谢您的帮助。但问题似乎是在初始化'SunPKCS11'级别,它甚至在'insertProviderAt'或'addProvider'之前抛出'CKR_DEVICE_ERROR'。 ''CKR_DEVICE_ERROR'正在被'sun.security.pkcs11.wrapper.PKCS11.C_Initialize(Native Method)引发'见我在帖子中更新。 – codenamezero

0

如果在FireFox之外执行,Firefox在Mac OS X中提供的库可能实际上完全损坏或无法正常工作。

尝试配置和方法的许多不同的组合之后,我终于得到了它的工作通过不使用图书馆从Firefox ...

这里是一步一步的方法来得到它的工作:

  1. 在你的Mac上安装自制
  2. 运行brew install nss
  3. 运行brew install nspr
  4. 您可能需要brew link nssbrew link nspr
  5. 在配置文件中手动链接它们,你需要把它指向你的自制libsoftokn3.dylib,像这样library = /usr/local/opt/nss/lib/libsoftokn3.dylib

然后你的Java代码应该能够加载的Firefox在Mac OS X下的keystore ...我已经提交了一个bug here。该工单包含工作sample code关于如何实例化PKCS11,加载Firefox密钥库并列出商店中的别名。

这绝对是一个与Firefox合作的噩梦......但至少我得到了它的工作......谁会想到他们提供的库不起作用(但它在Windows中起作用!)? :P

为了完整起见,我已经直接包含的代码示例在这篇文章中,以及:

import java.io.ByteArrayInputStream; 
import java.security.KeyStore; 
import java.security.Provider; 
import java.security.Security; 
import java.util.Collections; 

public class Sample { 

    private KeyStore load(String lib, String profile) throws Exception 
    { 
     String config = "library = " + lib + "\n" + 
       "name = FirefoxKeyStore\n" + 
       "attributes = compatibility\n" + 
       "nssArgs = \"configDir='" + profile + "' certPrefix='' keyPrefix='' secmod='secmod.db' flags='readOnly,forceOpen,optimizeSpace' \"\n" + 
       "slot = 2\n"; 

     ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes()); 
     Provider provider = new sun.security.pkcs11.SunPKCS11(bais); 
     Security.addProvider(provider); 

     return KeyStore.getInstance("PKCS11"); 
    } 

    public static void main(String[] args) throws Exception { 

     Sample s = new Sample(); 

     String profile = "/Users/blah/Library/Application Support/Firefox/Profiles/yougottachangethis"; 
     String[] libs = { 
      //"/Applications/Firefox.app/Contents/MacOS/libsoftokn3.dylib", 
      "/usr/local/opt/nss/lib/libsoftokn3.dylib" 
     }; 

     for (String lib : libs) { 
      System.out.println("TRYING >>> " + lib); 
      try { 
       KeyStore ks1 = s.load(lib, profile); 

       ks1.load(null, null); 
       for (String alias : Collections.list(ks1.aliases())) { 
        System.out.println(alias); 
       } 
      } 
      catch (Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

这里是otool从苹果的输出(包括为FaithReaper的评论):

otool -L libsoftokn3.dylib 
libsoftokn3.dylib: 
/usr/local/opt/nss/lib/libsoftokn3.dylib (compatibility version 1.0.0, current version 1.0.0) 
/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 253.0.0) 
/usr/local/Cellar/nss/3.34/lib/libnssutil3.dylib (compatibility version 1.0.0, current version 1.0.0) 
/usr/local/opt/nspr/lib/libplc4.dylib (compatibility version 1.0.0, current version 1.0.0) 
/usr/local/opt/nspr/lib/libplds4.dylib (compatibility version 1.0.0, current version 1.0.0) 
/usr/local/opt/nspr/lib/libnspr4.dylib (compatibility version 1.0.0, current version 1.0.0) 
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0) 
+0

我忘了说,但你如何配置系统env变量'LD_LIBRARY_PATH'?毫无疑问,'nss'取决于'nspr'。 – FaithReaper

+0

我不确定Mac是否加载了与Linux不同的库,但是我的'LD_LIBRARY_PATH'是空白的,当我使用'otool -L libsoftokn3.dylib'时,我可以看到它已经链接到'/ usr/local/opt/NSPR/LIB/libnspr4.dylib'。 – codenamezero

+0

嗯.....我认为'libsoftokn3.so'驻留在nss文件夹中,而不是nspr,并且Linux中的名称是原样的,没有链接到'libnspr4.so'。所以这可能是问题。添加这个系统变量指向你有'libsoftokn3.dylib'(不是链接,但是真实文件)的文件夹,然后再试一次。你可以调查nss在哪里? – FaithReaper