1/* 2 * Copyright (c) 2000-2001 Apple Computer, 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 * Created 2/20/2001 by dmitch. 23 */ 24 25#ifdef CRYPTKIT_CSP_ENABLE 26 27#include "FEESignatureObject.h" 28#include <security_cryptkit/feePublicKey.h> 29#include <security_cryptkit/feeDigitalSignature.h> 30#include <security_cryptkit/falloc.h> 31#include <stdexcept> 32#include <assert.h> 33#include <security_utilities/debugging.h> 34 35#define feeSigObjDebug(args...) secdebug("feeSig", ##args) 36 37CryptKit::FEESigner::~FEESigner() 38{ 39 if(mWeMallocdFeeKey) { 40 assert(mFeeKey != NULL); 41 feePubKeyFree(mFeeKey); 42 } 43} 44 45/* 46 * obtain key from context, validate, convert to native FEE key 47 */ 48void CryptKit::FEESigner::keyFromContext( 49 const Context &context) 50{ 51 if(initFlag() && (mFeeKey != NULL)) { 52 /* reusing context, OK */ 53 return; 54 } 55 56 CSSM_KEYCLASS keyClass; 57 CSSM_KEYUSE keyUse; 58 if(isSigning()) { 59 /* signing with private key */ 60 keyClass = CSSM_KEYCLASS_PRIVATE_KEY; 61 keyUse = CSSM_KEYUSE_SIGN; 62 } 63 else { 64 /* verifying with public key */ 65 keyClass = CSSM_KEYCLASS_PUBLIC_KEY; 66 keyUse = CSSM_KEYUSE_VERIFY; 67 } 68 if(mFeeKey == NULL) { 69 mFeeKey = contextToFeeKey(context, 70 mSession, 71 CSSM_ATTRIBUTE_KEY, 72 keyClass, 73 keyUse, 74 mWeMallocdFeeKey); 75 } 76} 77 78/* reusable init */ 79void CryptKit::FEESigner::signerInit( 80 const Context &context, 81 bool isSigning) 82{ 83 setIsSigning(isSigning); 84 keyFromContext(context); 85 setInitFlag(true); 86} 87 88/* 89 * Note that, unlike the implementation in security_cryptkit/feePublicKey.c, we ignore 90 * the Pm which used to be used as salt for the digest. That made staged verification 91 * impossible and I do not believe it increased security. 92 */ 93void CryptKit::FEERawSigner::sign( 94 const void *data, 95 size_t dataLen, 96 void *sig, 97 size_t *sigLen) /* IN/OUT */ 98{ 99 feeSig fsig; 100 feeReturn frtn; 101 unsigned char *feeSig; 102 unsigned feeSigLen=0; 103 104 if(mFeeKey == NULL) { 105 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)"); 106 } 107 fsig = feeSigNewWithKey(mFeeKey, mRandFcn, mRandRef); 108 if(fsig == NULL) { 109 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign"); 110 } 111 frtn = feeSigSign(fsig, 112 (unsigned char *)data, 113 (unsigned)dataLen, 114 mFeeKey); 115 if(frtn == FR_Success) { 116 frtn = feeSigData(fsig, &feeSig, &feeSigLen); 117 } 118 feeSigFree(fsig); 119 if(frtn) { 120 throwCryptKit(frtn, "FEERawSigner::sign"); 121 } 122 123 /* copy out to caller and ffree */ 124 if(*sigLen < feeSigLen) { 125 feeSigObjDebug("FEERawSigner sign overflow\n"); 126 ffree(feeSig); 127 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); 128 } 129 memmove(sig, feeSig, feeSigLen); 130 *sigLen = feeSigLen; 131 ffree(feeSig); 132} 133 134void CryptKit::FEERawSigner::verify( 135 const void *data, 136 size_t dataLen, 137 const void *sig, 138 size_t sigLen) 139{ 140 feeSig fsig; 141 feeReturn frtn; 142 143 if(mFeeKey == NULL) { 144 throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)"); 145 } 146 frtn = feeSigParse((unsigned char *)sig, sigLen, &fsig); 147 if(frtn) { 148 throwCryptKit(frtn, "feeSigParse"); 149 } 150 frtn = feeSigVerify(fsig, 151 (unsigned char *)data, 152 (unsigned int)dataLen, 153 mFeeKey); 154 feeSigFree(fsig); 155 if(frtn) { 156 throwCryptKit(frtn, NULL); 157 } 158} 159 160size_t CryptKit::FEERawSigner::maxSigSize() 161{ 162 unsigned rtn; 163 feeReturn frtn; 164 165 frtn = feeSigSize(mFeeKey, &rtn); 166 if(frtn) { 167 throwCryptKit(frtn, "feeSigSize"); 168 } 169 return rtn; 170} 171 172/* ECDSA - this is really easy. */ 173 174void CryptKit::FEEECDSASigner::sign( 175 const void *data, 176 size_t dataLen, 177 void *sig, 178 size_t *sigLen) /* IN/OUT */ 179{ 180 unsigned char *feeSig; 181 unsigned feeSigLen; 182 feeReturn frtn; 183 184 if(mFeeKey == NULL) { 185 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)"); 186 } 187 frtn = feeECDSASign(mFeeKey, 188 (unsigned char *)data, // data to be signed 189 (unsigned int)dataLen, // in bytes 190 mRandFcn, 191 mRandRef, 192 &feeSig, 193 &feeSigLen); 194 if(frtn) { 195 throwCryptKit(frtn, "feeECDSASign"); 196 } 197 /* copy out to caller and ffree */ 198 if(*sigLen < feeSigLen) { 199 feeSigObjDebug("feeECDSASign overflow\n"); 200 ffree(feeSig); 201 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); 202 } 203 memmove(sig, feeSig, feeSigLen); 204 *sigLen = feeSigLen; 205 ffree(feeSig); 206 207} 208 209void CryptKit::FEEECDSASigner::verify( 210 const void *data, 211 size_t dataLen, 212 const void *sig, 213 size_t sigLen) 214{ 215 feeReturn frtn; 216 217 if(mFeeKey == NULL) { 218 throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)"); 219 } 220 frtn = feeECDSAVerify((unsigned char *)sig, 221 sigLen, 222 (unsigned char *)data, 223 (unsigned int)dataLen, 224 mFeeKey); 225 if(frtn) { 226 throwCryptKit(frtn, NULL); 227 } 228} 229 230size_t CryptKit::FEEECDSASigner::maxSigSize() 231{ 232 unsigned rtn; 233 feeReturn frtn; 234 235 frtn = feeECDSASigSize(mFeeKey, &rtn); 236 if(frtn) { 237 throwCryptKit(frtn, "feeECDSASigSize"); 238 } 239 return rtn; 240} 241 242#endif /* CRYPTKIT_CSP_ENABLE */ 243