]> git.saurik.com Git - apple/libsecurity_codesigning.git/blame - lib/requirement.cpp
libsecurity_codesigning-32953.tar.gz
[apple/libsecurity_codesigning.git] / lib / requirement.cpp
CommitLineData
7d31e928
A
1/*
2 * Copyright (c) 2006-2007 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// requirement - Code Requirement Blob description
26//
27#include "requirement.h"
28#include "reqinterp.h"
29#include <security_utilities/errors.h>
30#include <security_utilities/unix++.h>
31#include <security_utilities/logging.h>
32#include <security_utilities/cfutilities.h>
33#include <security_utilities/hashing.h>
34
35#ifdef DEBUGDUMP
36#include <security_codesigning/reqdumper.h>
37#endif
38
39namespace Security {
40namespace CodeSigning {
41
42
43//
44// The (SHA-1) hash of the canonical Apple certificate root anchor
45//
46static const SHA1::Digest gAppleAnchorHash =
47 { 0x61, 0x1e, 0x5b, 0x66, 0x2c, 0x59, 0x3a, 0x08, 0xff, 0x58,
48 0xd1, 0x4a, 0xe2, 0x24, 0x52, 0xd1, 0x98, 0xdf, 0x6c, 0x60 };
49
50
51//
52// Canonical names for requirement types
53//
54const char *const Requirement::typeNames[] = {
55 "invalid",
56 "host",
57 "guest",
58 "designated",
59 "library"
60};
61
62
63//
64// validate a requirement against a code context
65//
66void Requirement::validate(const Requirement::Context &ctx, OSStatus failure /* = errSecCSReqFailed */) const
67{
68 switch (kind()) {
69 case exprForm:
70 if (!Requirement::Interpreter(this, &ctx).evaluate())
71 MacOSError::throwMe(failure);
72 return;
73 default:
74 secdebug("reqval", "unrecognized requirement kind %d", kind());
75 MacOSError::throwMe(errSecCSReqUnsupported);
76 }
77}
78
79
80//
81// Retrieve one certificate from the cert chain.
82// Positive and negative indices can be used:
83// [ leaf, intermed-1, ..., intermed-n, anchor ]
84// 0 1 ... -2 -1
85// Returns NULL if unavailable for any reason.
86//
87SecCertificateRef Requirement::Context::cert(int ix) const
88{
89 if (certs) {
90 if (ix < 0)
91 ix += certCount();
92 if (CFTypeRef element = CFArrayGetValueAtIndex(certs, ix))
93 return SecCertificateRef(element);
94 }
95 return NULL;
96}
97
98unsigned int Requirement::Context::certCount() const
99{
100 if (certs)
101 return CFArrayGetCount(certs);
102 else
103 return 0;
104}
105
106
107//
108// Return the hash of the canonical Apple certificate root (anchor).
109// In a special test mode, also return an alternate root hash for testing.
110//
111const SHA1::Digest &Requirement::appleAnchorHash()
112{
113 return gAppleAnchorHash;
114}
115
116#if defined(TEST_APPLE_ANCHOR)
117
118const char Requirement::testAppleAnchorEnv[] = "TEST_APPLE_ANCHOR";
119
120const SHA1::Digest &Requirement::testAppleAnchorHash()
121{
122 static bool tried = false;
123 static SHA1::Digest testHash;
124 if (!tried) {
125 // see if we have one configured
126 if (const char *path = getenv(testAppleAnchorEnv))
127 try {
128 UnixPlusPlus::FileDesc fd(path);
129 char buffer[2048]; // arbitrary limit
130 size_t size = fd.read(buffer, sizeof(buffer));
131 SHA1 hash;
132 hash(buffer, size);
133 hash.finish(testHash);
134 Syslog::alert("ACCEPTING TEST AUTHORITY %s FOR APPLE CODE IDENTITY", path);
135 } catch (...) { }
136 tried = true;
137 }
138 return testHash; // will be zeroes (no match) if not configured
139}
140
141#endif //TEST_APPLE_ANCHOR
142
143
144
145//
146// Debug dump support
147//
148#ifdef DEBUGDUMP
149
150void Requirement::dump() const
151{
152 Debug::dump("%s\n", Dumper::dump(this).c_str());
153}
154
155#endif //DEBUGDUMP
156
157
158} // CodeSigning
159} // Security