Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/util/dersubr.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 #include "secder.h" | |
6 #include <limits.h> | |
7 #include "secerr.h" | |
8 | |
9 int | |
10 DER_LengthLength(PRUint32 len) | |
11 { | |
12 if (len > 127) { | |
13 if (len > 255) { | |
14 if (len > 65535L) { | |
15 if (len > 16777215L) { | |
16 return 5; | |
17 } else { | |
18 return 4; | |
19 } | |
20 } else { | |
21 return 3; | |
22 } | |
23 } else { | |
24 return 2; | |
25 } | |
26 } else { | |
27 return 1; | |
28 } | |
29 } | |
30 | |
31 unsigned char * | |
32 DER_StoreHeader(unsigned char *buf, unsigned int code, PRUint32 len) | |
33 { | |
34 unsigned char b[4]; | |
35 | |
36 b[0] = (unsigned char)(len >> 24); | |
37 b[1] = (unsigned char)(len >> 16); | |
38 b[2] = (unsigned char)(len >> 8); | |
39 b[3] = (unsigned char)len; | |
40 if ((code & DER_TAGNUM_MASK) == DER_SET | |
41 || (code & DER_TAGNUM_MASK) == DER_SEQUENCE) | |
42 code |= DER_CONSTRUCTED; | |
43 *buf++ = code; | |
44 if (len > 127) { | |
45 if (len > 255) { | |
46 if (len > 65535) { | |
47 if (len > 16777215) { | |
48 *buf++ = 0x84; | |
49 *buf++ = b[0]; | |
50 *buf++ = b[1]; | |
51 *buf++ = b[2]; | |
52 *buf++ = b[3]; | |
53 } else { | |
54 *buf++ = 0x83; | |
55 *buf++ = b[1]; | |
56 *buf++ = b[2]; | |
57 *buf++ = b[3]; | |
58 } | |
59 } else { | |
60 *buf++ = 0x82; | |
61 *buf++ = b[2]; | |
62 *buf++ = b[3]; | |
63 } | |
64 } else { | |
65 *buf++ = 0x81; | |
66 *buf++ = b[3]; | |
67 } | |
68 } else { | |
69 *buf++ = b[3]; | |
70 } | |
71 return buf; | |
72 } | |
73 | |
74 /* | |
75 * XXX This should be rewritten, generalized, to take a long instead | |
76 * of a PRInt32. | |
77 */ | |
78 SECStatus | |
79 DER_SetInteger(PLArenaPool *arena, SECItem *it, PRInt32 i) | |
80 { | |
81 unsigned char bb[4]; | |
82 unsigned len; | |
83 | |
84 bb[0] = (unsigned char) (i >> 24); | |
85 bb[1] = (unsigned char) (i >> 16); | |
86 bb[2] = (unsigned char) (i >> 8); | |
87 bb[3] = (unsigned char) (i); | |
88 | |
89 /* | |
90 ** Small integers are encoded in a single byte. Larger integers | |
91 ** require progressively more space. | |
92 */ | |
93 if (i < -128) { | |
94 if (i < -32768L) { | |
95 if (i < -8388608L) { | |
96 len = 4; | |
97 } else { | |
98 len = 3; | |
99 } | |
100 } else { | |
101 len = 2; | |
102 } | |
103 } else if (i > 127) { | |
104 if (i > 32767L) { | |
105 if (i > 8388607L) { | |
106 len = 4; | |
107 } else { | |
108 len = 3; | |
109 } | |
110 } else { | |
111 len = 2; | |
112 } | |
113 } else { | |
114 len = 1; | |
115 } | |
116 it->data = (unsigned char*) PORT_ArenaAlloc(arena, len); | |
117 if (!it->data) { | |
118 return SECFailure; | |
119 } | |
120 it->len = len; | |
121 PORT_Memcpy(it->data, bb + (4 - len), len); | |
122 return SECSuccess; | |
123 } | |
124 | |
125 /* | |
126 * XXX This should be rewritten, generalized, to take an unsigned long instead | |
127 * of a PRUint32. | |
128 */ | |
129 SECStatus | |
130 DER_SetUInteger(PLArenaPool *arena, SECItem *it, PRUint32 ui) | |
131 { | |
132 unsigned char bb[5]; | |
133 int len; | |
134 | |
135 bb[0] = 0; | |
136 bb[1] = (unsigned char) (ui >> 24); | |
137 bb[2] = (unsigned char) (ui >> 16); | |
138 bb[3] = (unsigned char) (ui >> 8); | |
139 bb[4] = (unsigned char) (ui); | |
140 | |
141 /* | |
142 ** Small integers are encoded in a single byte. Larger integers | |
143 ** require progressively more space. | |
144 */ | |
145 if (ui > 0x7f) { | |
146 if (ui > 0x7fff) { | |
147 if (ui > 0x7fffffL) { | |
148 if (ui >= 0x80000000L) { | |
149 len = 5; | |
150 } else { | |
151 len = 4; | |
152 } | |
153 } else { | |
154 len = 3; | |
155 } | |
156 } else { | |
157 len = 2; | |
158 } | |
159 } else { | |
160 len = 1; | |
161 } | |
162 | |
163 it->data = (unsigned char *)PORT_ArenaAlloc(arena, len); | |
164 if (it->data == NULL) { | |
165 return SECFailure; | |
166 } | |
167 | |
168 it->len = len; | |
169 PORT_Memcpy(it->data, bb + (sizeof(bb) - len), len); | |
170 | |
171 return SECSuccess; | |
172 } | |
173 | |
174 /* | |
175 ** Convert a der encoded *signed* integer into a machine integral value. | |
176 ** If an underflow/overflow occurs, sets error code and returns min/max. | |
177 */ | |
178 long | |
179 DER_GetInteger(const SECItem *it) | |
180 { | |
181 long ival = 0; | |
182 unsigned len = it->len; | |
183 unsigned char *cp = it->data; | |
184 unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1); | |
185 unsigned long ofloinit; | |
186 | |
187 PORT_Assert(len); | |
188 if (!len) { | |
189 PORT_SetError(SEC_ERROR_INPUT_LEN); | |
190 return 0; | |
191 } | |
192 | |
193 if (*cp & 0x80) | |
194 ival = -1L; | |
195 ofloinit = ival & overflow; | |
196 | |
197 while (len) { | |
198 if ((ival & overflow) != ofloinit) { | |
199 PORT_SetError(SEC_ERROR_BAD_DER); | |
200 if (ival < 0) { | |
201 return LONG_MIN; | |
202 } | |
203 return LONG_MAX; | |
204 } | |
205 ival = ival << 8; | |
206 ival |= *cp++; | |
207 --len; | |
208 } | |
209 return ival; | |
210 } | |
211 | |
212 /* | |
213 ** Convert a der encoded *unsigned* integer into a machine integral value. | |
214 ** If an overflow occurs, sets error code and returns max. | |
215 */ | |
216 unsigned long | |
217 DER_GetUInteger(SECItem *it) | |
218 { | |
219 unsigned long ival = 0; | |
220 unsigned len = it->len; | |
221 unsigned char *cp = it->data; | |
222 unsigned long overflow = 0xffUL << ((sizeof(ival) - 1) * 8); | |
223 | |
224 PORT_Assert(len); | |
225 if (!len) { | |
226 PORT_SetError(SEC_ERROR_INPUT_LEN); | |
227 return 0; | |
228 } | |
229 | |
230 /* Cannot put a negative value into an unsigned container. */ | |
231 if (*cp & 0x80) { | |
232 PORT_SetError(SEC_ERROR_BAD_DER); | |
233 return 0; | |
234 } | |
235 | |
236 while (len) { | |
237 if (ival & overflow) { | |
238 PORT_SetError(SEC_ERROR_BAD_DER); | |
239 return ULONG_MAX; | |
240 } | |
241 ival = ival << 8; | |
242 ival |= *cp++; | |
243 --len; | |
244 } | |
245 return ival; | |
246 } |