/* Test basic add delete update copy matching stuff. */
static void tests(SecKeyDescriptor *descriptor)
{
    const uint8_t *keyData = (const uint8_t *)"abc";
    CFIndex keyDataLength = 3;
    SecKeyEncoding encoding = kSecKeyEncodingRaw;
    ok(customKey = SecKeyCreate(kCFAllocatorDefault,
        descriptor, keyData, keyDataLength, encoding),
        "create custom key");
    is(customKey, initedCustomKey, "CustomKeyInit got the right key");

    SecPadding padding = kSecPaddingPKCS1;
    const uint8_t *src = (const uint8_t *)"defgh";
    size_t srcLen = 5;
    uint8_t dst[5];
    size_t dstLen = 5;

    ok_status(SecKeyDecrypt(customKey, padding, src, srcLen, dst, &dstLen),
        "SecKeyDecrypt");
    ok_status(SecKeyEncrypt(customKey, padding, src, srcLen, dst, &dstLen),
        "SecKeyEncrypt");
    ok_status(SecKeyRawSign(customKey, padding, src, srcLen, dst, &dstLen),
        "SecKeyRawSign");
    ok_status(SecKeyRawVerify(customKey, padding, src, srcLen, dst, dstLen),
        "SecKeyRawVerify");
    is(SecKeyGetSize(customKey, kSecKeyKeySizeInBits), (size_t)5*8, "SecKeyGetSize");

    CFDictionaryRef attrDict = NULL;
    ok(attrDict = SecKeyCopyAttributeDictionary(customKey),
        "SecKeyCopyAttributeDictionary");
    CFReleaseNull(attrDict);

    CFDataRef pubdata = NULL;
    ok(SecKeyCopyPublicBytes(customKey, &pubdata) != 0, "SecKeyCopyPublicBytes");
    CFReleaseNull(pubdata);

    CFDataRef wrapped;
    wrapped = _SecKeyCopyWrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL);
    ok(wrapped == NULL, "_SecKeyCopyWrapKey");
    CFReleaseNull(wrapped);

    wrapped = _SecKeyCopyUnwrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL);
    ok(wrapped == NULL, "_SecKeyCopyUnwrapKey");
    CFReleaseNull(wrapped);

    //ok(SecKeyGeneratePair(customKey, ), "SecKeyGeneratePair");
    ok(SecKeyGetTypeID() != 0, "SecKeyGetTypeID works");

    if (customKey) {
        CFRelease(customKey);
        customKey = NULL;
    }
}
static void testkeywrap(unsigned long keySizeInBits, CFTypeRef alg)
{
    SecKeyRef pubKey = NULL, privKey = NULL;
    size_t keySizeInBytes = (keySizeInBits + 7) / 8;
    CFNumberRef kzib;
    int32_t keysz32 = (int32_t)keySizeInBits;

    CFUUIDRef ourUUID = CFUUIDCreate(kCFAllocatorDefault);
    CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, ourUUID);
    CFMutableStringRef publicName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);
    CFMutableStringRef privateName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, uuidString);

    CFReleaseNull(ourUUID);
    CFReleaseNull(uuidString);

    CFStringAppend(publicName, CFSTR("-Public-41"));
    CFStringAppend(privateName, CFSTR("-Private-41"));

    CFDictionaryRef pubd = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
                                                        kSecAttrLabel, publicName,
                                                        NULL);
    CFDictionaryRef privd = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
                                                         kSecAttrLabel, privateName,
                                                         NULL);

    CFReleaseNull(publicName);
    CFReleaseNull(privateName);

    kzib = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
    CFDictionaryRef kgp = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
                                                       kSecAttrKeyType, kSecAttrKeyTypeEC,
                                                       kSecAttrKeySizeInBits, kzib,
                                                       kSecAttrIsPermanent, kCFBooleanFalse,
                                                       kSecPublicKeyAttrs, pubd,
                                                       kSecPrivateKeyAttrs, privd,
                                                       NULL);
    CFReleaseNull(pubd);
    CFReleaseNull(privd);
    CFReleaseNull(kzib);

    OSStatus status;
    ok_status(status = SecKeyGeneratePair(kgp, &pubKey, &privKey),
              "Generate %ld bit (%ld byte) persistent RSA keypair (status = %d)",
              keySizeInBits, keySizeInBytes, (int)status);
    CFReleaseNull(kgp);

    CFErrorRef localError;

    CFDataRef secret = CFDataCreate(NULL, (void *)"0123456789012345", 16);
    ok(secret, "secret");

    CFDataRef fp = CFDataCreate(NULL, (void *)"01234567890123456789", 20);
    ok(fp, "fingerprint");


    int8_t sym_alg_data = 8;
    CFNumberRef symalg = CFNumberCreate(NULL, kCFNumberSInt8Type, &sym_alg_data);
    CFDictionaryRef param = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
                                                         _kSecKeyWrapPGPWrapAlg, alg,
                                                         _kSecKeyWrapPGPSymAlg, symalg,
                                                         _kSecKeyWrapPGPFingerprint, fp,
                                                         NULL);

    CFDataRef wrapped = _SecKeyCopyWrapKey(pubKey, kSecKeyWrapPublicKeyPGP, secret, param, NULL, &localError);
    ok(wrapped, "wrap key: %@", localError);

    CFDataRef unwrapped = _SecKeyCopyUnwrapKey(privKey, kSecKeyWrapPublicKeyPGP, wrapped, param, NULL, &localError);
    ok(unwrapped, "unwrap key: %@", localError);

    CFReleaseNull(symalg);

    ok(CFEqual(unwrapped, secret), "keys still same");

    CFReleaseNull(fp);
    CFReleaseNull(secret);
    CFReleaseNull(unwrapped);
    CFReleaseNull(wrapped);
    CFReleaseNull(param);
    CFReleaseNull(privKey);
    CFReleaseNull(pubKey);
}