Exemplo n.º 1
0
TransceiverPtr
IceObjC::StreamAcceptor::accept()
{
    SOCKET fd = doAccept(_fd);
    setBlock(fd, false);
    setTcpBufSize(fd, _instance);

    //
    // Create the read/write streams
    //
    UniqueRef<CFReadStreamRef> readStream;
    UniqueRef<CFWriteStreamRef> writeStream;
    try
    {
        CFStreamCreatePairWithSocket(ICE_NULLPTR, fd, &readStream.get(), &writeStream.get());
        _instance->setupStreams(readStream.get(), writeStream.get(), true, "");
        return new StreamTransceiver(_instance, readStream.release(), writeStream.release(), fd);
    }
    catch(const Ice::LocalException& ex)
    {
        if(fd != INVALID_SOCKET)
        {
            closeSocketNoThrow(fd);
        }
        throw;
    }
}
Exemplo n.º 2
0
//
// Imports a certificate private key and optionally add it to a keychain.
//
SecIdentityRef
IceSSL::loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keychain, const string& password,
                       const PasswordPromptPtr& prompt, int retryMax)
{
    //
    // Check if we already imported the certificate
    //
    UniqueRef<CFDataRef> hash;
    UniqueRef<CFDictionaryRef> subjectKeyProperty(getCertificateProperty(cert, kSecOIDSubjectKeyIdentifier));
    if(subjectKeyProperty)
    {
        CFArrayRef values = (CFArrayRef)CFDictionaryGetValue(subjectKeyProperty.get(), kSecPropertyKeyValue);
        for(int i = 0; i < CFArrayGetCount(values); ++i)
        {
            CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(values, i);
            if(CFEqual(CFDictionaryGetValue(dict, kSecPropertyKeyLabel), CFSTR("Key Identifier")))
            {
                hash.retain(CFDictionaryGetValue(dict, kSecPropertyKeyValue));
                break;
            }
        }
    }

    const void* values[] = { keychain };
    UniqueRef<CFArrayRef> searchList(CFArrayCreate(kCFAllocatorDefault, values, 1, &kCFTypeArrayCallBacks));

    UniqueRef<CFMutableDictionaryRef> query(CFDictionaryCreateMutable(0,
                                                                      0,
                                                                      &kCFTypeDictionaryKeyCallBacks,
                                                                      &kCFTypeDictionaryValueCallBacks));

    CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate);
    CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne);
    CFDictionarySetValue(query.get(), kSecMatchSearchList, searchList.get());
    CFDictionarySetValue(query.get(), kSecAttrSubjectKeyID, hash.get());
    CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue);

    CFTypeRef value = 0;
    OSStatus err = SecItemCopyMatching(query.get(), &value);
    UniqueRef<SecCertificateRef> item(value);
    if(err == noErr)
    {
        //
        // If the certificate has already been imported, create the
        // identity. The key should also have been imported.
        //
        SecIdentityRef identity;
        err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity);
        if(err != noErr)
        {
            ostringstream os;
            os << "IceSSL: error creating certificate identity:\n" << errorToString(err);
            throw CertificateReadException(__FILE__, __LINE__, os.str());
        }
        return identity;
    }
    else if(err != errSecItemNotFound)
    {
        ostringstream os;
        os << "IceSSL: error searching for keychain items:\n" << errorToString(err);
        throw CertificateReadException(__FILE__, __LINE__, os.str());
    }

    //
    // If the certificate isn't already in the keychain, load the
    // private key into the keychain and add the certificate.
    //
    UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypePrivateKey, keychain, password, prompt, retryMax));
    int count = CFArrayGetCount(items.get());
    UniqueRef<SecKeyRef> key;
    for(int i = 0; i < count; ++i)
    {
        SecKeychainItemRef item = (SecKeychainItemRef)CFArrayGetValueAtIndex(items.get(), 0);
        if(SecKeyGetTypeID() == CFGetTypeID(item))
        {
            key.retain(item);
            break;
        }
    }
    if(!key)
    {
        throw CertificateReadException(__FILE__, __LINE__, "IceSSL: no key in file `" + file + "'");
    }

    //
    // Add the certificate to the keychain
    //
    query.reset(CFDictionaryCreateMutable(kCFAllocatorDefault,
                                          0,
                                          &kCFTypeDictionaryKeyCallBacks,
                                          &kCFTypeDictionaryValueCallBacks));

    CFDictionarySetValue(query.get(), kSecUseKeychain, keychain);
    CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate);
    CFDictionarySetValue(query.get(), kSecValueRef, cert);
    CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue);

    value = 0;
    err = SecItemAdd(query.get(), (CFTypeRef*)&value);
    UniqueRef<CFArrayRef> added(value);
    if(err != noErr)
    {
        ostringstream os;
        os << "IceSSL: failure adding certificate to keychain\n" << errorToString(err);
        throw CertificateReadException(__FILE__, __LINE__, os.str());
    }
    item.retain(CFArrayGetValueAtIndex(added.get(), 0));

    //
    // Create the association between the private  key and the certificate,
    // kSecKeyLabel attribute should match the subject key identifier.
    //
    vector<SecKeychainAttribute> attributes;
    if(hash)
    {
        SecKeychainAttribute attr;
        attr.tag = kSecKeyLabel;
        attr.data = (void*)CFDataGetBytePtr(hash.get());
        attr.length = CFDataGetLength(hash.get());
        attributes.push_back(attr);
    }

    //
    // kSecKeyPrintName attribute correspond to the keychain display
    // name.
    //
    string label;
    CFStringRef commonName = 0;
    if(SecCertificateCopyCommonName(item.get(), &commonName) == noErr)
    {
        label = fromCFString(commonName);
        CFRelease(commonName);

        SecKeychainAttribute attr;
        attr.tag = kSecKeyPrintName;
        attr.data = (void*)label.c_str();
        attr.length = label.size();
        attributes.push_back(attr);
    }

    SecKeychainAttributeList attrs;
    attrs.attr = &attributes[0];
    attrs.count = attributes.size();
    SecKeychainItemModifyAttributesAndData((SecKeychainItemRef)key.get(), &attrs, 0, 0);

    SecIdentityRef identity;
    err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity);
    if(err != noErr)
    {
        ostringstream os;
        os << "IceSSL: error creating certificate identity:\n" << errorToString(err);
        throw CertificateReadException(__FILE__, __LINE__, os.str());
    }
    return identity;
}