]>
git.saurik.com Git - apple/security.git/blob - Security/libsecurity_cdsa_utilities/lib/cssmdata.cpp
2 * Copyright (c) 2000-2004,2006,2011-2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // cssmdata.cpp -- Manager different CssmData types
28 #include <security_cdsa_utilities/cssmdata.h>
29 #include <security_utilities/utilities.h>
38 // Comparing raw CSSM_DATA things
40 bool operator == (const CSSM_DATA
&d1
, const CSSM_DATA
&d2
)
43 return true; // identical
44 if (d1
.Length
!= d2
.Length
)
45 return false; // can't be
46 if (d1
.Data
== d2
.Data
)
47 return true; // points to same data
48 return !memcmp(d1
.Data
, d2
.Data
, d1
.Length
);
53 // CssmData out of line members
55 string
CssmData::toString() const
58 string(reinterpret_cast<const char *>(data()), length())
65 // Conversion from/to hex digits.
66 // This could be separate functions, or Rep templates, but we just hang
67 // it onto generic CssmData.
69 string
CssmData::toHex() const
71 static const char digits
[] = "0123456789abcdef";
73 unsigned char *p
= Data
;
74 for (uint32 n
= 0; n
< length(); n
++) {
75 result
.push_back(digits
[p
[n
] >> 4]);
76 result
.push_back(digits
[p
[n
] & 0xf]);
81 static unsigned char hexValue(char c
)
83 static const char digits
[] = "0123456789abcdef";
84 if (const char *p
= strchr(digits
, tolower(c
)))
90 void CssmData::fromHex(const char *hexDigits
)
92 size_t bytes
= strlen(hexDigits
) / 2; // (discards malformed odd end)
93 length(bytes
); // (will assert if we try to grow it)
94 for (size_t n
= 0; n
< bytes
; n
++) {
95 Data
[n
] = hexValue(hexDigits
[2*n
]) << 4 | hexValue(hexDigits
[2*n
+1]);
101 // Conversion from/to OID strings.
102 // These are not strict; invalid inputs are not necessarily flagged as errors.
104 static unsigned long getOid(const CssmData
&data
, unsigned int &pos
)
108 q
= q
* 128 + (data
.byte(pos
) & ~0x80);
109 } while (pos
< data
.length() && data
.byte(pos
++) & 0x80);
113 string
CssmData::toOid() const
118 unsigned int pos
= 0;
120 // first byte is composite (q1,q2)
122 unsigned long oid1
= getOid(*this, pos
);
123 unsigned long q1
= min(oid1
/ 40, 2ul);
124 snprintf(buffer
, sizeof(buffer
), "%lu.%lu", q1
, oid1
- q1
* 40);
128 while (pos
< length()) {
130 snprintf(buffer
, sizeof(buffer
), ".%lu", getOid(*this, pos
));
136 static void putOid(CssmOwnedData
&data
, unsigned long id
)
138 unsigned char buffer
[sizeof(unsigned long) * 2]; // * (8/7) + 1, conservative
139 unsigned char *p
= buffer
+ sizeof(buffer
);
141 *--p
= 0x80 | (id
& 0x7F); // last 7 bits, high bit set
142 } while ((id
>>= 7) > 0);
143 buffer
[sizeof(buffer
) - 1] &= ~0x80; // clear last high bit (end of number)
144 data
.append(p
, buffer
+ sizeof(buffer
) - p
); // append generated byte string
148 // Convert OID string (1.2.3...) into CssmOid form.
149 // Allocates the data, replacing current contents.
150 // Will not process oid elements out of unsigned long range.
152 void CssmOwnedData::fromOid(const char *oid
)
154 this->length(0); // make empty
156 // first two elements get combined in weird&wacky ways
157 unsigned long q1
= strtoul(oid
, (char **)&oid
, 10);
160 unsigned long q2
= strtoul(oid
, (char **)&oid
, 10);
161 putOid(*this, 40 * q1
+ q2
);
162 while (oid
[0] == '.') {
164 putOid(*this, strtoul(oid
, (char **)&oid
, 10));
170 // Managed data objects
172 CssmManagedData::~CssmManagedData()
179 void CssmOwnedData::set(CssmManagedData
&source
)
181 if (source
.length() == 0) { // source is empty
182 reset(); // so just clear old data
183 } else if (allocator
== source
.allocator
) { // compatible allocators
184 if (referent
.data() == source
.data()) { // same data *and* we own it?!
185 assert(this == &source
); // this better *be* me!
186 } else { // different data
187 reset(); // give up our old data
188 referent
= source
.release(); // take over source's data
190 } else { // different allocators
191 copy(source
); // make a copy with our allocator
192 source
.reset(); // release source's data
200 CssmData
CssmAutoData::release()
202 CssmData result
= mData
;
207 void CssmAutoData::reset()
209 allocator
.free(mData
);
217 CssmData
CssmRemoteData::release()
223 void CssmRemoteData::reset()
226 allocator
.free(referent
);
234 CssmDateData::CssmDateData(const CSSM_DATE
&date
)
235 : CssmData(buffer
, sizeof(buffer
))
237 memcpy(buffer
, date
.Year
, 4);
238 memcpy(buffer
+ 4, date
.Month
, 2);
239 memcpy(buffer
+ 6, date
.Day
, 2);
243 CssmData
& CssmOwnedData::get() const throw()
248 } // end namespace Security