]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_plugin/lib/csputilities.cpp
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_plugin / lib / csputilities.cpp
1 /*
2 * Copyright (c) 2000-2001,2011,2014 Apple 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 // csputilities - utility classes for CSP implementation
21 //
22 #include <security_cdsa_plugin/CSPsession.h>
23 #include <security_cdsa_plugin/cssmplugin.h>
24 #include <security_utilities/memutils.h>
25 #include <security_cdsa_utilities/cssmdates.h>
26
27 using LowLevelMemoryUtilities::increment;
28
29
30 //
31 // Writer objects
32 //
33 CSPFullPluginSession::Writer::Writer(CssmData *v, uint32 n, CssmData *rem)
34 : vec(v), firstVec(v), lastVec(v + n - 1), remData(rem)
35 {
36 if (vec == NULL || n == 0) {
37 CssmError::throwMe(CSSMERR_CSP_INVALID_OUTPUT_VECTOR); // CDSA p.253, amended
38 }
39 useData(vec);
40 written = 0;
41 }
42
43 void CSPFullPluginSession::Writer::allocate(size_t needed, Allocator &alloc)
44 {
45 if (!needed)
46 return; // No output buffer space needed so we're done.
47 else if (vec == firstVec && !*vec) { // initial null vector element, wants allocation there
48 *vec = makeBuffer(needed, alloc);
49 lastVec = vec; // ignore all subsequent buffers in vector
50 useData(vec);
51 } else {
52 // how much output space do we have left?
53 size_t size = currentSize;
54 for (CssmData *v = vec + 1; v <= lastVec; v++)
55 size += v->length();
56 if (size >= needed)
57 return; // we're fine
58 if (remData) {
59 if (!*remData) { // have overflow, can allocate
60 *remData = makeBuffer(needed - size, alloc);
61 return; // got it
62 }
63 if (size + remData->length() >= needed)
64 return; // will fit into overflow
65 }
66 // not enough buffer space, and can't allocate
67 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
68 }
69 }
70
71 void CSPFullPluginSession::Writer::nextBlock(void * &ptr, size_t &size)
72 {
73 ptr = currentBuffer;
74 size = currentSize;
75 }
76
77 void CSPFullPluginSession::Writer::use(size_t used)
78 {
79 assert(used <= currentSize);
80 written += used;
81 if (used < currentSize) {
82 currentBuffer = increment(currentBuffer, used);
83 currentSize -= used;
84 } else {
85 if (vec < lastVec) {
86 useData(vec++); // use next vector buffer
87 } else if (vec == lastVec && remData) {
88 useData(remData); // use remainder buffer
89 vec++; // mark used
90 #if !defined(NDEBUG) && 0
91 } else if (vec == lastVec) {
92 vec++;
93 } else if (vec > lastVec) {
94 assert(false); // 2nd try to overflow end
95 #endif /* !NDEBUG */
96 } else {
97 currentBuffer = NULL; // no more output buffer
98 currentSize = 0;
99 }
100 }
101 }
102
103 void CSPFullPluginSession::Writer::put(void *addr, size_t size)
104 {
105 while (size > 0) {
106 void *p; size_t sz;
107 nextBlock(p, sz);
108 if (size < sz)
109 sz = size; // cap transfer
110 memcpy(p, addr, sz);
111 use(sz);
112 addr = increment(addr, sz);
113 size -= sz;
114 }
115 }
116
117 size_t CSPFullPluginSession::Writer::close()
118 {
119 return written;
120 }
121
122
123 //
124 // Common algorithm utilities
125 //
126 void CSPFullPluginSession::setKey(CssmKey &key,
127 const Context &context, CSSM_KEYCLASS keyClass,
128 CSSM_KEYATTR_FLAGS attrs, CSSM_KEYUSE use)
129 {
130 // general setup
131 memset(&key.KeyHeader, 0, sizeof(key.KeyHeader));
132 key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
133 key.KeyHeader.CspId = plugin.myGuid();
134 key.KeyHeader.AlgorithmId = context.algorithm();
135 key.KeyHeader.KeyClass = keyClass;
136 key.KeyHeader.KeyUsage = use;
137 key.KeyHeader.KeyAttr = attrs;
138
139 CssmDate *theDate = context.get<CssmDate>(CSSM_ATTRIBUTE_START_DATE);
140 if(theDate) {
141 key.KeyHeader.StartDate = *theDate;
142 }
143 theDate = context.get<CssmDate>(CSSM_ATTRIBUTE_END_DATE);
144 if(theDate) {
145 key.KeyHeader.EndDate = *theDate;
146 }
147
148 // defaults (change as needed)
149 key.KeyHeader.WrapAlgorithmId = CSSM_ALGID_NONE;
150
151 // clear key data (standard says, "Always allocate this, ignore prior contents.")
152 key = CssmData();
153 }