1/*
2 * Copyright (c) 2004 Apple Computer, 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
24#include <Security/Security.h>
25#include <security_utilities/security_utilities.h>
26#include <security_cdsa_utilities/cssmbridge.h>
27#include <../sec/Security/SecBase.h>
28#include "Download.h"
29#include "SecureDownload.h"
30
31
32#define API_BEGIN \
33	try {
34
35#define API_END \
36	} \
37	catch (const MacOSError &err) { return err.osStatus(); } \
38	catch (const std::bad_alloc &) { return errSecAllocate; } \
39	catch (...) { return errSecInternalComponent; } \
40    return errSecSuccess;
41
42#define API_END_GENERIC_CATCH		} catch (...) { return; }
43
44#define API_END_ERROR_CATCH(bad)	} catch (...) { return bad; }
45
46
47
48OSStatus SecureDownloadCreateWithTicket (CFDataRef ticket,
49										 SecureDownloadTrustSetupCallback setup,
50										 void* setupContext,
51										 SecureDownloadTrustEvaluateCallback evaluate,
52										 void* evaluateContext,
53										 SecureDownloadRef* downloadRef)
54{
55	API_BEGIN
56
57	Download* sd = new Download ();
58	sd->Initialize (ticket, setup, setupContext, evaluate, evaluateContext);
59	Required (downloadRef) = sd;
60
61	API_END
62}
63
64
65
66OSStatus SecureDownloadCopyURLs (SecureDownloadRef downloadRef, CFArrayRef* urls)
67{
68	API_BEGIN
69
70	Required (downloadRef);
71	Download* d = (Download*) downloadRef;
72	Required (urls) = d->CopyURLs ();
73
74	API_END
75}
76
77
78
79OSStatus SecureDownloadCopyName (SecureDownloadRef downloadRef, CFStringRef* name)
80{
81	API_BEGIN
82
83	Required (downloadRef);
84	Download* d = (Download*) downloadRef;
85	Required (name) = d->CopyName ();
86
87	API_END
88}
89
90
91
92OSStatus SecureDownloadCopyCreationDate (SecureDownloadRef downloadRef, CFDateRef* date)
93{
94	API_BEGIN
95
96	Required (downloadRef);
97	Download* d = (Download*) downloadRef;
98	Required (date) = d->CopyDate ();
99
100	API_END
101}
102
103
104
105OSStatus SecureDownloadGetDownloadSize (SecureDownloadRef downloadRef, SInt64* size)
106{
107	API_BEGIN
108
109	Required (downloadRef);
110	Download* d = (Download*) downloadRef;
111	Required (size) = d->GetDownloadSize ();
112
113	API_END
114}
115
116
117
118OSStatus SecureDownloadUpdateWithData (SecureDownloadRef downloadRef, CFDataRef data)
119{
120	API_BEGIN
121	Required (downloadRef);
122	Required (data);
123	Download* d = (Download*) downloadRef;
124	d->UpdateWithData (data);
125	API_END
126}
127
128
129
130OSStatus SecureDownloadFinished (SecureDownloadRef downloadRef)
131{
132	API_BEGIN
133	Required (downloadRef);
134	Download* d = (Download*) downloadRef;
135	d->Finalize ();
136	API_END
137}
138
139
140
141OSStatus SecureDownloadRelease (SecureDownloadRef downloadRef)
142{
143	API_BEGIN
144		Required (downloadRef);
145		delete (Download*) downloadRef;
146	API_END
147}
148
149
150
151OSStatus SecureDownloadCopyTicketLocation (CFURLRef url, CFURLRef *ticketLocation)
152{
153	API_BEGIN
154		Required (ticketLocation);
155		Required (url);
156
157		// copy the resource specifier
158		CFStringRef resourceSpecifier = CFURLCopyResourceSpecifier (url);
159		if (resourceSpecifier == NULL)
160		{
161			CFError::throwMe ();
162		}
163
164		// make a new URL from the resource specifier
165		*ticketLocation = CFURLCreateWithString (NULL, resourceSpecifier, NULL);
166		if (*ticketLocation == NULL)
167		{
168			CFError::throwMe ();
169		}
170
171		// check the scheme to make sure that it isn't a file url
172		CFStringRef scheme = CFURLCopyScheme (*ticketLocation);
173		if (scheme != NULL)
174		{
175			CFComparisonResult equal = CFStringCompare (scheme, CFSTR("file"), kCFCompareCaseInsensitive);
176			CFRelease (scheme);
177
178			if (equal == kCFCompareEqualTo)
179			{
180				CFRelease (*ticketLocation);
181				*ticketLocation = NULL;
182				MacOSError::throwMe (errSecureDownloadInvalidDownload);
183			}
184		}
185
186		CFRelease (resourceSpecifier);
187	API_END
188}
189