#include "CMSUtils.h"
#include <stdlib.h>
#include <string.h>
#include <security_asn1/secerr.h>
#include <security_asn1/seccomon.h>
#include <Security/SecBase.h>
void cmsCopyCmsData(
const SecAsn1Item *src,
SecAsn1Item *dst)
{
dst->Data = (uint8_t *)malloc(src->Length);
memmove(dst->Data, src->Data, src->Length);
dst->Length = src->Length;
}
OSStatus cmsAppendToArray(
CFTypeRef srcItemOrArray,
CFMutableArrayRef *dstArray,
CFTypeID expectedType)
{
if(srcItemOrArray == NULL) {
return errSecSuccess;
}
if(*dstArray == NULL) {
*dstArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
}
CFTypeID inType = CFGetTypeID(srcItemOrArray);
if(inType == CFArrayGetTypeID()) {
CFArrayRef srcArray = (CFArrayRef)srcItemOrArray;
CFRange srcRange = {0, CFArrayGetCount(srcArray)};
CFArrayAppendArray(*dstArray, srcArray, srcRange);
}
else if(inType == expectedType) {
CFArrayAppendValue(*dstArray, srcItemOrArray);
}
else {
return errSecParam;
}
return errSecSuccess;
}
OSStatus cmsRtnToOSStatusDefault(OSStatus smimeRtn, OSStatus defaultRtn) {
if(smimeRtn == SECFailure) {
smimeRtn = PORT_GetError();
PORT_SetError(0); if(smimeRtn == 0) {
dprintf("cmsRtnToOSStatus: SECFailure, no status avilable\n");
return defaultRtn ? defaultRtn : errSecInternalComponent;
}
}
if(!IS_SEC_ERROR(smimeRtn)) {
return smimeRtn;
}
switch(smimeRtn) {
case SEC_ERROR_BAD_DER:
case SEC_ERROR_BAD_DATA:
return errSecUnknownFormat;
case SEC_ERROR_NO_MEMORY:
return errSecAllocate;
case SEC_ERROR_IO:
return errSecIO;
case SEC_ERROR_OUTPUT_LEN:
case SEC_ERROR_INPUT_LEN:
case SEC_ERROR_INVALID_ARGS:
case SEC_ERROR_INVALID_ALGORITHM:
case SEC_ERROR_INVALID_AVA:
case SEC_ERROR_INVALID_TIME:
return errSecParam;
case SEC_ERROR_PKCS7_BAD_SIGNATURE:
case SEC_ERROR_BAD_SIGNATURE:
return errSecInvalidSignature;
case SEC_ERROR_EXPIRED_CERTIFICATE:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
return errSecCertificateExpired;
case SEC_ERROR_REVOKED_CERTIFICATE:
return errSecCertificateRevoked;
case SEC_ERROR_UNKNOWN_ISSUER:
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_UNTRUSTED_CERT:
return errSecNotTrusted;
case SEC_ERROR_CERT_USAGES_INVALID:
case SEC_ERROR_INADEQUATE_KEY_USAGE:
return errSecKeyUsageIncorrect;
case SEC_INTERNAL_ONLY:
return errSecInternalComponent;
case SEC_ERROR_NO_USER_INTERACTION:
return errSecInteractionNotAllowed;
case SEC_ERROR_USER_CANCELLED:
return errSecUserCanceled;
default:
dprintf("cmsRtnToOSStatus: smimeRtn 0x%x\n", smimeRtn);
return defaultRtn ? defaultRtn : errSecInternalComponent;
}
}
OSStatus cmsRtnToOSStatus(OSStatus smimeRtn) {
return cmsRtnToOSStatusDefault(smimeRtn, 0);
}