X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_csp/lib/RSA_DSA_signature.cpp diff --git a/libsecurity_apple_csp/lib/RSA_DSA_signature.cpp b/libsecurity_apple_csp/lib/RSA_DSA_signature.cpp deleted file mode 100644 index 1864d32e..00000000 --- a/libsecurity_apple_csp/lib/RSA_DSA_signature.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS - * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT - * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the - * specific language governing rights and limitations under the License. - */ - - -/* - * RSA_DSA_signature.cpp - openssl-based signature classes. - */ - -#include "RSA_DSA_signature.h" -#include "RSA_DSA_utils.h" -#include -#include -#include -#include -#include -#include - -#define rsaSigDebug(args...) secdebug("rsaSig", ## args) - -static ModuleNexus gMutex; - -RSASigner::~RSASigner() -{ - StLock _(gMutex()); - if(mWeMallocdRsaKey) { - assert(mRsaKey != NULL); - RSA_free(mRsaKey); - mRsaKey = NULL; - mWeMallocdRsaKey = false; - } -} - -/* reusable init */ -void RSASigner::signerInit( - const Context &context, - bool isSigning) -{ - StLock _(gMutex()); - - setIsSigning(isSigning); - keyFromContext(context); - - /* optional padding attribute */ - uint32 padding; - bool padPresent = context.getInt(CSSM_ATTRIBUTE_PADDING, padding); - if(padPresent) { - /* padding specified in context, convert to openssl style */ - switch(padding) { - case CSSM_PADDING_NONE: - mPadding = RSA_NO_PADDING; - break; - case CSSM_PADDING_PKCS1: - mPadding = RSA_PKCS1_PADDING; - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); - } - } - - /* optional blinding attribute */ - uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING); - if(blinding) { - if(RSA_blinding_on(mRsaKey, NULL) <= 0) { - /* actually no legit failures */ - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - } - else { - RSA_blinding_off(mRsaKey); - } - - setInitFlag(true); -} - -/* sign */ -void RSASigner::sign( - const void *data, - size_t dataLen, - void *sig, - size_t *sigLen) /* IN/OUT */ -{ - StLock _(gMutex()); - - if(mRsaKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - - /* get encoded digest info */ - CssmAutoData encodedInfo(alloc()); - int irtn = generateDigestInfo(data, - dataLen, - digestAlg(), - encodedInfo, - RSA_size(mRsaKey)); - if(irtn) { - rsaSigDebug("***digestInfo error\n"); - throwOpensslErr(irtn); - } - - /* signature := encrypted digest info */ - irtn = RSA_private_encrypt((int)encodedInfo.length(), - (unsigned char *)encodedInfo.data(), - (unsigned char *)sig, - mRsaKey, - mPadding); - if(irtn < 0) { - throwRsaDsa("RSA_private_encrypt"); - } - if((unsigned)irtn > *sigLen) { - rsaSigDebug("RSA_private_encrypt: sig overflow"); - CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); - } - *sigLen = (unsigned)irtn; -} - -/* verify */ -void RSASigner::verify( - const void *data, - size_t dataLen, - const void *sig, - size_t sigLen) -{ - StLock _(gMutex()); - - const char *op = NULL; - bool throwSigVerify = false; - - if(mRsaKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - - /* get encoded digest info */ - CssmAutoData encodedInfo(alloc()); - int irtn = generateDigestInfo(data, - dataLen, - digestAlg(), - encodedInfo, - RSA_size(mRsaKey)); - if(irtn) { - rsaSigDebug("***digestInfo error\n"); - CssmError::throwMe(/* FIXME */CSSMERR_CSP_INTERNAL_ERROR); - } - - /* malloc decrypted signature */ - unsigned char *decryptSig = - (unsigned char *)alloc().malloc(RSA_size(mRsaKey)); - unsigned decryptSigLen; - - /* signature should be encrypted digest info; decrypt the signature */ - irtn = RSA_public_decrypt((int)sigLen, - (unsigned char *)sig, - decryptSig, - mRsaKey, - mPadding); - if(irtn < 0) { - op = "RSA_public_decrypt"; - throwSigVerify = true; - goto abort; - } - decryptSigLen = (unsigned)irtn; - if(decryptSigLen != encodedInfo.length()) { - rsaSigDebug("***Decrypted signature length error (exp %ld, got %d)\n", - encodedInfo.length(), decryptSigLen); - throwSigVerify = true; - op = "RSA Sig length check"; - goto abort; - } - if(memcmp(decryptSig, encodedInfo.data(), decryptSigLen)) { - rsaSigDebug("***Signature miscompare\n"); - throwSigVerify = true; - op = "RSA Sig miscompare"; - goto abort; - } - else { - irtn = 0; - } -abort: - if(decryptSig != NULL) { - alloc().free(decryptSig); - } - if(throwSigVerify) { - clearOpensslErrors(); - CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED); - } -} - -/* works for both, but only used for signing */ -size_t RSASigner::maxSigSize() -{ - StLock _(gMutex()); - if(mRsaKey == NULL) { - return 0; - } - return RSA_size(mRsaKey); -} - -/* - * obtain key from context, validate, convert to native RSA key - */ -void RSASigner::keyFromContext( - const Context &context) -{ - if(initFlag() && (mRsaKey != NULL)) { - /* reusing context, OK */ - return; - } - - CSSM_KEYCLASS keyClass; - CSSM_KEYUSE keyUse; - if(isSigning()) { - /* signing with private key */ - keyClass = CSSM_KEYCLASS_PRIVATE_KEY; - keyUse = CSSM_KEYUSE_SIGN; - } - else { - /* verifying with public key */ - keyClass = CSSM_KEYCLASS_PUBLIC_KEY; - keyUse = CSSM_KEYUSE_VERIFY; - } - if(mRsaKey == NULL) { - CSSM_DATA label = {0, NULL}; - mRsaKey = contextToRsaKey(context, - mSession, - keyClass, - keyUse, - mWeMallocdRsaKey, - label); - /* cannot have label param for signing */ - assert(label.Data == NULL); - } -} - -DSASigner::~DSASigner() -{ - if(mWeMallocdDsaKey) { - assert(mDsaKey != NULL); - DSA_free(mDsaKey); - mDsaKey = NULL; - mWeMallocdDsaKey = false; - } -} - -/* reusable init */ -void DSASigner::signerInit( - const Context &context, - bool isSigning) -{ - setIsSigning(isSigning); - keyFromContext(context); - setInitFlag(true); -} - -/* sign */ -void DSASigner::sign( - const void *data, - size_t dataLen, - void *sig, - size_t *sigLen) /* IN/OUT */ -{ - if(mDsaKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - if(mDsaKey->priv_key == NULL) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - - /* get signature in internal format */ - DSA_SIG *dsaSig = DSA_do_sign((unsigned char *)data, (int)dataLen, mDsaKey); - if(dsaSig == NULL) { - throwRsaDsa("DSA_do_sign"); - } - - /* DER encode the signature */ - CssmAutoData encodedSig(alloc()); - int irtn = DSASigEncode(dsaSig, encodedSig); - if(irtn) { - throwRsaDsa("DSASigEncode"); - } - if(encodedSig.length() > *sigLen) { - throwRsaDsa("DSA sign overflow"); - } - memmove(sig, encodedSig.data(), encodedSig.length()); - *sigLen = encodedSig.length(); - DSA_SIG_free(dsaSig); -} - -/* verify */ -void DSASigner::verify( - const void *data, - size_t dataLen, - const void *sig, - size_t sigLen) -{ - bool throwSigVerify = false; - DSA_SIG *dsaSig = NULL; - CSSM_RETURN crtn = CSSM_OK; - int irtn; - - if(mDsaKey == NULL) { - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - if(mDsaKey->pub_key == NULL) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - - /* incoming sig is DER encoded....decode into internal format */ - dsaSig = DSA_SIG_new(); - crtn = DSASigDecode(dsaSig, sig, (unsigned int)sigLen); - if(crtn) { - goto abort; - } - - irtn = DSA_do_verify((unsigned char *)data, (int)dataLen, dsaSig, mDsaKey); - if(irtn != 1) { - throwSigVerify = true; - } - -abort: - if(dsaSig != NULL) { - DSA_SIG_free(dsaSig); - } - if(throwSigVerify) { - clearOpensslErrors(); - CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED); - } - else if(crtn) { - CssmError::throwMe(crtn); - } -} - -/* - * Works for both, but only used for signing. - * DSA sig is a sequence of two 160-bit integers. - */ -size_t DSASigner::maxSigSize() -{ - if(mDsaKey == NULL) { - return 0; - } - size_t outSize; - size_t sizeOfOneInt; - - sizeOfOneInt = (160 / 8) + // the raw contents - 1 + // possible leading zero - 2; // tag + length (assume DER, not BER) - outSize = (2 * sizeOfOneInt) + 5; - return outSize; -} - -/* - * obtain key from context, validate, convert to native DSA key - */ -void DSASigner::keyFromContext( - const Context &context) -{ - if(initFlag() && (mDsaKey != NULL)) { - /* reusing context, OK */ - return; - } - - CSSM_KEYCLASS keyClass; - CSSM_KEYUSE keyUse; - if(isSigning()) { - /* signing with private key */ - keyClass = CSSM_KEYCLASS_PRIVATE_KEY; - keyUse = CSSM_KEYUSE_SIGN; - } - else { - /* verifying with public key */ - keyClass = CSSM_KEYCLASS_PUBLIC_KEY; - keyUse = CSSM_KEYUSE_VERIFY; - } - if(mDsaKey == NULL) { - mDsaKey = contextToDsaKey(context, - mSession, - keyClass, - keyUse, - mWeMallocdDsaKey); - } -}