2 * Copyright (c) 2000-2001 Apple Computer, 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 * cdsaUtils.cpp - utility functions for CDSA-related code
23 #include "cdsaUtils.h"
24 #include <Security/cssmerr.h>
28 #include <Security/globalizer.h>
30 /* silent cerr substitute */
31 ModuleNexus
<Asn1ErrorClass
> AsnNullError
;
34 /* malloc/copy AsnBits.bits -->CssmOwnedData */
35 void SC_asnBitsToCssmData(
39 size_t len
= (bits
.BitLen() + 7) / 8;
40 oData
.copy(reinterpret_cast<const uint8
*>(bits
.BitOcts()), len
);
43 /* given DER-encoded bit string, decoded it and malloc/copy results
44 * back to a CssmOwnedData */
45 void SC_decodeAsnBitsToCssmData(
46 const CssmData encodedBits
,
50 SC_decodeAsnObj(encodedBits
, decodedBits
);
51 size_t len
= (decodedBits
.BitLen() + 7) / 8;
52 oData
.copy(reinterpret_cast<const uint8
*>(decodedBits
.BitOcts()), len
);
56 * Universal BDecPdu/BEncPdu replacements, used below in SC_decodeAsnObj and
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
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
66 static int SC_BDecPDU(
75 asnObj
.BDec(b
, bytesDecoded
, env
);
76 return !b
.ReadError();
83 static int SC_BEncPdu(
88 bytesEncoded
= asnObj
.BEnc(b
);
89 return !b
.WriteError();
92 /* DER-decode any AsnType object */
94 const CssmData
&derEncoded
,
98 size_t len
= (size_t)derEncoded
.length();
100 buf
.InstallData(reinterpret_cast<char *>(derEncoded
.data()), len
);
101 if(!SC_BDecPDU(asnObj
, buf
, len
)) {
102 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
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
116 void SC_encodeAsnObj(
118 CssmOwnedData
&derEncoded
,
119 size_t maxEncodedSize
)
121 CssmAutoData
aData(derEncoded
.allocator
); // temp encode target
122 aData
.malloc(maxEncodedSize
);
123 memset(aData
.data(), 0, maxEncodedSize
);
125 encBuf
.Init(static_cast<char *>(aData
.data()), maxEncodedSize
);
126 encBuf
.ResetInWriteRvsMode();
128 int rtn
= SC_BEncPdu(asnObj
, encBuf
, encoded
);
129 if(encoded
> maxEncodedSize
) {
130 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL
);
133 /* not sure how this can happen... */
134 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL
);
136 /* success; copy out to caller */
137 derEncoded
.get().clear();
138 derEncoded
.copy(encBuf
.DataPtr(), encBuf
.DataLen());
142 * Given a contentLength, obtain the length of the DER length encoding.
144 size_t SC_lengthOfLength(
147 if(contentLen
< 128) {
150 else if(contentLen
< 256) {
153 else if(contentLen
< 65536) {
156 else if(contentLen
< 16777126) {
165 * Encode a DER length field. Pass in the lengthOfLength if you've obtained
166 * it in a previous call to SC_lengthOfLength.
168 void SC_encodeLength(
171 size_t lengthOfLength
)
173 if(lengthOfLength
== 0) {
174 lengthOfLength
= SC_lengthOfLength(contentLen
);
176 unsigned char *ucp
= reinterpret_cast<unsigned char *>(cp
);
177 if(lengthOfLength
== 1) {
183 *ucp
= (0x80 + lengthOfLength
);
184 ucp
+= lengthOfLength
;
185 for(size_t i
=0; i
<lengthOfLength
; i
++) {
186 *ucp
-- = contentLen
& 0xff;
192 * Explicitly non-inlined SnaccError throw
194 void SnaccExcep::throwMe(int err
)
196 throw SnaccExcep(err
);