1/* 2 * Copyright (c) 2000-2001,2004 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// Tester - test driver for securityserver client side. 27// 28#include "testclient.h" 29#include "testutils.h" 30 31 32// 33// Simple run-through. 34// This generates an RSA key, tests cleartext retrieval, signs a message, 35// and veries it both ways. 36// This is a basic integrity regression for the SecurityServer. 37// 38void signWithRSA() 39{ 40 printf("* RSA key signing test\n"); 41 CSP csp(gGuidAppleCSP); 42 ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard()); 43 StringData data("To sign or not to sign, is that the question?"); 44 45 // set up dummy credentials 46 CssmKey dummyKey; memset(&dummyKey, 0, sizeof(dummyKey)); 47 CssmData nullData; 48 49 // generate a key 50 detail("Asking for RSA key generation"); 51 KeyHandle publicKey, privateKey; 52 const CssmCryptoData seed(StringData("Seed ye well, my friend, and ye shall reap...")); 53 FakeContext genContext(CSSM_ALGCLASS_KEYGEN, CSSM_ALGID_RSA, 54 &::Context::Attr(CSSM_ATTRIBUTE_KEY_LENGTH, 512), 55 &::Context::Attr(CSSM_ATTRIBUTE_SEED, seed), 56 NULL); 57 CssmKey::Header pubHeader, privHeader; 58 ss.generateKey(noDb, genContext, 59 CSSM_KEYUSE_VERIFY, CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_DATA, 60 CSSM_KEYUSE_SIGN, CSSM_KEYATTR_SENSITIVE, 61 NULL/*cred*/, NULL/*owner*/, publicKey, pubHeader, privateKey, privHeader); 62 detail("Key pair generated"); 63 64 // retrieve the public key 65 CssmKey cpk; 66 FakeContext wrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0); 67 ss.wrapKey(wrapContext, noKey, publicKey, &nullCred, NULL, cpk); 68 Key clearPublicKey(csp, cpk); 69 detail("Retrieved public key"); 70 71 // make sure we can't retrieve the private key 72 CssmKey clearPrivateKey; 73 try { 74 ss.wrapKey(wrapContext, noKey, privateKey, NULL/*cred*/, NULL, clearPrivateKey); 75 error("SecurityServer ACTUALLY gave us the PRIVATE key bits!"); 76 } catch (CssmError &err) { 77 detail(err, "Private key retrieval properly rejected"); 78 } 79 80 // sign a message 81 CssmData signature; 82 FakeContext signContext(CSSM_ALGCLASS_SIGNATURE, CSSM_ALGID_SHA1WithRSA, 83 &::Context::Attr(CSSM_ATTRIBUTE_KEY, dummyKey), 84 NULL); 85 ss.generateSignature(signContext, privateKey, data, signature); 86 detail("Signature generated by SecurityServer"); 87 88 // verify the signature (local) 89 { 90 Verify verifier(csp, CSSM_ALGID_SHA1WithRSA); 91 verifier.key(clearPublicKey); 92 verifier.verify(data, signature); 93 detail("Signature verified locally"); 94 } 95 96 // verify the signature (SS) 97 ss.verifySignature(signContext, publicKey, data, signature); 98 detail("Signature verified by SecurityServer"); 99 100 // falsify the signature (SS) 101 DataBuffer<200> falseData; 102 memcpy(falseData.data(), data.data(), data.length()); 103 falseData.length(data.length()); 104 ((char *)falseData)[3] = '?'; // alter message 105 try { 106 ss.verifySignature(signContext, publicKey, falseData, signature); 107 error("Altered message incorrectly verifies"); 108 } catch (CssmError &err) { 109 if (err.cssmError() == CSSMERR_CSP_VERIFY_FAILED) 110 detail("Verify of altered message successfully failed"); 111 else 112 error(err, "Unexpected exception on verify failure test"); 113 } 114} 115 116 117// 118// Encrypt with DES 119// 120void desEncryption() 121{ 122 printf("* DES encryption test\n"); 123 ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard()); 124 CSP csp(gGuidAppleCSP); 125 126 StringData clearText("Insert witty quotation here."); 127 StringData iv("abcdefgh"); 128 129 // make up a DES key 130 StringData keyBits(strdup("Wallaby!")); 131 CssmKey keyForm(keyBits); 132 keyForm.header().KeyClass = CSSM_KEYCLASS_SESSION_KEY; 133 keyForm.header().BlobType = CSSM_KEYBLOB_RAW; 134 keyForm.header().AlgorithmId = CSSM_ALGID_DES; 135 keyForm.header().Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING; 136 Key key(csp, keyForm); 137 138 // encrypt locally 139 DataBuffer<200> localCipher; 140 Encrypt localCrypt(csp, CSSM_ALGID_DES); 141 localCrypt.mode(CSSM_ALGMODE_CBC_IV8); 142 localCrypt.padding(CSSM_PADDING_PKCS1); 143 localCrypt.initVector(iv); 144 localCrypt.key(key); 145 CssmData remData; 146 size_t localLen = localCrypt.encrypt(clearText, localCipher, remData); 147 if (remData) 148 error("LOCAL ENCRYPTION OVERFLOWED"); 149 localCipher.length(localLen); 150 detail("Locally encrypted %ld bytes", localLen); 151 152 // wrap in the key 153 CssmData unwrappedData; 154 ResourceControlContext owner; 155 FakeContext unwrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0); 156 KeyHandle keyRef; 157 CssmKey::Header keyHeader; 158 ss.unwrapKey(noDb, unwrapContext, noKey, noKey, 159 key, 160 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT, 161 CSSM_KEYATTR_RETURN_DEFAULT, 162 NULL/*cred*/, NULL/*owner*/, unwrappedData, keyRef, keyHeader); 163 detail("Placed key into SecurityServer; handle=%lx", keyRef); 164 165 // encrypt remotely and compare 166 const CssmKey &tKey = key; 167 FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES, 168 &::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm), 169 &::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv), 170 &::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8), 171 &::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1), 172 NULL); 173 CssmData remoteCipher; 174 ss.encrypt(cryptoContext, keyRef, clearText, remoteCipher); 175 detail("Plaintext encrypted on SecurityServer"); 176 if (remoteCipher == localCipher) 177 detail("Ciphertexts verified"); 178 else 179 error("CIPHERTEXTS DIFFER"); 180 181 // decrypt in SecurityServer 182 DataBuffer<200> clearRecovered; 183 ss.decrypt(cryptoContext, keyRef, localCipher, clearRecovered); 184 detail("Decrypted ciphertext in SecurityServer"); 185 if (clearRecovered == clearText) 186 detail("Plaintext recovered"); 187 else 188 error("PLAINTEXT MISMATCH"); 189} 190 191