简体   繁体   English

安全传输:从文件加载服务器证书

[英]Secure Transport: Load server certificate from file

I have some C++ code that uses the Apple Secure Transport and Keychain APIs to create an SSL/TLS server (CLI). 我有一些使用Apple Secure TransportKeychain API创建SSL / TLS服务器(CLI)的C ++代码。 The code is already able to load the server cert by a user-provided finger-print from the existing keychain. 该代码已经可以通过现有钥匙串中用户提供的指纹来加载服务器证书。

However, for compatibility reasons, I'd like to enable the server to also load a cert + key (PEM) from a user-provided set of files. 但是,出于兼容性原因,我想使服务器也能够从用户提供的文件集中加载证书+密钥(PEM)。

To be clear: I do not want to import the file into the user's keychain, but instead just use it in that "session". 需要明确的是:我不想将文件导入用户的钥匙串中,而只是在该“会话”中使用它。

Basically, fill in the XXX: 基本上,填写XXX:

bool AppleTLSContext::addCredentialFile(const std::string& certfile,
                                        const std::string& keyfile)
{
  if (tryAsFingerprint(certfile)) {
    return true;
  }

  // XXX
}

It seems one can use SecItemImport and/or SecKeychainItemCreateFromContent to import the cert/key into a throw-away keychain with a random password. 似乎可以使用SecItemImport和/或SecKeychainItemCreateFromContent将cert /密钥导入带有随机密码的SecKeychainItemCreateFromContent钥匙串中。

  • Is there a viable way without using a throw-away keychain? 有没有不使用一次性钥匙扣的可行方法?
  • If not, is the "throw-away keychain" option a viable solution? 如果不是,“扔掉钥匙串”选项是否可行?
  • Also, is it possible to create the throw-away keychain in-memory only? 另外,是否可以仅在内存中创建一次性钥匙扣? (It seems SecKeychainCreate does require a path) (似乎SecKeychainCreate确实需要路径)

I'm looking for a solution that will run at least on OSX 10.6+ once compiled ( #ifdef s are OK). 我正在寻找一种至少在编译后即可在OSX 10.6+上运行的解决方案( #ifdef可以)。

If both files can be clubbed and converted into pkcs 12 format then SecPKCS12Import method can be used. 如果两个文件都可以合并在一起并转换为pkcs 12格式,则可以使用SecPKCS12Import方法。

But SecPKCS12Import does not work properly in root context. 但是SecPKCS12Import在根上下文中无法正常工作。 I do not know reason of this misbehaviour. 我不知道这种不当行为的原因。

OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data,
                             SecIdentityRef *outIdentity,
                             SecTrustRef *outTrust,
                             CFStringRef keyPassword)
{

OSStatus securityError = errSecSuccess;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { keyPassword };
CFDictionaryRef optionsDictionary = NULL;

optionsDictionary = CFDictionaryCreate(
                                       NULL, keys,
                                       values, (keyPassword ? 1 : 0),
                                       NULL, NULL);
CFArrayRef items = NULL;
securityError = SecPKCS12Import(inPKCS12Data,
                                optionsDictionary,
                                &items);

if (securityError == 0)
{ 
    CFDictionaryRef myIdentityAndTrust = (CFDictionaryRef)CFArrayGetValueAtIndex (items, 0);

    const void *tempIdentity = NULL;
    tempIdentity = CFDictionaryGetValue (myIdentityAndTrust,
                                         kSecImportItemIdentity);
    CFRetain(tempIdentity);
    *outIdentity = (SecIdentityRef)tempIdentity;
    const void *tempTrust = NULL;
    tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
    CFRetain(tempTrust);
    *outTrust = (SecTrustRef)tempTrust;
}
if (optionsDictionary) 
    CFRelease(optionsDictionary);
if (items)
    CFRelease(items);
return securityError;
}

Anand 阿南德

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM