<true/>
<key>timeout</key>
<integer>0</integer>
+ <key>password-only</key>
+ <true/>
+ <key>version</key>
+ <integer>1</integer>
</dict>
<key>com.apple.library-repair</key>
<dict>
}
pid = auth_token_get_pid(engine->auth);
- if (auth_token_get_sandboxed(engine->auth) && sandbox_check(pid, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) {
+ if (auth_token_get_sandboxed(engine->auth) && sandbox_check_by_audit_token(auth_token_get_audit_info(engine->auth)->opaqueToken, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) {
LOGE("Sandbox denied authorizing right '%s' for authorization created by '%s' [%d]", right, auth_token_get_code_url(engine->auth), pid);
return false;
}
#include <pthread.h>
#include <syslog.h>
#include <sys/sysctl.h>
+#include <utilities/SecCFWrappers.h>
+
#include "SecCode.h"
#include "SecCodePriv.h"
struct __SecTask {
CFRuntimeBase base;
- pid_t pid;
+ pid_t pid_self;
- audit_token_t *token;
- audit_token_t token_storage;
+ audit_token_t token;
/* Track whether we've loaded entitlements independently since after the
* load, entitlements may legitimately be NULL */
Boolean entitlementsLoaded;
CFDictionaryRef entitlements;
+
+ /* for debugging only, shown by debugDescription */
+ int lastFailure;
};
enum {
static void SecTaskFinalize(CFTypeRef cfTask)
{
SecTaskRef task = (SecTaskRef) cfTask;
-
- if (task->entitlements != NULL) {
- CFRelease(task->entitlements);
- task->entitlements = NULL;
- }
+ CFReleaseNull(task->entitlements);
}
static CFStringRef SecTaskCopyDebugDescription(CFTypeRef cfTask)
{
SecTaskRef task = (SecTaskRef) cfTask;
+ pid_t pid;
+
+ if (task->pid_self==-1) {
+ audit_token_to_au32(task->token, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL);
+ } else {
+ pid = task->pid_self;
+ }
+
const char *task_name;
- int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, task->pid};
+ int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
struct kinfo_proc kp;
size_t len = sizeof(kp);
if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1 || len == 0)
else
task_name = kp.kp_proc.p_comm;
- return CFStringCreateWithFormat(CFGetAllocator(task), NULL, CFSTR("%s[%" PRIdPID "]"), task_name, task->pid);
+ return CFStringCreateWithFormat(CFGetAllocator(task), NULL, CFSTR("%s[%" PRIdPID "]"), task_name, pid);
}
static void SecTaskRegisterClass(void)
return _kSecTaskTypeID;
}
-static SecTaskRef SecTaskCreateWithPID(CFAllocatorRef allocator, pid_t pid)
+static SecTaskRef init_task_ref(CFAllocatorRef allocator)
{
- CFIndex extra = sizeof(struct __SecTask) - sizeof(CFRuntimeBase);
- SecTaskRef task = (SecTaskRef) _CFRuntimeCreateInstance(allocator, SecTaskGetTypeID(), extra, NULL);
- if (task != NULL) {
- task->pid = pid;
- task->entitlementsLoaded = false;
- task->entitlements = NULL;
- }
-
- return task;
+ CFIndex extra = sizeof(struct __SecTask) - sizeof(CFRuntimeBase);
+ return (SecTaskRef) _CFRuntimeCreateInstance(allocator, SecTaskGetTypeID(), extra, NULL);
}
SecTaskRef SecTaskCreateWithAuditToken(CFAllocatorRef allocator, audit_token_t token)
{
- SecTaskRef task;
-
- task = SecTaskCreateWithPID(allocator, audit_token_to_pid(token));
- if (task != NULL) {
-#if 0
- task->token_storage = token;
- task->token = &task->token_storage;
-#endif
- }
+ SecTaskRef task = init_task_ref(allocator);
+ if (task != NULL) {
- return task;
+ memcpy(&task->token, &token, sizeof(token));
+ task->entitlementsLoaded = false;
+ task->entitlements = NULL;
+ task->pid_self = -1;
+ }
+
+ return task;
}
SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator)
{
- return SecTaskCreateWithPID(allocator, getpid());
+ SecTaskRef task = init_task_ref(allocator);
+ if (task != NULL) {
+
+ memset(&task->token, 0, sizeof(task->token));
+ task->entitlementsLoaded = false;
+ task->entitlements = NULL;
+ task->pid_self = getpid();
+ }
+
+ return task;
}
/*
OSStatus status;
SecCodeRef code = NULL;
SecRequirementRef req = NULL;
- pid_t pid = task->pid;
- if (pid <= 0) {
- return errSecParam;
+ CFDataRef auditData = NULL;
+ CFNumberRef pidRef = NULL;
+
+ CFMutableDictionaryRef codeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if(task->pid_self==-1) {
+ auditData = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)&task->token, sizeof(audit_token_t));
+ CFDictionarySetValue(codeDict, kSecGuestAttributeAudit, auditData);
+ } else {
+ pidRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &task->pid_self);
+ CFDictionarySetValue(codeDict, kSecGuestAttributePid, pidRef);
}
- status = SecCodeCreateWithPID(pid, kSecCSDefaultFlags, &code);
- //syslog(LOG_NOTICE, "SecTaskValidateForRequirement: SecCodeCreateWithPID=%d", status);
+
+ status = SecCodeCopyGuestWithAttributes(NULL, codeDict, kSecCSDefaultFlags, &code);
+ CFReleaseNull(codeDict);
+ CFReleaseNull(auditData);
+ CFReleaseNull(pidRef);
+
if (!status) {
status = SecRequirementCreateWithString(requirement,
kSecCSDefaultFlags, &req);
- //syslog(LOG_NOTICE, "SecTaskValidateForRequirement: SecRequirementCreateWithString=%d", status);
}
if (!status) {
status = SecCodeCheckValidity(code, kSecCSDefaultFlags, req);
- //syslog(LOG_NOTICE, "SecTaskValidateForRequirement: SecCodeCheckValidity=%d", status);
}
- if (req)
- CFRelease(req);
- if (code)
- CFRelease(code);
+
+ CFReleaseNull(req);
+ CFReleaseNull(code);
return status;
}
static int
csops_task(SecTaskRef task, int ops, void *blob, size_t size)
{
-#if 0
- if (task->token)
- return csops_audittoken(task->pid, ops, blob, size, task->token);
- else
-#endif
- return csops(task->pid, ops, blob, size);
+ int rc;
+ if (task->pid_self==-1) {
+ pid_t pid;
+ audit_token_to_au32(task->token, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL);
+ rc = csops_audittoken(pid, ops, blob, size, &task->token);
+ }
+ else
+ rc = csops(task->pid_self, ops, blob, size);
+ task->lastFailure = (rc == -1) ? errno : 0;
+ return rc;
}
static int SecTaskLoadEntitlements(SecTaskRef task, CFErrorRef *error)
void appendPropertyP(CFMutableArrayRef properties,
CFStringRef propertyType, CFStringRef label, CFTypeRef value);
+#if 0
/* Utility functions. */
CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator,
const DERItem *oid);
NULL_TIME otherwise. */
CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
size_t length);
+#endif
#if defined(__cplusplus)
}
static void SecCertificateDestroy(CFTypeRef cf) {
SecCertificateRefP certificate = (SecCertificateRefP)cf;
- if (certificate->_certificatePolicies.policies)
+ if (certificate->_certificatePolicies.policies) {
free(certificate->_certificatePolicies.policies);
- CFReleaseSafe(certificate->_policyMappings);
- CFReleaseSafe(certificate->_crlDistributionPoints);
- CFReleaseSafe(certificate->_ocspResponders);
- CFReleaseSafe(certificate->_caIssuers);
+ certificate->_certificatePolicies.policies = NULL;
+ }
+ CFReleaseNull(certificate->_policyMappings);
+ CFReleaseNull(certificate->_crlDistributionPoints);
+ CFReleaseNull(certificate->_ocspResponders);
+ CFReleaseNull(certificate->_caIssuers);
if (certificate->_extensions) {
free(certificate->_extensions);
+ certificate->_extensions = NULL;
}
- CFReleaseSafe(certificate->_pubKey);
- CFReleaseSafe(certificate->_der_data);
- CFReleaseSafe(certificate->_properties);
- CFReleaseSafe(certificate->_serialNumber);
- CFReleaseSafe(certificate->_normalizedIssuer);
- CFReleaseSafe(certificate->_normalizedSubject);
- CFReleaseSafe(certificate->_authorityKeyID);
- CFReleaseSafe(certificate->_subjectKeyID);
- CFReleaseSafe(certificate->_sha1Digest);
+ CFReleaseNull(certificate->_pubKey);
+ CFReleaseNull(certificate->_der_data);
+ CFReleaseNull(certificate->_properties);
+ CFReleaseNull(certificate->_serialNumber);
+ CFReleaseNull(certificate->_normalizedIssuer);
+ CFReleaseNull(certificate->_normalizedSubject);
+ CFReleaseNull(certificate->_authorityKeyID);
+ CFReleaseNull(certificate->_subjectKeyID);
+ CFReleaseNull(certificate->_sha1Digest);
}
static Boolean SecCertificateEqual(CFTypeRef cf1, CFTypeRef cf2) {
/* Given the contents of an X.501 Name return the contents of a normalized
X.501 name. */
-CFDataRef createNormalizedX501Name(CFAllocatorRef allocator,
+static CFDataRef createNormalizedX501Name(CFAllocatorRef allocator,
const DERItem *x501name) {
CFMutableDataRef result = CFDataCreateMutable(allocator, x501name->length);
CFIndex length = x501name->length;
atvTagLocation += atvTLLength + atvContentLength;
atvTag = atvSeq.nextItem;
}
+ require_quiet(drtn == DR_EndOfSequence, badDER);
rdnTagLocation += rdnTLLength + rdnContentLength;
rdnTag = rdnSeq.nextItem;
}
/* Oids longer than this are considered invalid. */
#define MAX_OID_SIZE 32
-CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator,
+static CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator,
const DERItem *oid) {
if (oid->length == 0) {
/* Decode a choice of UTCTime or GeneralizedTime to a CFAbsoluteTime. Return
true if the date was valid and properly decoded, also return the result in
absTime. Return false otherwise. */
-CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
+static CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
size_t length) {
check(bytes);
if (length == 0)
&pqi.qualifier);
}
}
+ require_quiet(drtn == DR_EndOfSequence, badDER);
}
require_quiet(drtn == DR_EndOfSequence, badDER);
return;
#include <string.h>
#include <stdio.h>
#include <utilities/SecCFRelease.h>
+#include <utilities/debugging.h>
CFStringRef kSecRecVersionNumber = CFSTR("SRVersionNumber");
CFStringRef kSecRecQuestions = CFSTR("SRQuestions");
CFDataRef retval = NULL;
CFErrorRef error = NULL;
CFDataRef inputString = CFStringCreateExternalRepresentation(kCFAllocatorDefault, str, kCFStringEncodingMacRoman, 0xff);
-
- SecTransformRef encryptTrans = SecEncryptTransformCreate(wrapKey, &error);
- if(error == NULL) {
- SecTransformRef group = SecTransformCreateGroupTransform();
-
- SecTransformSetAttribute(encryptTrans, kSecEncryptionMode, kSecModeCBCKey, &error);
- if(error == NULL) SecTransformSetAttribute(encryptTrans, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
- if(error == NULL) SecTransformSetAttribute(encryptTrans, kSecTransformInputAttributeName, inputString, &error);
- if(error == NULL) SecTransformSetAttribute(encryptTrans, kSecIVKey, iv, &error);
- SecTransformRef encodeTrans = SecEncodeTransformCreate(kSecBase64Encoding, &error);
- SecTransformConnectTransforms(encryptTrans, kSecTransformOutputAttributeName, encodeTrans, kSecTransformInputAttributeName, group, &error);
- CFRelease(encodeTrans);
- CFRelease(encryptTrans);
- if(error == NULL) retval = SecTransformExecute(group, &error);
- if(error != NULL) secDebug(ASL_LEVEL_ERR, "Failed to encrypt recovery password\n", NULL);
- CFRelease(group);
+ SecTransformRef encrypt = NULL;
+ SecTransformRef encode = NULL;
+ SecTransformRef group = NULL;
+
+ encrypt = SecEncryptTransformCreate(wrapKey, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(encrypt, kSecEncryptionMode, kSecModeCBCKey, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(encrypt, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(encrypt, kSecTransformInputAttributeName, inputString, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(encrypt, kSecIVKey, iv, &error);
+ if (error) goto out;
+
+ encode = SecEncodeTransformCreate(kSecBase64Encoding, &error);
+ if (error) goto out;
+
+ group = SecTransformCreateGroupTransform();
+ SecTransformConnectTransforms(encrypt, kSecTransformOutputAttributeName, encode, kSecTransformInputAttributeName, group, &error);
+ if (error) goto out;
+ retval = SecTransformExecute(group, &error);
+ if (error) goto out;
+
+out:
+ if (error) {
+ secerror("Failed to encrypt recovery password: %@", error);
}
+
+ CFReleaseNull(error);
+ CFReleaseNull(inputString);
+ CFReleaseNull(encrypt);
+ CFReleaseNull(encode);
+ CFReleaseNull(group);
+
return retval;
}
{
CFStringRef retval = NULL;
CFDataRef retData = NULL;
- CFErrorRef error = NULL;
-
- SecTransformRef decryptTrans = SecDecryptTransformCreate(wrapKey, &error);
- if(error == NULL) {
- SecTransformRef group = SecTransformCreateGroupTransform();
-
- SecTransformRef decodeTrans = SecDecodeTransformCreate(kSecBase64Encoding, &error);
- if(error == NULL) SecTransformSetAttribute(decodeTrans, kSecTransformInputAttributeName, wrappedPassword, &error);
-
- if(error == NULL) SecTransformSetAttribute(decryptTrans, kSecEncryptionMode, kSecModeCBCKey, &error);
- if(error == NULL) SecTransformSetAttribute(decryptTrans, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
- if(error == NULL) SecTransformSetAttribute(decryptTrans, kSecIVKey, iv, &error);
- SecTransformConnectTransforms(decodeTrans, kSecTransformOutputAttributeName, decryptTrans, kSecTransformInputAttributeName, group, &error);
- CFRelease(decodeTrans);
- CFRelease(decryptTrans);
- if(error == NULL) retData = SecTransformExecute(group, &error);
-
- if(error == NULL) retval = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, retData, kCFStringEncodingMacRoman);
- else secDebug(ASL_LEVEL_ERR, "Failed to decrypt recovery password\n", NULL);
- CFRelease(group);
+ CFErrorRef error = NULL;
+ SecTransformRef decode = NULL;
+ SecTransformRef decrypt = NULL;
+ SecTransformRef group = NULL;
+
+ decode = SecDecodeTransformCreate(kSecBase64Encoding, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(decode, kSecTransformInputAttributeName, wrappedPassword, &error);
+ if (error) goto out;
+
+ decrypt = SecDecryptTransformCreate(wrapKey, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(decrypt, kSecEncryptionMode, kSecModeCBCKey, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(decrypt, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
+ if (error) goto out;
+ SecTransformSetAttribute(decrypt, kSecIVKey, iv, &error);
+ if (error) goto out;
+
+ group = SecTransformCreateGroupTransform();
+ SecTransformConnectTransforms(decode, kSecTransformOutputAttributeName, decrypt, kSecTransformInputAttributeName, group, &error);
+ if (error) goto out;
+ retData = SecTransformExecute(group, &error);
+ if (error) goto out;
+ retval = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, retData, kCFStringEncodingMacRoman);
+
+out:
+ if (error) {
+ secerror("Failed to decrypt recovery password: %@", error);
}
- CFReleaseNull(decryptTrans);
+
+ CFReleaseNull(retData);
+ CFReleaseNull(error);
+ CFReleaseNull(decode);
+ CFReleaseNull(decrypt);
+ CFReleaseNull(group);
+
return retval;
}
/*
- * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2005-2017 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
const DERItem *der, /* data to decode */
DERDecodedInfo *decoded) /* RETURNED */
{
- return DERDecodeItemPartialBuffer(der, decoded, false);
+ return DERDecodeItemPartialBufferGetLength(der, decoded, NULL);
}
/*
*
* No malloc or copy of the contents is performed; the returned
* content->content.data is a pointer into the incoming der data.
+ *
+ * WARNING: Using a partial buffer can return a DERDecodedInfo object with
+ * a length larger than the buffer. It is recommended to instead use
+ * DERDecodeItemPartialBufferGetLength if you need partial buffers.
+ *
*/
DERReturn DERDecodeItemPartialBuffer(
const DERItem *der, /* data to decode */
return DR_Success;
}
+/*
+ * Same as above, but returns a DERDecodedInfo with a length no larger than the buffer.
+ * The actual encoded length can be retrieved from encodedLength parameter.
+ * encodedLength can be NULL to achieve the same behavior as DERDecodeItemPartialBuffer,
+ * with allowPartialBuffer=false
+ *
+ * NOTE: The DERDecoded length will never be larger than the input buffer.
+ * This is a key difference from DERDecodeItemPartialBuffer which could return invalid length.
+ *
+ */
+DERReturn DERDecodeItemPartialBufferGetLength(
+ const DERItem *der, /* data to decode */
+ DERDecodedInfo *decoded, /* RETURNED */
+ DERSize *encodedLength)
+{
+ DERByte tag1; /* first tag byte */
+ DERByte len1; /* first length byte */
+ DERTag tagNumber; /* tag number without class and method bits */
+ DERByte *derPtr = der->data;
+ DERSize derLen = der->length;
+
+ /* The tag decoding below is fully BER complient. We support a max tag
+ value of 2 ^ ((sizeof(DERTag) * 8) - 3) - 1 so for tag size 1 byte we
+ support tag values from 0 - 0x1F. For tag size 2 tag values
+ from 0 - 0x1FFF and for tag size 4 values from 0 - 0x1FFFFFFF. */
+ if(derLen < 2) {
+ return DR_DecodeError;
+ }
+ /* Grab the first byte of the tag. */
+ tag1 = *derPtr++;
+ derLen--;
+ tagNumber = tag1 & 0x1F;
+ if(tagNumber == 0x1F) {
+#ifdef DER_MULTIBYTE_TAGS
+ /* Long tag form: bit 8 of each octet shall be set to one unless it is
+ the last octet of the tag */
+ const DERTag overflowMask = ((DERTag)0x7F << (sizeof(DERTag) * 8 - 7));
+ DERByte tagByte;
+ tagNumber = 0;
+ if (*derPtr == 0x80 || *derPtr < 0x1F)
+ return DR_DecodeError;
+ do {
+ if(derLen < 2 || (tagNumber & overflowMask) != 0) {
+ return DR_DecodeError;
+ }
+ tagByte = *derPtr++;
+ derLen--;
+ tagNumber = (tagNumber << 7) | (tagByte & 0x7F);
+ } while((tagByte & 0x80) != 0);
+
+ /* Check for any of the top 3 reserved bits being set. */
+ if ((tagNumber & (overflowMask << 4)) != 0)
+#endif
+ return DR_DecodeError;
+ }
+ /* Returned tag, top 3 bits are class/method remaining bits are number. */
+ decoded->tag = ((DERTag)(tag1 & 0xE0) << ((sizeof(DERTag) - 1) * 8)) | tagNumber;
+
+ /* Tag decoding above ensured we have at least one more input byte left. */
+ len1 = *derPtr++;
+ derLen--;
+ if(len1 & 0x80) {
+ /* long length form - first byte is length of length */
+ DERSize longLen = 0; /* long form length */
+ unsigned dex;
+
+ len1 &= 0x7f;
+ if((len1 > sizeof(DERSize)) || (len1 > derLen) || len1 == 0 || *derPtr == 0) {
+ /* no can do */
+ return DR_DecodeError;
+ }
+ for(dex=0; dex<len1; dex++) {
+ longLen <<= 8;
+ longLen |= *derPtr++;
+ derLen--;
+ }
+ if(longLen > derLen && !encodedLength) {
+ /* not enough data left for this encoding */
+ return DR_DecodeError;
+ }
+ if (longLen<derLen) {
+ derLen = longLen;
+ }
+ decoded->content.data = derPtr;
+ decoded->content.length = derLen;
+ if (encodedLength) {
+ *encodedLength = longLen;
+ }
+ }
+ else {
+ /* short length form, len1 is the length */
+ if(len1 > derLen && !encodedLength) {
+ /* not enough data left for this encoding */
+ return DR_DecodeError;
+ }
+ if (len1<derLen) {
+ derLen=len1;
+ }
+ decoded->content.data = derPtr;
+ decoded->content.length = derLen;
+ if (encodedLength) {
+ *encodedLength = len1;
+ }
+ }
+
+ return DR_Success;
+}
+
/*
* Given a BIT_STRING, in the form of its raw content bytes,
* obtain the number of unused bits and the raw bit string bytes.
/*
- * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2005-2017 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*
* No malloc or copy of the contents is performed; the returned
* content->content.data is a pointer into the incoming der data.
+ *
+ * WARNING: Using a partial buffer can return a DERDecodedInfo object with
+ * a length larger than the buffer. It is recommended to instead use
+ * DERDecodeItemPartialBufferGetLength if you need partial buffers.
+ *
*/
DERReturn DERDecodeItemPartialBuffer(
const DERItem *der, /* data to decode */
DERDecodedInfo *decoded, /* RETURNED */
bool allowPartialBuffer);
+/*
+ * Same as above, but returns a DERDecodedInfo with a length no larger than the buffer.
+ * The actual encoded length can be retrieved from encodedLength parameter.
+ * encodedLength can be NULL to achieve the same behavior as DERDecodeItemPartialBuffer,
+ * with allowPartialBuffer=false
+ *
+ * NOTE: The DERDecoded length will never be larger than the input buffer.
+ * This is a key difference from DERDecodeItemPartialBuffer which could return invalid length.
+ *
+ */
+DERReturn DERDecodeItemPartialBufferGetLength(
+ const DERItem *der, /* data to decode */
+ DERDecodedInfo *decoded, /* RETURNED */
+ DERSize *encodedLength);
+
/*
* Given a BIT_STRING, in the form of its raw content bytes,
* obtain the number of unused bits and the raw bit string bytes.
--- /dev/null
+/*
+ * Copyright (c) 2017 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <Security/SecRecoveryPassword.h>
+
+#include "keychain_regressions.h"
+
+static void tests(void)
+{
+ const void *qs[] = {CFSTR("q1"), CFSTR("q2"), CFSTR("q3")};
+ CFArrayRef questions = CFArrayCreate(kCFAllocatorDefault, qs, 3, NULL);
+
+ const void *as[] = {CFSTR("a1"), CFSTR("a2"), CFSTR("a3")};
+ CFArrayRef answers = CFArrayCreate(kCFAllocatorDefault, as, 3, NULL);
+
+ CFStringRef password = CFSTR("AAAA-AAAA-AAAA-AAAA-AAAA-AAAA");
+
+ CFDictionaryRef wrappedPassword = SecWrapRecoveryPasswordWithAnswers(password, questions, answers);
+ isnt(wrappedPassword, NULL, "wrappedPassword NULL");
+
+ CFStringRef recoveredPassword = SecUnwrapRecoveryPasswordWithAnswers(wrappedPassword, answers);
+ isnt(recoveredPassword, NULL, "recoveredPassword NULL");
+
+ is(CFStringCompare(password, recoveredPassword, 0), kCFCompareEqualTo, "SecRecoveryPassword");
+
+ CFRelease(questions);
+ CFRelease(answers);
+ CFRelease(wrappedPassword);
+ CFRelease(recoveredPassword);
+}
+
+int kc_44_secrecoverypassword(int argc, char *const *argv)
+{
+ plan_tests(3);
+ tests();
+
+ return 0;
+}
+
ONE_TEST(kc_41_sececkey)
ONE_TEST(kc_42_trust_revocation)
ONE_TEST(kc_43_seckey_interop)
+ONE_TEST(kc_44_secrecoverypassword)
ONE_TEST(si_20_sectrust_provisioning)
ONE_TEST(si_33_keychain_backup)
ONE_TEST(si_34_one_true_keychain)
void Thread::run()
{
+ pthread_t pt;
pthread_attr_t ptattrs;
int err, ntries = 10; // 10 is arbitrary
{
syslog(LOG_ERR, "error %d setting thread detach state", err);
}
- while ((err = pthread_create(&self.mIdent, &ptattrs, runner, this) &&
+ while ((err = pthread_create(&pt, &ptattrs, runner, this) &&
--ntries))
{
syslog(LOG_ERR, "pthread_create() error %d", err);
syslog(LOG_ERR, "too many failed pthread_create() attempts");
}
else
- secinfo("thread", "%p created", self.mIdent);
+ secinfo("thread", "%p created", pt);
}
void *Thread::runner(void *arg)
// otherwise it will crash if something underneath throws.
{
Thread *me = static_cast<Thread *>(arg);
- secinfo("thread", "%p starting", me->self.mIdent);
+ secinfo("thread", "%p starting", pthread_self());
me->action();
- secinfo("thread", "%p terminating", me->self.mIdent);
+ secinfo("thread", "%p terminating", pthread_self());
delete me;
return NULL;
}
//
class Thread {
NOCOPY(Thread)
-public:
- class Identity {
- friend class Thread;
-
- Identity(pthread_t id) : mIdent(id) { }
- public:
- Identity() { }
-
- static Identity current() { return pthread_self(); }
-
- bool operator == (const Identity &other) const
- { return pthread_equal(mIdent, other.mIdent); }
-
- bool operator != (const Identity &other) const
- { return !(*this == other); }
-
- private:
- pthread_t mIdent;
- };
public:
Thread() { } // constructor
virtual void action() = 0; // the action to be performed
private:
- Identity self; // my own identity (instance constant)
-
static void *runner(void *); // argument to pthread_create
};
// Send this event off to the listeners
{
+ StLock<Mutex> lock (gNotificationLock ());
EventListenerList& eventList = gEventListeners();
// route the message to its destination
ONE_TEST(si_12_item_stress)
ONE_TEST(si_13_item_system)
ONE_TEST(si_14_dateparse)
-ONE_TEST(si_15_delete_access_group)
+DISABLED_ONE_TEST(si_15_delete_access_group)
ONE_TEST(si_17_item_system_bluetooth)
DISABLED_ONE_TEST(si_30_keychain_upgrade) //obsolete, needs updating
DISABLED_ONE_TEST(si_31_keychain_bad)
static void SecCTKKeyDestroy(SecKeyRef key) {
SecCTKKeyData *kd = key->key;
- CFReleaseSafe(kd->token);
- CFReleaseSafe(kd->token_id);
- CFReleaseSafe(kd->objectID);
- CFReleaseSafe(kd->auth_params.mutable_dictionary);
- CFReleaseSafe(kd->attributes.mutable_dictionary);
- CFReleaseSafe(kd->params);
+ CFReleaseNull(kd->token);
+ CFReleaseNull(kd->token_id);
+ CFReleaseNull(kd->objectID);
+ CFReleaseNull(kd->auth_params.mutable_dictionary);
+ CFReleaseNull(kd->attributes.mutable_dictionary);
+ CFReleaseNull(kd->params);
}
static CFIndex SecCTKGetAlgorithmID(SecKeyRef key) {
static void SecCertificateDestroy(CFTypeRef cf) {
SecCertificateRef certificate = (SecCertificateRef)cf;
- if (certificate->_certificatePolicies.policies)
+ if (certificate->_certificatePolicies.policies) {
free(certificate->_certificatePolicies.policies);
+ certificate->_certificatePolicies.policies = NULL;
+ }
if (certificate->_policyMappings.mappings) {
free(certificate->_policyMappings.mappings);
+ certificate->_policyMappings.mappings = NULL;
}
- CFReleaseSafe(certificate->_crlDistributionPoints);
- CFReleaseSafe(certificate->_ocspResponders);
- CFReleaseSafe(certificate->_caIssuers);
+ CFReleaseNull(certificate->_crlDistributionPoints);
+ CFReleaseNull(certificate->_ocspResponders);
+ CFReleaseNull(certificate->_caIssuers);
if (certificate->_extensions) {
free(certificate->_extensions);
+ certificate->_extensions = NULL;
}
- CFReleaseSafe(certificate->_pubKey);
- CFReleaseSafe(certificate->_der_data);
- CFReleaseSafe(certificate->_properties);
- CFReleaseSafe(certificate->_serialNumber);
- CFReleaseSafe(certificate->_normalizedIssuer);
- CFReleaseSafe(certificate->_normalizedSubject);
- CFReleaseSafe(certificate->_authorityKeyID);
- CFReleaseSafe(certificate->_subjectKeyID);
- CFReleaseSafe(certificate->_sha1Digest);
- CFReleaseSafe(certificate->_keychain_item);
- CFReleaseSafe(certificate->_permittedSubtrees);
- CFReleaseSafe(certificate->_excludedSubtrees);
+ CFReleaseNull(certificate->_pubKey);
+ CFReleaseNull(certificate->_der_data);
+ CFReleaseNull(certificate->_properties);
+ CFReleaseNull(certificate->_serialNumber);
+ CFReleaseNull(certificate->_normalizedIssuer);
+ CFReleaseNull(certificate->_normalizedSubject);
+ CFReleaseNull(certificate->_authorityKeyID);
+ CFReleaseNull(certificate->_subjectKeyID);
+ CFReleaseNull(certificate->_sha1Digest);
+ CFReleaseNull(certificate->_keychain_item);
+ CFReleaseNull(certificate->_permittedSubtrees);
+ CFReleaseNull(certificate->_excludedSubtrees);
}
static Boolean SecCertificateEqual(CFTypeRef cf1, CFTypeRef cf2) {
atvTagLocation += atvTLLength + atvContentLength;
atvTag = atvSeq.nextItem;
}
+ require_quiet(drtn == DR_EndOfSequence, badDER);
rdnTagLocation += rdnTLLength + rdnContentLength;
rdnTag = rdnSeq.nextItem;
}
&pqi.qualifier);
}
}
+ require_quiet(drtn == DR_EndOfSequence, badDER);
}
require_quiet(drtn == DR_EndOfSequence, badDER);
return;
/*
- * Copyright (c) 2002-2004,2007-2008,2010,2012-2014 Apple Inc. All Rights Reserved.
- *
+ * Copyright (c) 2002-2004,2007-2008,2010,2012-2017 Apple Inc. All Rights Reserved.
+ *
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The 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,
* 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.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
static void SecIdentityDestroy(CFTypeRef cf) {
SecIdentityRef identity = (SecIdentityRef)cf;
- CFReleaseSafe(identity->_certificate);
- CFReleaseSafe(identity->_privateKey);
+ CFReleaseNull(identity->_certificate);
+ CFReleaseNull(identity->_privateKey);
}
static Boolean SecIdentityCompare(CFTypeRef cf1, CFTypeRef cf2) {
return 0;
}
-OSStatus SecIdentityCopyPrivateKey(SecIdentityRef identity,
+OSStatus SecIdentityCopyPrivateKey(SecIdentityRef identity,
SecKeyRef *privateKeyRef) {
*privateKeyRef = identity->_privateKey;
CFRetain(*privateKeyRef);
}
bool SecItemDeleteAllWithAccessGroups(CFArrayRef accessGroups, CFErrorRef *error) {
+#if 0
os_activity_t trace_activity = os_activity_start("SecItemDeleteAllWithAccessGroups", OS_ACTIVITY_FLAG_DEFAULT);
bool ok = SECURITYD_XPC(sec_delete_items_with_access_groups, agrps_client_to_error_request, accessGroups,
os_activity_end(trace_activity);
return ok;
+#else
+ os_activity_t trace_activity = os_activity_start("SecItemDeleteAllWithAccessGroups", OS_ACTIVITY_FLAG_DEFAULT);
+ os_activity_end(trace_activity);
+ return true;
+#endif
}
OSStatus
static void SecKeyDestroy(CFTypeRef cf) {
SecKeyRef key = (SecKeyRef)cf;
#if !TARGET_OS_IPHONE
- CFReleaseSafe(key->cdsaKey);
+ CFReleaseNull(key->cdsaKey);
#endif
if (key->key_class->destroy)
key->key_class->destroy(key);
const SecKeyAlgorithm kSecKeyAlgorithmECIESEncryptionAKSSmartCard = CFSTR("algid:encrypt:ECIES:ECDH:SHA256:2PubKeys");
void SecKeyOperationContextDestroy(SecKeyOperationContext *context) {
- CFReleaseSafe(context->algorithm);
+ CFReleaseNull(context->algorithm);
}
static void PerformWithCFDataBuffer(CFIndex size, void (^operation)(uint8_t *buffer, CFDataRef data)) {
if (desc->kind != kSecDbAccessControlAttr) {
/* Record the new attr key, value in q_pairs. */
- q->q_pairs[q->q_attr_end].key = desc->name;
- q->q_pairs[q->q_attr_end++].value = attr;
+ if (q->q_attr_end + 1 < q->q_pairs_count) {
+ q->q_pairs[q->q_attr_end].key = desc->name;
+ q->q_pairs[q->q_attr_end++].value = attr;
+ } else {
+ SecError(errSecInternal, &q->q_error, CFSTR("q_pairs overflow"));
+ CFReleaseSafe(attr);
+ }
} else {
CFReleaseSafe(attr);
}
return NULL;
}
+ q->q_pairs_count = key_count;
q->q_musrView = (CFDataRef)CFRetain(musr);
q->q_keybag = KEYBAG_DEVICE;
q->q_class = qclass;
//trusted only certs and identities
CFBooleanRef q_match_trusted_only;
+ CFIndex q_pairs_count;
Pair q_pairs[];
} Query;
secdebug("alloc", "%p", builder);
dispatch_release_null(builder->queue);
if (builder->anchorSource) {
- SecMemoryCertificateSourceDestroy(builder->anchorSource); }
+ SecMemoryCertificateSourceDestroy(builder->anchorSource);
+ builder->anchorSource = NULL;
+ }
if (builder->certificateSource) {
- SecMemoryCertificateSourceDestroy(builder->certificateSource); }
+ SecMemoryCertificateSourceDestroy(builder->certificateSource);
+ builder->certificateSource = NULL;
+ }
if (builder->itemCertificateSource) {
- SecItemCertificateSourceDestroy(builder->itemCertificateSource); }
+ SecItemCertificateSourceDestroy(builder->itemCertificateSource);
+ builder->itemCertificateSource = NULL;
+ }
if (builder->appleAnchorSource) {
- SecMemoryCertificateSourceDestroy(builder->appleAnchorSource); }
- CFReleaseSafe(builder->clientAuditToken);
- CFReleaseSafe(builder->anchorSources);
- CFReleaseSafe(builder->parentSources);
- CFReleaseSafe(builder->allPaths);
- CFReleaseSafe(builder->partialPaths);
- CFReleaseSafe(builder->rejectedPaths);
- CFReleaseSafe(builder->candidatePaths);
- CFReleaseSafe(builder->leafDetails);
- CFReleaseSafe(builder->ocspResponses);
- CFReleaseSafe(builder->signedCertificateTimestamps);
- CFReleaseSafe(builder->trustedLogs);
+ SecMemoryCertificateSourceDestroy(builder->appleAnchorSource);
+ builder->appleAnchorSource = NULL;
+ }
+ CFReleaseNull(builder->clientAuditToken);
+ CFReleaseNull(builder->anchorSources);
+ CFReleaseNull(builder->parentSources);
+ CFReleaseNull(builder->allPaths);
+ CFReleaseNull(builder->partialPaths);
+ CFReleaseNull(builder->rejectedPaths);
+ CFReleaseNull(builder->candidatePaths);
+ CFReleaseNull(builder->leafDetails);
+ CFReleaseNull(builder->ocspResponses);
+ CFReleaseNull(builder->signedCertificateTimestamps);
+ CFReleaseNull(builder->trustedLogs);
SecPVCDelete(&builder->path);
}
/*
- * Copyright (c) 2012-2016 Apple Inc. All Rights Reserved.
+ * Copyright (c) 2012-2017 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The 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,
* 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.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
SecDbDestroy(CFTypeRef value)
{
SecDbRef db = (SecDbRef)value;
- CFReleaseSafe(db->connections);
- CFReleaseSafe(db->db_path);
- dispatch_release(db->queue);
- dispatch_release(db->commitQueue);
- dispatch_release(db->read_semaphore);
- dispatch_release(db->write_semaphore);
- if (db->opened)
+ CFReleaseNull(db->connections);
+ CFReleaseNull(db->db_path);
+ if (db->queue) {
+ dispatch_release(db->queue);
+ db->queue = NULL;
+ }
+ if (db->commitQueue) {
+ dispatch_release(db->commitQueue);
+ db->commitQueue = NULL;
+ }
+ if (db->read_semaphore) {
+ dispatch_release(db->read_semaphore);
+ db->read_semaphore = NULL;
+ }
+ if (db->write_semaphore) {
+ dispatch_release(db->write_semaphore);
+ db->write_semaphore = NULL;
+ }
+ if (db->opened) {
Block_release(db->opened);
+ db->opened = NULL;
+ }
CFReleaseNull(db->notifyPhase);
}
18F7F67914D77F4400F88A12 /* NtlmGenerator.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C999BA10AB5F0BB0010451D /* NtlmGenerator.c */; };
18F7F67A14D77F4400F88A12 /* ntlmBlobPriv.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C999BA30AB5F0BB0010451D /* ntlmBlobPriv.c */; };
18F7F67C14D77F5000F88A12 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; };
+ 24CBF8751E9D4E6100F09F0E /* kc-44-secrecoverypassword.c in Sources */ = {isa = PBXBuildFile; fileRef = 24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */; };
433E519E1B66D5F600482618 /* AppSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 433E519D1B66D5F600482618 /* AppSupport.framework */; };
4381603A1B4DCE8F00C54D58 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; };
4381603B1B4DCEFF00C54D58 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; };
18351B8F14CB65870097860E /* SecBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecBase64.h; sourceTree = "<group>"; };
2281820D17B4686C0067C9C9 /* BackgroundTaskAgent.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BackgroundTaskAgent.framework; path = System/Library/PrivateFrameworks/BackgroundTaskAgent.framework; sourceTree = SDKROOT; };
22C002A31AC9D33100B3469E /* OTAPKIAssetTool.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = OTAPKIAssetTool.xcconfig; sourceTree = "<group>"; };
+ 24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "kc-44-secrecoverypassword.c"; path = "regressions/kc-44-secrecoverypassword.c"; sourceTree = "<group>"; };
433E519D1B66D5F600482618 /* AppSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppSupport.framework; path = System/Library/PrivateFrameworks/AppSupport.framework; sourceTree = SDKROOT; };
4381690C1B4EDCBD00C54D58 /* SOSCCAuthPlugin.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SOSCCAuthPlugin.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
4381690F1B4EDCBD00C54D58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DCB3446C1D8A35270054D16E /* kc-41-sececkey.m */,
DCB3446D1D8A35270054D16E /* kc-43-seckey-interop.m */,
DCB3446E1D8A35270054D16E /* kc-42-trust-revocation.c */,
+ 24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */,
DCB3446F1D8A35270054D16E /* si-20-sectrust-provisioning.c */,
DCB344701D8A35270054D16E /* si-20-sectrust-provisioning.h */,
DCB344711D8A35270054D16E /* si-33-keychain-backup.c */,
files = (
DCB3447A1D8A35270054D16E /* kc-01-keychain-creation.c in Sources */,
DCB3447B1D8A35270054D16E /* kc-02-unlock-noui.c in Sources */,
+ 24CBF8751E9D4E6100F09F0E /* kc-44-secrecoverypassword.c in Sources */,
DCB3447D1D8A35270054D16E /* kc-03-keychain-list.c in Sources */,
DCB3447C1D8A35270054D16E /* kc-03-status.c in Sources */,
DCB3447E1D8A35270054D16E /* kc-04-is-valid.c in Sources */,
unsigned char **flat, // mallocd and RETURNED
unsigned *flatLen) // RETURNED
{
- char hostname[MAXHOSTNAMELEN];
- if(gethostname(hostname, MAXHOSTNAMELEN)) {
- #ifndef NDEBUG
- perror("gethostname");
- #endif
- return errSecInternalComponent;
- }
+ char hostname[] = "WORKSTATION";
size_t len = strlen(hostname);
if(unicode) {
/* quickie "little endian unicode" conversion */