OSX Security フレームワークで動作するプログラムがあります。プログラムを 2 つのモードで開始します。
最初のモードでは、プログラムはいくつかのセキュリティ フレームワーク関数を呼び出します。
SecPCS12Import 関数を呼び出し、秘密鍵を使用して証明書を正常にインポートし、ID ref を作成します。
CFStringRef passwordRef = CFStringCreateWithCString(0, password.c_str(), kCFStringEncodingUTF8); const void *keys[] = { kSecImportExportPassphrase, kSecReturnRef }; const void *values[] = { passwordRef, kCFBooleanTrue }; CFDictionaryRef optionsDictionary = CFDictionaryCreate(0, keys, values, 2, 0, 0); CFDataRef inPKCS12Data = CFDataCreate(0, (const UInt8*)data.data(), data.size()); CFArrayRef items = 0; OSStatus status = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items); CFRelease(passwordRef); CFRelease(optionsDictionary); CFRelease(inPKCS12Data); throwIfError(errSecSuccess != status); CFDictionaryRef myIdentityAndTrust = (CFDictionaryRef)CFArrayGetValueAtIndex(items, 0); SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity); KeyInfo info(alias, OSStoreImplementation::getCertificate(identity)); IKey::Ptr result = new OSKey(info, new OSKeyImplementation(identity, false)); CFRelease(items); return result;
前のステップで取得した ID ref を使用して CMSEncodeContent を呼び出し、メッセージに正常に署名します。
CFDataRef content = 0; CMSSignedAttributes signedAttributes = kCMSAttrSmimeCapabilities | kCMSAttrSmimeMSEncryptionKeyPrefs; throwIfError(errSecSuccess == CMSEncodeContent(_identity, 0, 0, FALSE, signedAttributes, message.data(), message.size(), &content)); char* buf = (char*)CFDataGetBytePtr(content); const ByteArray result(buf, buf + CFDataGetLength(content)); CFRelease(content); return result;
すべてのプログラムが終了した後。
2 番目のモードでは、プログラムは呼び出しの別のリストを作成します。
- プログラムの最初の起動からの秘密鍵に対応する DER 形式の証明書を使用して SecCertificateCreateWithData を呼び出し、証明書 ref を正常に作成します。
前の手順で取得した証明書参照を使用して SecIdentityCreateWithCertificate を呼び出し、ID 参照を正常に作成します。
CFDataRef content = CFCreateData(0, info.certificate.getData().data(), info.certificate.getData().size()); SecCertificateRef cert = SecCertificateCreateWithData(0, content); CFRelease(content); SecIdentityRef identity = 0; OSStatus status = SecIdentityCreateWithCertificate(0, cert, &identity); CFRelease(cert); throwIfError(errSecSuccess != status); KeyPtr result = new OSKey(info, new OSKeyImplementation(identity, true)); CFReleases(identity); return result;
前のステップで取得した ID ref を使用して CMSEncodeContent を呼び出し、errSecNoSuchKeychain (-25294) を使用してメッセージの署名に失敗します。ソース コードは、プログラムの最初のモードとまったく同じです。
このバグを修正するにはどうすればよいですか? また、プログラムを 2 番目のモードで起動するたびにこのエラーが発生するのはなぜですか?