1/*
2 * Copyright (c) 2007-2008,2010,2012-2014 Apple 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#include <CoreFoundation/CoreFoundation.h>
26#include <Security/SecKeyPriv.h>
27
28#include "Security_regressions.h"
29
30#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) {  (CF) = NULL; CFRelease(_cf); } }
31
32static SecKeyRef customKey;
33static SecKeyRef initedCustomKey;
34
35static OSStatus CustomKeyInit(SecKeyRef key, const uint8_t *key_data,
36    CFIndex key_len, SecKeyEncoding encoding)
37{
38    ok(key, "CustomKeyInit");
39    ok(key && key->key == NULL, "key->key is NULL");
40    initedCustomKey = key;
41    return errSecSuccess;
42}
43
44static void CustomKeyDestroy(SecKeyRef key)
45{
46    is(customKey, key, "CustomKeyDestroy");
47}
48
49static OSStatus CustomKeyRawSign(SecKeyRef key, SecPadding padding,
50	const uint8_t *dataToSign, size_t dataToSignLen,
51	uint8_t *sig, size_t *sigLen)
52{
53    is(customKey, key, "CustomKeyRawSign");
54    return errSecSuccess;
55}
56
57static OSStatus CustomKeyRawVerify(
58    SecKeyRef key, SecPadding padding, const uint8_t *signedData,
59    size_t signedDataLen, const uint8_t *sig, size_t sigLen)
60{
61    is(customKey, key, "CustomKeyRawVerify");
62    return errSecSuccess;
63}
64
65static OSStatus CustomKeyEncrypt(SecKeyRef key, SecPadding padding,
66    const uint8_t *plainText, size_t plainTextLen,
67	uint8_t *cipherText, size_t *cipherTextLen)
68{
69    is(customKey, key, "CustomKeyEncrypt");
70    return errSecSuccess;
71}
72
73static OSStatus CustomKeyDecrypt(SecKeyRef key, SecPadding padding,
74    const uint8_t *cipherText, size_t cipherTextLen,
75    uint8_t *plainText, size_t *plainTextLen)
76{
77    is(customKey, key, "CustomKeyDecrypt");
78    return errSecSuccess;
79}
80
81static OSStatus CustomKeyCompute(SecKeyRef key,
82    const uint8_t *pub_key, size_t pub_key_len,
83    uint8_t *computed_key, size_t *computed_key_len)
84{
85    is(customKey, key, "CustomKeyCompute");
86    return errSecSuccess;
87}
88
89static size_t CustomKeyBlockSize(SecKeyRef key)
90{
91    is(customKey, key, "CustomKeyBlockSize");
92    return 42;
93}
94
95static CFDictionaryRef CustomKeyCopyAttributeDictionary(SecKeyRef key)
96{
97    is(customKey, key, "CustomKeyCopyAttributeDictionary");
98    CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL,
99        0, NULL, NULL);
100    return dict;
101}
102
103static CFStringRef CustomKeyCopyDescribe(SecKeyRef key)
104{
105    return CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), key->key_class->name);
106}
107
108
109SecKeyDescriptor kCustomKeyDescriptor_version0 = {
110    0,
111    "CustomKeyVersion0",
112    0, /* extraBytes */
113    CustomKeyInit,
114    CustomKeyDestroy,
115    CustomKeyRawSign,
116    CustomKeyRawVerify,
117    CustomKeyEncrypt,
118    CustomKeyDecrypt,
119    CustomKeyCompute,
120    CustomKeyBlockSize,
121    CustomKeyCopyAttributeDictionary,
122    CustomKeyCopyDescribe,
123    (void *)abort,
124    (void *)abort,
125    (void *)abort,
126    (void *)abort,
127};
128
129SecKeyDescriptor kCustomKeyDescriptor_version1 = {
130    1,
131    "CustomKeyVersion1",
132    0, /* extraBytes */
133    CustomKeyInit,
134    CustomKeyDestroy,
135    CustomKeyRawSign,
136    CustomKeyRawVerify,
137    CustomKeyEncrypt,
138    CustomKeyDecrypt,
139    CustomKeyCompute,
140    CustomKeyBlockSize,
141    CustomKeyCopyAttributeDictionary,
142    CustomKeyCopyDescribe,
143    NULL,
144    (void *)abort,
145    (void *)abort,
146    (void *)abort,
147};
148
149SecKeyDescriptor kCustomKeyDescriptor_version2 = {
150    2,
151    "CustomKeyVersion2",
152    0, /* extraBytes */
153    CustomKeyInit,
154    CustomKeyDestroy,
155    CustomKeyRawSign,
156    CustomKeyRawVerify,
157    CustomKeyEncrypt,
158    CustomKeyDecrypt,
159    CustomKeyCompute,
160    CustomKeyBlockSize,
161    CustomKeyCopyAttributeDictionary,
162    CustomKeyCopyDescribe,
163    NULL,
164    NULL,
165    (void *)abort,
166    (void *)abort,
167};
168
169SecKeyDescriptor kCustomKeyDescriptor_version3 = {
170    3,
171    "CustomKeyVersion3",
172    0, /* extraBytes */
173    CustomKeyInit,
174    CustomKeyDestroy,
175    CustomKeyRawSign,
176    CustomKeyRawVerify,
177    CustomKeyEncrypt,
178    CustomKeyDecrypt,
179    CustomKeyCompute,
180    CustomKeyBlockSize,
181    CustomKeyCopyAttributeDictionary,
182    CustomKeyCopyDescribe,
183    NULL,
184    NULL,
185    NULL,
186    NULL,
187};
188
189/* Test basic add delete update copy matching stuff. */
190static void tests(SecKeyDescriptor *descriptor)
191{
192    const uint8_t *keyData = (const uint8_t *)"abc";
193    CFIndex keyDataLength = 3;
194    SecKeyEncoding encoding = kSecKeyEncodingRaw;
195    ok(customKey = SecKeyCreate(kCFAllocatorDefault,
196        descriptor, keyData, keyDataLength, encoding),
197        "create custom key");
198    is(customKey, initedCustomKey, "CustomKeyInit got the right key");
199
200    SecPadding padding = kSecPaddingPKCS1;
201    const uint8_t *src = NULL;
202    size_t srcLen = 3;
203    uint8_t *dst = NULL;
204    size_t dstLen = 3;
205
206    ok_status(SecKeyDecrypt(customKey, padding, src, srcLen, dst, &dstLen),
207        "SecKeyDecrypt");
208    ok_status(SecKeyEncrypt(customKey, padding, src, srcLen, dst, &dstLen),
209        "SecKeyEncrypt");
210    ok_status(SecKeyRawSign(customKey, padding, src, srcLen, dst, &dstLen),
211        "SecKeyRawSign");
212    ok_status(SecKeyRawVerify(customKey, padding, src, srcLen, dst, dstLen),
213        "SecKeyRawVerify");
214    is(SecKeyGetSize(customKey, kSecKeyKeySizeInBits), (size_t)42*8, "SecKeyGetSize");
215
216    CFDictionaryRef attrDict = NULL;
217    ok(attrDict = SecKeyCopyAttributeDictionary(customKey),
218        "SecKeyCopyAttributeDictionary");
219    CFReleaseNull(attrDict);
220
221    CFDataRef pubdata = NULL;
222    ok(SecKeyCopyPublicBytes(customKey, &pubdata) != 0, "SecKeyCopyPublicBytes");
223    CFReleaseNull(pubdata);
224
225    CFDataRef wrapped;
226    wrapped = _SecKeyCopyWrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL);
227    ok(wrapped == NULL, "_SecKeyCopyWrapKey");
228    CFReleaseNull(wrapped);
229
230    wrapped = _SecKeyCopyUnwrapKey(customKey, kSecKeyWrapPublicKeyPGP, pubdata, NULL, NULL, NULL);
231    ok(wrapped == NULL, "_SecKeyCopyUnwrapKey");
232    CFReleaseNull(wrapped);
233
234    //ok(SecKeyGeneratePair(customKey, ), "SecKeyGeneratePair");
235    ok(SecKeyGetTypeID() != 0, "SecKeyGetTypeID works");
236
237    if (customKey) {
238        CFRelease(customKey);
239        customKey = NULL;
240    }
241}
242
243int si_40_seckey_custom(int argc, char *const *argv)
244{
245	plan_tests(21 * 4);
246
247	tests(&kCustomKeyDescriptor_version0);
248	tests(&kCustomKeyDescriptor_version1);
249	tests(&kCustomKeyDescriptor_version2);
250	tests(&kCustomKeyDescriptor_version3);
251
252	return 0;
253}
254