1/* 2 * Copyright (c) 2006,2011,2013-2014 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 24/* 25 * CMSUtils.cpp - common utility routines for libCMS. 26 */ 27 28#include "CMSUtils.h" 29#include <stdlib.h> 30#include <string.h> 31#include <security_asn1/secerr.h> 32#include <security_asn1/seccomon.h> 33#include <Security/SecBase.h> 34 35/* 36 * Copy a CSSM_DATA, mallocing the result. 37 */ 38void cmsCopyCmsData( 39 const CSSM_DATA *src, 40 CSSM_DATA *dst) 41{ 42 dst->Data = (uint8 *)malloc(src->Length); 43 memmove(dst->Data, src->Data, src->Length); 44 dst->Length = src->Length; 45} 46 47/* 48 * Append a CF type, or the contents of an array, to another array. 49 * destination array will be created if necessary. 50 * If srcItemOrArray is not of the type specified in expectedType, 51 * errSecParam will be returned. 52 */ 53OSStatus cmsAppendToArray( 54 CFTypeRef srcItemOrArray, 55 CFMutableArrayRef *dstArray, 56 CFTypeID expectedType) 57{ 58 if(srcItemOrArray == NULL) { 59 return errSecSuccess; 60 } 61 if(*dstArray == NULL) { 62 *dstArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 63 } 64 CFTypeID inType = CFGetTypeID(srcItemOrArray); 65 if(inType == CFArrayGetTypeID()) { 66 CFArrayRef srcArray = (CFArrayRef)srcItemOrArray; 67 CFRange srcRange = {0, CFArrayGetCount(srcArray)}; 68 CFArrayAppendArray(*dstArray, srcArray, srcRange); 69 } 70 else if(inType == expectedType) { 71 CFArrayAppendValue(*dstArray, srcItemOrArray); 72 } 73 else { 74 return errSecParam; 75 } 76 return errSecSuccess; 77} 78 79/* 80 * Munge an OSStatus returned from libsecurity_smime, which may well be an ASN.1 private 81 * error code, to a real OSStatus. 82 */ 83OSStatus cmsRtnToOSStatus( 84 OSStatus smimeRtn, // from libsecurity_smime 85 OSStatus defaultRtn) // use this if we can't map smimeRtn 86{ 87 if(smimeRtn == SECFailure) { 88 /* This is a SECStatus. Try to get detailed error info. */ 89 smimeRtn = PORT_GetError(); 90 if(smimeRtn == 0) { 91 /* S/MIME just gave us generic error; no further info available; punt. */ 92 dprintf("cmsRtnToOSStatus: SECFailure, no status avilable\n"); 93 return defaultRtn ? defaultRtn : errSecInternalComponent; 94 } 95 /* else proceed to map smimeRtn to OSStatus */ 96 } 97 if(!IS_SEC_ERROR(smimeRtn)) { 98 /* isn't ASN.1 or S/MIME error; use as is. */ 99 return smimeRtn; 100 } 101 102 /* Convert SECErrorCodes to OSStatus */ 103 switch(smimeRtn) { 104 case SEC_ERROR_BAD_DER: 105 case SEC_ERROR_BAD_DATA: 106 return errSecUnknownFormat; 107 case SEC_ERROR_NO_MEMORY: 108 return errSecAllocate; 109 case SEC_ERROR_IO: 110 return errSecIO; 111 case SEC_ERROR_OUTPUT_LEN: 112 case SEC_ERROR_INPUT_LEN: 113 case SEC_ERROR_INVALID_ARGS: 114 case SEC_ERROR_INVALID_ALGORITHM: 115 case SEC_ERROR_INVALID_AVA: 116 case SEC_ERROR_INVALID_TIME: 117 return errSecParam; 118 case SEC_ERROR_PKCS7_BAD_SIGNATURE: 119 case SEC_ERROR_BAD_SIGNATURE: 120 return CSSMERR_CSP_VERIFY_FAILED; 121 case SEC_ERROR_EXPIRED_CERTIFICATE: 122 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: 123 return CSSMERR_TP_CERT_EXPIRED; 124 case SEC_ERROR_REVOKED_CERTIFICATE: 125 return CSSMERR_TP_CERT_REVOKED; 126 case SEC_ERROR_UNKNOWN_ISSUER: 127 case SEC_ERROR_UNTRUSTED_ISSUER: 128 case SEC_ERROR_UNTRUSTED_CERT: 129 return CSSMERR_TP_NOT_TRUSTED; 130 case SEC_ERROR_CERT_USAGES_INVALID: 131 case SEC_ERROR_INADEQUATE_KEY_USAGE: 132 return CSSMERR_CSP_KEY_USAGE_INCORRECT; 133 case SEC_INTERNAL_ONLY: 134 return errSecInternalComponent; 135 case SEC_ERROR_NO_USER_INTERACTION: 136 return errSecInteractionNotAllowed; 137 case SEC_ERROR_USER_CANCELLED: 138 return errSecUserCanceled; 139 default: 140 dprintf("cmsRtnToOSStatus: smimeRtn 0x%x\n", smimeRtn); 141 return defaultRtn ? defaultRtn : errSecInternalComponent; 142 } 143} 144