1/* 2 * Copyright (c) 2006,2011,2013-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// blob - generic extensible binary blob frame 27// 28#include "blob.h" 29#include <security_utilities/unix++.h> 30 31namespace Security { 32 33 34// 35// Content access and validation calls 36// 37char *BlobCore::stringAt(Offset offset) 38{ 39 char *s = at<char>(offset); 40 if (offset < this->length() && memchr(s, 0, this->length() - offset)) 41 return s; 42 else 43 return NULL; 44} 45 46const char *BlobCore::stringAt(Offset offset) const 47{ 48 const char *s = at<const char>(offset); 49 if (offset < this->length() && memchr(s, 0, this->length() - offset)) 50 return s; 51 else 52 return NULL; 53} 54 55 56// 57// Read a blob from a standard file stream. 58// Reads in one pass, so it's suitable for transmission over pipes and networks. 59// The blob is allocated with malloc(3). 60// On error, sets errno and returns NULL; in which case the input stream may 61// be partially consumed. 62// 63BlobCore *BlobCore::readBlob(int fd, size_t offset, uint32_t magic, size_t minSize, size_t maxSize) 64{ 65 BlobCore header; 66 if (::pread(fd, &header, sizeof(header), offset) == sizeof(header)) 67 if (header.validateBlob(magic, minSize, maxSize)) 68 if (BlobCore *blob = (BlobCore *)malloc(header.length())) { 69 memcpy(blob, &header, sizeof(header)); 70 size_t remainder = header.length() - sizeof(header); 71 if (::pread(fd, blob+1, remainder, offset + sizeof(header)) == ssize_t(remainder)) 72 return blob; 73 free(blob); 74 errno = EINVAL; 75 } 76 return NULL; 77} 78 79BlobCore *BlobCore::readBlob(int fd, uint32_t magic, size_t minSize, size_t maxSize) 80{ 81 BlobCore header; 82 if (::read(fd, &header, sizeof(header)) == sizeof(header)) 83 if (header.validateBlob(magic, minSize, maxSize)) 84 if (BlobCore *blob = (BlobCore *)malloc(header.length())) { 85 memcpy(blob, &header, sizeof(header)); 86 size_t remainder = header.length() - sizeof(header); 87 if (::read(fd, blob+1, remainder) == ssize_t(remainder)) 88 return blob; 89 free(blob); 90 errno = EINVAL; 91 } 92 return NULL; 93} 94 95BlobCore *BlobCore::readBlob(std::FILE *file, uint32_t magic, size_t minSize, size_t maxSize) 96{ 97 BlobCore header; 98 if (::fread(&header, sizeof(header), 1, file) == 1) 99 if (header.validateBlob(magic, minSize, maxSize)) 100 if (BlobCore *blob = (BlobCore *)malloc(header.length())) { 101 memcpy(blob, &header, sizeof(header)); 102 if (::fread(blob+1, header.length() - sizeof(header), 1, file) == 1) 103 return blob; 104 free(blob); 105 errno = EINVAL; 106 } 107 return NULL; 108} 109 110 111// 112// BlobWrappers 113// 114BlobWrapper *BlobWrapper::alloc(size_t length, Magic magic /* = _magic */) 115{ 116 size_t wrapLength = length + sizeof(BlobCore); 117 if (wrapLength < length) // overflow 118 return NULL; 119 BlobWrapper *w = (BlobWrapper *)malloc(wrapLength); 120 if (w) 121 w->BlobCore::initialize(magic, wrapLength); 122 return w; 123} 124 125BlobWrapper *BlobWrapper::alloc(const void *data, size_t length, Magic magic /* = _magic */) 126{ 127 BlobWrapper *w = alloc(length, magic); 128 if (w) 129 memcpy(w->data(), data, w->length()); 130 return w; 131} 132 133 134} // Security 135