1/* 2 * Copyright (c) 2002-2004,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#include <Security/SecCertificateRequest.h> 25 26#include "SecBridge.h" 27#include "CertificateRequest.h" 28#include "SecImportExport.h" 29#include "SecCertificate.h" 30 31CFTypeID 32SecCertificateRequestGetTypeID(void) 33{ 34 BEGIN_SECAPI 35 36 return gTypes().CertificateRequest.typeID; 37 38 END_SECAPI1(_kCFRuntimeNotATypeID) 39} 40 41 42OSStatus SecCertificateRequestCreate( 43 const CSSM_OID *policy, 44 CSSM_CERT_TYPE certificateType, 45 CSSM_TP_AUTHORITY_REQUEST_TYPE requestType, 46 SecKeyRef privateKeyItemRef, 47 SecKeyRef publicKeyItemRef, 48 const SecCertificateRequestAttributeList* attributeList, 49 SecCertificateRequestRef* certRequest) 50{ 51 BEGIN_SECAPI 52 Required(certRequest); 53 Required(policy); 54 *certRequest = (new CertificateRequest(*policy, certificateType, requestType, 55 privateKeyItemRef, publicKeyItemRef, attributeList))->handle(); 56 END_SECAPI 57} 58 59 60OSStatus SecCertificateRequestSubmit( 61 SecCertificateRequestRef certRequest, 62 sint32* estimatedTime) 63{ 64 BEGIN_SECAPI 65 66 CertificateRequest::required(certRequest)->submit(estimatedTime); 67 68 END_SECAPI 69} 70 71 72OSStatus SecCertificateRequestGetType( 73 SecCertificateRequestRef certRequestRef, 74 CSSM_TP_AUTHORITY_REQUEST_TYPE *requestType) 75{ 76 BEGIN_SECAPI 77 78 Required(requestType); 79 *requestType = CertificateRequest::required(certRequestRef)->reqType(); 80 81 END_SECAPI 82} 83 84OSStatus SecCertificateRequestGetResult( 85 SecCertificateRequestRef certRequestRef, 86 SecKeychainRef keychain, 87 sint32 *estimatedTime, 88 SecCertificateRef *certificateRef) 89{ 90 BEGIN_SECAPI 91 92 CssmData certData; 93 *certificateRef = NULL; 94 CertificateRequest::required(certRequestRef)->getResult(estimatedTime, certData); 95 if(certData.data() != NULL) { 96 /* 97 * Convert to SecCertifcateRef, optionally import. 98 */ 99 CFDataRef cfCert = CFDataCreate(NULL, (UInt8 *)certData.data(), certData.Length); 100 SecExternalItemType itemType = kSecItemTypeCertificate; 101 CFArrayRef outItems = NULL; 102 bool freeKcRef = false; 103 OSStatus ortn; 104 105 if(keychain == NULL) { 106 /* 107 * Unlike most Sec* calls, if the keychain argument to SecKeychainItemImport() 108 * is NULL, the item is not imported to the default keychain. At our 109 * interface, however, a NULL keychain means "import to the default 110 * keychain". 111 */ 112 ortn = SecKeychainCopyDefault(&keychain); 113 if(ortn) { 114 certReqDbg("GetResult: SecKeychainCopyDefault failure"); 115 /* oh well, there's nothing we can do about this */ 116 } 117 else { 118 freeKcRef = true; 119 } 120 } 121 ortn = SecKeychainItemImport(cfCert, NULL, 122 NULL, // format, don't care 123 &itemType, 124 0, // flags 125 NULL, // keyParams 126 keychain, // optional, like ours 127 &outItems); 128 CFRelease(cfCert); 129 if(freeKcRef) { 130 CFRelease(keychain); 131 } 132 if(ortn) { 133 certReqDbg("SecCertificateRequestGetResult: SecKeychainItemImport failure"); 134 MacOSError::throwMe(ortn); 135 } 136 CFIndex numItems = CFArrayGetCount(outItems); 137 switch(numItems) { 138 case 0: 139 certReqDbg("SecCertificateRequestGetResult: import zero items"); 140 MacOSError::throwMe(errSecInternalComponent); 141 default: 142 certReqDbg("SecCertificateRequestGetResult: import %d items", 143 (int)numItems); 144 /* but drop thru anyway, take the first one */ 145 case 1: 146 SecCertificateRef certRef = 147 (SecCertificateRef)(CFArrayGetValueAtIndex(outItems, 0)); 148 if(CFGetTypeID(certRef) != SecCertificateGetTypeID()) { 149 certReqDbg("SecCertificateRequestGetResult: bad type"); 150 } 151 else { 152 CFRetain(certRef); 153 *certificateRef = certRef; 154 } 155 } 156 CFRelease(outItems); 157 } 158 END_SECAPI 159} 160 161OSStatus SecCertificateFindRequest( 162 const CSSM_OID *policy, 163 CSSM_CERT_TYPE certificateType, 164 CSSM_TP_AUTHORITY_REQUEST_TYPE requestType, 165 SecKeyRef publicKeyItemRef, 166 SecKeyRef privateKeyItemRef, 167 const SecCertificateRequestAttributeList* attributeList, 168 SecCertificateRequestRef* certRequest) 169{ 170 BEGIN_SECAPI 171 172 Required(certRequest); 173 Required(policy); 174 *certRequest = (new CertificateRequest(*policy, certificateType, requestType, 175 privateKeyItemRef, publicKeyItemRef, attributeList, false))->handle(); 176 END_SECAPI 177} 178 179 180OSStatus SecCertificateRequestGetData( 181 SecCertificateRequestRef certRequestRef, 182 CSSM_DATA *data) 183{ 184 BEGIN_SECAPI 185 186 Required(data); 187 CertificateRequest::required(certRequestRef)->getReturnData(CssmData::overlay(*data)); 188 189 END_SECAPI 190} 191