X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_transform/lib/Digest.cpp diff --git a/Security/libsecurity_transform/lib/Digest.cpp b/Security/libsecurity_transform/lib/Digest.cpp deleted file mode 100644 index 20c9abd4..00000000 --- a/Security/libsecurity_transform/lib/Digest.cpp +++ /dev/null @@ -1,592 +0,0 @@ -#include "Digest.h" -#include "SecDigestTransform.h" -#include "Utilities.h" - -Digest::Digest(CFStringRef digestType, size_t digestLength) : mDigestType(digestType), mDigestLength(digestLength) -{ - // we don't need to retain the type here because it's a constant -} - - - -Digest::~Digest() -{ -} - -int Digest::LengthForType(CFStringRef type) -{ - if (!CFStringCompare(kSecDigestSHA1, type, kCFCompareAnchored)) { - return CC_SHA1_DIGEST_LENGTH; - } else if (!CFStringCompare(kSecDigestSHA2, type, kCFCompareAnchored)) { - // XXX SHA2 comes in multiple length flavors, our buest guess is "the big one" - return CC_SHA256_DIGEST_LENGTH; - } else if (!CFStringCompare(kSecDigestMD2, type, kCFCompareAnchored)) { - return CC_MD2_DIGEST_LENGTH; - } else if (!CFStringCompare(kSecDigestMD4, type, kCFCompareAnchored)) { - return CC_MD4_DIGEST_LENGTH; - } else if (!CFStringCompare(kSecDigestMD5, type, kCFCompareAnchored)) { - return CC_MD5_DIGEST_LENGTH; - } else { - return transforms_assume(type == CFSTR("A supported digest type")); - } -} - -CFDictionaryRef Digest::CopyState() -{ - CFMutableDictionaryRef dr = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(dr, kSecDigestTypeAttribute, mDigestType); - - CFIndex size = mDigestLength; - CFNumberRef nr = CFNumberCreate(NULL, kCFNumberCFIndexType, &size); - CFDictionaryAddValue(dr, kSecDigestLengthAttribute, nr); - CFRelease(nr); - - return dr; -} - - - -MD2Digest::MD2Digest() : Digest(kSecDigestMD2, CC_MD2_DIGEST_LENGTH) -{ - CC_MD2_Init(&mContext); -} - - - -void MD2Digest::Update(const void* buffer, size_t length) -{ - CC_MD2_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t MD2Digest::DigestLength() -{ - return CC_MD2_DIGEST_LENGTH; -} - - - -const void* MD2Digest::Finalize() -{ - CC_MD2_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - -MD4Digest::MD4Digest() : Digest(kSecDigestMD4, CC_MD4_DIGEST_LENGTH) -{ - CC_MD4_Init(&mContext); -} - - - -void MD4Digest::Update(const void* buffer, size_t length) -{ - CC_MD4_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t MD4Digest::DigestLength() -{ - return CC_MD4_DIGEST_LENGTH; -} - - - -const void* MD4Digest::Finalize() -{ - CC_MD4_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - - - - -MD5Digest::MD5Digest() : Digest(kSecDigestMD5, CC_MD5_DIGEST_LENGTH) -{ - CC_MD5_Init(&mContext); -} - - - -void MD5Digest::Update(const void* buffer, size_t length) -{ - CC_MD5_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t MD5Digest::DigestLength() -{ - return CC_MD5_DIGEST_LENGTH; -} - - - -const void* MD5Digest::Finalize() -{ - CC_MD5_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - -SHA1Digest::SHA1Digest() : Digest(kSecDigestSHA1, CC_SHA1_DIGEST_LENGTH) -{ - CC_SHA1_Init(&mContext); -} - - - -void SHA1Digest::Update(const void* buffer, size_t length) -{ - CC_SHA1_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t SHA1Digest::DigestLength() -{ - return CC_SHA1_DIGEST_LENGTH; -} - - - -const void* SHA1Digest::Finalize() -{ - CC_SHA1_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - -SHA256Digest::SHA256Digest() : Digest(kSecDigestSHA2, CC_SHA256_DIGEST_LENGTH) -{ - CC_SHA256_Init(&mContext); -} - - - -void SHA256Digest::Update(const void* buffer, size_t length) -{ - CC_SHA256_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t SHA256Digest::DigestLength() -{ - return CC_SHA256_DIGEST_LENGTH; -} - - - -const void* SHA256Digest::Finalize() -{ - CC_SHA256_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - -SHA224Digest::SHA224Digest() : Digest(kSecDigestSHA2, CC_SHA224_DIGEST_LENGTH) -{ - CC_SHA224_Init(&mContext); -} - - - -void SHA224Digest::Update(const void* buffer, size_t length) -{ - CC_SHA224_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t SHA224Digest::DigestLength() -{ - return CC_SHA224_DIGEST_LENGTH; -} - - - -const void* SHA224Digest::Finalize() -{ - CC_SHA224_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - -SHA512Digest::SHA512Digest() : Digest(kSecDigestSHA2, CC_SHA512_DIGEST_LENGTH) -{ - CC_SHA512_Init(&mContext); -} - - - -void SHA512Digest::Update(const void* buffer, size_t length) -{ - CC_SHA512_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t SHA512Digest::DigestLength() -{ - return CC_SHA512_DIGEST_LENGTH; -} - - - -const void* SHA512Digest::Finalize() -{ - CC_SHA512_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - -SHA384Digest::SHA384Digest() : Digest(kSecDigestSHA2, CC_SHA384_DIGEST_LENGTH) -{ - CC_SHA384_Init(&mContext); -} - - - -void SHA384Digest::Update(const void* buffer, size_t length) -{ - CC_SHA384_Update(&mContext, buffer, (CC_LONG)length); -} - - - -size_t SHA384Digest::DigestLength() -{ - return CC_SHA384_DIGEST_LENGTH; -} - - - -const void* SHA384Digest::Finalize() -{ - CC_SHA384_Final(mDigestBuffer, &mContext); - return mDigestBuffer; -} - - - -DigestTransform::DigestTransform() : Transform(CFSTR("Digest Transform")) -{ - mDigest = NULL; -} - - -CFErrorRef DigestTransform::Setup(CFTypeRef dt, CFIndex length) -{ - if (dt == NULL) - { - dt = kSecDigestSHA2; - length = 512; - } - transforms_assume_zero(mDigest); - - CFStringRef digestType = (CFStringRef) dt; - - // figure out what kind of digest is being requested - if (CFStringCompare(digestType, kSecDigestMD2, 0) == kCFCompareEqualTo) - { - mDigest = new MD2Digest(); - } - else if (CFStringCompare(digestType, kSecDigestMD4, 0) == kCFCompareEqualTo) - { - mDigest = new MD4Digest(); - } - else if (CFStringCompare(digestType, kSecDigestMD5, 0) == kCFCompareEqualTo) - { - mDigest = new MD5Digest(); - } - else if (CFStringCompare(digestType, kSecDigestSHA1, 0) == kCFCompareEqualTo) - { - mDigest = new SHA1Digest(); - } - else if (CFStringCompare(digestType, kSecDigestSHA2, 0) == kCFCompareEqualTo) - { - switch (length) - { - case 224: - mDigest = new SHA224Digest(); - break; - - case 256: - mDigest = new SHA256Digest(); - break; - - case 384: - mDigest = new SHA384Digest(); - break; - - case 0: - case 512: - mDigest = new SHA512Digest(); - break; - - default: - { - CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidLength, "%d is an invalid digest size (use 224, 256, 384, 512, or 0).", length); - return result; - } - } - } - else - { - if (CFStringCompare(digestType, kSecDigestHMACMD5, 0) == kCFCompareEqualTo) - { - mDigest = new Hmac(this, digestType, kCCHmacAlgMD5, CC_MD5_DIGEST_LENGTH); - } - else if (CFStringCompare(digestType, kSecDigestHMACSHA1, 0) == kCFCompareEqualTo) - { - mDigest = new Hmac(this, digestType, kCCHmacAlgSHA1, CC_SHA1_DIGEST_LENGTH); - } - else if (CFStringCompare(digestType, kSecDigestHMACSHA2, 0) == kCFCompareEqualTo) - { - switch (length) - { - case 224: - { - mDigest = new Hmac(this, digestType, kCCHmacAlgSHA224, CC_SHA224_DIGEST_LENGTH); - } - break; - - case 256: - { - mDigest = new Hmac(this, digestType, kCCHmacAlgSHA256, CC_SHA256_DIGEST_LENGTH); - } - break; - - case 384: - { - mDigest = new Hmac(this, digestType, kCCHmacAlgSHA384, CC_SHA384_DIGEST_LENGTH); - } - break; - - case 0: - case 512: - { - mDigest = new Hmac(this, digestType, kCCHmacAlgSHA512, CC_SHA512_DIGEST_LENGTH); - } - break; - - default: - { - CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidLength, "%d is an invalid digest size (use 224, 256, 384, 512, or 0).", length); - return result; - } - } - } - else - { - CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidAlgorithm, "%@ is not a supported digest algorithm (use kSecDigestSHA2, kSecDigestMD2, kSecDigestMD5, kSecDigestSHA or kSecDigestSHA2", digestType); - return result; - } - } - - long lengthInt = mDigest->DigestLength(); - CFNumberRef lengthNumber = CFNumberCreate(NULL, kCFNumberLongType, &lengthInt); - SendAttribute(kSecDigestLengthAttribute, lengthNumber); - CFRelease(lengthNumber); - return NULL; -} - - - -static CFStringRef gDigestTransformName = CFSTR("SecDigestTransform"); - -CFTypeRef DigestTransform::Make() -{ - DigestTransform* dt = new DigestTransform(); - return CoreFoundationHolder::MakeHolder(gDigestTransformName, dt); -} - - - -DigestTransform::~DigestTransform() -{ - if (mDigest != NULL) - { - delete mDigest; - } -} - - - -void DigestTransform::AttributeChanged(CFStringRef name, CFTypeRef value) -{ - if (CFStringCompare(name, kSecTransformInputAttributeName, 0) == kCFCompareEqualTo) - { - if (value == NULL) - { - // we are done, finalize the digest and send the result forward - const void* result = mDigest->Finalize(); - - // send the result - CFDataRef resultRef = CFDataCreate(NULL, (UInt8*) result, mDigest->DigestLength()); - SendAttribute(kSecTransformOutputAttributeName, resultRef); - CFRelease(resultRef); - - // send the EOS - SendAttribute(kSecTransformOutputAttributeName, NULL); - } - else - { - // if we got an error, just pass it on - CFTypeID valueType = CFGetTypeID(value); - if (valueType == CFErrorGetTypeID()) - { - SendAttribute(kSecTransformOutputAttributeName, value); - } - else if (valueType != CFDataGetTypeID()) - { - CFStringRef idType = CFCopyTypeIDDescription(valueType); - CFErrorRef result = CreateSecTransformErrorRef(kSecTransformErrorInvalidType, "value is not a CFDataRef -- it's a %@ instead", idType); - CFRelease(idType); - SetAttributeNoCallback(kSecTransformOutputAttributeName, result); - } - else - { - CFDataRef valueRef = (CFDataRef) value; - mDigest->Update(CFDataGetBytePtr(valueRef), CFDataGetLength(valueRef)); - } - } - } -} - - - -class DigestTransformFactory : public TransformFactory -{ -public: - DigestTransformFactory(); - virtual CFTypeRef Make(); -}; - - -DigestTransformFactory::DigestTransformFactory() : TransformFactory(gDigestTransformName, true) -{ -} - - - -CFTypeRef DigestTransformFactory::Make() -{ - return DigestTransform::Make(); -} - - - -TransformFactory* DigestTransform::MakeTransformFactory() -{ - return new DigestTransformFactory(); -} - - - -CFDictionaryRef DigestTransform::CopyState() -{ - return mDigest->CopyState(); -} - - - -void DigestTransform::RestoreState(CFDictionaryRef state) -{ - if (mDigest != NULL) - { - delete mDigest; - } - - // get the type and state from the dictionary - CFStringRef type = (CFStringRef) CFDictionaryGetValue(state, kSecDigestTypeAttribute); - CFNumberRef size = (CFNumberRef) CFDictionaryGetValue(state, kSecDigestLengthAttribute); - CFIndex realSize; - CFNumberGetValue(size, kCFNumberCFIndexType, &realSize); - - Setup(type, realSize); -} - - - -CFTypeID DigestTransform::GetCFTypeID() -{ - return CoreFoundationObject::FindObjectType(gDigestTransformName); -} - - - -Hmac::Hmac(Transform* parentTransform, CFStringRef digestType, CCHmacAlgorithm alg, size_t length) : - Digest(digestType, length), mInitialized(false), mParentTransform(parentTransform), mAlg(alg) -{ -} - - - -Hmac::~Hmac() -{ - free(mDigestBuffer); -} - - - -void Hmac::Initialize() -{ - // initialize - const UInt8* data = NULL; - size_t dataLength = 0; - - CFDataRef key = (CFDataRef) mParentTransform->GetAttribute(kSecDigestHMACKeyAttribute); - if (key) - { - data = CFDataGetBytePtr(key); - dataLength = CFDataGetLength(key); - } - - CCHmacInit(&mHMACContext, mAlg, data, dataLength); - - // make room to hold the result - mDigestBuffer = (UInt8*) malloc(mDigestLength); - - mInitialized = true; -} - - - -void Hmac::Update(const void* buffer, size_t length) -{ - if (!mInitialized) - { - Initialize(); - } - - CCHmacUpdate(&mHMACContext, buffer, length); -} - - - -size_t Hmac::DigestLength() -{ - return mDigestLength; -} - - - -const void* Hmac::Finalize() -{ - CCHmacFinal(&mHMACContext, mDigestBuffer); - return mDigestBuffer; -} -