comparison nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.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 * pkix_pl_bigint.c
6 *
7 * BigInt Object Functions
8 *
9 */
10
11 #include "pkix_pl_bigint.h"
12
13 /* --Private-Big-Int-Functions------------------------------------ */
14
15 /*
16 * FUNCTION: pkix_pl_BigInt_Comparator
17 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
18 */
19 static PKIX_Error *
20 pkix_pl_BigInt_Comparator(
21 PKIX_PL_Object *firstObject,
22 PKIX_PL_Object *secondObject,
23 PKIX_Int32 *pResult,
24 void *plContext)
25 {
26 PKIX_PL_BigInt *firstBigInt = NULL;
27 PKIX_PL_BigInt *secondBigInt = NULL;
28 char *firstPtr = NULL;
29 char *secondPtr = NULL;
30 PKIX_UInt32 firstLen, secondLen;
31
32 PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Comparator");
33 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
34
35 PKIX_CHECK(pkix_CheckTypes
36 (firstObject, secondObject, PKIX_BIGINT_TYPE, plContext),
37 PKIX_ARGUMENTSNOTBIGINTS);
38
39 /* It's safe to cast */
40 firstBigInt = (PKIX_PL_BigInt*)firstObject;
41 secondBigInt = (PKIX_PL_BigInt*)secondObject;
42
43 *pResult = 0;
44 firstPtr = firstBigInt->dataRep;
45 secondPtr = secondBigInt->dataRep;
46 firstLen = firstBigInt->length;
47 secondLen = secondBigInt->length;
48
49 if (firstLen < secondLen) {
50 *pResult = -1;
51 } else if (firstLen > secondLen) {
52 *pResult = 1;
53 } else if (firstLen == secondLen) {
54 PKIX_BIGINT_DEBUG("\t\tCalling PORT_Memcmp).\n");
55 *pResult = PORT_Memcmp(firstPtr, secondPtr, firstLen);
56 }
57
58 cleanup:
59
60 PKIX_RETURN(BIGINT);
61 }
62
63 /*
64 * FUNCTION: pkix_pl_BigInt_Destroy
65 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
66 */
67 static PKIX_Error *
68 pkix_pl_BigInt_Destroy(
69 PKIX_PL_Object *object,
70 void *plContext)
71 {
72 PKIX_PL_BigInt *bigInt = NULL;
73
74 PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Destroy");
75 PKIX_NULLCHECK_ONE(object);
76
77 PKIX_CHECK(pkix_CheckType(object, PKIX_BIGINT_TYPE, plContext),
78 PKIX_OBJECTNOTBIGINT);
79
80 bigInt = (PKIX_PL_BigInt*)object;
81
82 PKIX_FREE(bigInt->dataRep);
83 bigInt->dataRep = NULL;
84 bigInt->length = 0;
85
86 cleanup:
87
88 PKIX_RETURN(BIGINT);
89 }
90
91
92 /*
93 * FUNCTION: pkix_pl_BigInt_ToString
94 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
95 */
96 static PKIX_Error *
97 pkix_pl_BigInt_ToString(
98 PKIX_PL_Object *object,
99 PKIX_PL_String **pString,
100 void *plContext)
101 {
102 PKIX_PL_BigInt *bigInt = NULL;
103 char *outputText = NULL;
104 PKIX_UInt32 i, j, lengthChars;
105
106 PKIX_ENTER(BIGINT, "pkix_pl_BigInt_ToString");
107 PKIX_NULLCHECK_TWO(object, pString);
108
109 PKIX_CHECK(pkix_CheckType(object, PKIX_BIGINT_TYPE, plContext),
110 PKIX_OBJECTNOTBIGINT);
111
112 bigInt = (PKIX_PL_BigInt*)object;
113
114 /* number of chars = 2 * (number of bytes) + null terminator */
115 lengthChars = (bigInt->length * 2) + 1;
116
117 PKIX_CHECK(PKIX_PL_Malloc
118 (lengthChars, (void **)&outputText, plContext),
119 PKIX_MALLOCFAILED);
120
121 for (i = 0, j = 0; i < bigInt->length; i += 1, j += 2){
122 outputText[j] = pkix_i2hex
123 ((char) ((*(bigInt->dataRep+i) & 0xf0) >> 4));
124 outputText[j+1] = pkix_i2hex
125 ((char) (*(bigInt->dataRep+i) & 0x0f));
126 }
127
128 outputText[lengthChars-1] = '\0';
129
130 PKIX_CHECK(PKIX_PL_String_Create
131 (PKIX_ESCASCII,
132 outputText,
133 0,
134 pString,
135 plContext),
136 PKIX_STRINGCREATEFAILED);
137
138 cleanup:
139
140 PKIX_FREE(outputText);
141
142 PKIX_RETURN(BIGINT);
143 }
144
145
146 /*
147 * FUNCTION: pkix_pl_BigInt_Hashcode
148 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
149 */
150 static PKIX_Error *
151 pkix_pl_BigInt_Hashcode(
152 PKIX_PL_Object *object,
153 PKIX_UInt32 *pHashcode,
154 void *plContext)
155 {
156 PKIX_PL_BigInt *bigInt = NULL;
157
158 PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Hashcode");
159 PKIX_NULLCHECK_TWO(object, pHashcode);
160
161 PKIX_CHECK(pkix_CheckType(object, PKIX_BIGINT_TYPE, plContext),
162 PKIX_OBJECTNOTBIGINT);
163
164 bigInt = (PKIX_PL_BigInt*)object;
165
166 PKIX_CHECK(pkix_hash
167 ((void *)bigInt->dataRep,
168 bigInt->length,
169 pHashcode,
170 plContext),
171 PKIX_HASHFAILED);
172
173 cleanup:
174
175 PKIX_RETURN(BIGINT);
176 }
177
178 /*
179 * FUNCTION: pkix_pl_BigInt_Equals
180 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
181 */
182 static PKIX_Error *
183 pkix_pl_BigInt_Equals(
184 PKIX_PL_Object *first,
185 PKIX_PL_Object *second,
186 PKIX_Boolean *pResult,
187 void *plContext)
188 {
189 PKIX_UInt32 secondType;
190 PKIX_Int32 cmpResult = 0;
191
192 PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Equals");
193 PKIX_NULLCHECK_THREE(first, second, pResult);
194
195 PKIX_CHECK(pkix_CheckType(first, PKIX_BIGINT_TYPE, plContext),
196 PKIX_FIRSTOBJECTNOTBIGINT);
197
198 PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
199 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
200
201 *pResult = PKIX_FALSE;
202
203 if (secondType != PKIX_BIGINT_TYPE) goto cleanup;
204
205 PKIX_CHECK(pkix_pl_BigInt_Comparator
206 (first, second, &cmpResult, plContext),
207 PKIX_BIGINTCOMPARATORFAILED);
208
209 *pResult = (cmpResult == 0);
210
211 cleanup:
212
213 PKIX_RETURN(BIGINT);
214 }
215
216 /*
217 * FUNCTION: pkix_pl_BigInt_RegisterSelf
218 * DESCRIPTION:
219 * Registers PKIX_BIGINT_TYPE and its related functions with systemClasses[]
220 * THREAD SAFETY:
221 * Not Thread Safe - for performance and complexity reasons
222 *
223 * Since this function is only called by PKIX_PL_Initialize, which should
224 * only be called once, it is acceptable that this function is not
225 * thread-safe.
226 */
227 PKIX_Error *
228 pkix_pl_BigInt_RegisterSelf(void *plContext)
229 {
230
231 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
232 pkix_ClassTable_Entry entry;
233
234 PKIX_ENTER(BIGINT, "pkix_pl_BigInt_RegisterSelf");
235
236 entry.description = "BigInt";
237 entry.objCounter = 0;
238 entry.typeObjectSize = sizeof(PKIX_PL_BigInt);
239 entry.destructor = pkix_pl_BigInt_Destroy;
240 entry.equalsFunction = pkix_pl_BigInt_Equals;
241 entry.hashcodeFunction = pkix_pl_BigInt_Hashcode;
242 entry.toStringFunction = pkix_pl_BigInt_ToString;
243 entry.comparator = pkix_pl_BigInt_Comparator;
244 entry.duplicateFunction = pkix_duplicateImmutable;
245
246 systemClasses[PKIX_BIGINT_TYPE] = entry;
247
248 PKIX_RETURN(BIGINT);
249 }
250
251 /*
252 * FUNCTION: pkix_pl_BigInt_CreateWithBytes
253 * DESCRIPTION:
254 *
255 * Creates a new BigInt of size "length" representing the array of bytes
256 * pointed to by "bytes" and stores it at "pBigInt". The caller should make
257 * sure that the first byte is not 0x00 (unless it is the the only byte).
258 * This function does not do that checking.
259 *
260 * Once created, a PKIX_PL_BigInt object is immutable.
261 *
262 * PARAMETERS:
263 * "bytes"
264 * Address of array of bytes. Must be non-NULL.
265 * "length"
266 * Length of the array. Must be non-zero.
267 * "pBigInt"
268 * Address where object pointer will be stored. Must be non-NULL.
269 * "plContext" - Platform-specific context pointer.
270 * THREAD SAFETY:
271 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
272 * RETURNS:
273 * Returns NULL if the function succeeds.
274 * Returns a Fatal Error if the function fails in an unrecoverable way.
275 */
276 PKIX_Error *
277 pkix_pl_BigInt_CreateWithBytes(
278 char *bytes,
279 PKIX_UInt32 length,
280 PKIX_PL_BigInt **pBigInt,
281 void *plContext)
282 {
283 PKIX_PL_BigInt *bigInt = NULL;
284
285 PKIX_ENTER(BIGINT, "pkix_pl_BigInt_CreateWithBytes");
286 PKIX_NULLCHECK_TWO(pBigInt, bytes);
287
288 if (length == 0) {
289 PKIX_ERROR(PKIX_BIGINTLENGTH0INVALID)
290 }
291
292 PKIX_CHECK(PKIX_PL_Object_Alloc
293 (PKIX_BIGINT_TYPE,
294 sizeof (PKIX_PL_BigInt),
295 (PKIX_PL_Object **)&bigInt,
296 plContext),
297 PKIX_COULDNOTCREATEOBJECT);
298
299 PKIX_CHECK(PKIX_PL_Malloc
300 (length, (void **)&(bigInt->dataRep), plContext),
301 PKIX_MALLOCFAILED);
302
303 PKIX_BIGINT_DEBUG("\t\tCalling PORT_Memcpy).\n");
304 (void) PORT_Memcpy(bigInt->dataRep, bytes, length);
305
306 bigInt->length = length;
307
308 *pBigInt = bigInt;
309
310 cleanup:
311
312 if (PKIX_ERROR_RECEIVED){
313 PKIX_DECREF(bigInt);
314 }
315
316 PKIX_RETURN(BIGINT);
317 }
318
319 /* --Public-Functions------------------------------------------------------- */
320
321 /*
322 * FUNCTION: PKIX_PL_BigInt_Create (see comments in pkix_pl_system.h)
323 */
324 PKIX_Error *
325 PKIX_PL_BigInt_Create(
326 PKIX_PL_String *stringRep,
327 PKIX_PL_BigInt **pBigInt,
328 void *plContext)
329 {
330 PKIX_PL_BigInt *bigInt = NULL;
331 char *asciiString = NULL;
332 PKIX_UInt32 lengthBytes;
333 PKIX_UInt32 lengthString;
334 PKIX_UInt32 i;
335 char currChar;
336
337 PKIX_ENTER(BIGINT, "PKIX_PL_BigInt_Create");
338 PKIX_NULLCHECK_TWO(pBigInt, stringRep);
339
340 PKIX_CHECK(PKIX_PL_String_GetEncoded
341 (stringRep,
342 PKIX_ESCASCII,
343 (void **)&asciiString,
344 &lengthString,
345 plContext),
346 PKIX_STRINGGETENCODEDFAILED);
347
348 if ((lengthString == 0) || ((lengthString % 2) != 0)){
349 PKIX_ERROR(PKIX_SOURCESTRINGHASINVALIDLENGTH);
350 }
351
352 if (lengthString != 2){
353 if ((asciiString[0] == '0') && (asciiString[1] == '0')){
354 PKIX_ERROR(PKIX_FIRSTDOUBLEHEXMUSTNOTBE00);
355 }
356 }
357
358 for (i = 0; i < lengthString; i++) {
359 currChar = asciiString[i];
360 if (!PKIX_ISXDIGIT(currChar)){
361 PKIX_ERROR(PKIX_INVALIDCHARACTERINBIGINT);
362 }
363 }
364
365 PKIX_CHECK(PKIX_PL_Object_Alloc
366 (PKIX_BIGINT_TYPE,
367 sizeof (PKIX_PL_BigInt),
368 (PKIX_PL_Object **)&bigInt,
369 plContext),
370 PKIX_COULDNOTCREATEOBJECT);
371
372 /* number of bytes = 0.5 * (number of chars) */
373 lengthBytes = lengthString/2;
374
375 PKIX_CHECK(PKIX_PL_Malloc
376 (lengthBytes, (void **)&(bigInt->dataRep), plContext),
377 PKIX_MALLOCFAILED);
378
379 for (i = 0; i < lengthString; i += 2){
380 (bigInt->dataRep)[i/2] =
381 (pkix_hex2i(asciiString[i])<<4) |
382 pkix_hex2i(asciiString[i+1]);
383 }
384
385 bigInt->length = lengthBytes;
386
387 *pBigInt = bigInt;
388
389 cleanup:
390
391 PKIX_FREE(asciiString);
392
393 if (PKIX_ERROR_RECEIVED){
394 PKIX_DECREF(bigInt);
395 }
396
397 PKIX_RETURN(BIGINT);
398 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)