1/* 2 * Copyright (c) 2003-2009 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 * keychain_delete.c 24 */ 25 26#include "keychain_delete.h" 27#include "keychain_find.h" 28 29#include "keychain_utilities.h" 30#include "security.h" 31#include <unistd.h> 32#include <Security/SecKeychain.h> 33#include <Security/SecKeychainItem.h> 34#include <Security/SecTrustSettings.h> 35 36static int 37do_delete(CFTypeRef keychainOrArray) 38{ 39 /* @@@ SecKeychainDelete should really take a CFTypeRef argument. */ 40 OSStatus result = SecKeychainDelete((SecKeychainRef)keychainOrArray); 41 if (result) 42 { 43 /* @@@ Add printing of keychainOrArray. */ 44 sec_perror("SecKeychainDelete", result); 45 } 46 47 return result; 48} 49 50static int 51do_delete_certificate(CFTypeRef keychainOrArray, const char *name, const char *hash, Boolean deleteTrust) 52{ 53 OSStatus result = noErr; 54 SecKeychainItemRef itemToDelete = NULL; 55 if (!name && !hash) { 56 return 2; 57 } 58 59 itemToDelete = find_unique_certificate(keychainOrArray, name, hash); 60 if (itemToDelete) { 61 if (deleteTrust) { 62 result = SecTrustSettingsRemoveTrustSettings((SecCertificateRef)itemToDelete, 63 kSecTrustSettingsDomainUser); 64 if (result && result != errSecItemNotFound) { 65 sec_perror("SecTrustSettingsRemoveTrustSettings (user)", result); 66 } 67 if (geteuid() == 0) { 68 result = SecTrustSettingsRemoveTrustSettings((SecCertificateRef)itemToDelete, 69 kSecTrustSettingsDomainAdmin); 70 if (result && result != errSecItemNotFound) { 71 sec_perror("SecTrustSettingsRemoveTrustSettings (admin)", result); 72 } 73 } 74 } 75 result = SecKeychainItemDelete(itemToDelete); 76 if (result) { 77 sec_perror("SecKeychainItemDelete", result); 78 goto cleanup; 79 } 80 } else { 81 result = 1; 82 fprintf(stderr, "Unable to delete certificate matching \"%s\"", 83 (name) ? name : (hash) ? hash : ""); 84 } 85 86cleanup: 87 safe_CFRelease(&itemToDelete); 88 89 return result; 90} 91 92int 93keychain_delete_certificate(int argc, char * const *argv) 94{ 95 CFTypeRef keychainOrArray = NULL; 96 char *name = NULL; 97 char *hash = NULL; 98 Boolean delete_trust = FALSE; 99 int ch, result = 0; 100 101 while ((ch = getopt(argc, argv, "hc:Z:t")) != -1) 102 { 103 switch (ch) 104 { 105 case 'c': 106 name = optarg; 107 break; 108 case 'Z': 109 hash = optarg; 110 break; 111 case 't': 112 delete_trust = TRUE; 113 break; 114 case '?': 115 default: 116 result = 2; /* @@@ Return 2 triggers usage message. */ 117 goto cleanup; 118 } 119 } 120 121 argc -= optind; 122 argv += optind; 123 124 keychainOrArray = keychain_create_array(argc, argv); 125 126 result = do_delete_certificate(keychainOrArray, name, hash, delete_trust); 127 128cleanup: 129 safe_CFRelease(&keychainOrArray); 130 131 return result; 132} 133 134int 135keychain_delete(int argc, char * const *argv) 136{ 137 CFTypeRef keychainOrArray = NULL; 138 int ch, result = 0; 139 140 while ((ch = getopt(argc, argv, "h")) != -1) 141 { 142 switch (ch) 143 { 144 case '?': 145 default: 146 return 2; /* @@@ Return 2 triggers usage message. */ 147 } 148 } 149 150 argc -= optind; 151 argv += optind; 152 153 keychainOrArray = keychain_create_array(argc, argv); 154 155 result = do_delete(keychainOrArray); 156 if (keychainOrArray) 157 CFRelease(keychainOrArray); 158 159 return result; 160} 161