]> git.saurik.com Git - apple/security.git/blame - SecuritySNACCRuntime/c++-lib/src/cdsaUtils.cpp
Security-54.1.9.tar.gz
[apple/security.git] / SecuritySNACCRuntime / c++-lib / src / cdsaUtils.cpp
CommitLineData
bac41a7b
A
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 * cdsaUtils.cpp - utility functions for CDSA-related code
21 */
22
23#include "cdsaUtils.h"
24#include <Security/cssmerr.h>
25
26#ifdef NDEBUG
27
28#include <Security/globalizer.h>
29
30/* silent cerr substitute */
31ModuleNexus<Asn1ErrorClass> AsnNullError;
32#endif /* NDEBUG */
33
34/* malloc/copy AsnBits.bits -->CssmOwnedData */
35void SC_asnBitsToCssmData(
36 const AsnBits &bits,
37 CssmOwnedData &oData)
38{
39 size_t len = (bits.BitLen() + 7) / 8;
40 oData.copy(reinterpret_cast<const uint8 *>(bits.BitOcts()), len);
41}
42
43/* given DER-encoded bit string, decoded it and malloc/copy results
44 * back to a CssmOwnedData */
45void SC_decodeAsnBitsToCssmData(
46 const CssmData encodedBits,
47 CssmOwnedData &oData)
48{
49 AsnBits decodedBits;
50 SC_decodeAsnObj(encodedBits, decodedBits);
51 size_t len = (decodedBits.BitLen() + 7) / 8;
52 oData.copy(reinterpret_cast<const uint8 *>(decodedBits.BitOcts()), len);
53}
54
55/*
56 * Universal BDecPdu/BEncPdu replacements, used below in SC_decodeAsnObj and
57 * SC_encodeAsnObj.
58 *
59 * All AsnType subclasses implement this either via PDU_MEMBER_MACROS
60 * for SecuritySNACCRuntime built-in types, or explicitly for all
61 * other classes using asn-useful.h. To faciliate a global "one
29654253
A
62 * routine for encode/decode" which operates on AsnType &'s, we have
63 * to explicitly provide this here. Why this is not in AsnType, I don't
bac41a7b
A
64 * know.
65 */
66static int SC_BDecPDU(
67 AsnType &asnObj,
68 BUF_TYPE b,
69 AsnLen &bytesDecoded)
70{
71 ENV_TYPE env;
bac41a7b
A
72
73 bytesDecoded = 0;
29654253 74 try {
bac41a7b
A
75 asnObj.BDec(b, bytesDecoded, env);
76 return !b.ReadError();
77 }
29654253 78 catch(...) {
bac41a7b 79 return false;
29654253 80 }
bac41a7b
A
81}
82
83static int SC_BEncPdu(
84 AsnType &asnObj,
85 BUF_TYPE b,
86 AsnLen &bytesEncoded)
87{
88 bytesEncoded = asnObj.BEnc(b);
89 return !b.WriteError();
90}
91
92/* DER-decode any AsnType object */
93void SC_decodeAsnObj(
94 const CssmData &derEncoded,
95 AsnType &asnObj)
96{
97 AsnBuf buf;
98 size_t len = (size_t)derEncoded.length();
99
100 buf.InstallData(reinterpret_cast<char *>(derEncoded.data()), len);
101 if(!SC_BDecPDU(asnObj, buf, len)) {
102 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
103 }
104}
105
106/*
107 * DER-encode any AsnType object.
108 * Unfortunately the call has to give an estimate of the max encoded size of
109 * the result. There is no way (that I know of) to figure this out at encode
110 * time. If this turns out to be a problem we might have to do a retry,
111 * doubling the size of the encoded buffer. Be liberal; the maxEncodedSize
112 * buffer is only temporary - due to snacc encoding style, a copy out is
113 * necessary in any case, so the mallocd size of encodedBuf is exactly the
114 * right size.
115 */
116void SC_encodeAsnObj(
117 AsnType &asnObj,
118 CssmOwnedData &derEncoded,
119 size_t maxEncodedSize)
120{
121 CssmAutoData aData(derEncoded.allocator); // temp encode target
122 aData.malloc(maxEncodedSize);
123 memset(aData.data(), 0, maxEncodedSize);
124 AsnBuf encBuf;
125 encBuf.Init(static_cast<char *>(aData.data()), maxEncodedSize);
126 encBuf.ResetInWriteRvsMode();
127 AsnLen encoded;
128 int rtn = SC_BEncPdu(asnObj, encBuf, encoded);
129 if(encoded > maxEncodedSize) {
130 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
131 }
132 if(!rtn) {
133 /* not sure how this can happen... */
134 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL);
135 }
136 /* success; copy out to caller */
137 derEncoded.get().clear();
138 derEncoded.copy(encBuf.DataPtr(), encBuf.DataLen());
139}
140
141/*
142 * Given a contentLength, obtain the length of the DER length encoding.
143 */
144size_t SC_lengthOfLength(
145 size_t contentLen)
146{
147 if(contentLen < 128) {
148 return 1;
149 }
150 else if(contentLen < 256) {
151 return 2;
152 }
153 else if(contentLen < 65536) {
154 return 3;
155 }
156 else if(contentLen < 16777126) {
157 return 4;
158 }
159 else {
160 return 5;
161 }
162}
163
164/*
165 * Encode a DER length field. Pass in the lengthOfLength if you've obtained
166 * it in a previous call to SC_lengthOfLength.
167 */
168void SC_encodeLength(
169 size_t contentLen,
170 void *cp,
171 size_t lengthOfLength)
172{
173 if(lengthOfLength == 0) {
174 lengthOfLength = SC_lengthOfLength(contentLen);
175 }
176 unsigned char *ucp = reinterpret_cast<unsigned char *>(cp);
177 if(lengthOfLength == 1) {
178 /* easy case */
179 *ucp = contentLen;
180 return;
181 }
182 lengthOfLength--;
183 *ucp = (0x80 + lengthOfLength);
184 ucp += lengthOfLength;
185 for(size_t i=0; i<lengthOfLength; i++) {
186 *ucp-- = contentLen & 0xff;
187 contentLen >>= 8;
188 }
189}
29654253
A
190
191/*
192 * Explicitly non-inlined SnaccError throw
193 */
194void SnaccExcep::throwMe(int err)
195{
196 throw SnaccExcep(err);
197}