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; }
// 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; }