]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/acl_codesigning.cpp
Security-177.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / acl_codesigning.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // acl_codesigning - ACL subject for signature of calling application
21 //
22 #ifdef __MWERKS__
23 #define _CPP_ACL_CODESIGNING
24 #endif
25
26 #include <Security/acl_codesigning.h>
27 #include <Security/cssmdata.h>
28 #include <Security/endian.h>
29 #include <algorithm>
30
31
32 //
33 // Construct a password ACL subject.
34 // Note that this takes over ownership of the signature object.
35 //
36 CodeSignatureAclSubject::CodeSignatureAclSubject(CssmAllocator &alloc,
37 const Signature *signature, const void *comment, size_t commentLength)
38 : AclSubject(CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE),
39 allocator(alloc), mSignature(signature),
40 mHaveComment(true), mComment(alloc, comment, commentLength)
41 { }
42
43 CodeSignatureAclSubject::CodeSignatureAclSubject(CssmAllocator &alloc,
44 const Signature *signature)
45 : AclSubject(CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE),
46 allocator(alloc), mSignature(signature), mHaveComment(false), mComment(alloc)
47 { }
48
49 CodeSignatureAclSubject::~CodeSignatureAclSubject()
50 {
51 delete mSignature;
52 }
53
54 //
55 // Code signature credentials are validated globally - they are entirely
56 // a feature of "the" process (defined by the environment), and take no
57 // samples whatsoever.
58 //
59 bool CodeSignatureAclSubject::validate(const AclValidationContext &context) const
60 {
61 // a suitable environment is required for a match
62 if (Environment *env = context.environment<Environment>())
63 return env->verifyCodeSignature(mSignature,
64 mHaveComment ? &mComment.get() : NULL);
65 else
66 return false;
67 }
68
69
70 //
71 // Make a copy of this subject in CSSM_LIST form.
72 // The format is (head), (type code: Wordid), (signature data: datum), (comment: datum)
73 //
74 CssmList CodeSignatureAclSubject::toList(CssmAllocator &alloc) const
75 {
76 // all associated data is public (no secrets)
77 TypedList list(alloc, CSSM_ACL_SUBJECT_TYPE_CODE_SIGNATURE,
78 new(alloc) ListElement(mSignature->type()),
79 new(alloc) ListElement(alloc.alloc(*mSignature)));
80 if (mHaveComment)
81 list += new(alloc) ListElement(alloc.alloc(mComment));
82 return list;
83 }
84
85
86 //
87 // Create a CodeSignatureAclSubject
88 //
89 CodeSignatureAclSubject *CodeSignatureAclSubject::Maker::make(const TypedList &list) const
90 {
91 CssmAllocator &alloc = CssmAllocator::standard();
92 if (list.length() == 3+1) {
93 // signature type: int, signature data: datum, comment: datum
94 ListElement *elem[3];
95 crack(list, 3, elem,
96 CSSM_LIST_ELEMENT_WORDID, CSSM_LIST_ELEMENT_DATUM, CSSM_LIST_ELEMENT_DATUM);
97 CssmData &commentData(*elem[2]);
98 return new CodeSignatureAclSubject(alloc, signer.restore(*elem[0], *elem[1]),
99 commentData.data(), commentData.length());
100 } else {
101 // signature type: int, signature data: datum [no comment]
102 ListElement *elem[2];
103 crack(list, 2, elem,
104 CSSM_LIST_ELEMENT_WORDID, CSSM_LIST_ELEMENT_DATUM);
105 return new CodeSignatureAclSubject(alloc, signer.restore(*elem[0], *elem[1]));
106 }
107 }
108
109 CodeSignatureAclSubject *CodeSignatureAclSubject::Maker::make(Version version,
110 Reader &pub, Reader &priv) const
111 {
112 assert(version == 0);
113 CssmAllocator &alloc = CssmAllocator::standard();
114 Endian<uint32> sigType; pub(sigType);
115 const void *data; uint32 length; pub.countedData(data, length);
116 const void *commentData; uint32 commentLength; pub.countedData(commentData, commentLength);
117 return new CodeSignatureAclSubject(alloc,
118 signer.restore(sigType, data, length),
119 commentData, commentLength);
120 }
121
122
123 //
124 // Export the subject to a memory blob
125 //
126 void CodeSignatureAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv)
127 {
128 Endian<uint32> sigType = mSignature->type(); pub(sigType);
129 pub.countedData(*mSignature);
130 pub.countedData(mComment);
131 }
132
133 void CodeSignatureAclSubject::exportBlob(Writer &pub, Writer &priv)
134 {
135 Endian<uint32> sigType = mSignature->type(); pub(sigType);
136 pub.countedData(*mSignature);
137 pub.countedData(mComment);
138 }
139
140
141 #ifdef DEBUGDUMP
142
143 void CodeSignatureAclSubject::debugDump() const
144 {
145 Debug::dump("CodeSigning");
146 if (mHaveComment) {
147 Debug::dump(" comment=");
148 Debug::dumpData(mComment);
149 }
150 }
151
152 #endif //DEBUGDUMP