]> git.saurik.com Git - apple/security.git/blob - securityd/tests/testcrypto.cpp
Security-58286.260.20.tar.gz
[apple/security.git] / securityd / tests / testcrypto.cpp
1 /*
2 * Copyright (c) 2000-2001,2003-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 //
38 void 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 //
120 void 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