]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-23-key-export-symmetric.m
Security-57740.1.18.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 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
79 // Store in keychain
80 CFDictionarySetValue(parameters, kSecUseKeychain, keychainRef);
81 CFDictionarySetValue(parameters, kSecAttrApplicationLabel, label);
82 CFDictionarySetValue(parameters, kSecAttrLabel, label);
83
84
85 // Extractable and permanent
86 CFDictionarySetValue(parameters, kSecAttrIsExtractable, kCFBooleanTrue);
87 CFDictionarySetValue(parameters, kSecAttrIsPermanent, kCFBooleanTrue);
88
89
90 cryptokey = SecKeyGenerateSymmetric(parameters, &error);
91 is(error, NULL, "%s: SecKeyGenerateSymmetric: %s", testName, (error) ? CFStringGetCStringPtr(CFErrorCopyDescription(error), kCFStringEncodingUTF8) : "no error");
92 if (error) {
93 return NULL;
94 }
95
96 return cryptokey;
97 }
98
99 int kc_23_key_export_symmetric(int argc, char *const *argv)
100 {
101 plan_tests(6);
102 initializeKeychainTests(__FUNCTION__);
103
104 SecKeychainRef kc = getPopulatedTestKeychain();
105
106 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
107 SecKeyRef cryptokey;
108 OSStatus status;
109
110 CFStringRef label = (CFStringRef)([NSString stringWithFormat:@"Symmetric Cryptotest %ld %d", (long)time(NULL), arc4random(), nil]);
111 cryptokey = generateSymmetricKey(kc, label);
112
113 // Using SecItemExport
114 CFMutableArrayRef keyUsage = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
115 CFArrayAppendValue(keyUsage, kSecAttrCanEncrypt);
116 CFArrayAppendValue(keyUsage, kSecAttrCanDecrypt);
117 CFMutableArrayRef keyAttributes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
118 SecItemImportExportKeyParameters exportParams;
119 exportParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
120 exportParams.flags = 0;
121 exportParams.passphrase = NULL;
122 exportParams.alertTitle = NULL;
123 exportParams.alertPrompt = NULL;
124 exportParams.accessRef = NULL;
125 exportParams.keyUsage = keyUsage;
126 exportParams.keyAttributes = keyAttributes;
127 CFDataRef exportedKey2;
128 status = SecItemExport(cryptokey, kSecFormatRawKey, 0, &exportParams, (CFDataRef *)&exportedKey2);
129 ok_status(status, "%s: SecItemExport", testName);
130
131 is(CFDataGetLength(exportedKey2), 32, "%s: wrong AES-256 key size", testName);
132
133 CFRelease(exportedKey2);
134
135 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", testName);
136 CFReleaseNull(kc);
137
138 [pool drain];
139
140 deleteTestFiles();
141 return 0;
142 }