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 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)