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 operattes on AsnType &'s, we have
63 * to explicitly provide this here. Why this is no in AsnType, I don't
66 static int SC_BDecPDU(
75 if ((val
= setjmp (env
)) == 0)
77 asnObj
.BDec(b
, bytesDecoded
, env
);
78 return !b
.ReadError();
84 static int SC_BEncPdu(
89 bytesEncoded
= asnObj
.BEnc(b
);
90 return !b
.WriteError();
93 /* DER-decode any AsnType object */
95 const CssmData
&derEncoded
,
99 size_t len
= (size_t)derEncoded
.length();
101 buf
.InstallData(reinterpret_cast<char *>(derEncoded
.data()), len
);
102 if(!SC_BDecPDU(asnObj
, buf
, len
)) {
103 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
108 * DER-encode any AsnType object.
109 * Unfortunately the call has to give an estimate of the max encoded size of
110 * the result. There is no way (that I know of) to figure this out at encode
111 * time. If this turns out to be a problem we might have to do a retry,
112 * doubling the size of the encoded buffer. Be liberal; the maxEncodedSize
113 * buffer is only temporary - due to snacc encoding style, a copy out is
114 * necessary in any case, so the mallocd size of encodedBuf is exactly the
117 void SC_encodeAsnObj(
119 CssmOwnedData
&derEncoded
,
120 size_t maxEncodedSize
)
122 CssmAutoData
aData(derEncoded
.allocator
); // temp encode target
123 aData
.malloc(maxEncodedSize
);
124 memset(aData
.data(), 0, maxEncodedSize
);
126 encBuf
.Init(static_cast<char *>(aData
.data()), maxEncodedSize
);
127 encBuf
.ResetInWriteRvsMode();
129 int rtn
= SC_BEncPdu(asnObj
, encBuf
, encoded
);
130 if(encoded
> maxEncodedSize
) {
131 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL
);
134 /* not sure how this can happen... */
135 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL
);
137 /* success; copy out to caller */
138 derEncoded
.get().clear();
139 derEncoded
.copy(encBuf
.DataPtr(), encBuf
.DataLen());
143 * Given a contentLength, obtain the length of the DER length encoding.
145 size_t SC_lengthOfLength(
148 if(contentLen
< 128) {
151 else if(contentLen
< 256) {
154 else if(contentLen
< 65536) {
157 else if(contentLen
< 16777126) {
166 * Encode a DER length field. Pass in the lengthOfLength if you've obtained
167 * it in a previous call to SC_lengthOfLength.
169 void SC_encodeLength(
172 size_t lengthOfLength
)
174 if(lengthOfLength
== 0) {
175 lengthOfLength
= SC_lengthOfLength(contentLen
);
177 unsigned char *ucp
= reinterpret_cast<unsigned char *>(cp
);
178 if(lengthOfLength
== 1) {
184 *ucp
= (0x80 + lengthOfLength
);
185 ucp
+= lengthOfLength
;
186 for(size_t i
=0; i
<lengthOfLength
; i
++) {
187 *ucp
-- = contentLen
& 0xff;