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