SOSCoderRef SOSCoderCreate(SOSPeerInfoRef peerInfo, SOSFullPeerInfoRef myPeerInfo, CFErrorRef *error) {        
    CFAllocatorRef allocator = CFGetAllocator(peerInfo);
    
    SOSCoderRef coder = calloc(1, sizeof(struct __OpaqueSOSCoder));
    CFErrorRef localError = NULL;

    SecOTRFullIdentityRef myRef = NULL;
    SecOTRPublicIdentityRef peerRef = NULL;
    SecKeyRef privateKey = NULL;
    SecKeyRef publicKey = NULL;

    if (myPeerInfo && peerInfo) {
        privateKey = SOSFullPeerInfoCopyDeviceKey(myPeerInfo, &localError);
        require_quiet(privateKey, errOut);

        myRef = SecOTRFullIdentityCreateFromSecKeyRef(allocator, privateKey, &localError);
        require_quiet(myRef, errOut);
        
        CFReleaseNull(privateKey);
    
        publicKey = SOSPeerInfoCopyPubKey(peerInfo);
        
        peerRef = SecOTRPublicIdentityCreateFromSecKeyRef(allocator, publicKey, &localError);
        require_quiet(peerRef, errOut);
        
        coder->sessRef = SecOTRSessionCreateFromID(allocator, myRef, peerRef);

        require(coder->sessRef, errOut);
        
        coder->waitingForDataPacket = false;
        coder->pendingResponse = NULL;
        
        CFReleaseNull(publicKey);
        CFReleaseNull(privateKey);
        CFReleaseNull(myRef);
        CFReleaseNull(peerRef);
    } else {
        secnotice("coder", "NULL Coder requested, no transport security");
    }

    SOSCoderStart(coder, NULL);

    return coder;

errOut:
    secerror("Coder create failed: %@\n", localError ? localError : (CFTypeRef)CFSTR("No local error in SOSCoderCreate"));
    secerror("Coder create failed: %@\n", error ? *error : (CFTypeRef)CFSTR("WTF NULL?"));
    CFReleaseNull(myRef);
    CFReleaseNull(peerRef);
    CFReleaseNull(publicKey);
    CFReleaseNull(privateKey);

    free(coder);
    return NULL;
}
Example #2
0
// Return true (1) if the signature verifies.
static bool SOSPeerInfoVerify(SOSPeerInfoRef peer, CFErrorRef *error) {
    bool result = false;
    const struct ccdigest_info *di = ccsha256_di();
    uint8_t hbuf[di->output_size];

    SecKeyRef pubKey = SOSPeerInfoCopyPubKey(peer);
    require_action_quiet(pubKey, error_out,
                         SOSErrorCreate(kSOSErrorNoKey, error, NULL,
                                        CFSTR("Couldn't find pub key for %@"), peer));

    require_quiet(SOSDescriptionHash(peer, di, hbuf, error), error_out);

    require_action_quiet(sosVerifyHash(pubKey, di, hbuf, peer->signature), error_out,
                         SOSErrorCreate(kSOSErrorBadSignature, error, NULL,
                                        CFSTR("Signature didn't verify for %@"), peer));
    result = true;

error_out:
    CFReleaseNull(pubKey);
    return result;
}