]>
git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/requirement.cpp
b1e136e198406ae4a45bf2a9c8d04f8a082f7018
2 * Copyright (c) 2006-2007 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 <security_codesigning/reqdumper.h>
41 namespace CodeSigning
{
45 // The (SHA-1) hash of the canonical Apple certificate root anchor
47 static const SHA1::Digest gAppleAnchorHash
=
48 { 0x61, 0x1e, 0x5b, 0x66, 0x2c, 0x59, 0x3a, 0x08, 0xff, 0x58,
49 0xd1, 0x4a, 0xe2, 0x24, 0x52, 0xd1, 0x98, 0xdf, 0x6c, 0x60 };
53 // Canonical names for requirement types
55 const char *const Requirement::typeNames
[] = {
65 // validate a requirement against a code context
67 void Requirement::validate(const Requirement::Context
&ctx
, OSStatus failure
/* = errSecCSReqFailed */) const
69 CODESIGN_EVAL_REQINT_START((void*)this, this->length());
72 if (Requirement::Interpreter(this, &ctx
).evaluate()) {
73 CODESIGN_EVAL_REQINT_END(0);
76 CODESIGN_EVAL_REQINT_END(failure
);
77 MacOSError::throwMe(failure
);
80 CODESIGN_EVAL_REQINT_END(errSecCSReqUnsupported
);
81 MacOSError::throwMe(errSecCSReqUnsupported
);
87 // Retrieve one certificate from the cert chain.
88 // Positive and negative indices can be used:
89 // [ leaf, intermed-1, ..., intermed-n, anchor ]
91 // Returns NULL if unavailable for any reason.
93 SecCertificateRef
Requirement::Context::cert(int ix
) const
98 if (CFTypeRef element
= CFArrayGetValueAtIndex(certs
, ix
))
99 return SecCertificateRef(element
);
104 unsigned int Requirement::Context::certCount() const
107 return CFArrayGetCount(certs
);
114 // Return the hash of the canonical Apple certificate root (anchor).
115 // In a special test mode, also return an alternate root hash for testing.
117 const SHA1::Digest
&Requirement::appleAnchorHash()
119 return gAppleAnchorHash
;
122 #if defined(TEST_APPLE_ANCHOR)
124 const char Requirement::testAppleAnchorEnv
[] = "TEST_APPLE_ANCHOR";
126 const SHA1::Digest
&Requirement::testAppleAnchorHash()
128 static bool tried
= false;
129 static SHA1::Digest testHash
;
131 // see if we have one configured
132 if (const char *path
= getenv(testAppleAnchorEnv
))
134 UnixPlusPlus::FileDesc
fd(path
);
135 char buffer
[2048]; // arbitrary limit
136 size_t size
= fd
.read(buffer
, sizeof(buffer
));
139 hash
.finish(testHash
);
140 Syslog::alert("ACCEPTING TEST AUTHORITY %s FOR APPLE CODE IDENTITY", path
);
144 return testHash
; // will be zeroes (no match) if not configured
147 #endif //TEST_APPLE_ANCHOR
151 // InternalRequirements
153 void InternalRequirements::operator () (const Requirements
*given
, const Requirements
*defaulted
)
156 this->add(defaulted
);
157 ::free((void *)defaulted
); // was malloc(3)ed by DiskRep
166 // Debug dump support
170 void Requirement::dump() const
172 Debug::dump("%s\n", Dumper::dump(this).c_str());