1/* 2 * Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please 7 * obtain a copy of the License at http://www.apple.com/publicsource and 8 * read it before using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 12 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 13 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 14 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 15 * Please see the License for the specific language governing rights and 16 * limitations under the License. 17 */ 18 19/* 20 * crlrefresh: command line access to ocspd's CRL cache refresh mechanism 21 */ 22 23#include <stdlib.h> 24#include <stdio.h> 25#include <security_ocspd/ocspdClient.h> 26#include <security_utilities/alloc.h> 27#include <security_cdsa_utils/cuTimeStr.h> 28#include <security_cdsa_utils/cuCdsaUtils.h> 29#include <security_cdsa_utils/cuFileIo.h> 30#include <Security/cssmtype.h> 31#include <Security/cssmapple.h> 32 33#define DEFAULT_STALE_DAYS 10 34#define DEFAULT_EXPIRE_OVERLAP_SECONDS 3600 35 36#ifdef NDEBUG 37#define DEBUG_PRINT 0 38#else 39#define DEBUG_PRINT 1 40#endif 41 42#if DEBUG_PRINT 43#define dprintf(args...) fprintf(stderr, args) 44#else 45#define dprintf(args...) 46#endif 47 48static void usage(char **argv) 49{ 50 printf("Usage\n"); 51 printf("Refresh : %s r [options]\n", argv[0]); 52 printf("Fetch CRL : %s f URI [options]\n", argv[0]); 53 printf("Fetch cert : %s F URI [options]\n", argv[0]); 54 printf("Refresh options:\n"); 55 printf(" s=stale_period in DAYS; default=%d\n", DEFAULT_STALE_DAYS); 56 printf(" o=expire_overlap in SECONDS; default=%d\n", 57 DEFAULT_EXPIRE_OVERLAP_SECONDS); 58 printf(" p (Purge all entries, ensuring refresh with fresh CRLs)\n"); 59 printf(" f (Full crypto CRL verification)\n"); 60 printf("Fetch options:\n"); 61 printf(" F=outFileName (default is stdout)\n"); 62 printf(" n (no write to cache after fetch)\n"); 63 exit(1); 64} 65 66/* 67 * Fetch a CRL or Cert from net; write it to a file. 68 */ 69int fetchItemFromNet( 70 bool fetchCrl, 71 const char *URI, 72 char *outFileName, // NULL indicates write to stdout 73 bool writeToCache) 74{ 75 const CSSM_DATA uriData = {strlen(URI) + 1, (uint8 *)URI}; 76 CSSM_DATA item; 77 CSSM_RETURN crtn; 78 int irtn; 79 Allocator &alloc = Allocator::standard(); 80 char *op = ""; 81 82 dprintf("fetchItemFromNet %s outFile %s\n", 83 URI, outFileName ? outFileName : "stdout"); 84 85 if(fetchCrl) { 86 char *cssmTime = cuTimeAtNowPlus(0, TIME_CSSM); 87 op = "ocspdCRLFetch"; 88 crtn = ocspdCRLFetch(alloc, uriData, NULL, 89 true, // cacheRead 90 writeToCache, 91 cssmTime, 92 item); 93 APP_FREE(cssmTime); 94 } 95 else { 96 op = "ocspdCertFetch"; 97 crtn = ocspdCertFetch(alloc, uriData, item); 98 } 99 100 if(crtn) { 101 cssmPerror(op, crtn); 102 return 1; 103 } 104 dprintf("fetchItemFromNet %s complete, %lu bytes read\n", 105 op, item.Length); 106 if(outFileName == NULL) { 107 irtn = write(STDOUT_FILENO, item.Data, item.Length); 108 if(irtn != (int)item.Length) { 109 irtn = errno; 110 perror("write"); 111 } 112 else { 113 irtn = 0; 114 } 115 } 116 else { 117 irtn = writeFile(outFileName, item.Data, item.Length); 118 if(irtn) { 119 perror(outFileName); 120 } 121 } 122 alloc.free(item.Data); 123 dprintf("fetchItemFromNet returning %d\n", irtn); 124 return irtn; 125} 126 127int main(int argc, char **argv) 128{ 129 CSSM_RETURN crtn; 130 char *argp; 131 int arg; 132 int optArg = 1; 133 134 /* user-specified variables */ 135 bool verbose = false; 136 bool purgeAll = false; 137 bool fullCryptoValidation = false; 138 int staleDays = DEFAULT_STALE_DAYS; 139 int expireOverlapSeconds = DEFAULT_EXPIRE_OVERLAP_SECONDS; 140 141 /* fetch options */ 142 bool fetchCrl = true; 143 char *outFileName = NULL; 144 bool writeToCache = true; 145 char *uri = NULL; 146 147 if(argc < 2) { 148 usage(argv); 149 } 150 switch(argv[1][0]) { 151 case 'F': 152 fetchCrl = false; 153 /* and drop thru */ 154 case 'f': 155 if(argc < 3) { 156 usage(argv); 157 } 158 uri = argv[2]; 159 optArg = 3; 160 break; 161 case 'r': 162 optArg = 2; 163 break; 164 default: 165 usage(argv); 166 } 167 /* refresh options */ 168 for(arg=optArg; arg<argc; arg++) { 169 argp = argv[arg]; 170 switch(argp[0]) { 171 case 's': 172 if(argp[1] != '=') { 173 usage(argv); 174 } 175 staleDays = atoi(&argp[2]); 176 break; 177 case 'o': 178 if(argp[1] != '=') { 179 usage(argv); 180 } 181 expireOverlapSeconds = atoi(&argp[2]); 182 break; 183 case 'p': 184 purgeAll = true; 185 break; 186 case 'f': 187 fullCryptoValidation = true; 188 break; 189 case 'k': 190 /* keychain argument no longer used but we'll allow/ignore it */ 191 fprintf(stderr, "Warning: keychain specification no longer used\n"); 192 break; 193 case 'n': 194 writeToCache = false; 195 break; 196 case 'F': 197 if(argp[1] != '=') { 198 usage(argv); 199 } 200 outFileName = &argp[2]; 201 break; 202 case 'v': 203 verbose = true; 204 break; 205 default: 206 usage(argv); 207 } 208 } 209 if(argv[1][0] != 'r') { 210 return fetchItemFromNet(fetchCrl, uri, outFileName, writeToCache); 211 } 212 213 dprintf("...staleDays %d expireOverlapSeconds %d\n", 214 staleDays, expireOverlapSeconds); 215 216 crtn = ocspdCRLRefresh(staleDays, expireOverlapSeconds, purgeAll, 217 fullCryptoValidation); 218 if(crtn) { 219 cssmPerror("ocspdCRLRefresh", crtn); 220 return -1; 221 } 222 return 0; 223} 224