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.
22 #include <Security/utilities.h>
24 #include <Security/cssmerrno.h>
25 #include <Security/debugging.h>
31 // The base of the exception hierarchy.
32 // Note that the debug output here depends on a particular
33 // implementation feature of gcc; to wit, that the exception object
34 // is created and then copied (at least once) via its copy constructor.
35 // If your compiler does not invoke the copy constructor, you won't get
36 // debug output, but nothing worse should happen.
38 CssmCommonError::CssmCommonError()
39 IFDEBUG(: mCarrier(true))
43 CssmCommonError::CssmCommonError(const CssmCommonError
&source
)
46 source
.debugDiagnose(this);
47 mCarrier
= source
.mCarrier
;
48 source
.mCarrier
= false;
52 CssmCommonError::~CssmCommonError() throw ()
56 debug("exception", "%p handled", this);
60 OSStatus
CssmCommonError::osStatus() const
61 { return cssmError(); }
63 CSSM_RETURN
CssmCommonError::cssmError(CSSM_RETURN base
) const
64 { return CssmError::merge(cssmError(), base
); }
66 // default debugDiagnose gets what it can (virtually)
67 void CssmCommonError::debugDiagnose(const void *id
) const
70 debug("exception", "%p %s %s/0x%lx osstatus %ld",
71 id
, Debug::typeName(*this).c_str(),
72 cssmErrorString(cssmError()).c_str(), cssmError(),
79 // CssmError exceptions
81 CssmError::CssmError(CSSM_RETURN err
) : error(err
) { }
83 const char *CssmError::what() const throw ()
84 { return "CSSM exception"; }
86 CSSM_RETURN
CssmError::cssmError() const { return error
; }
88 OSStatus
CssmError::osStatus() const { return error
; }
90 void CssmError::throwMe(CSSM_RETURN err
) { throw CssmError(err
); }
94 // UnixError exceptions
96 UnixError::UnixError() : error(errno
) { }
98 UnixError::UnixError(int err
) : error(err
) { }
100 const char *UnixError::what() const throw ()
101 { return "UNIX error exception"; }
103 CSSM_RETURN
UnixError::cssmError() const
105 // @@@ this is a sample - go through and map errnos better
109 return CSSM_ERRCODE_MEMORY_ERROR
;
113 return CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED
;
117 return CSSMERR_APPLEDL_DISK_FULL
;
121 return CSSMERR_APPLEDL_QUOTA_EXCEEDED
;
125 return CSSMERR_APPLEDL_FILE_TOO_BIG
;
128 return CSSM_ERRCODE_INTERNAL_ERROR
;
132 OSStatus
UnixError::osStatus() const { return cssmError(); }
134 void UnixError::throwMe(int err
) { throw UnixError(err
); }
136 // @@@ This is a hack for the Network protocol state machine
137 UnixError
UnixError::make(int err
) { return UnixError(err
); }
140 void UnixError::debugDiagnose(const void *id
) const
142 debug("exception", "%p UnixError %s (%d) osStatus %ld",
143 id
, strerror(error
), error
, osStatus());
149 // MacOSError exceptions
151 MacOSError::MacOSError(int err
) : error(err
) { }
153 const char *MacOSError::what() const throw ()
154 { return "MacOS error"; }
156 CSSM_RETURN
MacOSError::cssmError() const
157 { return error
; } // @@@ eventually...
159 OSStatus
MacOSError::osStatus() const
162 void MacOSError::throwMe(int error
)
163 { throw MacOSError(error
); }
167 // Manage CSSM errors
169 CSSM_RETURN
CssmError::merge(CSSM_RETURN error
, CSSM_RETURN base
)
171 if (0 < error
&& error
< CSSM_ERRORCODE_COMMON_EXTENT
) {
180 // CssmData out of line members
182 string
CssmData::toString() const
185 string(reinterpret_cast<const char *>(data()), length())
192 // GUID <-> string conversions.
193 // Note that we DO check for {} on input and insist on rigid formatting.
194 // We don't require a terminating null byte on input, but generate it on output.
196 char *Guid::toString(char buffer
[stringRepLength
+1]) const
198 sprintf(buffer
, "{%8.8lx-%4.4x-%4.4x-",
199 (unsigned long)Data1
, unsigned(Data2
), unsigned(Data3
));
200 for (int n
= 0; n
< 2; n
++)
201 sprintf(buffer
+ 20 + 2*n
, "%2.2x", Data4
[n
]);
203 for (int n
= 2; n
< 8; n
++)
204 sprintf(buffer
+ 21 + 2*n
, "%2.2x", Data4
[n
]);
210 Guid::Guid(const char *string
)
212 // Arguably, we should be more flexible on input. But exactly what
213 // padding rules should we follow, and how should we try to interprete
214 // "doubtful" variations? Given that GUIDs are essentially magic
215 // cookies, everybody's better off if we just cut-and-paste them
216 // around the universe...
219 if (sscanf(string
, "{%lx-%x-%x-", &d1
, &d2
, &d3
) != 3)
220 CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID
);
221 Data1
= d1
; Data2
= d2
; Data3
= d3
;
222 // once, we did not expect the - after byte 2 of Data4
223 bool newForm
= string
[24] == '-';
224 for (int n
= 0; n
< 8; n
++) {
226 if (sscanf(string
+ 20 + 2*n
+ (newForm
&& n
>= 2), "%2x", &dn
) != 1)
227 CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID
);
230 if (string
[37 - !newForm
] != '}')
231 CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID
);
236 // Methods for the CssmKey class
238 CssmKey::CssmKey(CSSM_KEY
&key
)
240 KeyHeader
= key
.KeyHeader
;
241 KeyData
= key
.KeyData
;
242 key
.KeyData
.Length
= 0;
243 key
.KeyData
.Data
= NULL
;
246 CssmKey::CssmKey(CSSM_DATA
&keyData
)
248 memset(this, 0, sizeof(*this));
252 KeyHeader
.HeaderVersion
= CSSM_KEYHEADER_VERSION
;
253 KeyHeader
.BlobType
= CSSM_KEYBLOB_RAW
;
254 KeyHeader
.Format
= CSSM_KEYBLOB_RAW_FORMAT_NONE
;
257 CssmKey::CssmKey(uint32 length
, uint8
*data
)
259 memset(this, 0, sizeof(*this));
260 KeyData
.Length
= length
;
262 KeyHeader
.HeaderVersion
= CSSM_KEYHEADER_VERSION
;
263 KeyHeader
.BlobType
= CSSM_KEYBLOB_RAW
;
264 KeyHeader
.Format
= CSSM_KEYBLOB_RAW_FORMAT_NONE
;
267 CryptoDataClass::~CryptoDataClass()