1/*
2 * Copyright (c) 2004,2011,2013-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 * SecImportExportUtils.h - misc. utilities for import/export module
24 */
25
26#ifndef	_SECURITY_SEC_IMPORT_EXPORT_UTILS_H_
27#define _SECURITY_SEC_IMPORT_EXPORT_UTILS_H_
28
29#include "SecImportExport.h"
30#include "SecKeychainPriv.h"
31#include "SecBasePriv.h"
32#include <security_utilities/debugging.h>
33#include <security_utilities/errors.h>
34
35#ifdef	__cplusplus
36extern "C" {
37#endif
38
39/*
40 * Macros for begin/end of public functions. Although the import/export
41 * module does not intentionally throw C++ exceptions which are intended to
42 * be caught like this, we catch possible exceptions which can conceivably
43 * be thrown here or below.
44 */
45
46#define BEGIN_IMP_EXP_SECAPI \
47	try {
48
49#define END_IMP_EXP_SECAPI \
50	} \
51	catch (const MacOSError &err) { return err.osStatus(); } \
52	catch (const CommonError &err) { return SecKeychainErrFromOSStatus(err.osStatus()); } \
53	catch (const std::bad_alloc &) { return errSecAllocate; }\
54	catch (...) { return errSecInternalComponent; }
55
56/*
57 * Debug support.
58 */
59
60#ifdef  NDEBUG
61
62#define impExpExtFormatStr(f)
63#define impExpExtItemTypeStr(t)
64
65#else
66
67extern const char *impExpExtFormatStr(SecExternalFormat format);
68extern const char *impExpExtItemTypeStr(SecExternalItemType itemType);
69
70#endif  /* NDEBUG */
71
72#define SecImpExpDbg(args...)	secdebug("SecImpExp", ## args)
73#define SecImpInferDbg(args...)	secdebug("SecImpInfer", ## args)
74
75/*
76 * Parse file extension and attempt to map it to format and type. Returns true
77 * on success.
78 */
79bool impExpImportParseFileExten(
80	CFStringRef			fstr,
81	SecExternalFormat   *inputFormat,   // RETURNED
82	SecExternalItemType	*itemType);		// RETURNED
83
84/* do a [NSString stringByDeletingPathExtension] equivalent */
85CFStringRef impExpImportDeleteExtension(
86	CFStringRef			fileStr);
87
88/*
89 * map {algorithm, class, SecExternalFormat} to a CSSM_KEYBLOB_FORMAT.
90 * Returns errSecUnsupportedFormat in the rare appropriate case.
91 */
92OSStatus impExpKeyForm(
93	SecExternalFormat		externForm,
94	SecExternalItemType		itemType,
95	CSSM_ALGORITHMS			alg,
96	CSSM_KEYBLOB_FORMAT		*cssmForm,		// RETURNED
97	CSSM_KEYCLASS			*cssmClass);	// RETRUNED
98
99/*
100 * Guess an incoming blob's type, format and (for keys only) algorithm
101 * by examining its contents. Returns true on success, in which case
102 * *inputFormat and *itemType, and *keyAlg are valid. Caller optionally
103 * passes in valid values any number of these as a clue.
104 */
105bool impExpImportGuessByExamination(
106	CFDataRef			inData,
107	SecExternalFormat   *inputFormat,	// may be kSecFormatUnknown on entry
108	SecExternalItemType	*itemType,		// may be kSecItemTypeUnknown on entry
109	CSSM_ALGORITHMS		*keyAlg);		// CSSM_ALGID_NONE - unknown
110
111/*
112 * Obtain the CDSA-layer CSSM_RESOURCE_CONTROL_CONTEXT given a SecAccessRef.
113 */
114extern OSStatus impExpAccessToRcc(
115	SecAccessRef	accessRef,
116	const CSSM_RESOURCE_CONTROL_CONTEXT **rcc);
117
118
119
120/* low-level crypto/CSP support */
121
122/*
123 * Given a context specified via a CSSM_CC_HANDLE, add a new
124 * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
125 * AttributeLength, and an untyped pointer.
126 */
127CSSM_RETURN impExpAddContextAttribute(CSSM_CC_HANDLE CCHandle,
128	uint32 AttributeType,
129	uint32 AttributeLength,
130	const void *AttributePtr);
131
132/*
133 * Free memory via specified plugin's app-level allocator
134 */
135void impExpFreeCssmMemory(
136	CSSM_HANDLE		hand,
137	void 			*p);
138
139/*
140 * Calculate digest of any CSSM_KEY. Unlike older implementations
141 * of this logic, you can actually calculate the public key hash
142 * on any class of key, any format, raw CSP or CSPDL.
143 *
144 * Caller must free keyDigest->Data using impExpFreeCssmMemory() since
145 * this is allocated by the CSP's app-specified allocator.
146 */
147CSSM_RETURN impExpKeyDigest(
148	CSSM_CSP_HANDLE cspHand,
149	CSSM_KEY_PTR	key,
150	CSSM_DATA_PTR   keyDigest);		// contents allocd and RETURNED
151
152/*
153 * Given a CFTypeRef passphrase which may be a CFDataRef or a CFStringRef,
154 * return a refcounted CFStringRef suitable for use with the PKCS12 library.
155 * PKCS12 passphrases in CFData format must be UTF8 encoded.
156 */
157OSStatus impExpPassphraseToCFString(
158	CFTypeRef   passin,
159	CFStringRef *passout);	// may be the same as passin, but refcounted
160
161/*
162 * Given a CFTypeRef passphrase which may be a CFDataRef or a CFStringRef,
163 * return a refcounted CFDataRef whose bytes are suitable for use with
164 * PKCS5 (v1.5 and v2.0) key derivation.
165 */
166OSStatus impExpPassphraseToCFData(
167	CFTypeRef   passin,
168	CFDataRef   *passout);	// may be the same as passin, but refcounted
169
170/*
171 * Obtain passphrase, given a SecKeyImportExportParameters.
172 *
173 * Passphrase comes from one of two places: app-specified, in
174 * SecKeyImportExportParameters.passphrase (either as CFStringRef
175 * or CFDataRef); or via the secure passphrase mechanism.
176 *
177 * Passphrase is returned in one of two forms:
178 *
179 * -- Secure passphrase is returned as a CSSM_KEY_PTR, which the
180 *    caller must CSSM_FreeKey later. THe CSSM_KEY_PTR must also
181 *    be free()d.
182 *
183 * -- CFTypeRef for app-supplied passphrases. This can be one of
184 *    two types:
185 *
186 *    -- CFStringRef, for use with P12
187 *    -- CFDataRef, for more general use (e.g. for PKCS5).
188 *
189 *    In either case the caller must CFRelease the result.
190 */
191typedef enum {
192	SPF_String,			// CFStringRef, P12
193	SPF_Data			// CFDataRef, PKCS5
194} impExpPassphraseForm;
195
196typedef enum {
197	VP_Export,			// verify passphrase
198	VP_Import			// no verify
199} impExpVerifyPhrase;
200
201OSStatus impExpPassphraseCommon(
202	const SecKeyImportExportParameters *keyParams,
203	CSSM_CSP_HANDLE			cspHand,		// MUST be CSPDL, for passKey generation
204	impExpPassphraseForm	phraseForm,
205	impExpVerifyPhrase		verifyPhrase,   // for secure passphrase
206	CFTypeRef				*phrase,		// RETURNED, or
207	CSSM_KEY_PTR			*passKey);		// mallocd and RETURNED
208
209CSSM_KEYATTR_FLAGS ConvertArrayToKeyAttributes(SecKeyRef aKey, CFArrayRef usage);
210
211Boolean ConvertSecKeyImportExportParametersToSecImportExportKeyParameters(SecKeyRef aKey,
212	const SecItemImportExportKeyParameters* newPtr, SecKeyImportExportParameters* oldPtr);
213
214#ifdef	__cplusplus
215}
216#endif
217
218#endif  /* _SECURITY_SEC_IMPORT_EXPORT_UTILS_H_ */
219
220