1/* 2 * Copyright (c) 2011 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// xar++ - interface to XAR-format archive files 26// 27#include "xar++.h" 28#include <security_utilities/cfutilities.h> 29#include <Security/Security.h> 30 31 32namespace Security { 33namespace CodeSigning { 34 35 36Xar::Xar(const char *path) 37{ 38 mXar = 0; 39 mSigCMS = 0; 40 mSigClassic = 0; 41 if (path) 42 open(path); 43} 44 45void Xar::open(const char *path) 46{ 47 if ((mXar = ::xar_open(path, READ)) == NULL) 48 return; 49 50 xar_signature_t sig = ::xar_signature_first(mXar); 51 // read signatures until we find a CMS signature 52 while (sig && mSigCMS == NULL) { 53 const char *type = ::xar_signature_type(sig); 54 if (strcmp(type, "CMS") == 0) { 55 mSigCMS = sig; 56 } else if (strcmp(type, "RSA") == 0) { 57 mSigClassic = sig; 58 } 59 sig = ::xar_signature_next(sig); 60 } 61} 62 63Xar::~Xar() 64{ 65 if (mXar) 66 ::xar_close(mXar); 67} 68 69static CFArrayRef copyCertChainFromSignature(xar_signature_t sig) 70{ 71 unsigned count = xar_signature_get_x509certificate_count(sig); 72 CFRef<CFMutableArrayRef> certs = makeCFMutableArray(0); 73 for (unsigned ix = 0; ix < count; ix++) { 74 const uint8_t *data; 75 uint32_t length; 76 if (xar_signature_get_x509certificate_data(sig, ix, &data, &length) == 0) { 77 CFTempData cdata(data, length); 78 CFRef<SecCertificateRef> cert = SecCertificateCreateWithData(NULL, cdata); 79 CFArrayAppendValue(certs, cert.get()); 80 } 81 } 82 return certs.yield(); 83} 84 85CFArrayRef Xar::copyCertChain() 86{ 87 if (mSigCMS) 88 return copyCertChainFromSignature(mSigCMS); 89 else if (mSigClassic) 90 return copyCertChainFromSignature(mSigClassic); 91 return NULL; 92} 93 94 95} // end namespace CodeSigning 96} // end namespace Security 97