]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-23-key-export-symmetric.m
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / regressions / kc-23-key-export-symmetric.m
1 /*
2 * Copyright (c) 2016 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 xLicense.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #import <Security/Security.h>
25
26 #include "keychain_regressions.h"
27 #include "kc-helpers.h"
28
29 #import <Cocoa/Cocoa.h>
30 #import <Security/SecTransform.h>
31 #import <Security/SecItemPriv.h>
32 #import <Security/CMSEncoder.h>
33 #import <Security/CMSDecoder.h>
34 #import <Foundation/NSData_Private.h>
35 #import <SecurityFoundation/SFCertificateAuthority.h>
36 #import <SecurityFoundation/SFCertificateAuthorityPriv.h>
37 #import <SecurityFoundation/CACertInfo.h>
38 #import <SecurityFoundation/CAKeyUsageExtension.h>
39 #import <SecurityFoundation/CAExtendedKeyUsageExtension.h>
40
41 #if 0
42 static void checkCryptoError(OSStatus status, NSString *functionName) {
43 if (status != errSecSuccess) {
44 NSError *underlyingError = [[NSError alloc] initWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
45 NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:underlyingError, NSUnderlyingErrorKey, nil];
46
47 [underlyingError release];
48
49 CFStringRef message = SecCopyErrorMessageString(status, NULL);
50
51 NSLog(@"%@ failed with error %d: %@: %@: %@", functionName, (int)status, underlyingError, userInfo, message);
52
53 CFRelease(message);
54
55 cssmPerror([functionName UTF8String], status);
56
57 exit(EXIT_FAILURE);
58 }
59 }
60 #endif
61
62 static CF_RETURNS_RETAINED SecKeyRef generateSymmetricKey(SecKeychainRef keychainRef, CFStringRef label)
63 {
64 CFMutableDictionaryRef parameters;
65 int32_t rawnum;
66 CFNumberRef num;
67 CFErrorRef error = NULL;
68 SecKeyRef cryptokey;
69
70 rawnum = 256;
71
72 // Type
73 parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
74 CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);
75
76 num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &rawnum);
77 CFDictionarySetValue(parameters, kSecAttrKeySizeInBits, num);
78 CFReleaseNull(num);
79
80 // Store in keychain
81 CFDictionarySetValue(parameters, kSecUseKeychain, keychainRef);
82 CFDictionarySetValue(parameters, kSecAttrApplicationLabel, label);
83 CFDictionarySetValue(parameters, kSecAttrLabel, label);
84
85
86 // Extractable and permanent
87 CFDictionarySetValue(parameters, kSecAttrIsExtractable, kCFBooleanTrue);
88 CFDictionarySetValue(parameters, kSecAttrIsPermanent, kCFBooleanTrue);
89
90
91 cryptokey = SecKeyGenerateSymmetric(parameters, &error);
92 is(error, NULL, "%s: SecKeyGenerateSymmetric: %s", testName, (error) ? CFStringGetCStringPtr(CFErrorCopyDescription(error), kCFStringEncodingUTF8) : "no error");
93 if (error) {
94 return NULL;
95 }
96
97 return cryptokey;
98 }
99
100 int kc_23_key_export_symmetric(int argc, char *const *argv)
101 {
102 plan_tests(6);
103 initializeKeychainTests(__FUNCTION__);
104
105 SecKeychainRef kc = getPopulatedTestKeychain();
106
107 SecKeyRef cryptokey;
108 OSStatus status;
109
110 CFStringRef label = (__bridge_retained CFStringRef)([NSString stringWithFormat:@"Symmetric Cryptotest %ld %d", (long)time(NULL), arc4random(), nil]);
111 cryptokey = generateSymmetricKey(kc, label);
112 CFReleaseNull(label);
113
114 // Using SecItemExport
115 CFMutableArrayRef keyUsage = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
116 CFArrayAppendValue(keyUsage, kSecAttrCanEncrypt);
117 CFArrayAppendValue(keyUsage, kSecAttrCanDecrypt);
118 CFMutableArrayRef keyAttributes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
119 SecItemImportExportKeyParameters exportParams;
120 exportParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
121 exportParams.flags = 0;
122 exportParams.passphrase = NULL;
123 exportParams.alertTitle = NULL;
124 exportParams.alertPrompt = NULL;
125 exportParams.accessRef = NULL;
126 exportParams.keyUsage = keyUsage;
127 exportParams.keyAttributes = keyAttributes;
128 CFDataRef exportedKey2;
129 status = SecItemExport(cryptokey, kSecFormatRawKey, 0, &exportParams, (CFDataRef *)&exportedKey2);
130 ok_status(status, "%s: SecItemExport", testName);
131
132 CFReleaseNull(cryptokey);
133
134 is(CFDataGetLength(exportedKey2), 32, "%s: wrong AES-256 key size", testName);
135
136 CFRelease(exportedKey2);
137
138 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", testName);
139 CFReleaseNull(kc);
140
141 deleteTestFiles();
142 return 0;
143 }