]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. | |
3 | * | |
4 | * The contents of this file constitute Original Code as defined in and are | |
5 | * subject to the Apple Public Source License Version 1.2 (the 'License'). | |
6 | * You may not use this file except in compliance with the License. Please obtain | |
7 | * a copy of the License at http://www.apple.com/publicsource and read it before | |
8 | * using this file. | |
9 | * | |
10 | * This Original Code and all software distributed under the License are | |
11 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS | |
12 | * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT | |
13 | * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
14 | * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the | |
15 | * specific language governing rights and limitations under the License. | |
16 | */ | |
17 | ||
18 | ||
19 | /* | |
20 | * CryptKitDER.h - snacc-based routines to create and parse DER-encoded FEE | |
21 | * keys and signatures | |
22 | * | |
23 | * Created 3/12/2001 by dmitch. | |
24 | */ | |
25 | ||
26 | #ifdef CRYPTKIT_CSP_ENABLE | |
27 | ||
28 | #include <Security/asn-incl.h> | |
29 | #include <Security/sm_vdatypes.h> | |
30 | #include <CryptKit/CryptKitDER.h> | |
31 | #include <CryptKit/falloc.h> | |
32 | #include <CryptKit/feeDebug.h> | |
33 | #include <CryptKit/feeFunctions.h> | |
34 | #include <Security/cdsaUtils.h> | |
35 | #include <Security/appleoids.h> | |
36 | ||
37 | #define PRINT_SIG_GIANTS 0 | |
38 | #define PRINT_CURVE_PARAMS 0 | |
39 | #define PRINT_SIZES 0 | |
40 | #if PRINT_SIZES | |
41 | #define szprint(s) printf s | |
42 | #else | |
43 | #define szprint(s) | |
44 | #endif | |
45 | ||
46 | /* | |
47 | * Trivial exception class associated with a feeReturn. | |
48 | */ | |
49 | class feeException | |
50 | { | |
51 | protected: | |
52 | feeException(feeReturn frtn, const char *op); | |
53 | public: | |
54 | ~feeException() { } | |
55 | feeReturn frtn() { return mFrtn; } | |
56 | static void throwMe(feeReturn frtn, const char *op = NULL) __attribute__((noreturn)); | |
57 | private: | |
58 | feeReturn mFrtn; | |
59 | }; | |
60 | ||
61 | feeException::feeException( | |
62 | feeReturn frtn, | |
63 | const char *op) | |
64 | : mFrtn(frtn) | |
65 | { | |
66 | if(op) { | |
67 | dbgLog(("%s: %s\n", op, feeReturnString(frtn))); | |
68 | } | |
69 | } | |
70 | ||
71 | void feeException::throwMe(feeReturn frtn, const char *op = NULL) { throw feeException(frtn, op); } | |
72 | ||
73 | /* | |
74 | * ASN1 encoding rules specify that an integer's sign is indicated by the MSB | |
75 | * of the first (MS) content byte. For a non-negative number, if the MSB of | |
76 | * the MS byte (of the unencoded number) is one, then the encoding starts with | |
77 | * a byte of zeroes to indicate positive sign. For a negative number, the first | |
78 | * nine bits can not be all 1 - if they are (in the undecoded number), leading | |
79 | * bytes of 0xff are trimmed off until the first nine bits are something other | |
80 | * than one. Also, the first nine bits of the encoded number can not all be | |
81 | * zero. | |
82 | * | |
83 | * CryptKit giants express their sign as part of the giantstruct.sign field. | |
84 | * The giantDigit array (giantstruct.n[]) is stored l.s. digit first. | |
85 | * | |
86 | * These routines are independent of platform, endianness, and giatn digit size. | |
87 | */ | |
88 | ||
89 | /* routines to guess maximum size of DER-encoded objects */ | |
90 | static unsigned feeSizeOfSnaccGiant( | |
91 | giant g) | |
92 | { | |
93 | unsigned rtn = abs(g->sign) * GIANT_BYTES_PER_DIGIT; | |
94 | szprint(("feeSizeOfSnaccGiant: sign %d size %d\n", g->sign, rtn + 4)); | |
95 | return rtn + 4; | |
96 | } | |
97 | ||
98 | static unsigned feeSizeofSnaccInt() | |
99 | { | |
100 | return 7; | |
101 | } | |
102 | ||
103 | /* PUBLIC... */ | |
104 | unsigned feeSizeOfDERSig( | |
105 | giant g1, | |
106 | giant g2) | |
107 | { | |
108 | unsigned rtn = feeSizeOfSnaccGiant(g1); | |
109 | rtn += feeSizeOfSnaccGiant(g2); | |
110 | szprint(("feeSizeOfDERSig: size %d\n", rtn + 4)); | |
111 | return rtn + 4; | |
112 | } | |
113 | ||
114 | static unsigned feeSizeofSnaccCurveParams(const curveParams *cp) | |
115 | { | |
116 | unsigned rtn = 5 * feeSizeofSnaccInt(); // primeType, curveType, q, k, m | |
117 | rtn += 10 * feeSizeOfSnaccGiant(cp->basePrime); | |
118 | szprint(("feeSizeofSnaccCurveParams: size %d\n", rtn)); | |
119 | return rtn; | |
120 | } | |
121 | ||
122 | static unsigned feeSizeOfSnaccPubKey(const curveParams *cp) | |
123 | { | |
124 | unsigned rtn = 11; // version plus sequence overhead | |
125 | rtn += feeSizeofSnaccCurveParams(cp); | |
126 | rtn += (3 * feeSizeOfSnaccGiant(cp->basePrime)); | |
127 | szprint(("feeSizeOfSnaccPubKey: size %d\n", rtn)); | |
128 | return rtn; | |
129 | } | |
130 | ||
131 | static unsigned feeSizeOfSnaccPrivKey(const curveParams *cp) | |
132 | { | |
133 | unsigned rtn = 11; // version plus sequence overhead | |
134 | rtn += feeSizeofSnaccCurveParams(cp); | |
135 | rtn += feeSizeOfSnaccGiant(cp->basePrime); | |
136 | szprint(("feeSizeOfSnaccPrivKey: size %d\n", rtn)); | |
137 | return rtn; | |
138 | } | |
139 | ||
140 | /* perform 2's complement of byte array, expressed MS byte first */ | |
141 | static void twosComplement( | |
142 | unsigned char *bytePtr, // points to MS byte | |
143 | unsigned numBytes) | |
144 | { | |
145 | unsigned char *outp = bytePtr + numBytes - 1; | |
146 | unsigned char carry = 1; // first time thru, carry = 1 to add one to 1's comp | |
147 | for(unsigned byteDex=0; byteDex<numBytes; byteDex++) { | |
148 | /* first complement, then add carry */ | |
149 | *outp = ~*outp + carry; | |
150 | if(carry && (*outp == 0)) { | |
151 | /* overflow/carry */ | |
152 | carry = 1; | |
153 | } | |
154 | else { | |
155 | carry = 0; | |
156 | } | |
157 | outp--; | |
158 | } | |
159 | } | |
160 | ||
161 | /* | |
162 | * Convert a BigIntegerStr to a (mallocd) giant. | |
163 | * Only known exception is a feeException. | |
164 | */ | |
165 | static giant bigIntStrToGiant( | |
166 | BigIntegerStr &bigInt) | |
167 | { | |
168 | char *rawOcts = bigInt; | |
169 | unsigned numBytes = bigInt.Len(); | |
170 | unsigned numGiantDigits; | |
171 | int sign = 1; | |
172 | giant grtn; | |
173 | feeReturn frtn = FR_Success; | |
174 | unsigned char *inp = NULL; | |
175 | unsigned digitDex; // index into g->giantDigit[] | |
176 | ||
177 | /* handle degenerate case (value of zero) */ | |
178 | if((numBytes == 0) || ((numBytes == 1) && rawOcts[0] == 0)) { | |
179 | grtn = newGiant(1); | |
180 | if(grtn == NULL) { | |
181 | feeException::throwMe(FR_Memory, "newGiant(1)"); | |
182 | } | |
183 | int_to_giant(0, grtn); | |
184 | return grtn; | |
185 | } | |
186 | ||
187 | /* make a copy of raw octets if we have to do two's complement */ | |
188 | unsigned char *byteArray = NULL; | |
189 | bool didMalloc = false; | |
190 | if(rawOcts[0] & 0x80) { | |
191 | sign = -1; | |
192 | numBytes++; | |
193 | byteArray = (unsigned char *)fmalloc(numBytes); | |
194 | didMalloc = true; | |
195 | byteArray[0] = 0xff; | |
196 | memmove(byteArray + 1, rawOcts, numBytes-1); | |
197 | twosComplement(byteArray, numBytes); | |
198 | } | |
199 | else { | |
200 | /* no copy */ | |
201 | char *foo = rawOcts; | |
202 | byteArray = (unsigned char *)foo; | |
203 | } | |
204 | ||
205 | /* cook up a new giant */ | |
206 | numGiantDigits = (numBytes + GIANT_BYTES_PER_DIGIT - 1) / | |
207 | GIANT_BYTES_PER_DIGIT; | |
208 | grtn = newGiant(numGiantDigits); | |
209 | if(grtn == NULL) { | |
210 | frtn = FR_Memory; | |
211 | goto abort; | |
212 | } | |
213 | ||
214 | /* | |
215 | * Convert byteArray to array of giantDigits | |
216 | * inp - raw input bytes, LSB last | |
217 | * grtn->n[] - output array of giantDigits, LSD first | |
218 | * Start at LS byte and LD digit | |
219 | */ | |
220 | digitDex = 0; // index into g->giantDigit[] | |
221 | giantDigit thisDigit; | |
222 | inp = byteArray + numBytes - 1; | |
223 | unsigned dex; // total byte counter | |
224 | unsigned byteDex; // index into one giantDigit | |
225 | unsigned shiftCount; | |
226 | for(dex=0; dex<numBytes; ) { // increment dex inside | |
227 | thisDigit = 0; | |
228 | shiftCount = 0; | |
229 | for(byteDex=0; byteDex<GIANT_BYTES_PER_DIGIT; byteDex++) { | |
230 | thisDigit |= ((giantDigit)(*inp--) << shiftCount); | |
231 | shiftCount += 8; | |
232 | if(++dex == numBytes) { | |
233 | /* must be partial giantDigit */ | |
234 | break; | |
235 | } | |
236 | } | |
237 | CKASSERT(digitDex < numGiantDigits); | |
238 | grtn->n[digitDex++] = thisDigit; | |
239 | } | |
240 | grtn->sign = (int)numGiantDigits * sign; | |
241 | ||
242 | /* trim leading (MS) zeroes */ | |
243 | gtrimSign(grtn); | |
244 | abort: | |
245 | if(didMalloc) { | |
246 | ffree(byteArray); | |
247 | } | |
248 | if(frtn) { | |
249 | feeException::throwMe(frtn, "bigIntStrToGiant"); | |
250 | } | |
251 | return grtn; | |
252 | } | |
253 | ||
254 | /* | |
255 | * Convert a giant to an existing BigIntegerString. | |
256 | * Only known exception is a feeException. | |
257 | */ | |
258 | static void giantToBigIntStr( | |
259 | giant g, | |
260 | BigIntegerStr &bigInt) | |
261 | { | |
262 | unsigned char doPrepend = 0; | |
263 | unsigned numGiantDigits = abs(g->sign); | |
264 | unsigned numBytes = numGiantDigits * GIANT_BYTES_PER_DIGIT; | |
265 | giantDigit msGiantBit = 0; | |
266 | if(isZero(g)) { | |
267 | /* special degenerate case */ | |
268 | bigInt.ReSet("", 1); | |
269 | return; | |
270 | } | |
271 | else { | |
272 | msGiantBit = g->n[numGiantDigits - 1] >> (GIANT_BITS_PER_DIGIT - 1); | |
273 | } | |
274 | ||
275 | /* prepend a byte of zero if necessary */ | |
276 | if((g->sign < 0) || // negative - to handle 2's complement | |
277 | ((g->sign > 0) && msGiantBit)) { // ensure MS byte is zero | |
278 | doPrepend = 1; | |
279 | numBytes++; | |
280 | } | |
281 | ||
282 | unsigned char *rawBytes = (unsigned char *)fmalloc(numBytes); | |
283 | if(rawBytes == NULL) { | |
284 | feeException::throwMe(FR_Memory, "giantToBigIntStr fmalloc(rawBytes)"); | |
285 | } | |
286 | unsigned char *outp = rawBytes; | |
287 | if(doPrepend) { | |
288 | *outp++ = 0; | |
289 | } | |
290 | ||
291 | /* | |
292 | * Convert array of giantDigits to bytes. | |
293 | * outp point to MS output byte. | |
294 | */ | |
295 | int digitDex; // index into g->giantDigit[] | |
296 | unsigned byteDex; // byte index into a giantDigit | |
297 | for(digitDex=numGiantDigits-1; digitDex>=0; digitDex--) { | |
298 | /* one loop per giantDigit, starting at MS end */ | |
299 | giantDigit thisDigit = g->n[digitDex]; | |
300 | unsigned char *bp = outp + GIANT_BYTES_PER_DIGIT - 1; | |
301 | for(byteDex=0; byteDex<GIANT_BYTES_PER_DIGIT; byteDex++) { | |
302 | /* one loop per byte within the digit, starting at LS end */ | |
303 | *bp-- = (unsigned char)(thisDigit) & 0xff; | |
304 | thisDigit >>= 8; | |
305 | } | |
306 | outp += GIANT_BYTES_PER_DIGIT; | |
307 | } | |
308 | ||
309 | /* do two's complement for negative giants */ | |
310 | if(g->sign < 0) { | |
311 | twosComplement(rawBytes, numBytes); | |
312 | } | |
313 | ||
314 | /* strip off redundant leading bits (nine zeroes or nine ones) */ | |
315 | outp = rawBytes; | |
316 | unsigned char *endp = outp + numBytes - 1; | |
317 | while((*outp == 0) && // m.s. byte zero | |
318 | (outp < endp) && // more bytes exist | |
319 | (!(outp[1] & 0x80))) { // 9th bit is 0 | |
320 | outp++; | |
321 | numBytes--; | |
322 | } | |
323 | while((*outp == 0xff) && // m.s. byte all ones | |
324 | (outp < endp) && // more bytes exist | |
325 | (outp[1] & 0x80)) { // 9th bit is 1 | |
326 | outp++; | |
327 | numBytes--; | |
328 | } | |
329 | ||
330 | /* rawBytes are the ASN-compliant contents */ | |
331 | bigInt.ReSet(reinterpret_cast<const char *>(outp), numBytes); | |
332 | ffree(rawBytes); | |
333 | } | |
334 | ||
335 | /* curveParams : CryptKit <--> snacc */ | |
336 | /* Only known exception is a feeException */ | |
337 | static FEECurveParameters *feeCurveParamsToSnacc( | |
338 | const curveParams *cp) | |
339 | { | |
340 | #if PRINT_CURVE_PARAMS | |
341 | printf("===encoding curveParams; cp:\n"); printCurveParams(cp); | |
342 | #endif | |
343 | FEECurveParameters *snaccCp = NULL; | |
344 | try { | |
345 | snaccCp = new FEECurveParameters(); | |
346 | AsnIntType val; | |
347 | switch(cp->primeType) { | |
348 | case FPT_Mersenne: | |
349 | val = FEEPrimeType::pt_mersenne; | |
350 | break; | |
351 | case FPT_FEE: | |
352 | val = FEEPrimeType::pt_fee; | |
353 | break; | |
354 | case FPT_General: | |
355 | val = FEEPrimeType::pt_general; | |
356 | break; | |
357 | default: | |
358 | feeException::throwMe(FR_Internal, "bad cp->primeType"); | |
359 | } | |
360 | snaccCp->primeType.Set(val); | |
361 | switch(cp->curveType) { | |
362 | case FCT_Montgomery: | |
363 | val = FEECurveType::ct_montgomery; | |
364 | break; | |
365 | case FCT_Weierstrass: | |
366 | val = FEECurveType::ct_weierstrass; | |
367 | break; | |
368 | case FCT_General: | |
369 | val = FEECurveType::ct_general; | |
370 | break; | |
371 | default: | |
372 | feeException::throwMe(FR_Internal, "bad cp->curveType"); | |
373 | } | |
374 | snaccCp->curveType.Set(val); | |
375 | snaccCp->q.Set(cp->q); | |
376 | snaccCp->k.Set(cp->k); | |
377 | snaccCp->m.Set(cp->m); | |
378 | giantToBigIntStr(cp->a, snaccCp->a); | |
379 | giantToBigIntStr(cp->b, snaccCp->bb); | |
380 | giantToBigIntStr(cp->c, snaccCp->c); | |
381 | giantToBigIntStr(cp->x1Plus, snaccCp->x1Plus); | |
382 | giantToBigIntStr(cp->x1Minus, snaccCp->x1Minus); | |
383 | giantToBigIntStr(cp->cOrderPlus, snaccCp->cOrderPlus); | |
384 | giantToBigIntStr(cp->cOrderMinus, snaccCp->cOrderMinus); | |
385 | giantToBigIntStr(cp->x1OrderPlus, snaccCp->x1OrderPlus); | |
386 | giantToBigIntStr(cp->x1OrderMinus, snaccCp->x1OrderMinus); | |
387 | if(cp->primeType == FPT_General) { | |
388 | snaccCp->basePrime = new BigIntegerStr(); | |
389 | giantToBigIntStr(cp->basePrime, *snaccCp->basePrime); | |
390 | } | |
391 | } | |
392 | catch(feeException ferr) { | |
393 | delete snaccCp; | |
394 | throw; | |
395 | } | |
396 | catch(...) { | |
397 | delete snaccCp; | |
398 | feeException::throwMe(FR_Memory, "feeCurveParamsToSnacc catchall"); // ??? | |
399 | } | |
400 | return snaccCp; | |
401 | } | |
402 | ||
403 | static curveParams *feeCurveParamsFromSnacc( | |
404 | FEECurveParameters &snaccCp) | |
405 | { | |
406 | curveParams *cp = newCurveParams(); | |
407 | if(cp == NULL) { | |
408 | feeException::throwMe(FR_Memory, "feeCurveParamsFromSnacc alloc cp"); | |
409 | } | |
410 | AsnIntType val = snaccCp.primeType; | |
411 | switch(val) { | |
412 | case FEEPrimeType::pt_mersenne: | |
413 | cp->primeType = FPT_Mersenne; | |
414 | break; | |
415 | case FEEPrimeType::pt_fee: | |
416 | cp->primeType = FPT_FEE; | |
417 | break; | |
418 | case FEEPrimeType::pt_general: | |
419 | cp->primeType = FPT_General; | |
420 | break; | |
421 | default: | |
422 | feeException::throwMe(FR_BadPubKey, "feeCurveParamsFromSnacc bad primeType"); | |
423 | } | |
424 | val = snaccCp.curveType; | |
425 | switch(val) { | |
426 | case FEECurveType::ct_montgomery: | |
427 | cp->curveType = FCT_Montgomery; | |
428 | break; | |
429 | case FEECurveType::ct_weierstrass: | |
430 | cp->curveType = FCT_Weierstrass; | |
431 | break; | |
432 | case FEECurveType::ct_general: | |
433 | cp->curveType = FCT_General; | |
434 | break; | |
435 | default: | |
436 | feeException::throwMe(FR_BadPubKey, "feeCurveParamsFromSnacc bad curveType"); | |
437 | } | |
438 | cp->q = snaccCp.q; | |
439 | cp->k = snaccCp.k; | |
440 | cp->m = snaccCp.m; | |
441 | cp->a = bigIntStrToGiant(snaccCp.a); | |
442 | cp->b = bigIntStrToGiant(snaccCp.bb); | |
443 | cp->c = bigIntStrToGiant(snaccCp.c); | |
444 | cp->x1Plus = bigIntStrToGiant(snaccCp.x1Plus); | |
445 | cp->x1Minus = bigIntStrToGiant(snaccCp.x1Minus); | |
446 | cp->cOrderPlus = bigIntStrToGiant(snaccCp.cOrderPlus); | |
447 | cp->cOrderMinus = bigIntStrToGiant(snaccCp.cOrderMinus); | |
448 | cp->x1OrderPlus = bigIntStrToGiant(snaccCp.x1OrderPlus); | |
449 | cp->x1OrderMinus = bigIntStrToGiant(snaccCp.x1OrderMinus); | |
450 | if(snaccCp.basePrime != NULL) { | |
451 | cp->basePrime = bigIntStrToGiant(*snaccCp.basePrime); | |
452 | } | |
453 | ||
454 | /* remaining fields inferred */ | |
455 | curveParamsInferFields(cp); | |
456 | allocRecipGiants(cp); | |
457 | #if PRINT_CURVE_PARAMS | |
458 | printf("===decoding curveParams; cp:\n"); printCurveParams(cp); | |
459 | #endif | |
460 | return cp; | |
461 | } | |
462 | ||
463 | /*** | |
464 | *** Public routines. These are usable from C code; they never throw. | |
465 | ***/ | |
466 | ||
467 | /* | |
468 | * Encode/decode the two FEE signature types. We malloc returned data via | |
469 | * fmalloc(); caller must free via ffree(). | |
470 | */ | |
471 | feeReturn feeDEREncodeElGamalSignature( | |
472 | giant u, | |
473 | giant PmX, | |
474 | unsigned char **encodedSig, // fmallocd and RETURNED | |
475 | unsigned *encodedSigLen) // RETURNED | |
476 | { | |
477 | FEEElGamalSignature snaccSig; | |
478 | CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive)); | |
479 | ||
480 | try { | |
481 | giantToBigIntStr(u, snaccSig.u); | |
482 | giantToBigIntStr(PmX, snaccSig.pmX); | |
483 | } | |
484 | catch(feeException ferr) { | |
485 | return ferr.frtn(); | |
486 | } | |
487 | try { | |
488 | SC_encodeAsnObj(snaccSig, oData, feeSizeOfDERSig(u, PmX)); | |
489 | } | |
490 | catch(...) { | |
491 | /* FIXME - bad sig? memory? */ | |
492 | return FR_BadSignatureFormat; | |
493 | } | |
494 | *encodedSig = (unsigned char *)fmalloc(oData.length()); | |
495 | *encodedSigLen = oData.length(); | |
496 | memmove(*encodedSig, oData.get().Data, oData.length()); | |
497 | #if PRINT_SIG_GIANTS | |
498 | printf("feeEncodeElGamalSignature:\n"); | |
499 | printf(" u : "); printGiantHex(u); | |
500 | printf(" PmX : "); printGiantHex(PmX); | |
501 | printf(" u : "); snaccSig.u.Print(cout); printf("\n"); | |
502 | printf(" PmX : "); snaccSig.pmX.Print(cout); printf("\n"); | |
503 | #endif | |
504 | return FR_Success; | |
505 | } | |
506 | ||
507 | feeReturn feeDEREncodeECDSASignature( | |
508 | giant c, | |
509 | giant d, | |
510 | unsigned char **encodedSig, // fmallocd and RETURNED | |
511 | unsigned *encodedSigLen) // RETURNED | |
512 | { | |
513 | FEEECDSASignature snaccSig; | |
514 | CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive)); | |
515 | ||
516 | try { | |
517 | giantToBigIntStr(c, snaccSig.c); | |
518 | giantToBigIntStr(d, snaccSig.d); | |
519 | } | |
520 | catch(feeException ferr) { | |
521 | return ferr.frtn(); | |
522 | } | |
523 | try { | |
524 | SC_encodeAsnObj(snaccSig, oData, feeSizeOfDERSig(c, d)); | |
525 | } | |
526 | catch(...) { | |
527 | /* FIXME - bad sig? memory? */ | |
528 | return FR_BadSignatureFormat; | |
529 | } | |
530 | *encodedSig = (unsigned char *)fmalloc(oData.length()); | |
531 | *encodedSigLen = oData.length(); | |
532 | memmove(*encodedSig, oData.get().Data, oData.length()); | |
533 | #if PRINT_SIG_GIANTS | |
534 | printf("feeEncodeECDSASignature:\n"); | |
535 | printf(" c : "); printGiantHex(*c); | |
536 | printf(" d : "); printGiantHex(*d); | |
537 | printf(" c : "); snaccSig.c.Print(cout); printf("\n"); | |
538 | printf(" d : "); snaccSig.d.Print(cout); printf("\n"); | |
539 | #endif | |
540 | return FR_Success; | |
541 | } | |
542 | ||
543 | feeReturn feeDERDecodeElGamalSignature( | |
544 | const unsigned char *encodedSig, | |
545 | unsigned encodedSigLen, | |
546 | giant *u, // newGiant'd and RETURNED | |
547 | giant *PmX) // newGiant'd and RETURNED | |
548 | { | |
549 | FEEElGamalSignature snaccSig; | |
550 | CssmData cData((void *)encodedSig, encodedSigLen); | |
551 | try { | |
552 | SC_decodeAsnObj(cData, snaccSig); | |
553 | } | |
554 | catch(...) { | |
555 | return FR_BadSignatureFormat; | |
556 | } | |
557 | try { | |
558 | *u = bigIntStrToGiant(snaccSig.u); | |
559 | *PmX = bigIntStrToGiant(snaccSig.pmX); | |
560 | } | |
561 | catch(feeException ferr) { | |
562 | return ferr.frtn(); | |
563 | } | |
564 | catch(...) { | |
565 | /* FIXME - bad sig? memory? */ | |
566 | return FR_Memory; | |
567 | } | |
568 | #if PRINT_SIG_GIANTS | |
569 | printf("feeDecodeElGamalSignature:\n"); | |
570 | printf(" u : "); printGiantHex(*u); | |
571 | printf(" PmX : "); printGiantHex(*PmX); | |
572 | printf(" u : "); snaccSig.u.Print(cout); printf("\n"); | |
573 | printf(" PmX : "); snaccSig.pmX.Print(cout); printf("\n"); | |
574 | #endif | |
575 | return FR_Success; | |
576 | } | |
577 | ||
578 | feeReturn feeDERDecodeECDSASignature( | |
579 | const unsigned char *encodedSig, | |
580 | unsigned encodedSigLen, | |
581 | giant *c, // newGiant'd and RETURNED | |
582 | giant *d) // newGiant'd and RETURNED | |
583 | { | |
584 | FEEECDSASignature snaccSig; | |
585 | CssmData cData((void *)encodedSig, encodedSigLen); | |
586 | try { | |
587 | SC_decodeAsnObj(cData, snaccSig); | |
588 | } | |
589 | catch(...) { | |
590 | return FR_BadSignatureFormat; | |
591 | } | |
592 | try { | |
593 | *c = bigIntStrToGiant(snaccSig.c); | |
594 | *d = bigIntStrToGiant(snaccSig.d); | |
595 | } | |
596 | catch(feeException ferr) { | |
597 | return ferr.frtn(); | |
598 | } | |
599 | catch(...) { | |
600 | /* FIXME - bad sig? memory? */ | |
601 | return FR_Memory; | |
602 | } | |
603 | #if PRINT_SIG_GIANTS | |
604 | printf("feeDecodeECDSASignature:\n"); | |
605 | printf(" c : "); printGiantHex(*c); | |
606 | printf(" d : "); printGiantHex(*d); | |
607 | printf(" c : "); snaccSig.c.Print(cout); printf("\n"); | |
608 | printf(" d : "); snaccSig.d.Print(cout); printf("\n"); | |
609 | #endif | |
610 | return FR_Success; | |
611 | } | |
612 | ||
613 | /* | |
614 | * Encode/decode the FEE private and public keys. We malloc returned data via | |
615 | * falloc(); caller must free via ffree(). Public C functions which never throw. | |
616 | */ | |
617 | feeReturn feeDEREncodePublicKey( | |
618 | int version, | |
619 | const curveParams *cp, | |
620 | giant plusX, | |
621 | giant minusX, | |
622 | giant plusY, // may be NULL | |
623 | unsigned char **keyBlob, // fmallocd and RETURNED | |
624 | unsigned *keyBlobLen) // RETURNED | |
625 | { | |
626 | FEEPublicKey snaccKey; | |
627 | ||
628 | /* set up the SNACC object */ | |
629 | snaccKey.version.Set(version); | |
630 | try { | |
631 | snaccKey.curveParams = feeCurveParamsToSnacc(cp); | |
632 | giantToBigIntStr(plusX, snaccKey.plusX); | |
633 | giantToBigIntStr(minusX, snaccKey.minusX); | |
634 | if(plusY != NULL) { | |
635 | snaccKey.plusY = new BigIntegerStr(); | |
636 | giantToBigIntStr(plusY, *snaccKey.plusY); | |
637 | } | |
638 | } | |
639 | catch(feeException ferr) { | |
640 | return ferr.frtn(); | |
641 | } | |
642 | ||
643 | /* encode the SNACC object */ | |
644 | CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive)); | |
645 | ||
646 | try { | |
647 | SC_encodeAsnObj(snaccKey, oData, feeSizeOfSnaccPubKey(cp)); | |
648 | } | |
649 | catch(...) { | |
650 | /* FIXME - ???? */ | |
651 | return FR_Memory; | |
652 | } | |
653 | *keyBlob = (unsigned char *)fmalloc(oData.length()); | |
654 | *keyBlobLen = oData.length(); | |
655 | memmove(*keyBlob, oData.get().Data, oData.length()); | |
656 | return FR_Success; | |
657 | } | |
658 | ||
659 | feeReturn feeDEREncodePrivateKey( | |
660 | int version, | |
661 | const curveParams *cp, | |
662 | const giant privData, | |
663 | unsigned char **keyBlob, // fmallocd and RETURNED | |
664 | unsigned *keyBlobLen) // RETURNED | |
665 | { | |
666 | FEEPrivateKey snaccKey; | |
667 | ||
668 | /* set up the SNACC object */ | |
669 | snaccKey.version.Set(version); | |
670 | try { | |
671 | snaccKey.curveParams = feeCurveParamsToSnacc(cp); | |
672 | giantToBigIntStr(privData, snaccKey.privData); | |
673 | } | |
674 | catch(feeException ferr) { | |
675 | return ferr.frtn(); | |
676 | } | |
677 | ||
678 | /* encode the SNACC object */ | |
679 | CssmAutoData oData(CssmAllocator::standard(CssmAllocator::sensitive)); | |
680 | ||
681 | try { | |
682 | SC_encodeAsnObj(snaccKey, oData, feeSizeOfSnaccPrivKey(cp)); | |
683 | } | |
684 | catch(...) { | |
685 | /* FIXME - ???? */ | |
686 | return FR_Memory; | |
687 | } | |
688 | *keyBlob = (unsigned char *)fmalloc(oData.length()); | |
689 | *keyBlobLen = oData.length(); | |
690 | memmove(*keyBlob, oData.get().Data, oData.length()); | |
691 | return FR_Success; | |
692 | } | |
693 | ||
694 | feeReturn feeDERDecodePublicKey( | |
695 | const unsigned char *keyBlob, | |
696 | unsigned keyBlobLen, | |
697 | int *version, // this and remainder RETURNED | |
698 | curveParams **cp, | |
699 | giant *plusX, | |
700 | giant *minusX, | |
701 | giant *plusY) // may be NULL | |
702 | { | |
703 | FEEPublicKey snaccKey; | |
704 | CssmData cData((unsigned char *)keyBlob, (size_t)keyBlobLen); | |
705 | try { | |
706 | SC_decodeAsnObj(cData, snaccKey); | |
707 | } | |
708 | catch(...) { | |
709 | return FR_BadPubKey; | |
710 | } | |
711 | try { | |
712 | *version = snaccKey.version; | |
713 | *cp = feeCurveParamsFromSnacc(*snaccKey.curveParams); | |
714 | *plusX = bigIntStrToGiant(snaccKey.plusX); | |
715 | *minusX = bigIntStrToGiant(snaccKey.minusX); | |
716 | if(snaccKey.plusY != NULL) { | |
717 | /* optional */ | |
718 | *plusY = bigIntStrToGiant(*snaccKey.plusY); | |
719 | } | |
720 | else { | |
721 | *plusY = newGiant(1); | |
722 | int_to_giant(0, *plusY); | |
723 | } | |
724 | } | |
725 | catch(feeException ferr) { | |
726 | return ferr.frtn(); | |
727 | } | |
728 | catch(...) { | |
729 | /* FIXME - bad sig? memory? */ | |
730 | return FR_Memory; | |
731 | } | |
732 | return FR_Success; | |
733 | } | |
734 | ||
735 | feeReturn feeDERDecodePrivateKey( | |
736 | const unsigned char *keyBlob, | |
737 | unsigned keyBlobLen, | |
738 | int *version, // this and remainder RETURNED | |
739 | curveParams **cp, | |
740 | giant *privData) // RETURNED | |
741 | { | |
742 | FEEPrivateKey snaccKey; | |
743 | CssmData cData((unsigned char *)keyBlob, (size_t)keyBlobLen); | |
744 | try { | |
745 | SC_decodeAsnObj(cData, snaccKey); | |
746 | } | |
747 | catch(...) { | |
748 | return FR_BadPubKey; | |
749 | } | |
750 | try { | |
751 | *version = snaccKey.version; | |
752 | *cp = feeCurveParamsFromSnacc(*snaccKey.curveParams); | |
753 | *privData = bigIntStrToGiant(snaccKey.privData); | |
754 | } | |
755 | catch(feeException ferr) { | |
756 | return ferr.frtn(); | |
757 | } | |
758 | catch(...) { | |
759 | /* FIXME - bad sig? memory? */ | |
760 | return FR_Memory; | |
761 | } | |
762 | return FR_Success; | |
763 | } | |
764 | ||
765 | #endif /* CRYPTKIT_CSP_ENABLE */ |