2 * crlNetwork.cpp - Network support for crlTool
5 #include "crlNetwork.h"
6 #include <CoreFoundation/CoreFoundation.h>
7 #include <CoreServices/CoreServices.h>
8 #include <security_cdsa_utils/cuEnc64.h>
10 #include <Security/cssmapple.h>
11 #include <LDAP/ldap.h>
13 #define ocspdErrorLog(args...) printf(args)
15 #pragma mark ----- LDAP fetch -----
18 * LDAP attribute names, used if not present in URI.
20 #define LDAP_ATTR_CERT "cacertificate;binary"
21 #define LDAP_ATTR_CRL "certificaterevocationlist;binary"
24 * Default LDAP options.
26 #define LDAP_REFERRAL_DEFAULT LDAP_OPT_ON
28 static CSSM_RETURN
ldapRtnToCssm(
32 case LDAP_SERVER_DOWN
:
34 case LDAP_CONNECT_ERROR
:
35 return CSSMERR_APPLETP_CRL_SERVER_DOWN
;
36 case LDAP_PARAM_ERROR
:
37 case LDAP_FILTER_ERROR
:
38 return CSSMERR_APPLETP_CRL_BAD_URI
;
40 return CSSMERR_APPLETP_CRL_NOT_FOUND
;
44 static CSSM_RETURN
ldapFetch(
47 CSSM_DATA
&fetched
) // mallocd and RETURNED
49 BerValue
**value
= NULL
;
50 LDAPURLDesc
*urlDesc
= NULL
;
52 LDAPMessage
*msg
= NULL
;
54 LDAPMessage
*entry
= NULL
;
55 bool mallocdString
= false;
58 CSSM_RETURN ourRtn
= CSSM_OK
;
59 /* attr input to ldap_search_s() */
61 char **attrArrayP
= NULL
;
63 /* don't assume URL string is NULL terminated */
64 if(url
.Data
[url
.Length
- 1] == '\0') {
65 urlStr
= (char *)url
.Data
;
68 urlStr
= (char *)malloc(url
.Length
+ 1);
69 memmove(urlStr
, url
.Data
, url
.Length
);
70 urlStr
[url
.Length
] = '\0';
74 /* break up the URL into something usable */
75 rtn
= ldap_url_parse(urlStr
, &urlDesc
);
77 ocspdErrorLog("ldap_url_parse returned %d", rtn
);
78 return CSSMERR_APPLETP_CRL_BAD_URI
;
82 * Determine what attr we're looking for.
84 if((urlDesc
->lud_attrs
!= NULL
) && // attrs present in URL
85 (urlDesc
->lud_attrs
[0] != NULL
) && // at least one attr present
86 (urlDesc
->lud_attrs
[1] == NULL
)) {
88 * Exactly one attr present in the caller-specified URL;
89 * assume that this is exactly what we want.
91 attrArrayP
= &urlDesc
->lud_attrs
[0];
94 /* use caller-specified attr */
97 attrArray
[0] = (char *)LDAP_ATTR_CRL
;
100 attrArray
[0] = (char *)LDAP_ATTR_CERT
;
103 printf("***ldapFetch screwup: bogus lfType (%d)\n",
105 return CSSMERR_CSSM_INTERNAL_ERROR
;
108 attrArrayP
= &attrArray
[0];
111 /* establish connection */
112 rtn
= ldap_initialize(&ldap
, urlStr
);
114 ocspdErrorLog("ldap_initialize returned %d\n", rtn
);
115 return ldapRtnToCssm(rtn
);
117 /* subsequent errors to cleanup: */
118 rtn
= ldap_simple_bind_s(ldap
, NULL
, NULL
);
120 ocspdErrorLog("ldap_simple_bind_s returned %d\n", rtn
);
121 ourRtn
= ldapRtnToCssm(rtn
);
125 rtn
= ldap_set_option(ldap
, LDAP_OPT_REFERRALS
, LDAP_REFERRAL_DEFAULT
);
127 ocspdErrorLog("ldap_set_option(referrals) returned %d\n", rtn
);
128 ourRtn
= ldapRtnToCssm(rtn
);
141 ocspdErrorLog("ldap_search_s returned %d\n", rtn
);
142 ourRtn
= ldapRtnToCssm(rtn
);
147 * We require exactly one entry (for now).
149 numEntries
= ldap_count_entries(ldap
, msg
);
150 if(numEntries
!= 1) {
151 ocspdErrorLog("tpCrlViaLdap: numEntries %d\n", numEntries
);
152 ourRtn
= CSSMERR_APPLETP_CRL_NOT_FOUND
;
156 entry
= ldap_first_entry(ldap
, msg
);
157 value
= ldap_get_values_len(ldap
, msg
, attrArrayP
[0]);
159 ocspdErrorLog("Error on ldap_get_values_len\n");
160 ourRtn
= CSSMERR_APPLETP_CRL_NOT_FOUND
;
164 fetched
.Length
= value
[0]->bv_len
;
165 fetched
.Data
= (uint8
*)malloc(fetched
.Length
);
166 memmove(fetched
.Data
, value
[0]->bv_val
, fetched
.Length
);
168 ldap_value_free_len(value
);
177 ldap_free_urldesc(urlDesc
);
178 rtn
= ldap_unbind(ldap
);
180 ocspdErrorLog("Error %d on ldap_unbind\n", rtn
);
186 #pragma mark ----- HTTP fetch via GET -----
189 static CSSM_RETURN
httpFetch(
190 const CSSM_DATA
&url
,
191 CSSM_DATA
&fetched
) // mallocd in alloc space and RETURNED
193 /* trim off possible NULL terminator */
194 CSSM_DATA theUrl
= url
;
195 if(theUrl
.Data
[theUrl
.Length
- 1] == '\0') {
198 CFURLRef cfUrl
= CFURLCreateWithBytes(NULL
,
199 theUrl
.Data
, theUrl
.Length
,
200 kCFStringEncodingUTF8
, // right?
201 //kCFStringEncodingASCII, // right?
202 NULL
); // this is absolute path
204 ocspdErrorLog("CFURLCreateWithBytes returned NULL\n");
205 return CSSMERR_APPLETP_CRL_BAD_URI
;
207 CFDataRef urlData
= NULL
;
209 Boolean brtn
= CFURLCreateDataAndPropertiesFromResource(NULL
,
212 NULL
, // no properties
217 ocspdErrorLog("CFURLCreateDataAndPropertiesFromResource err: %d\n",
220 return CSSMERR_APPLETP_NETWORK_FAILURE
;
223 if(urlData
== NULL
) {
224 ocspdErrorLog("CFURLCreateDataAndPropertiesFromResource: no data\n");
225 return CSSMERR_APPLETP_NETWORK_FAILURE
;
227 CFIndex len
= CFDataGetLength(urlData
);
228 fetched
.Data
= (uint8
*)malloc(len
);
229 fetched
.Length
= len
;
230 memmove(fetched
.Data
, CFDataGetBytePtr(urlData
), len
);
235 /* Fetch cert or CRL from net, we figure out the schema */
236 CSSM_RETURN
crlNetFetch(
237 const CSSM_DATA
*url
,
239 CSSM_DATA
*fetched
) // mallocd in alloc space and RETURNED
241 if(url
->Length
< 5) {
242 return CSSMERR_APPLETP_CRL_BAD_URI
;
244 if(!strncmp((char *)url
->Data
, "ldap:", 5)) {
245 return ldapFetch(*url
, lfType
, *fetched
);
247 if(!strncmp((char *)url
->Data
, "http:", 5) ||
248 !strncmp((char *)url
->Data
, "https:", 6)) {
249 return httpFetch(*url
, *fetched
);
251 return CSSMERR_APPLETP_CRL_BAD_URI
;