]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/lib/FEESignatureObject.cpp
Security-59306.120.7.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / lib / FEESignatureObject.cpp
1 /*
2 * Copyright (c) 2000-2001,2011-2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * FEESignatureObject.cpp - implementations of FEE-style raw sign/verify classes
21 *
22 */
23
24 #ifdef CRYPTKIT_CSP_ENABLE
25
26 #include "FEESignatureObject.h"
27 #include <security_cryptkit/feePublicKey.h>
28 #include <security_cryptkit/feeDigitalSignature.h>
29 #include <security_cryptkit/falloc.h>
30 #include <stdexcept>
31 #include <assert.h>
32 #include <security_utilities/debugging.h>
33
34 #define feeSigObjDebug(args...) secinfo("feeSig", ##args)
35
36 CryptKit::FEESigner::~FEESigner()
37 {
38 if(mWeMallocdFeeKey) {
39 assert(mFeeKey != NULL);
40 feePubKeyFree(mFeeKey);
41 }
42 }
43
44 /*
45 * padding from context
46 */
47 void CryptKit::FEESigner::sigFormatFromContext(
48 const Context &context)
49 {
50 CSSM_PADDING padding = context.getInt(CSSM_ATTRIBUTE_PADDING);
51 switch(padding) {
52 case CSSM_PADDING_SIGRAW:
53 mSigFormat=FSF_RAW;
54 break;
55 default:
56 mSigFormat=FSF_DER;
57 }
58 }
59 /*
60 * obtain key from context, validate, convert to native FEE key
61 */
62 void CryptKit::FEESigner::keyFromContext(
63 const Context &context)
64 {
65 if(initFlag() && (mFeeKey != NULL)) {
66 /* reusing context, OK */
67 return;
68 }
69
70 CSSM_KEYCLASS keyClass;
71 CSSM_KEYUSE keyUse;
72 if(isSigning()) {
73 /* signing with private key */
74 keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
75 keyUse = CSSM_KEYUSE_SIGN;
76 }
77 else {
78 /* verifying with public key */
79 keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
80 keyUse = CSSM_KEYUSE_VERIFY;
81 }
82 if(mFeeKey == NULL) {
83 mFeeKey = contextToFeeKey(context,
84 mSession,
85 CSSM_ATTRIBUTE_KEY,
86 keyClass,
87 keyUse,
88 mWeMallocdFeeKey);
89 }
90 }
91
92 /* reusable init */
93 void CryptKit::FEESigner::signerInit(
94 const Context &context,
95 bool isSigning)
96 {
97 setIsSigning(isSigning);
98 keyFromContext(context);
99 sigFormatFromContext(context);
100 setInitFlag(true);
101 }
102
103 /*
104 * Note that, unlike the implementation in security_cryptkit/feePublicKey.c, we ignore
105 * the Pm which used to be used as salt for the digest. That made staged verification
106 * impossible and I do not believe it increased security.
107 */
108 void CryptKit::FEERawSigner::sign(
109 const void *data,
110 size_t dataLen,
111 void *sig,
112 size_t *sigLen) /* IN/OUT */
113 {
114 feeSig fsig;
115 feeReturn frtn;
116 unsigned char *feeSig = NULL;
117 unsigned feeSigLen=0;
118
119 if(mFeeKey == NULL) {
120 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
121 }
122 fsig = feeSigNewWithKey(mFeeKey, mRandFcn, mRandRef);
123 if(fsig == NULL) {
124 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign");
125 }
126 frtn = feeSigSign(fsig,
127 (unsigned char *)data,
128 (unsigned)dataLen,
129 mFeeKey);
130 if(frtn == FR_Success) {
131 frtn = feeSigData(fsig, &feeSig, &feeSigLen);
132 }
133 feeSigFree(fsig);
134 if(frtn) {
135 throwCryptKit(frtn, "FEERawSigner::sign");
136 }
137
138 /* copy out to caller and ffree */
139 if(*sigLen < feeSigLen) {
140 feeSigObjDebug("FEERawSigner sign overflow\n");
141 ffree(feeSig);
142 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
143 }
144 memmove(sig, feeSig, feeSigLen);
145 *sigLen = feeSigLen;
146 ffree(feeSig);
147 }
148
149 void CryptKit::FEERawSigner::verify(
150 const void *data,
151 size_t dataLen,
152 const void *sig,
153 size_t sigLen)
154 {
155 feeSig fsig;
156 feeReturn frtn;
157
158 if(mFeeKey == NULL) {
159 throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)");
160 }
161 frtn = feeSigParse((unsigned char *)sig, sigLen, &fsig);
162 if(frtn) {
163 throwCryptKit(frtn, "feeSigParse");
164 }
165 frtn = feeSigVerify(fsig,
166 (unsigned char *)data,
167 (unsigned int)dataLen,
168 mFeeKey);
169 feeSigFree(fsig);
170 if(frtn) {
171 throwCryptKit(frtn, NULL);
172 }
173 }
174
175 size_t CryptKit::FEERawSigner::maxSigSize()
176 {
177 unsigned rtn;
178 feeReturn frtn;
179
180 frtn = feeSigSize(mFeeKey, &rtn);
181 if(frtn) {
182 throwCryptKit(frtn, "feeSigSize");
183 }
184 return rtn;
185 }
186
187 /* ECDSA - this is really easy. */
188
189 void CryptKit::FEEECDSASigner::sign(
190 const void *data,
191 size_t dataLen,
192 void *sig,
193 size_t *sigLen) /* IN/OUT */
194 {
195 unsigned char *feeSig;
196 unsigned feeSigLen;
197 feeReturn frtn;
198
199 if(mFeeKey == NULL) {
200 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
201 }
202 frtn = feeECDSASign(mFeeKey,
203 mSigFormat,
204 (unsigned char *)data, // data to be signed
205 (unsigned int)dataLen, // in bytes
206 mRandFcn,
207 mRandRef,
208 &feeSig,
209 &feeSigLen);
210 if(frtn) {
211 throwCryptKit(frtn, "feeECDSASign");
212 }
213 /* copy out to caller and ffree */
214 if(*sigLen < feeSigLen) {
215 feeSigObjDebug("feeECDSASign overflow\n");
216 ffree(feeSig);
217 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
218 }
219 memmove(sig, feeSig, feeSigLen);
220 *sigLen = feeSigLen;
221 ffree(feeSig);
222
223 }
224
225 void CryptKit::FEEECDSASigner::verify(
226 const void *data,
227 size_t dataLen,
228 const void *sig,
229 size_t sigLen)
230 {
231 feeReturn frtn;
232
233 if(mFeeKey == NULL) {
234 throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)");
235 }
236 frtn = feeECDSAVerify(
237 (unsigned char *)sig,
238 sigLen,
239 (unsigned char *)data,
240 (unsigned int)dataLen,
241 mFeeKey,
242 mSigFormat);
243 if(frtn) {
244 throwCryptKit(frtn, NULL);
245 }
246 }
247
248 size_t CryptKit::FEEECDSASigner::maxSigSize()
249 {
250 unsigned rtn;
251 feeReturn frtn;
252
253 frtn = feeECDSASigSize(mFeeKey, &rtn);
254 if(frtn) {
255 throwCryptKit(frtn, "feeECDSASigSize");
256 }
257 return rtn;
258 }
259
260 #endif /* CRYPTKIT_CSP_ENABLE */