]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/ocspTool/ocspNetwork.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / ocspTool / ocspNetwork.cpp
1 /*
2 * Copyright (c) 2000,2002,2005-2006 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 /*
24 * ocspdNetwork.cpp - Network support for ocspd and CRL/cert fetch
25 */
26
27 #include <security_ocspd/ocspdDebug.h>
28 #include "ocspNetwork.h"
29 #include <security_ocspd/ocspdUtils.h>
30 #include <CoreFoundation/CoreFoundation.h>
31 #include <CoreServices/CoreServices.h>
32 #include <security_cdsa_utils/cuEnc64.h>
33 #include <stdlib.h>
34 #include <Security/cssmapple.h>
35 #include <LDAP/ldap.h>
36
37 #pragma mark ----- OCSP support -----
38
39 /* POST method has Content-Type header line equal to "application/ocsp-request" */
40 static CFStringRef kContentType = CFSTR("Content-Type");
41 static CFStringRef kAppOcspRequest = CFSTR("application/ocsp-request");
42
43 #ifndef NDEBUG
44 #define DUMP_BLOBS 0
45 #else
46 #define DUMP_BLOBS 0
47 #endif
48
49 #define OCSP_GET_FILE "/tmp/ocspGet"
50 #define OCSP_RESP_FILE "/tmp/ocspResp"
51
52 #if DUMP_BLOBS
53
54 #include <security_cdsa_utils/cuFileIo.h>
55
56 static void writeBlob(
57 const char *fileName,
58 const char *whatIsIt,
59 const unsigned char *data,
60 unsigned dataLen)
61 {
62 if(writeFile(fileName, data, dataLen)) {
63 printf("***Error writing %s to %s\n", whatIsIt, fileName);
64 }
65 else {
66 printf("...wrote %u bytes of %s to %s\n", dataLen, whatIsIt, fileName);
67 }
68 }
69
70 #else
71
72 #define writeBlob(f,w,d,l)
73
74 #endif /* DUMP_BLOBS */
75
76 /* fetch via HTTP POST */
77
78 #define POST_BUFSIZE 1024
79
80 CSSM_RETURN ocspdHttpPost(
81 SecAsn1CoderRef coder,
82 const CSSM_DATA &url,
83 const CSSM_DATA &ocspReq, // DER encoded
84 CSSM_DATA &fetched) // mallocd in coder space and RETURNED
85 {
86 CSSM_RETURN ourRtn = CSSM_OK;
87 CFIndex thisMove;
88 UInt8 inBuf[POST_BUFSIZE];
89 /* resources to release on exit */
90 CFMutableDataRef inData = NULL;
91 CFReadStreamRef cfStream = NULL;
92 CFHTTPMessageRef request = NULL;
93 CFDataRef postData = NULL;
94 CFURLRef cfUrl = NULL;
95
96 /* trim off possible NULL terminator from incoming URL */
97 uint32 urlLen = url.Length;
98 if(url.Data[urlLen - 1] == '\0') {
99 urlLen--;
100 }
101
102 cfUrl = CFURLCreateWithBytes(NULL,
103 url.Data, urlLen,
104 kCFStringEncodingUTF8, // right?
105 NULL); // this is absolute path
106 if(cfUrl == NULL) {
107 ocspdErrorLog("CFURLCreateWithBytes returned NULL\n");
108 /* FIXME..? */
109 return CSSMERR_APPLETP_CRL_BAD_URI;
110 }
111 /* subsequent errors to errOut: */
112
113 #ifndef NDEBUG
114 {
115 char *ustr = (char *)malloc(urlLen + 1);
116 memmove(ustr, url.Data, urlLen);
117 ustr[urlLen] = '\0';
118 ocspdDebug("ocspdHttpPost: posting to URI %s", ustr);
119 free(ustr);
120 }
121 #endif
122
123 writeBlob(OCSP_GET_FILE, "OCSP Request as POST data", ocspReq.Data, ocspReq.Length);
124 postData = CFDataCreate(NULL, ocspReq.Data, ocspReq.Length);
125
126 /* Create a new HTTP request. */
127 request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("POST"), cfUrl,
128 kCFHTTPVersion1_1);
129 if (request == NULL) {
130 ocspdErrorLog("ocspdHttpPost: error creating CFHTTPMessage\n");
131 ourRtn = CSSMERR_TP_INTERNAL_ERROR;
132 goto errOut;
133 }
134
135 // Set the body and required header fields.
136 CFHTTPMessageSetBody(request, postData);
137 CFHTTPMessageSetHeaderFieldValue(request, kContentType, kAppOcspRequest);
138
139 // Create the stream for the request.
140 cfStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);
141 if (cfStream == NULL) {
142 ocspdErrorLog("ocspdHttpPost: error creating CFReadStream\n");
143 ourRtn = CSSMERR_TP_INTERNAL_ERROR;
144 goto errOut;
145 }
146
147 /* go, synchronously */
148 if(!CFReadStreamOpen(cfStream)) {
149 ocspdErrorLog("ocspdHttpPost: error opening CFReadStream\n");
150 ourRtn = CSSMERR_TP_INTERNAL_ERROR;
151 goto errOut;
152 }
153 inData = CFDataCreateMutable(NULL, 0);
154 for(;;) {
155 thisMove = CFReadStreamRead(cfStream, inBuf, POST_BUFSIZE);
156 if(thisMove < 0) {
157 CFStreamError error = CFReadStreamGetError(cfStream);
158 ocspdErrorLog("ocspdHttpPost: error on CFReadStreamRead: domain "
159 "%ld error %ld\n", (long)error.domain, (long)error.error);
160 ourRtn = CSSMERR_APPLETP_NETWORK_FAILURE;
161 break;
162 }
163 else if(thisMove == 0) {
164 ocspdDebug("ocspdHttpPost: transfer complete, moved %ld bytes",
165 CFDataGetLength(inData));
166 ourRtn = CSSM_OK;
167 break;
168 }
169 else {
170 CFDataAppendBytes(inData, inBuf, thisMove);
171 }
172 }
173 if(ourRtn == CSSM_OK) {
174 SecAsn1AllocCopy(coder, CFDataGetBytePtr(inData), CFDataGetLength(inData),
175 &fetched);
176 writeBlob(OCSP_RESP_FILE, "OCSP Response", fetched.Data, fetched.Length);
177 }
178
179 errOut:
180 CFRELEASE(inData);
181 CFRELEASE(cfStream);
182 CFRELEASE(request);
183 CFRELEASE(postData);
184 CFRELEASE(cfUrl);
185 return ourRtn;
186 }
187