]>
git.saurik.com Git - apple/security.git/blob - 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 <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
[] = {
66 // validate a requirement against a code context
68 void Requirement::validate(const Requirement::Context
&ctx
, OSStatus failure
/* = errSecCSReqFailed */) const
70 if (!this->validates(ctx
, failure
))
71 MacOSError::throwMe(failure
);
74 bool Requirement::validates(const Requirement::Context
&ctx
, OSStatus failure
/* = errSecCSReqFailed */) const
76 CODESIGN_EVAL_REQINT_START((void*)this, this->length());
79 if (Requirement::Interpreter(this, &ctx
).evaluate()) {
80 CODESIGN_EVAL_REQINT_END(this, 0);
83 CODESIGN_EVAL_REQINT_END(this, failure
);
87 CODESIGN_EVAL_REQINT_END(this, errSecCSReqUnsupported
);
88 MacOSError::throwMe(errSecCSReqUnsupported
);
94 // Retrieve one certificate from the cert chain.
95 // Positive and negative indices can be used:
96 // [ leaf, intermed-1, ..., intermed-n, anchor ]
98 // Returns NULL if unavailable for any reason.
100 SecCertificateRef
Requirement::Context::cert(int ix
) const
105 if (ix
>= CFArrayGetCount(certs
))
107 if (CFTypeRef element
= CFArrayGetValueAtIndex(certs
, ix
))
108 return SecCertificateRef(element
);
113 unsigned int Requirement::Context::certCount() const
116 return CFArrayGetCount(certs
);
123 // Return the hash of the canonical Apple certificate root (anchor).
124 // In a special test mode, also return an alternate root hash for testing.
126 const SHA1::Digest
&Requirement::appleAnchorHash()
128 return gAppleAnchorHash
;
131 #if defined(TEST_APPLE_ANCHOR)
133 const char Requirement::testAppleAnchorEnv
[] = "TEST_APPLE_ANCHOR";
135 const SHA1::Digest
&Requirement::testAppleAnchorHash()
137 static bool tried
= false;
138 static SHA1::Digest testHash
;
140 // see if we have one configured
141 if (const char *path
= getenv(testAppleAnchorEnv
))
143 UnixPlusPlus::FileDesc
fd(path
);
144 char buffer
[2048]; // arbitrary limit
145 size_t size
= fd
.read(buffer
, sizeof(buffer
));
148 hash
.finish(testHash
);
149 Syslog::alert("ACCEPTING TEST AUTHORITY %s FOR APPLE CODE IDENTITY", path
);
153 return testHash
; // will be zeroes (no match) if not configured
156 #endif //TEST_APPLE_ANCHOR
160 // Debug dump support
164 void Requirement::dump() const
166 Debug::dump("%s\n", Dumper::dump(this).c_str());