]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_utilities/lib/osxverifier.cpp
2 * Copyright (c) 2000-2001,2011,2013-2014 Apple Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // osxsigner - MacOS X's standard code signing algorithm.
22 #include <security_cdsa_utilities/osxverifier.h>
23 #include <security_utilities/unix++.h>
24 #include <security_utilities/hashing.h>
25 #include <security_utilities/memutils.h>
26 #include <security_utilities/debugging.h>
27 #include <security_codesigning/requirement.h>
28 #include <security_codesigning/reqdumper.h> // debug only
31 using namespace CodeSigning
;
38 // Create a Verifier from a code object.
40 // This does not add any auxiliary information blobs. You can do that
41 // by calling add() after construction, of course.
43 OSXVerifier::OSXVerifier(OSXCode
*code
)
45 mPath
= code
->canonicalPath();
46 secdebug("codesign", "building verifier for %s", mPath
.c_str());
48 // build new-style verifier
49 CFRef
<SecStaticCodeRef
> staticCode
= code
->codeRef();
50 switch (OSStatus rc
= SecCodeCopyDesignatedRequirement(staticCode
,
51 kSecCSDefaultFlags
, &mRequirement
.aref())) {
53 secdebug("codesign", " is signed; canonical requirement loaded");
55 case errSecCSUnsigned
:
56 secdebug("codesign", " is unsigned; no requirement");
59 MacOSError::throwMe(rc
);
62 // build old-style verifier
63 makeLegacyHash(code
, mLegacyHash
);
64 secdebug("codesign", " hash generated");
69 // Create a Verifier from hash, path, and requirement.
70 // Again, this has no auxiliary data when constructed.
72 OSXVerifier::OSXVerifier(const SHA1::Byte
*hash
, const std::string
&path
)
75 secdebug("codesign", "building verifier from hash %p and path=%s", hash
, path
.c_str());
77 memcpy(mLegacyHash
, hash
, sizeof(mLegacyHash
));
79 memset(mLegacyHash
, 0, sizeof(mLegacyHash
));
83 OSXVerifier::~OSXVerifier()
85 secdebug("codesign", "%p verifier destroyed", this);
90 // Add an auxiliary comment blob.
91 // Note that we only allow one auxiliary blob for each magic number.
93 void OSXVerifier::add(const BlobCore
*blob
)
95 if (blob
->is
<Requirement
>()) {
97 secdebug("codesign", "%p verifier adds requirement", this);
99 secdebug("codesign", "%p verifier adds requirement %s", this,
100 Dumper::dump(Requirement::specific(blob
), true).c_str());
102 MacOSError::check(SecRequirementCreateWithData(CFTempData(*blob
),
103 kSecCSDefaultFlags
, &mRequirement
.aref()));
105 secdebug("codesign", "%p verifier adds blob (0x%x,%zd)",
106 this, blob
->magic(), blob
->length());
107 BlobCore
* &slot
= mAuxiliary
[blob
->magic()];
110 slot
= blob
->clone();
116 // Find a comment blob, by magic number
118 const BlobCore
*OSXVerifier::find(BlobCore::Magic magic
)
120 AuxMap::const_iterator it
= mAuxiliary
.find(magic
);
121 return (it
== mAuxiliary
.end()) ? NULL
: it
->second
;
125 void OSXVerifier::makeLegacyHash(OSXCode
*code
, SHA1::Digest digest
)
127 secdebug("codesign", "calculating legacy hash for %s", code
->canonicalPath().c_str());
128 UnixPlusPlus::AutoFileDesc
fd(code
->executablePath(), O_RDONLY
);
129 char buffer
[legacyHashLimit
];
130 size_t size
= fd
.read(buffer
, legacyHashLimit
);
138 // The AuxMap helper class provides a map-to-Blob-pointers with automatic memory management.
140 OSXVerifier::AuxMap::AuxMap(const OSXVerifier::AuxMap
&src
)
142 for (const_iterator it
= src
.begin(); it
!= src
.end(); it
++)
146 OSXVerifier::AuxMap::~AuxMap()
148 for (const_iterator it
= this->begin(); it
!= this->end(); ++it
)
155 void OSXVerifier::dump() const
157 static const SHA1::Digest nullDigest
= { 0 };
158 if (!memcmp(mLegacyHash
, nullDigest
, sizeof(mLegacyHash
))) {
159 Debug::dump("(no hash)");
161 Debug::dump("oldHash=");
162 Debug::dumpData(mLegacyHash
, sizeof(mLegacyHash
));
165 CFRef
<CFDataRef
> reqData
;
166 if (!SecRequirementCopyData(mRequirement
, 0, &reqData
.aref())) {
167 Debug::dump(" Requirement =>");
168 ((const Requirement
*)CFDataGetBytePtr(reqData
))->dump();
171 Debug::dump(" NO REQ");
177 } // end namespace Security