]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2006,2011-2012,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // | |
26 | // Miscellaneous CSSM PODWrappers | |
27 | // | |
28 | #include <security_cdsa_utilities/cssmpods.h> | |
29 | #include <security_cdsa_utilities/cssmbridge.h> | |
30 | #include <security_utilities/endian.h> | |
31 | ||
32 | // | |
33 | // GUID <-> string conversions. | |
34 | // Note that we DO check for {} on input and insist on rigid formatting. | |
35 | // We don't require a terminating null byte on input, but generate it on output. | |
36 | // | |
37 | char *Guid::toString(char buffer[stringRepLength+1]) const | |
38 | { | |
39 | sprintf(buffer, "{%8.8x-%4.4hx-%4.4hx-", | |
40 | int(n2h(Data1)), n2h(Data2), n2h(Data3)); | |
41 | for (int n = 0; n < 2; n++) | |
42 | sprintf(buffer + 20 + 2*n, "%2.2hhx", Data4[n]); | |
43 | buffer[24] = '-'; | |
44 | for (int n = 2; n < 8; n++) | |
45 | sprintf(buffer + 21 + 2*n, "%2.2hhx", Data4[n]); | |
46 | buffer[37] = '}'; | |
47 | buffer[38] = '\0'; | |
48 | return buffer; | |
49 | } | |
50 | ||
51 | string Guid::toString() const | |
52 | { | |
53 | char buffer[stringRepLength+1]; | |
54 | return toString(buffer); | |
55 | } | |
56 | ||
57 | Guid::Guid(const char *s) | |
58 | { | |
59 | parseGuid(s); | |
60 | } | |
61 | ||
62 | Guid::Guid(const string &s) | |
63 | { | |
64 | parseGuid(s.c_str()); | |
65 | } | |
66 | ||
67 | void Guid::parseGuid(const char *string) | |
68 | { | |
69 | // Arguably, we should be more flexible on input. But exactly what | |
70 | // padding rules should we follow, and how should we try to interprete | |
71 | // "doubtful" variations? Given that GUIDs are essentially magic | |
72 | // cookies, everybody's better off if we just cut-and-paste them | |
73 | // around the universe... | |
74 | ||
75 | // do sanity checking, don't assume that what's passed in makes sense | |
76 | if (string == NULL) | |
77 | { | |
78 | CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID); | |
79 | } | |
80 | ||
81 | // what follows had better be big enough | |
82 | if (strlen(string) < 37) // needed because the code hard codes the length | |
83 | { | |
84 | CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID); | |
85 | } | |
86 | ||
87 | int d1; | |
88 | uint16 d2, d3; | |
89 | if (sscanf(string, "{%8x-%4hx-%4hx-", &d1, &d2, &d3) != 3) | |
90 | CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID); | |
91 | Data1 = h2n(uint32(d1)); | |
92 | Data2 = h2n(d2); | |
93 | Data3 = h2n(d3); | |
94 | // once, we did not expect the - after byte 2 of Data4 | |
95 | bool newForm = string[24] == '-'; | |
96 | for (int n = 0; n < 8; n++) { | |
97 | unsigned char dn; | |
98 | if (sscanf(string + 20 + 2*n + (newForm && n >= 2), "%2hhx", &dn) != 1) | |
99 | CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID); | |
100 | Data4[n] = dn; | |
101 | } | |
102 | if (string[37 - !newForm] != '}') | |
103 | CssmError::throwMe(CSSM_ERRCODE_INVALID_GUID); | |
104 | } | |
105 | ||
106 | ||
107 | CssmGuidData::CssmGuidData(const CSSM_GUID &guid) : CssmData(buffer, sizeof(buffer)) | |
108 | { | |
109 | Guid::overlay(guid).toString(buffer); | |
110 | } | |
111 | ||
112 | ||
113 | // | |
114 | // CssmSubserviceUids. | |
115 | // Note that for comparison, we ignore the version field. | |
116 | // This is not necessarily the Right Choice, but suits certain | |
117 | // constraints in the Sec* layer. Perhaps we might reconsider | |
118 | // this after a thorough code review to determine the intended | |
119 | // (by the standard) semantics and proper use. Yeah, right. | |
120 | // | |
121 | CssmSubserviceUid::CssmSubserviceUid(const CSSM_GUID &guid, | |
122 | const CSSM_VERSION *version, uint32 subserviceId, CSSM_SERVICE_TYPE subserviceType) | |
123 | { | |
124 | Guid = guid; | |
125 | SubserviceId = subserviceId; | |
126 | SubserviceType = subserviceType; | |
127 | if (version) | |
128 | Version = *version; | |
129 | else | |
130 | Version.Major = Version.Minor = 0; | |
131 | } | |
132 | ||
133 | ||
134 | bool CssmSubserviceUid::operator == (const CSSM_SUBSERVICE_UID &otherUid) const | |
135 | { | |
c38e3ce9 | 136 | // make sure we don't crash if we get bad data |
5c19dc3a A |
137 | #pragma clang diagnostic push |
138 | #pragma clang diagnostic ignored "-Wtautological-undefined-compare" | |
139 | if (&otherUid == 0x0) { return false; } | |
140 | #pragma clang diagnostic pop | |
141 | ||
b1ab9ed8 A |
142 | const CssmSubserviceUid &other = CssmSubserviceUid::overlay(otherUid); |
143 | return subserviceId() == other.subserviceId() | |
144 | && subserviceType() == other.subserviceType() | |
145 | && guid() == other.guid(); | |
146 | } | |
147 | ||
148 | bool CssmSubserviceUid::operator < (const CSSM_SUBSERVICE_UID &otherUid) const | |
149 | { | |
5c19dc3a A |
150 | #pragma clang diagnostic push |
151 | #pragma clang diagnostic ignored "-Wtautological-undefined-compare" | |
152 | if (&otherUid == 0x0) { return false; } | |
153 | #pragma clang diagnostic pop | |
154 | ||
b1ab9ed8 A |
155 | const CssmSubserviceUid &other = CssmSubserviceUid::overlay(otherUid); |
156 | if (subserviceId() < other.subserviceId()) | |
157 | return true; | |
158 | if (subserviceId() > other.subserviceId()) | |
159 | return false; | |
160 | if (subserviceType() < other.subserviceType()) | |
161 | return true; | |
162 | if (subserviceType() > other.subserviceType()) | |
163 | return false; | |
164 | return guid() < other.guid(); | |
165 | } | |
166 | ||
167 | ||
168 | // | |
169 | // CryptoData & friends | |
170 | // | |
171 | CryptoDataClass::~CryptoDataClass() | |
172 | { } | |
173 | ||
174 | CSSM_RETURN CryptoDataClass::callbackShim(CSSM_DATA *output, void *ctx) | |
175 | { | |
176 | BEGIN_API | |
177 | *output = reinterpret_cast<CryptoDataClass *>(ctx)->yield(); | |
178 | END_API(CSSM) | |
179 | } |