]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-26-key-import-public.m
Security-57740.31.2.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / regressions / kc-26-key-import-public.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 #import <Security/SecCertificatePriv.h>
26
27 #include "keychain_regressions.h"
28 #include "kc-helpers.h"
29
30 #pragma clang diagnostic push
31 #pragma clang diagnostic ignored "-Wunused-variable"
32 #pragma clang diagnostic ignored "-Wunused-function"
33
34 //
35 // testPubKeyImport
36 // <rdar://problem/10473567>
37 //
38
39 #import <Foundation/Foundation.h>
40 #import <Security/Security.h>
41
42 #include <libDER/asn1Types.h>
43 #include <libDER/DER_Encode.h>
44 #include <libDER/DER_Decode.h>
45 #include <libDER/DER_Keys.h>
46
47
48 /* test RSA public key to import */
49 static const uint8_t kPublicKey[] =
50 {
51 0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE7,0xD7,0x44,0xF2,0xA2,0xE2,0x78,
52 0x8B,0x6C,0x1F,0x55,0xA0,0x8E,0xB7,0x05,0x44,0xA8,0xFA,0x79,0x45,0xAA,0x8B,0xE6,
53 0xC6,0x2C,0xE5,0xF5,0x1C,0xBD,0xD4,0xDC,0x68,0x42,0xFE,0x3D,0x10,0x83,0xDD,0x2E,
54 0xDE,0xC1,0xBF,0xD4,0x25,0x2D,0xC0,0x2E,0x6F,0x39,0x8B,0xDF,0x0E,0x61,0x48,0xEA,
55 0x84,0x85,0x5E,0x2E,0x44,0x2D,0xA6,0xD6,0x26,0x64,0xF6,0x74,0xA1,0xF3,0x04,0x92,
56 0x9A,0xDE,0x4F,0x68,0x93,0xEF,0x2D,0xF6,0xE7,0x11,0xA8,0xC7,0x7A,0x0D,0x91,0xC9,
57 0xD9,0x80,0x82,0x2E,0x50,0xD1,0x29,0x22,0xAF,0xEA,0x40,0xEA,0x9F,0x0E,0x14,0xC0,
58 0xF7,0x69,0x38,0xC5,0xF3,0x88,0x2F,0xC0,0x32,0x3D,0xD9,0xFE,0x55,0x15,0x5F,0x51,
59 0xBB,0x59,0x21,0xC2,0x01,0x62,0x9F,0xD7,0x33,0x52,0xD5,0xE2,0xEF,0xAA,0xBF,0x9B,
60 0xA0,0x48,0xD7,0xB8,0x13,0xA2,0xB6,0x76,0x7F,0x6C,0x3C,0xCF,0x1E,0xB4,0xCE,0x67,
61 0x3D,0x03,0x7B,0x0D,0x2E,0xA3,0x0C,0x5F,0xFF,0xEB,0x06,0xF8,0xD0,0x8A,0xDD,0xE4,
62 0x09,0x57,0x1A,0x9C,0x68,0x9F,0xEF,0x10,0x72,0x88,0x55,0xDD,0x8C,0xFB,0x9A,0x8B,
63 0xEF,0x5C,0x89,0x43,0xEF,0x3B,0x5F,0xAA,0x15,0xDD,0xE6,0x98,0xBE,0xDD,0xF3,0x59,
64 0x96,0x03,0xEB,0x3E,0x6F,0x61,0x37,0x2B,0xB6,0x28,0xF6,0x55,0x9F,0x59,0x9A,0x78,
65 0xBF,0x50,0x06,0x87,0xAA,0x7F,0x49,0x76,0xC0,0x56,0x2D,0x41,0x29,0x56,0xF8,0x98,
66 0x9E,0x18,0xA6,0x35,0x5B,0xD8,0x15,0x97,0x82,0x5E,0x0F,0xC8,0x75,0x34,0x3E,0xC7,
67 0x82,0x11,0x76,0x25,0xCD,0xBF,0x98,0x44,0x7B,0x02,0x03,0x01,0x00,0x01,0xD4,0x9D
68 };
69
70 #if 0
71 static const uint8_t k512PublicKeyModulus[] =
72 {
73 0x00,
74 0xE2,0x7E,0x6C,0xDE,0xF4,0x45,0x8E,0x69,0xFF,0x9B,0x39,0x76,0x41,0x44,0x2E,0x2E,
75 0x61,0x27,0x07,0x0F,0x56,0xC9,0x6F,0x3F,0x71,0x82,0x67,0x1F,0xEB,0x0B,0xED,0x65,
76 0x09,0x9B,0x12,0x29,0x61,0x1D,0x66,0x3B,0x8C,0x63,0x0F,0x30,0x5C,0x00,0x42,0x85,
77 0x6F,0xD5,0xFB,0xF5,0x3D,0x63,0x99,0xC1,0xDE,0xD7,0x42,0x30,0x51,0x42,0xF3,0xD9
78 };
79
80 static const uint8_t k512PublicKeyExponent[] = { 0x01,0x00,0x01 }; // 65537
81 #endif
82
83 static const uint8_t k1024PublicKeyModulus[] =
84 {
85 0x00,
86 0xBF,0x53,0x5F,0x27,0x26,0x28,0xD1,0x02,0x52,0x75,0x54,0xFB,0x5F,0xF1,0xBE,0x94,
87 0xB0,0x3B,0x33,0xB0,0x36,0xF6,0xF8,0x14,0xB9,0x62,0xEC,0xFC,0x31,0xF2,0xAB,0x60,
88 0x59,0x02,0xB7,0x68,0x6C,0x91,0x91,0x9E,0xE8,0x08,0xF0,0x49,0xD9,0xBD,0x24,0x5A,
89 0xB9,0xD6,0x08,0x89,0xA0,0xF1,0xBC,0xC7,0xB4,0x55,0xB5,0x0E,0x1A,0xA5,0xCC,0x94,
90 0x4E,0x57,0xB6,0xA9,0x6B,0x5C,0x90,0x28,0x6F,0xBD,0x8C,0x12,0xF9,0x59,0x5E,0x47,
91 0xDB,0x4C,0x7F,0x4D,0xB8,0x12,0x0A,0x36,0x9B,0x6F,0x8B,0xCC,0xB3,0x0F,0x60,0x23,
92 0xED,0x91,0x78,0x28,0x0A,0x5E,0xF4,0x24,0xC6,0xDD,0x80,0x50,0xC4,0xCD,0xF6,0x52,
93 0x6B,0xDD,0x35,0x82,0xCE,0xF2,0x7B,0xA4,0x73,0xD9,0x5F,0x75,0x2D,0xB6,0x77,0xAD
94 };
95
96 static const uint8_t k1024PublicKeyExponent[] = { 0x01,0x00,0x01 }; // 65537
97
98
99 static void
100 testPubKeyImport(void)
101 {
102 OSStatus status = errSecSuccess;
103 NSArray* outputItems = nil;
104 SecKeychainRef keychain = NULL;
105 NSData* keyData = [NSData dataWithBytes:kPublicKey length:sizeof(kPublicKey)];
106 SecExternalFormat format = kSecFormatUnknown;
107 SecExternalItemType keyType = kSecItemTypePublicKey;
108
109 status = SecKeychainCopyDefault(&keychain);
110 // ignoring error
111
112 status = SecItemImport((CFDataRef)keyData,
113 NULL, &format, &keyType, 0, NULL,
114 keychain, (CFArrayRef *)&outputItems);
115
116 NSLog(@"SecItemImport result = %d", (int)status);
117
118 if (keychain) CFRelease(keychain);
119 if (outputItems) CFRelease(outputItems);
120 }
121
122 static void
123 testPubKeyImportWithModulusAndExponent(SecKeychainRef keychain)
124 {
125 OSStatus status = errSecSuccess;
126
127 typedef struct SecRSAPublicKeyParams {
128 uint8_t *modulus; /* modulus */
129 CFIndex modulusLength;
130 uint8_t *exponent; /* public exponent */
131 CFIndex exponentLength;
132 } SecRSAPublicKeyParams;
133 #if 0
134 SecRSAPublicKeyParams pubKeyParams = {
135 .modulus = (uint8_t *)k512PublicKeyModulus,
136 .modulusLength = sizeof(k512PublicKeyModulus),
137 .exponent = (uint8_t *)k512PublicKeyExponent,
138 .exponentLength = sizeof(k512PublicKeyExponent),
139 };
140 #else
141 SecRSAPublicKeyParams pubKeyParams = {
142 .modulus = (uint8_t *)k1024PublicKeyModulus,
143 .modulusLength = sizeof(k1024PublicKeyModulus),
144 .exponent = (uint8_t *)k1024PublicKeyExponent,
145 .exponentLength = sizeof(k1024PublicKeyExponent),
146 };
147 #endif
148 // SecKeyRef key = SecKeyCreateRSAPublicKey(NULL, (const uint8_t *)&pubKeyParams,
149 // sizeof(pubKeyParams), kSecKeyEncodingRSAPublicParams);
150
151 // wrap as PKCS1
152 DERSize m_size = pubKeyParams.modulusLength;
153 DERSize e_size = pubKeyParams.exponentLength;
154 const DERSize seq_size = DERLengthOfItem(ASN1_INTEGER, m_size) +
155 DERLengthOfItem(ASN1_INTEGER, e_size);
156 const DERSize result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
157 DERSize r_size, remaining_size = result_size;
158 DERReturn drtn;
159
160 CFMutableDataRef pkcs1 = CFDataCreateMutable(NULL, result_size);
161 ok(pkcs1, "%s: create CFData", testName);
162 if (pkcs1 == NULL) {
163 NSLog(@"CFDataCreateMutable failed");
164 return;
165 }
166 CFDataSetLength(pkcs1, result_size);
167 uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
168
169 *bytes++ = ONE_BYTE_ASN1_CONSTR_SEQUENCE;
170 remaining_size--;
171 r_size = 4;
172 drtn = DEREncodeLength(seq_size, bytes, &r_size);
173 if (r_size <= remaining_size) {
174 bytes += r_size;
175 remaining_size -= r_size;
176 }
177 r_size = remaining_size;
178 drtn = DEREncodeItem(ASN1_INTEGER, m_size, (const DERByte *)pubKeyParams.modulus, (DERByte *)bytes, &r_size);
179 if (r_size <= remaining_size) {
180 bytes += r_size;
181 remaining_size -= r_size;
182 }
183 r_size = remaining_size;
184 drtn = DEREncodeItem(ASN1_INTEGER, e_size, (const DERByte *)pubKeyParams.exponent, (DERByte *)bytes, &r_size);
185
186
187 SecExternalFormat externalFormat = kSecFormatBSAFE; //kSecFormatOpenSSL;
188 SecExternalItemType externalItemType = kSecItemTypePublicKey;
189 CFArrayRef outArray = NULL;
190
191 status = SecItemImport(pkcs1, NULL, &externalFormat, &externalItemType, 0, NULL, keychain, &outArray);
192 ok_status(status, "%s: SecItemImport", testName);
193 if (status != errSecSuccess) {
194 NSLog(@"SecItemImport result = %d", (int)status);
195 return;
196 }
197
198 // TODO: encrypt something with this key and check the result
199
200 if (outArray) CFRelease(outArray);
201 }
202
203 int kc_26_key_import_public(int argc, char *const *argv)
204 {
205 plan_tests(5);
206 initializeKeychainTests(__FUNCTION__);
207
208 SecKeychainRef kc = getPopulatedTestKeychain();
209
210 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
211 // testPubKeyImport();
212 testPubKeyImportWithModulusAndExponent(kc);
213 [pool drain];
214
215 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", testName);
216 CFReleaseNull(kc);
217
218 deleteTestFiles();
219 return 0;
220 }
221
222 #pragma clang diagnostic pop