2 * Copyright (c) 2016 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <libDER/asn1Types.h>
25 #include <libDER/DER_Encode.h>
26 #include <libDER/DER_Decode.h>
27 #include <libDER/DER_Keys.h>
29 #import <Foundation/Foundation.h>
31 #import <Security/Security.h>
32 #import <Security/SecCertificatePriv.h>
34 #include "keychain_regressions.h"
35 #include "kc-helpers.h"
37 #pragma clang diagnostic push
38 #pragma clang diagnostic ignored "-Wunused-variable"
39 #pragma clang diagnostic ignored "-Wunused-function"
43 // <rdar://problem/10473567>
46 /* test RSA public key to import */
47 static const uint8_t kPublicKey[] =
49 0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xE7,0xD7,0x44,0xF2,0xA2,0xE2,0x78,
50 0x8B,0x6C,0x1F,0x55,0xA0,0x8E,0xB7,0x05,0x44,0xA8,0xFA,0x79,0x45,0xAA,0x8B,0xE6,
51 0xC6,0x2C,0xE5,0xF5,0x1C,0xBD,0xD4,0xDC,0x68,0x42,0xFE,0x3D,0x10,0x83,0xDD,0x2E,
52 0xDE,0xC1,0xBF,0xD4,0x25,0x2D,0xC0,0x2E,0x6F,0x39,0x8B,0xDF,0x0E,0x61,0x48,0xEA,
53 0x84,0x85,0x5E,0x2E,0x44,0x2D,0xA6,0xD6,0x26,0x64,0xF6,0x74,0xA1,0xF3,0x04,0x92,
54 0x9A,0xDE,0x4F,0x68,0x93,0xEF,0x2D,0xF6,0xE7,0x11,0xA8,0xC7,0x7A,0x0D,0x91,0xC9,
55 0xD9,0x80,0x82,0x2E,0x50,0xD1,0x29,0x22,0xAF,0xEA,0x40,0xEA,0x9F,0x0E,0x14,0xC0,
56 0xF7,0x69,0x38,0xC5,0xF3,0x88,0x2F,0xC0,0x32,0x3D,0xD9,0xFE,0x55,0x15,0x5F,0x51,
57 0xBB,0x59,0x21,0xC2,0x01,0x62,0x9F,0xD7,0x33,0x52,0xD5,0xE2,0xEF,0xAA,0xBF,0x9B,
58 0xA0,0x48,0xD7,0xB8,0x13,0xA2,0xB6,0x76,0x7F,0x6C,0x3C,0xCF,0x1E,0xB4,0xCE,0x67,
59 0x3D,0x03,0x7B,0x0D,0x2E,0xA3,0x0C,0x5F,0xFF,0xEB,0x06,0xF8,0xD0,0x8A,0xDD,0xE4,
60 0x09,0x57,0x1A,0x9C,0x68,0x9F,0xEF,0x10,0x72,0x88,0x55,0xDD,0x8C,0xFB,0x9A,0x8B,
61 0xEF,0x5C,0x89,0x43,0xEF,0x3B,0x5F,0xAA,0x15,0xDD,0xE6,0x98,0xBE,0xDD,0xF3,0x59,
62 0x96,0x03,0xEB,0x3E,0x6F,0x61,0x37,0x2B,0xB6,0x28,0xF6,0x55,0x9F,0x59,0x9A,0x78,
63 0xBF,0x50,0x06,0x87,0xAA,0x7F,0x49,0x76,0xC0,0x56,0x2D,0x41,0x29,0x56,0xF8,0x98,
64 0x9E,0x18,0xA6,0x35,0x5B,0xD8,0x15,0x97,0x82,0x5E,0x0F,0xC8,0x75,0x34,0x3E,0xC7,
65 0x82,0x11,0x76,0x25,0xCD,0xBF,0x98,0x44,0x7B,0x02,0x03,0x01,0x00,0x01,0xD4,0x9D
69 static const uint8_t k512PublicKeyModulus[] =
72 0xE2,0x7E,0x6C,0xDE,0xF4,0x45,0x8E,0x69,0xFF,0x9B,0x39,0x76,0x41,0x44,0x2E,0x2E,
73 0x61,0x27,0x07,0x0F,0x56,0xC9,0x6F,0x3F,0x71,0x82,0x67,0x1F,0xEB,0x0B,0xED,0x65,
74 0x09,0x9B,0x12,0x29,0x61,0x1D,0x66,0x3B,0x8C,0x63,0x0F,0x30,0x5C,0x00,0x42,0x85,
75 0x6F,0xD5,0xFB,0xF5,0x3D,0x63,0x99,0xC1,0xDE,0xD7,0x42,0x30,0x51,0x42,0xF3,0xD9
78 static const uint8_t k512PublicKeyExponent[] = { 0x01,0x00,0x01 }; // 65537
81 static const uint8_t k1024PublicKeyModulus[] =
84 0xBF,0x53,0x5F,0x27,0x26,0x28,0xD1,0x02,0x52,0x75,0x54,0xFB,0x5F,0xF1,0xBE,0x94,
85 0xB0,0x3B,0x33,0xB0,0x36,0xF6,0xF8,0x14,0xB9,0x62,0xEC,0xFC,0x31,0xF2,0xAB,0x60,
86 0x59,0x02,0xB7,0x68,0x6C,0x91,0x91,0x9E,0xE8,0x08,0xF0,0x49,0xD9,0xBD,0x24,0x5A,
87 0xB9,0xD6,0x08,0x89,0xA0,0xF1,0xBC,0xC7,0xB4,0x55,0xB5,0x0E,0x1A,0xA5,0xCC,0x94,
88 0x4E,0x57,0xB6,0xA9,0x6B,0x5C,0x90,0x28,0x6F,0xBD,0x8C,0x12,0xF9,0x59,0x5E,0x47,
89 0xDB,0x4C,0x7F,0x4D,0xB8,0x12,0x0A,0x36,0x9B,0x6F,0x8B,0xCC,0xB3,0x0F,0x60,0x23,
90 0xED,0x91,0x78,0x28,0x0A,0x5E,0xF4,0x24,0xC6,0xDD,0x80,0x50,0xC4,0xCD,0xF6,0x52,
91 0x6B,0xDD,0x35,0x82,0xCE,0xF2,0x7B,0xA4,0x73,0xD9,0x5F,0x75,0x2D,0xB6,0x77,0xAD
94 static const uint8_t k1024PublicKeyExponent[] = { 0x01,0x00,0x01 }; // 65537
98 testPubKeyImport(void)
100 OSStatus status = errSecSuccess;
101 CFArrayRef outputItems = nil;
102 SecKeychainRef keychain = NULL;
103 NSData* keyData = [NSData dataWithBytes:kPublicKey length:sizeof(kPublicKey)];
104 SecExternalFormat format = kSecFormatUnknown;
105 SecExternalItemType keyType = kSecItemTypePublicKey;
107 status = SecKeychainCopyDefault(&keychain);
110 status = SecItemImport((CFDataRef)keyData,
111 NULL, &format, &keyType, 0, NULL,
112 keychain, &outputItems);
114 NSLog(@"SecItemImport result = %d", (int)status);
116 if (keychain) CFRelease(keychain);
117 if (outputItems) CFRelease(outputItems);
121 testPubKeyImportWithModulusAndExponent(SecKeychainRef keychain)
123 OSStatus status = errSecSuccess;
125 typedef struct SecRSAPublicKeyParams {
126 uint8_t *modulus; /* modulus */
127 CFIndex modulusLength;
128 uint8_t *exponent; /* public exponent */
129 CFIndex exponentLength;
130 } SecRSAPublicKeyParams;
132 SecRSAPublicKeyParams pubKeyParams = {
133 .modulus = (uint8_t *)k512PublicKeyModulus,
134 .modulusLength = sizeof(k512PublicKeyModulus),
135 .exponent = (uint8_t *)k512PublicKeyExponent,
136 .exponentLength = sizeof(k512PublicKeyExponent),
139 SecRSAPublicKeyParams pubKeyParams = {
140 .modulus = (uint8_t *)k1024PublicKeyModulus,
141 .modulusLength = sizeof(k1024PublicKeyModulus),
142 .exponent = (uint8_t *)k1024PublicKeyExponent,
143 .exponentLength = sizeof(k1024PublicKeyExponent),
146 // SecKeyRef key = SecKeyCreateRSAPublicKey(NULL, (const uint8_t *)&pubKeyParams,
147 // sizeof(pubKeyParams), kSecKeyEncodingRSAPublicParams);
150 DERSize m_size = pubKeyParams.modulusLength;
151 DERSize e_size = pubKeyParams.exponentLength;
152 const DERSize seq_size = DERLengthOfItem(ASN1_INTEGER, m_size) +
153 DERLengthOfItem(ASN1_INTEGER, e_size);
154 const DERSize result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
155 DERSize r_size, remaining_size = result_size;
158 CFMutableDataRef pkcs1 = CFDataCreateMutable(NULL, result_size);
159 ok(pkcs1, "%s: create CFData", testName);
161 NSLog(@"CFDataCreateMutable failed");
164 CFDataSetLength(pkcs1, result_size);
165 uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
167 *bytes++ = ONE_BYTE_ASN1_CONSTR_SEQUENCE;
170 drtn = DEREncodeLength(seq_size, bytes, &r_size);
171 if (r_size <= remaining_size) {
173 remaining_size -= r_size;
175 r_size = remaining_size;
176 drtn = DEREncodeItem(ASN1_INTEGER, m_size, (const DERByte *)pubKeyParams.modulus, (DERByte *)bytes, &r_size);
177 if (r_size <= remaining_size) {
179 remaining_size -= r_size;
181 r_size = remaining_size;
182 drtn = DEREncodeItem(ASN1_INTEGER, e_size, (const DERByte *)pubKeyParams.exponent, (DERByte *)bytes, &r_size);
185 SecExternalFormat externalFormat = kSecFormatBSAFE; //kSecFormatOpenSSL;
186 SecExternalItemType externalItemType = kSecItemTypePublicKey;
187 CFArrayRef outArray = NULL;
189 status = SecItemImport(pkcs1, NULL, &externalFormat, &externalItemType, 0, NULL, keychain, &outArray);
190 CFReleaseNull(pkcs1);
191 ok_status(status, "%s: SecItemImport", testName);
192 if (status != errSecSuccess) {
193 NSLog(@"SecItemImport result = %d", (int)status);
197 // TODO: encrypt something with this key and check the result
199 if (outArray) CFRelease(outArray);
202 int kc_26_key_import_public(int argc, char *const *argv)
205 initializeKeychainTests(__FUNCTION__);
207 SecKeychainRef kc = getPopulatedTestKeychain();
209 // testPubKeyImport();
210 testPubKeyImportWithModulusAndExponent(kc);
212 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", testName);
219 #pragma clang diagnostic pop