+++ /dev/null
-//
-// SecOTRUtils.c
-// libSecOTR
-//
-// Created by Keith Henrickson on 6/11/12.
-//
-//
-
-#include "SecOTR.h"
-#include "SecOTRIdentityPriv.h"
-#include "SecOTRSessionPriv.h"
-#include <utilities/SecCFWrappers.h>
-#include <stdlib.h>
-
-#include <AssertMacros.h>
-
-#include <Security/SecBase.h>
-#include <Security/SecItem.h>
-#include <Security/SecKey.h>
-#include <Security/SecKeyPriv.h>
-#include <Security/SecBase64.h>
-
-#include <TargetConditionals.h>
-
-CFStringRef sLocalErrorDomain = CFSTR("com.apple.security.otr.error");
-
-void SecOTRCreateError(enum SecOTRError family, CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError) {
- if (newError && !(*newError)) {
- const void* keys[2] = {kCFErrorDescriptionKey, kCFErrorUnderlyingErrorKey};
- const void* values[2] = {descriptionString, previousError};
- *newError = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, (family == secOTRErrorLocal) ? sLocalErrorDomain : kCFErrorDomainOSStatus, errorCode, keys, values, (previousError != NULL) ? 2 : 1);
- } else {
- CFReleaseSafe(previousError);
- }
-}
-
-OSStatus insertSize(CFIndex size, uint8_t* here)
-{
- require(size < 0xFFFF, fail);
-
- uint8_t bytes[] = { (size >> 8) & 0xFF, size & 0xFF };
- memcpy(here, bytes, sizeof(bytes));
-
- return errSecSuccess;
-
-fail:
- return errSecParam;
-}
-
-OSStatus appendSize(CFIndex size, CFMutableDataRef into)
-{
- require(size < 0xFFFF, fail);
-
- uint8_t bytes[] = { (size >> 8) & 0xFF, size & 0xFF };
- CFDataAppendBytes(into, bytes, sizeof(bytes));
-
- return errSecSuccess;
-
-fail:
- return errSecParam;
-}
-
-OSStatus readSize(const uint8_t** data, size_t* limit, uint16_t* size)
-{
- require(limit != NULL, fail);
- require(data != NULL, fail);
- require(size != NULL, fail);
- require(*limit > 1, fail);
-
- *size = ((uint16_t)(*data)[0]) << 8 | ((uint16_t) (*data)[1]) << 0;
-
- *limit -= 2;
- *data += 2;
-
- return errSecSuccess;
-fail:
- return errSecParam;
-}
-
-OSStatus appendSizeAndData(CFDataRef data, CFMutableDataRef appendTo)
-{
- OSStatus status = errSecNotAvailable;
-
- require_noerr(appendSize(CFDataGetLength(data), appendTo), exit);
- CFDataAppend(appendTo, data);
-
- status = errSecSuccess;
-
-exit:
- return status;
-}
-
-OSStatus appendPublicOctetsAndSize(SecKeyRef fromKey, CFMutableDataRef appendTo)
-{
- OSStatus status = errSecDecode;
- CFDataRef serializedKey = NULL;
-
- require_noerr(SecKeyCopyPublicBytes(fromKey, &serializedKey), exit);
- require(serializedKey, exit);
-
- status = appendSizeAndData(serializedKey, appendTo);
-
-exit:
- CFReleaseNull(serializedKey);
- return status;
-}
-
-OSStatus appendPublicOctets(SecKeyRef fromKey, CFMutableDataRef appendTo)
-{
- OSStatus status = errSecDecode;
- CFDataRef serializedKey = NULL;
-
- require_noerr(SecKeyCopyPublicBytes(fromKey, &serializedKey), exit);
- require(serializedKey, exit);
-
- CFDataAppend(appendTo, serializedKey);
-
- status = errSecSuccess;
-
-exit:
- CFReleaseNull(serializedKey);
- return status;
-}
-
-
-/* Given an EC public key in encoded form return a SecKeyRef representing
- that key. Supported encodings are kSecKeyEncodingPkcs1. */
-static SecKeyRef SecKeyCreateECPublicKey(CFAllocatorRef allocator,
- const uint8_t *keyData, CFIndex keyDataLength) {
- CFDataRef tempData = CFDataCreate(kCFAllocatorDefault, keyData, keyDataLength);
- SecKeyRef newPublicKey = SecKeyCreateFromPublicData(kCFAllocatorDefault, kSecECDSAAlgorithmID, tempData);
-
- CFRelease(tempData);
- return newPublicKey;
-}
-
-typedef SecKeyRef (*createFunction_t)(CFAllocatorRef allocator,
- const uint8_t *keyData, CFIndex keyDataLength);
-
-static SecKeyRef CallCreateFunctionFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit, createFunction_t create)
-{
- uint16_t foundLength = 0;
- const uint8_t* foundData = NULL;
-
- require(limit != NULL, fail);
- require(data != NULL, fail);
-
- require_noerr(readSize(data, limit, &foundLength), fail);
- require(foundLength <= *limit, fail);
-
- foundData = *data;
-
- *limit -= foundLength;
- *data += foundLength;
-
-fail:
-
- return create(allocator, foundData, foundLength);
-}
-
-SecKeyRef CreateECPublicKeyFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit)
-{
- return CallCreateFunctionFrom(allocator, data, limit, &SecKeyCreateECPublicKey);
-}
-
-void SecOTRGetIncomingBytes(CFDataRef incomingMessage, CFMutableDataRef decodedBytes)
-{
- CFDataRef header = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("?OTR:"), kCFStringEncodingUTF8, '?');
- CFDataRef footer = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("."), kCFStringEncodingUTF8, '?');
- CFRange headerLoc = CFDataFind(incomingMessage, header, CFRangeMake(0, CFDataGetLength(header)), 0);
- CFRange footerLoc = CFDataFind(incomingMessage, footer, CFRangeMake(0, CFDataGetLength(incomingMessage)), 0);
- if (kCFNotFound == headerLoc.location) {
- CFDataAppend(decodedBytes, incomingMessage);
- } else {
- CFDataRef bodyData = CFDataCreateReferenceFromRange(kCFAllocatorDefault, incomingMessage, CFRangeMake(headerLoc.length, footerLoc.location - headerLoc.length));
- size_t size = SecBase64Decode((char*)CFDataGetBytePtr(bodyData), CFDataGetLength(bodyData), NULL, 0);
- uint8_t decodedByteArray[size];
- SecBase64Decode((char*)CFDataGetBytePtr(bodyData), CFDataGetLength(bodyData), decodedByteArray, size);
- CFDataAppendBytes(decodedBytes, decodedByteArray, size);
- CFRelease(bodyData);
- }
- CFRelease(header);
- CFRelease(footer);
-}
-
-void SecOTRPrepareOutgoingBytes(CFMutableDataRef destinationMessage, CFMutableDataRef protectedMessage)
-{
- CFDataRef header = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("?OTR:"), kCFStringEncodingUTF8, '?');
- CFDataRef footer = CFStringCreateExternalRepresentation(kCFAllocatorDefault, CFSTR("."), kCFStringEncodingUTF8, '?');
- size_t base64Len = SecBase64Encode(CFDataGetBytePtr(destinationMessage), CFDataGetLength(destinationMessage), NULL, 0);
- char base64Message [base64Len];
- SecBase64Encode(CFDataGetBytePtr(destinationMessage), CFDataGetLength(destinationMessage), base64Message, base64Len);
- CFDataRef base64Data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (uint8_t*)base64Message, base64Len, kCFAllocatorNull);
-
- CFDataAppend(protectedMessage, header);
- CFDataAppend(protectedMessage, base64Data);
- CFDataAppend(protectedMessage, footer);
-
- CFRelease(header);
- CFRelease(footer);
- CFRelease(base64Data);
-}
-
-