]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/lib/requirement.cpp
2 * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 // requirement - Code Requirement Blob description
27 #include "requirement.h"
28 #include "reqinterp.h"
29 #include "codesigning_dtrace.h"
30 #include <security_utilities/errors.h>
31 #include <security_utilities/unix++.h>
32 #include <security_utilities/logging.h>
33 #include <security_utilities/cfutilities.h>
34 #include <security_utilities/hashing.h>
37 #include "reqdumper.h"
41 namespace CodeSigning
{
45 // Canonical names for requirement types
47 const char *const Requirement::typeNames
[] = {
58 // validate a requirement against a code context
60 void Requirement::validate(const Requirement::Context
&ctx
, OSStatus failure
/* = errSecCSReqFailed */) const
62 if (!this->validates(ctx
, failure
))
63 MacOSError::throwMe(failure
);
66 bool Requirement::validates(const Requirement::Context
&ctx
, OSStatus failure
/* = errSecCSReqFailed */) const
68 CODESIGN_EVAL_REQINT_START((void*)this, (int)this->length());
71 if (Requirement::Interpreter(this, &ctx
).evaluate()) {
72 CODESIGN_EVAL_REQINT_END(this, 0);
75 CODESIGN_EVAL_REQINT_END(this, failure
);
79 CODESIGN_EVAL_REQINT_END(this, errSecCSReqUnsupported
);
80 MacOSError::throwMe(errSecCSReqUnsupported
);
86 // Retrieve one certificate from the cert chain.
87 // Positive and negative indices can be used:
88 // [ leaf, intermed-1, ..., intermed-n, anchor ]
90 // Returns NULL if unavailable for any reason.
92 SecCertificateRef
Requirement::Context::cert(int ix
) const
97 if (ix
>= CFArrayGetCount(certs
))
99 if (CFTypeRef element
= CFArrayGetValueAtIndex(certs
, ix
))
100 return SecCertificateRef(element
);
105 unsigned int Requirement::Context::certCount() const
108 return (unsigned int)CFArrayGetCount(certs
);
115 // Produce the hash of a fake Apple root (only if compiled for internal testing)
117 #if defined(TEST_APPLE_ANCHOR)
119 const char Requirement::testAppleAnchorEnv
[] = "TEST_APPLE_ANCHOR";
121 const SHA1::Digest
&Requirement::testAppleAnchorHash()
123 static bool tried
= false;
124 static SHA1::Digest testHash
;
126 // see if we have one configured
127 if (const char *path
= getenv(testAppleAnchorEnv
))
129 UnixPlusPlus::FileDesc
fd(path
);
130 char buffer
[2048]; // arbitrary limit
131 size_t size
= fd
.read(buffer
, sizeof(buffer
));
134 hash
.finish(testHash
);
135 Syslog::alert("ACCEPTING TEST AUTHORITY %s FOR APPLE CODE IDENTITY", path
);
139 return testHash
; // will be zeroes (no match) if not configured
142 #endif //TEST_APPLE_ANCHOR
145 // Debug dump support
150 void Requirement::dump() const
152 Debug::dump("%s\n", Dumper::dump(this).c_str());