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