Bug 460926 A11y hierachy is broken on Ubuntu 8.10 (GNOME 2.24), r=Evan.Yan sr=roc
[wine-gecko.git] / security / nss / lib / util / dersubr.c
blob3aa0db8f13de173f0dcfd4bf2ce7066d1b591d1e
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #include "secder.h"
38 #include <limits.h>
39 #include "secerr.h"
41 int
42 DER_LengthLength(PRUint32 len)
44 if (len > 127) {
45 if (len > 255) {
46 if (len > 65535L) {
47 if (len > 16777215L) {
48 return 5;
49 } else {
50 return 4;
52 } else {
53 return 3;
55 } else {
56 return 2;
58 } else {
59 return 1;
63 unsigned char *
64 DER_StoreHeader(unsigned char *buf, unsigned int code, PRUint32 len)
66 unsigned char b[4];
68 b[0] = (unsigned char)(len >> 24);
69 b[1] = (unsigned char)(len >> 16);
70 b[2] = (unsigned char)(len >> 8);
71 b[3] = (unsigned char)len;
72 if ((code & DER_TAGNUM_MASK) == DER_SET
73 || (code & DER_TAGNUM_MASK) == DER_SEQUENCE)
74 code |= DER_CONSTRUCTED;
75 *buf++ = code;
76 if (len > 127) {
77 if (len > 255) {
78 if (len > 65535) {
79 if (len > 16777215) {
80 *buf++ = 0x84;
81 *buf++ = b[0];
82 *buf++ = b[1];
83 *buf++ = b[2];
84 *buf++ = b[3];
85 } else {
86 *buf++ = 0x83;
87 *buf++ = b[1];
88 *buf++ = b[2];
89 *buf++ = b[3];
91 } else {
92 *buf++ = 0x82;
93 *buf++ = b[2];
94 *buf++ = b[3];
96 } else {
97 *buf++ = 0x81;
98 *buf++ = b[3];
100 } else {
101 *buf++ = b[3];
103 return buf;
107 * XXX This should be rewritten, generalized, to take a long instead
108 * of a PRInt32.
110 SECStatus
111 DER_SetInteger(PRArenaPool *arena, SECItem *it, PRInt32 i)
113 unsigned char bb[4];
114 unsigned len;
116 bb[0] = (unsigned char) (i >> 24);
117 bb[1] = (unsigned char) (i >> 16);
118 bb[2] = (unsigned char) (i >> 8);
119 bb[3] = (unsigned char) (i);
122 ** Small integers are encoded in a single byte. Larger integers
123 ** require progressively more space.
125 if (i < -128) {
126 if (i < -32768L) {
127 if (i < -8388608L) {
128 len = 4;
129 } else {
130 len = 3;
132 } else {
133 len = 2;
135 } else if (i > 127) {
136 if (i > 32767L) {
137 if (i > 8388607L) {
138 len = 4;
139 } else {
140 len = 3;
142 } else {
143 len = 2;
145 } else {
146 len = 1;
148 it->data = (unsigned char*) PORT_ArenaAlloc(arena, len);
149 if (!it->data) {
150 return SECFailure;
152 it->len = len;
153 PORT_Memcpy(it->data, bb + (4 - len), len);
154 return SECSuccess;
158 * XXX This should be rewritten, generalized, to take an unsigned long instead
159 * of a PRUint32.
161 SECStatus
162 DER_SetUInteger(PRArenaPool *arena, SECItem *it, PRUint32 ui)
164 unsigned char bb[5];
165 int len;
167 bb[0] = 0;
168 bb[1] = (unsigned char) (ui >> 24);
169 bb[2] = (unsigned char) (ui >> 16);
170 bb[3] = (unsigned char) (ui >> 8);
171 bb[4] = (unsigned char) (ui);
174 ** Small integers are encoded in a single byte. Larger integers
175 ** require progressively more space.
177 if (ui > 0x7f) {
178 if (ui > 0x7fff) {
179 if (ui > 0x7fffffL) {
180 if (ui >= 0x80000000L) {
181 len = 5;
182 } else {
183 len = 4;
185 } else {
186 len = 3;
188 } else {
189 len = 2;
191 } else {
192 len = 1;
195 it->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
196 if (it->data == NULL) {
197 return SECFailure;
200 it->len = len;
201 PORT_Memcpy(it->data, bb + (sizeof(bb) - len), len);
203 return SECSuccess;
207 ** Convert a der encoded *signed* integer into a machine integral value.
208 ** If an underflow/overflow occurs, sets error code and returns min/max.
210 long
211 DER_GetInteger(SECItem *it)
213 long ival = 0;
214 unsigned len = it->len;
215 unsigned char *cp = it->data;
216 unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1);
217 unsigned long ofloinit;
219 if (*cp & 0x80)
220 ival = -1L;
221 ofloinit = ival & overflow;
223 while (len) {
224 if ((ival & overflow) != ofloinit) {
225 PORT_SetError(SEC_ERROR_BAD_DER);
226 if (ival < 0) {
227 return LONG_MIN;
229 return LONG_MAX;
231 ival = ival << 8;
232 ival |= *cp++;
233 --len;
235 return ival;
239 ** Convert a der encoded *unsigned* integer into a machine integral value.
240 ** If an underflow/overflow occurs, sets error code and returns min/max.
242 unsigned long
243 DER_GetUInteger(SECItem *it)
245 unsigned long ival = 0;
246 unsigned len = it->len;
247 unsigned char *cp = it->data;
248 unsigned long overflow = 0xffUL << ((sizeof(ival) - 1) * 8);
250 /* Cannot put a negative value into an unsigned container. */
251 if (*cp & 0x80) {
252 PORT_SetError(SEC_ERROR_BAD_DER);
253 return 0;
256 while (len) {
257 if (ival & overflow) {
258 PORT_SetError(SEC_ERROR_BAD_DER);
259 return ULONG_MAX;
261 ival = ival << 8;
262 ival |= *cp++;
263 --len;
265 return ival;