#include "testclient.h"
#include "testutils.h"
void signWithRSA()
{
printf("* RSA key signing test\n");
CSP csp(gGuidAppleCSP);
ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
StringData data("To sign or not to sign, is that the question?");
CssmKey dummyKey; memset(&dummyKey, 0, sizeof(dummyKey));
CssmData nullData;
detail("Asking for RSA key generation");
KeyHandle publicKey, privateKey;
const CssmCryptoData seed(StringData("Seed ye well, my friend, and ye shall reap..."));
FakeContext genContext(CSSM_ALGCLASS_KEYGEN, CSSM_ALGID_RSA,
&::Context::Attr(CSSM_ATTRIBUTE_KEY_LENGTH, 512),
&::Context::Attr(CSSM_ATTRIBUTE_SEED, seed),
NULL);
CssmKey::Header pubHeader, privHeader;
ss.generateKey(noDb, genContext,
CSSM_KEYUSE_VERIFY, CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA,
CSSM_KEYUSE_SIGN, CSSM_KEYATTR_SENSITIVE,
NULL, NULL, publicKey, pubHeader, privateKey, privHeader);
detail("Key pair generated");
CssmKey cpk;
FakeContext wrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
ss.wrapKey(wrapContext, noKey, publicKey, &nullCred, NULL, cpk);
Key clearPublicKey(csp, cpk);
detail("Retrieved public key");
CssmKey clearPrivateKey;
try {
ss.wrapKey(wrapContext, noKey, privateKey, NULL, NULL, clearPrivateKey);
error("SecurityServer ACTUALLY gave us the PRIVATE key bits!");
} catch (CssmError &err) {
detail(err, "Private key retrieval properly rejected");
}
CssmData signature;
FakeContext signContext(CSSM_ALGCLASS_SIGNATURE, CSSM_ALGID_SHA1WithRSA,
&::Context::Attr(CSSM_ATTRIBUTE_KEY, dummyKey),
NULL);
ss.generateSignature(signContext, privateKey, data, signature);
detail("Signature generated by SecurityServer");
{
Verify verifier(csp, CSSM_ALGID_SHA1WithRSA);
verifier.key(clearPublicKey);
verifier.verify(data, signature);
detail("Signature verified locally");
}
ss.verifySignature(signContext, publicKey, data, signature);
detail("Signature verified by SecurityServer");
DataBuffer<200> falseData;
memcpy(falseData.data(), data.data(), data.length());
falseData.length(data.length());
((char *)falseData)[3] = '?'; try {
ss.verifySignature(signContext, publicKey, falseData, signature);
error("Altered message incorrectly verifies");
} catch (CssmError &err) {
if (err.cssmError() == CSSMERR_CSP_VERIFY_FAILED)
detail("Verify of altered message successfully failed");
else
error(err, "Unexpected exception on verify failure test");
}
}
void desEncryption()
{
printf("* DES encryption test\n");
ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
CSP csp(gGuidAppleCSP);
StringData clearText("Insert witty quotation here.");
StringData iv("abcdefgh");
StringData keyBits(strdup("Wallaby!"));
CssmKey keyForm(keyBits);
keyForm.header().KeyClass = CSSM_KEYCLASS_SESSION_KEY;
keyForm.header().BlobType = CSSM_KEYBLOB_RAW;
keyForm.header().AlgorithmId = CSSM_ALGID_DES;
keyForm.header().Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
Key key(csp, keyForm);
DataBuffer<200> localCipher;
Encrypt localCrypt(csp, CSSM_ALGID_DES);
localCrypt.mode(CSSM_ALGMODE_CBC_IV8);
localCrypt.padding(CSSM_PADDING_PKCS1);
localCrypt.initVector(iv);
localCrypt.key(key);
CssmData remData;
size_t localLen = localCrypt.encrypt(clearText, localCipher, remData);
if (remData)
error("LOCAL ENCRYPTION OVERFLOWED");
localCipher.length(localLen);
detail("Locally encrypted %ld bytes", localLen);
CssmData unwrappedData;
ResourceControlContext owner;
FakeContext unwrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
KeyHandle keyRef;
CssmKey::Header keyHeader;
ss.unwrapKey(noDb, unwrapContext, noKey, noKey,
key,
CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
CSSM_KEYATTR_RETURN_DEFAULT,
NULL, NULL, unwrappedData, keyRef, keyHeader);
detail("Placed key into SecurityServer; handle=%lx", keyRef);
const CssmKey &tKey = key;
FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
&::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
&::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
&::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
&::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
NULL);
CssmData remoteCipher;
ss.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
detail("Plaintext encrypted on SecurityServer");
if (remoteCipher == localCipher)
detail("Ciphertexts verified");
else
error("CIPHERTEXTS DIFFER");
DataBuffer<200> clearRecovered;
ss.decrypt(cryptoContext, keyRef, localCipher, clearRecovered);
detail("Decrypted ciphertext in SecurityServer");
if (clearRecovered == clearText)
detail("Plaintext recovered");
else
error("PLAINTEXT MISMATCH");
}