/* * Copyright (c) 2003-2010,2012,2014 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ * * identity_prefs.c */ #include "identity_prefs.h" #include "identity_find.h" #include "keychain_utilities.h" #include "security.h" #include #include #include #include #include #include #include #include // SecCertificateInferLabel, SecDigestGetData #include static int do_set_identity_preference(CFTypeRef keychainOrArray, const char *identity, const char *service, CSSM_KEYUSE keyUsage, const char *hash) { int result = 0; CFStringRef serviceRef = NULL; SecIdentityRef identityRef = NULL; // must have a service name if (!service) { return 2; } // find identity (if specified by name or hash) if (identity || hash) { identityRef = find_identity(keychainOrArray, identity, hash, keyUsage); if (!identityRef) { sec_error("No matching identity found for \"%s\"", (hash) ? hash : identity); result = 1; goto cleanup; } } // set the identity preference serviceRef = CFStringCreateWithCString(NULL, service, kCFStringEncodingUTF8); result = SecIdentitySetPreference(identityRef, serviceRef, keyUsage); cleanup: if (identityRef) CFRelease(identityRef); if (serviceRef) CFRelease(serviceRef); return result; } int do_get_identity_preference(const char *service, CSSM_KEYUSE keyUsage, Boolean printName, Boolean printHash, Boolean pemFormat) { int result = 0; if (!service) { return 2; } CFStringRef serviceRef = CFStringCreateWithCString(NULL, service, kCFStringEncodingUTF8); SecCertificateRef certRef = NULL; SecIdentityRef identityRef = NULL; CSSM_DATA certData = { 0, NULL }; result = SecIdentityCopyPreference(serviceRef, keyUsage, NULL, &identityRef); if (result) { sec_perror("SecIdentityCopyPreference", result); goto cleanup; } result = SecIdentityCopyCertificate(identityRef, &certRef); if (result) { sec_perror("SecIdentityCopyCertificate", result); goto cleanup; } result = SecCertificateGetData(certRef, &certData); if (result) { sec_perror("SecCertificateGetData", result); goto cleanup; } if (printName) { char *nameBuf = NULL; CFStringRef nameRef = NULL; (void)SecCertificateCopyCommonName(certRef, &nameRef); CFIndex nameLen = (nameRef) ? CFStringGetLength(nameRef) : 0; if (nameLen > 0) { CFIndex bufLen = 1 + CFStringGetMaximumSizeForEncoding(nameLen, kCFStringEncodingUTF8); nameBuf = (char *)malloc(bufLen); if (!CFStringGetCString(nameRef, nameBuf, bufLen-1, kCFStringEncodingUTF8)) nameBuf[0]=0; } fprintf(stdout, "common name: \"%s\"\n", (nameBuf && nameBuf[0] != 0) ? nameBuf : ""); if (nameBuf) free(nameBuf); safe_CFRelease(&nameRef); } if (printHash) { uint8 sha1_hash[20]; CSSM_DATA digest; digest.Length = sizeof(sha1_hash); digest.Data = sha1_hash; if (SecDigestGetData(CSSM_ALGID_SHA1, &digest, &certData) == CSSM_OK) { unsigned int i; uint32 len = digest.Length; uint8 *cp = digest.Data; fprintf(stdout, "SHA-1 hash: "); for(i=0; i