static void tests(void)
{
    SOSCircleRef circle = SOSCircleCreate(NULL, CFSTR("TEST DOMAIN"), NULL);
    
    ok(NULL != circle, "Circle creation");

    ok(0 == SOSCircleCountPeers(circle), "Zero peers");

    //SecKeyRef publicKey = NULL;
    SecKeyRef dev_a_key = NULL;
    SecKeyRef dev_b_key = NULL;
    CFErrorRef error = NULL;
    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
    
    if(cfpassword == NULL) printf("WTF\n");
    
    CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
    ok(parameters, "No parameters!");
    ok(error == NULL, "Error: (%@)", error);
    CFReleaseNull(error);

    SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
    CFReleaseNull(parameters);

    SOSFullPeerInfoRef peer_a_full_info = SOSCreateFullPeerInfoFromName(CFSTR("Peer A"), &dev_a_key, NULL);
    
    SOSFullPeerInfoRef peer_b_full_info = SOSCreateFullPeerInfoFromName(CFSTR("Peer B"), &dev_b_key, NULL);
    
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));

    ok(SOSCircleAcceptRequest(circle, user_privkey, peer_a_full_info, SOSFullPeerInfoGetPeerInfo(peer_a_full_info), NULL));
    
    ok(!SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_b_full_info, NULL));
    
    ok(SOSCircleCountPeers(circle) == 1, "Peer count");

    size_t size = SOSCircleGetDEREncodedSize(circle, &error);
    uint8_t buffer[size];
    uint8_t* start = SOSCircleEncodeToDER(circle, &error, buffer, buffer + sizeof(buffer));
    
    ok(start, "successful encoding");
    ok(start == buffer, "Used whole buffer");
    
    const uint8_t *der = buffer;
    SOSCircleRef inflated = SOSCircleCreateFromDER(NULL, &error, &der, buffer + sizeof(buffer));
    
    ok(inflated, "inflated");
    ok(CFEqualSafe(inflated, circle), "Compares");
    
    
    ok(SOSCircleRemovePeer(circle, user_privkey, peer_a_full_info, SOSFullPeerInfoGetPeerInfo(peer_a_full_info), NULL));
    ok(SOSCircleCountPeers(circle) == 0, "Peer count");
    
    CFReleaseNull(dev_a_key);
    CFReleaseNull(cfpassword);
}
static void tests(void)
{
    CFErrorRef error = NULL;
    CFDataRef testData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)testbytes, testbytes_size, kCFAllocatorNull);

    SecCertificateRef cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, public_cert_der, sizeof(public_cert_der));
    CFArrayRef certInArray = CFArrayCreateForCFTypes(kCFAllocatorDefault, cert, NULL);

    SecKeyRef full_key = SecKeyCreateECPrivateKey(kCFAllocatorDefault, private_key_der, sizeof(private_key_der), kSecKeyEncodingPkcs1);

    SecTrustRef trust = NULL;
    SecPolicyRef basic = SecPolicyCreateBasicX509();
    OSStatus status = SecTrustCreateWithCertificates(cert, basic, &trust);
    ok_status(status, "created");
    CFReleaseNull(basic);
    status = SecTrustSetAnchorCertificates(trust, certInArray);
    ok_status(status, "Anchors");

    SecTrustResultType result;
    status = SecTrustEvaluate(trust, &result);
    ok_status(status, "Trust evaluation");
    is(result, (SecTrustResultType)kSecTrustResultUnspecified, "Trust result");

    CFDataRef encrypted = SecCopyEncryptedToServer(trust, testData, &error);
    ok(encrypted != NULL, "Encrypt to server (%@)", error);
    CFReleaseNull(error);

    ok(!CFEqualSafe(testData, encrypted), "encrypted different");

    CFDataRef decrypted = SecCopyDecryptedForServer(full_key, encrypted, &error);
    ok(decrypted != NULL, "Decrypt from server (%@)", error);
    ok(CFEqualSafe(testData, decrypted), "round trip");


    CFReleaseNull(cert);
    CFReleaseNull(certInArray);
    CFReleaseNull(trust);
    CFReleaseNull(testData);
    CFReleaseNull(encrypted);
    CFReleaseNull(decrypted);
}
static bool SOSAccountIsThisPeerIDMe(SOSAccountRef account, CFStringRef peerID) {
    SOSPeerInfoRef mypi = SOSFullPeerInfoGetPeerInfo(account->my_identity);
    CFStringRef myPeerID = SOSPeerInfoGetPeerID(mypi);
    
    return myPeerID && CFEqualSafe(myPeerID, peerID);
}
static void tests(void)
{
    SecKeyRef publicKey = NULL;
   
    CFErrorRef error = NULL;

    SOSCircleRef circle = SOSCircleCreate(NULL, CFSTR("Test Circle"), &error);
    
    CFStringRef circle_key = SOSCircleKeyCreateWithCircle(circle, NULL);

    CFStringRef circle_name = NULL;
    ok(circle_key, "Circle key created");
    is(SOSKVSKeyGetKeyType(circle_key), kCircleKey, "Is circle key");
    is(SOSKVSKeyGetKeyTypeAndParse(circle_key, &circle_name, NULL, NULL, NULL, NULL, NULL), kCircleKey, "Is circle key, extract name");
    ok(circle_name, "Circle name extracted");
    ok(CFEqualSafe(circle_name, SOSCircleGetName(circle)), "Circle name matches '%@' '%@'", circle_name, SOSCircleGetName(circle));
    CFReleaseNull(circle_name);
    CFReleaseNull(circle_key);
    
    SOSPeerInfoRef pi = SOSCreatePeerInfoFromName(CFSTR("Test Peer"), &publicKey, &error);
    
    CFStringRef other_peer_id = CFSTR("OTHER PEER");
    
    CFStringRef messageKey = SOSMessageKeyCreateWithCircleAndPeerNames(circle, SOSPeerInfoGetPeerID(pi), other_peer_id);
    
    ok(messageKey, "Getting message key '%@'", messageKey);
    
    CFStringRef message_circle_name = NULL;
    CFStringRef message_from_peer_id = NULL;
    CFStringRef message_to_peer_id = NULL;
    CFStringRef message_ring = NULL;
    CFStringRef message_peer_info = NULL;
    CFStringRef message_backup = NULL;
    
    is(SOSKVSKeyGetKeyType(messageKey), kMessageKey, "Is message key");
    is(SOSKVSKeyGetKeyTypeAndParse(messageKey,
                                   &message_circle_name,
                                   &message_peer_info,
                                   &message_ring,
                                   &message_backup,
                                   &message_from_peer_id,
                                   &message_to_peer_id), kMessageKey, "Is message key, extract parts");
    
    
    ok(CFEqualSafe(SOSCircleGetName(circle), message_circle_name), "circle key matches in message (%@ v %@)",SOSCircleGetName(circle), message_circle_name);

    
    ok(CFEqualSafe(SOSPeerInfoGetPeerID(pi), message_from_peer_id), "from peer set correctly (%@ v %@)", SOSPeerInfoGetPeerID(pi), message_from_peer_id);
    
    ok(CFEqualSafe(other_peer_id, message_to_peer_id), "to peer set correctly (%@ v %@)", other_peer_id, message_to_peer_id);
    
    CFStringRef retirementKey = SOSRetirementKeyCreateWithCircleAndPeer(circle, SOSPeerInfoGetPeerID(pi));
    CFStringRef retirement_circle_name = NULL;
    CFStringRef retirement_peer_id = NULL;
    
    is(SOSKVSKeyGetKeyType(retirementKey), kRetirementKey, "Is retirement key");
    is(SOSKVSKeyGetKeyTypeAndParse(retirementKey,
                                   &retirement_circle_name,
                                   NULL,
                                   NULL,
                                   NULL,
                                   &retirement_peer_id,
                                   NULL), kRetirementKey, "Is retirement key, extract parts");
    CFReleaseSafe(retirementKey);
    ok(CFEqualSafe(SOSCircleGetName(circle), retirement_circle_name), "circle key matches in retirement (%@ v %@)",
       SOSCircleGetName(circle), retirement_circle_name);
    ok(CFEqualSafe(SOSPeerInfoGetPeerID(pi), retirement_peer_id), "retirement peer set correctly (%@ v %@)",
       SOSPeerInfoGetPeerID(pi), retirement_peer_id);
    
    CFReleaseNull(publicKey);
    CFReleaseNull(circle);
    CFReleaseNull(error);
    CFReleaseNull(pi);
    CFReleaseNull(messageKey);
    CFReleaseNull(message_circle_name);
    CFReleaseNull(message_from_peer_id);
    CFReleaseNull(message_to_peer_id);
    CFReleaseNull(retirement_circle_name);
    CFReleaseNull(retirement_peer_id);

}
bool SOSRecoveryKeyBagDSIDIs(SOSRecoveryKeyBagRef rkbg, CFStringRef dsid) {
    if(!rkbg) return false;
    return CFEqualSafe(rkbg->accountDSID, dsid);
}