]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/lib/SecCertificateRequest.cpp
Security-57740.60.18.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / SecCertificateRequest.cpp
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
31 CFTypeID
32 SecCertificateRequestGetTypeID(void)
33 {
34 BEGIN_SECAPI
35
36 return gTypes().CertificateRequest.typeID;
37
38 END_SECAPI1(_kCFRuntimeNotATypeID)
39 }
40
41
42 OSStatus 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
60 OSStatus 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
72 OSStatus 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
84 OSStatus 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
161 OSStatus 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
180 OSStatus 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 }