Imported Upstream version 3.13.6
[platform/upstream/nss.git] / mozilla / security / nss / lib / util / nssb64d.c
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
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/
8  *
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.
13  *
14  * The Original Code is the Netscape security libraries.
15  *
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.
20  *
21  * Contributor(s):
22  *
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.
34  *
35  * ***** END LICENSE BLOCK ***** */
36
37 /*
38  * Base64 decoding (ascii to binary).
39  *
40  * $Id: nssb64d.c,v 1.8 2011/05/07 18:20:45 kaie%kuix.de Exp $
41  */
42
43 #include "nssb64.h"
44 #include "nspr.h"
45 #include "secitem.h"
46 #include "secerr.h"
47
48 /*
49  * XXX We want this basic support to go into NSPR (the PL part).
50  * Until that can happen, the PL interface is going to be kept entirely
51  * internal here -- all static functions and opaque data structures.
52  * When someone can get it moved over into NSPR, that should be done:
53  *    - giving everything names that are accepted by the NSPR module owners
54  *      (though I tried to choose ones that would work without modification)
55  *    - exporting the functions (remove static declarations and add
56  *      to nssutil.def as necessary)
57  *    - put prototypes into appropriate header file (probably replacing
58  *      the entire current lib/libc/include/plbase64.h in NSPR)
59  *      along with a typedef for the context structure (which should be
60  *      kept opaque -- definition in the source file only, but typedef
61  *      ala "typedef struct PLBase64FooStr PLBase64Foo;" in header file)
62  *    - modify anything else as necessary to conform to NSPR required style
63  *      (I looked but found no formatting guide to follow)
64  *
65  * You will want to move over everything from here down to the comment
66  * which says "XXX End of base64 decoding code to be moved into NSPR",
67  * into a new file in NSPR.
68  */
69
70 /*
71  **************************************************************
72  * XXX Beginning of base64 decoding code to be moved into NSPR.
73  */
74
75 /*
76  * This typedef would belong in the NSPR header file (i.e. plbase64.h).
77  */
78 typedef struct PLBase64DecoderStr PLBase64Decoder;
79
80 /*
81  * The following implementation of base64 decoding was based on code
82  * found in libmime (specifically, in mimeenc.c).  It has been adapted to
83  * use PR types and naming as well as to provide other necessary semantics
84  * (like buffer-in/buffer-out in addition to "streaming" without undue
85  * performance hit of extra copying if you made the buffer versions
86  * use the output_fn).  It also incorporates some aspects of the current
87  * NSPR base64 decoding code.  As such, you may find similarities to
88  * both of those implementations.  I tried to use names that reflected
89  * the original code when possible.  For this reason you may find some
90  * inconsistencies -- libmime used lots of "in" and "out" whereas the
91  * NSPR version uses "src" and "dest"; sometimes I changed one to the other
92  * and sometimes I left them when I thought the subroutines were at least
93  * self-consistent.
94  */
95
96 PR_BEGIN_EXTERN_C
97
98 /*
99  * Opaque object used by the decoder to store state.
100  */
101 struct PLBase64DecoderStr {
102     /* Current token (or portion, if token_size < 4) being decoded. */
103     unsigned char token[4];
104     int token_size;
105
106     /*
107      * Where to write the decoded data (used when streaming, not when
108      * doing all in-memory (buffer) operations).
109      *
110      * Note that this definition is chosen to be compatible with PR_Write.
111      */
112     PRInt32 (*output_fn) (void *output_arg, const unsigned char *buf,
113                           PRInt32 size);
114     void *output_arg;
115
116     /*
117      * Where the decoded output goes -- either temporarily (in the streaming
118      * case, staged here before it goes to the output function) or what will
119      * be the entire buffered result for users of the buffer version.
120      */
121     unsigned char *output_buffer;
122     PRUint32 output_buflen;     /* the total length of allocated buffer */
123     PRUint32 output_length;     /* the length that is currently populated */
124 };
125
126 PR_END_EXTERN_C
127
128
129 /*
130  * Table to convert an ascii "code" to its corresponding binary value.
131  * For ease of use, the binary values in the table are the actual values
132  * PLUS ONE.  This is so that the special value of zero can denote an
133  * invalid mapping; that was much easier than trying to fill in the other
134  * values with some value other than zero, and to check for it.
135  * Just remember to SUBTRACT ONE when using the value retrieved.
136  */
137 static unsigned char base64_codetovaluep1[256] = {
138 /*   0: */        0,      0,      0,      0,      0,      0,      0,      0,
139 /*   8: */        0,      0,      0,      0,      0,      0,      0,      0,
140 /*  16: */        0,      0,      0,      0,      0,      0,      0,      0,
141 /*  24: */        0,      0,      0,      0,      0,      0,      0,      0,
142 /*  32: */        0,      0,      0,      0,      0,      0,      0,      0,
143 /*  40: */        0,      0,      0,     63,      0,      0,      0,     64,
144 /*  48: */       53,     54,     55,     56,     57,     58,     59,     60,
145 /*  56: */       61,     62,      0,      0,      0,      0,      0,      0,
146 /*  64: */        0,      1,      2,      3,      4,      5,      6,      7,
147 /*  72: */        8,      9,     10,     11,     12,     13,     14,     15,
148 /*  80: */       16,     17,     18,     19,     20,     21,     22,     23,
149 /*  88: */       24,     25,     26,      0,      0,      0,      0,      0,
150 /*  96: */        0,     27,     28,     29,     30,     31,     32,     33,
151 /* 104: */       34,     35,     36,     37,     38,     39,     40,     41,
152 /* 112: */       42,     43,     44,     45,     46,     47,     48,     49,
153 /* 120: */       50,     51,     52,      0,      0,      0,      0,      0,
154 /* 128: */        0,      0,      0,      0,      0,      0,      0,      0
155 /* and rest are all zero as well */
156 };
157
158 #define B64_PAD '='
159
160
161 /*
162  * Reads 4; writes 3 (known, or expected, to have no trailing padding).
163  * Returns bytes written; -1 on error (unexpected character).
164  */
165 static int
166 pl_base64_decode_4to3 (const unsigned char *in, unsigned char *out)
167 {
168     int j;
169     PRUint32 num = 0;
170     unsigned char bits;
171
172     for (j = 0; j < 4; j++) {
173         bits = base64_codetovaluep1[in[j]];
174         if (bits == 0)
175             return -1;
176         num = (num << 6) | (bits - 1);
177     }
178
179     out[0] = (unsigned char) (num >> 16);
180     out[1] = (unsigned char) ((num >> 8) & 0xFF);
181     out[2] = (unsigned char) (num & 0xFF);
182
183     return 3;
184 }
185
186 /*
187  * Reads 3; writes 2 (caller already confirmed EOF or trailing padding).
188  * Returns bytes written; -1 on error (unexpected character).
189  */
190 static int
191 pl_base64_decode_3to2 (const unsigned char *in, unsigned char *out)
192 {
193     PRUint32 num = 0;
194     unsigned char bits1, bits2, bits3;
195
196     bits1 = base64_codetovaluep1[in[0]];
197     bits2 = base64_codetovaluep1[in[1]];
198     bits3 = base64_codetovaluep1[in[2]];
199
200     if ((bits1 == 0) || (bits2 == 0) || (bits3 == 0))
201         return -1;
202
203     num = ((PRUint32)(bits1 - 1)) << 10;
204     num |= ((PRUint32)(bits2 - 1)) << 4;
205     num |= ((PRUint32)(bits3 - 1)) >> 2;
206
207     out[0] = (unsigned char) (num >> 8);
208     out[1] = (unsigned char) (num & 0xFF);
209
210     return 2;
211 }
212
213 /*
214  * Reads 2; writes 1 (caller already confirmed EOF or trailing padding).
215  * Returns bytes written; -1 on error (unexpected character).
216  */
217 static int
218 pl_base64_decode_2to1 (const unsigned char *in, unsigned char *out)
219 {
220     PRUint32 num = 0;
221     unsigned char bits1, bits2;
222
223     bits1 = base64_codetovaluep1[in[0]];
224     bits2 = base64_codetovaluep1[in[1]];
225
226     if ((bits1 == 0) || (bits2 == 0))
227         return -1;
228
229     num = ((PRUint32)(bits1 - 1)) << 2;
230     num |= ((PRUint32)(bits2 - 1)) >> 4;
231
232     out[0] = (unsigned char) num;
233
234     return 1;
235 }
236
237 /*
238  * Reads 4; writes 0-3.  Returns bytes written or -1 on error.
239  * (Writes less than 3 only at (presumed) EOF.)
240  */
241 static int
242 pl_base64_decode_token (const unsigned char *in, unsigned char *out)
243 {
244     if (in[3] != B64_PAD)
245         return pl_base64_decode_4to3 (in, out);
246
247     if (in[2] == B64_PAD)
248         return pl_base64_decode_2to1 (in, out);
249
250     return pl_base64_decode_3to2 (in, out);
251 }
252
253 static PRStatus
254 pl_base64_decode_buffer (PLBase64Decoder *data, const unsigned char *in,
255                          PRUint32 length)
256 {
257     unsigned char *out = data->output_buffer;
258     unsigned char *token = data->token;
259     int i, n = 0;
260
261     i = data->token_size;
262     data->token_size = 0;
263
264     while (length > 0) {
265         while (i < 4 && length > 0) {
266             /*
267              * XXX Note that the following simply ignores any unexpected
268              * characters.  This is exactly what the original code in
269              * libmime did, and I am leaving it.  We certainly want to skip
270              * over whitespace (we must); this does much more than that.
271              * I am not confident changing it, and I don't want to slow
272              * the processing down doing more complicated checking, but
273              * someone else might have different ideas in the future.
274              */
275             if (base64_codetovaluep1[*in] > 0 || *in == B64_PAD)
276                 token[i++] = *in;
277             in++;
278             length--;
279         }
280
281         if (i < 4) {
282             /* Didn't get enough for a complete token. */
283             data->token_size = i;
284             break;
285         }
286         i = 0;
287
288         PR_ASSERT((out - data->output_buffer + 3) <= data->output_buflen);
289
290         /*
291          * Assume we are not at the end; the following function only works
292          * for an internal token (no trailing padding characters) but is
293          * faster that way.  If it hits an invalid character (padding) it
294          * will return an error; we break out of the loop and try again
295          * calling the routine that will handle a final token.
296          * Note that we intentionally do it this way rather than explicitly
297          * add a check for padding here (because that would just slow down
298          * the normal case) nor do we rely on checking whether we have more
299          * input to process (because that would also slow it down but also
300          * because we want to allow trailing garbage, especially white space
301          * and cannot tell that without read-ahead, also a slow proposition).
302          * Whew.  Understand?
303          */
304         n = pl_base64_decode_4to3 (token, out);
305         if (n < 0)
306             break;
307
308         /* Advance "out" by the number of bytes just written to it. */
309         out += n;
310         n = 0;
311     }
312
313     /*
314      * See big comment above, before call to pl_base64_decode_4to3.
315      * Here we check if we error'd out of loop, and allow for the case
316      * that we are processing the last interesting token.  If the routine
317      * which should handle padding characters also fails, then we just
318      * have bad input and give up.
319      */
320     if (n < 0) {
321         n = pl_base64_decode_token (token, out);
322         if (n < 0)
323             return PR_FAILURE;
324
325         out += n;
326     }
327
328     /*
329      * As explained above, we can get here with more input remaining, but
330      * it should be all characters we do not care about (i.e. would be
331      * ignored when transferring from "in" to "token" in loop above,
332      * except here we choose to ignore extraneous pad characters, too).
333      * Swallow it, performing that check.  If we find more characters that
334      * we would expect to decode, something is wrong.
335      */
336     while (length > 0) {
337         if (base64_codetovaluep1[*in] > 0)
338             return PR_FAILURE;
339         in++;
340         length--;
341     }
342
343     /* Record the length of decoded data we have left in output_buffer. */
344     data->output_length = (PRUint32) (out - data->output_buffer);
345     return PR_SUCCESS;
346 }
347
348 /*
349  * Flush any remaining buffered characters.  Given well-formed input,
350  * this will have nothing to do.  If the input was missing the padding
351  * characters at the end, though, there could be 1-3 characters left
352  * behind -- we will tolerate that by adding the padding for them.
353  */
354 static PRStatus
355 pl_base64_decode_flush (PLBase64Decoder *data)
356 {
357     int count;
358
359     /*
360      * If no remaining characters, or all are padding (also not well-formed
361      * input, but again, be tolerant), then nothing more to do.  (And, that
362      * is considered successful.)
363      */
364     if (data->token_size == 0 || data->token[0] == B64_PAD)
365         return PR_SUCCESS;
366
367     /*
368      * Assume we have all the interesting input except for some expected
369      * padding characters.  Add them and decode the resulting token.
370      */
371     while (data->token_size < 4)
372         data->token[data->token_size++] = B64_PAD;
373
374     data->token_size = 0;       /* so a subsequent flush call is a no-op */
375
376     count = pl_base64_decode_token (data->token,
377                                     data->output_buffer + data->output_length);
378     if (count < 0)
379         return PR_FAILURE;
380
381     /*
382      * If there is an output function, call it with this last bit of data.
383      * Otherwise we are doing all buffered output, and the decoded bytes
384      * are now there, we just need to reflect that in the length.
385      */
386     if (data->output_fn != NULL) {
387         PRInt32 output_result;
388
389         PR_ASSERT(data->output_length == 0);
390         output_result = data->output_fn (data->output_arg,
391                                          data->output_buffer,
392                                          (PRInt32) count);
393         if (output_result < 0)
394             return  PR_FAILURE;
395     } else {
396         data->output_length += count;
397     }
398
399     return PR_SUCCESS;
400 }
401
402
403 /*
404  * The maximum space needed to hold the output of the decoder given
405  * input data of length "size".
406  */
407 static PRUint32
408 PL_Base64MaxDecodedLength (PRUint32 size)
409 {
410     return ((size * 3) / 4);
411 }
412
413
414 /*
415  * A distinct internal creation function for the buffer version to use.
416  * (It does not want to specify an output_fn, and we want the normal
417  * Create function to require that.)  If more common initialization
418  * of the decoding context needs to be done, it should be done *here*.
419  */
420 static PLBase64Decoder *
421 pl_base64_create_decoder (void)
422 {
423     return PR_NEWZAP(PLBase64Decoder);
424 }
425
426 /*
427  * Function to start a base64 decoding context.
428  * An "output_fn" is required; the "output_arg" parameter to that is optional.
429  */
430 static PLBase64Decoder *
431 PL_CreateBase64Decoder (PRInt32 (*output_fn) (void *, const unsigned char *,
432                                               PRInt32),
433                         void *output_arg)
434 {
435     PLBase64Decoder *data;
436
437     if (output_fn == NULL) {
438         PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
439         return NULL;
440     }
441
442     data = pl_base64_create_decoder ();
443     if (data != NULL) {
444         data->output_fn = output_fn;
445         data->output_arg = output_arg;
446     }
447     return data;
448 }
449
450
451 /*
452  * Push data through the decoder, causing the output_fn (provided to Create)
453  * to be called with the decoded data.
454  */
455 static PRStatus
456 PL_UpdateBase64Decoder (PLBase64Decoder *data, const char *buffer,
457                         PRUint32 size)
458 {
459     PRUint32 need_length;
460     PRStatus status;
461
462     /* XXX Should we do argument checking only in debug build? */
463     if (data == NULL || buffer == NULL || size == 0) {
464         PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
465         return PR_FAILURE;
466     }
467
468     /*
469      * How much space could this update need for decoding?
470      */
471     need_length = PL_Base64MaxDecodedLength (size + data->token_size);
472
473     /*
474      * Make sure we have at least that much.  If not, (re-)allocate.
475      */
476     if (need_length > data->output_buflen) {
477         unsigned char *output_buffer = data->output_buffer;
478
479         if (output_buffer != NULL)
480             output_buffer = (unsigned char *) PR_Realloc(output_buffer,
481                                                          need_length);
482         else
483             output_buffer = (unsigned char *) PR_Malloc(need_length);
484
485         if (output_buffer == NULL)
486             return PR_FAILURE;
487
488         data->output_buffer = output_buffer;
489         data->output_buflen = need_length;
490     }
491
492     /* There should not have been any leftover output data in the buffer. */
493     PR_ASSERT(data->output_length == 0);
494     data->output_length = 0;
495
496     status = pl_base64_decode_buffer (data, (const unsigned char *) buffer,
497                                       size);
498
499     /* Now that we have some decoded data, write it. */
500     if (status == PR_SUCCESS && data->output_length > 0) {
501         PRInt32 output_result;
502
503         PR_ASSERT(data->output_fn != NULL);
504         output_result = data->output_fn (data->output_arg,
505                                          data->output_buffer,
506                                          (PRInt32) data->output_length);
507         if (output_result < 0)
508             status = PR_FAILURE;
509     }
510
511     data->output_length = 0;
512     return status;
513 }
514
515
516 /*
517  * When you're done decoding, call this to free the data.  If "abort_p"
518  * is false, then calling this may cause the output_fn to be called
519  * one last time (as the last buffered data is flushed out).
520  */
521 static PRStatus
522 PL_DestroyBase64Decoder (PLBase64Decoder *data, PRBool abort_p)
523 {
524     PRStatus status = PR_SUCCESS;
525
526     /* XXX Should we do argument checking only in debug build? */
527     if (data == NULL) {
528         PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
529         return PR_FAILURE;
530     }
531
532     /* Flush out the last few buffered characters. */
533     if (!abort_p)
534         status = pl_base64_decode_flush (data);
535
536     if (data->output_buffer != NULL)
537         PR_Free(data->output_buffer);
538     PR_Free(data);
539
540     return status;
541 }
542
543
544 /*
545  * Perform base64 decoding from an input buffer to an output buffer.
546  * The output buffer can be provided (as "dest"); you can also pass in
547  * a NULL and this function will allocate a buffer large enough for you,
548  * and return it.  If you do provide the output buffer, you must also
549  * provide the maximum length of that buffer (as "maxdestlen").
550  * The actual decoded length of output will be returned to you in
551  * "output_destlen".
552  *
553  * Return value is NULL on error, the output buffer (allocated or provided)
554  * otherwise.
555  */
556 static unsigned char *
557 PL_Base64DecodeBuffer (const char *src, PRUint32 srclen, unsigned char *dest,
558                        PRUint32 maxdestlen, PRUint32 *output_destlen)
559 {
560     PRUint32 need_length;
561     unsigned char *output_buffer = NULL;
562     PLBase64Decoder *data = NULL;
563     PRStatus status;
564
565     PR_ASSERT(srclen > 0);
566     if (srclen == 0) {
567         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
568         return NULL;
569     }
570
571     /*
572      * How much space could we possibly need for decoding this input?
573      */
574     need_length = PL_Base64MaxDecodedLength (srclen);
575
576     /*
577      * Make sure we have at least that much, if output buffer provided.
578      * If no output buffer provided, then we allocate that much.
579      */
580     if (dest != NULL) {
581         PR_ASSERT(maxdestlen >= need_length);
582         if (maxdestlen < need_length) {
583             PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
584             goto loser;
585         }
586         output_buffer = dest;
587     } else {
588         output_buffer = (unsigned char *) PR_Malloc(need_length);
589         if (output_buffer == NULL)
590             goto loser;
591         maxdestlen = need_length;
592     }
593
594     data = pl_base64_create_decoder();
595     if (data == NULL)
596         goto loser;
597
598     data->output_buflen = maxdestlen;
599     data->output_buffer = output_buffer;
600
601     status = pl_base64_decode_buffer (data, (const unsigned char *) src,
602                                       srclen);
603
604     /*
605      * We do not wait for Destroy to flush, because Destroy will also
606      * get rid of our decoder context, which we need to look at first!
607      */
608     if (status == PR_SUCCESS)
609         status = pl_base64_decode_flush (data);
610
611     /* Must clear this or Destroy will free it. */
612     data->output_buffer = NULL;
613
614     if (status == PR_SUCCESS) {
615         *output_destlen = data->output_length;
616         status = PL_DestroyBase64Decoder (data, PR_FALSE);
617         data = NULL;
618         if (status == PR_FAILURE)
619             goto loser;
620         return output_buffer;
621     }
622
623 loser:
624     if (dest == NULL && output_buffer != NULL)
625         PR_Free(output_buffer);
626     if (data != NULL)
627         (void) PL_DestroyBase64Decoder (data, PR_TRUE);
628     return NULL;
629 }
630
631
632 /*
633  * XXX End of base64 decoding code to be moved into NSPR.
634  ********************************************************
635  */
636
637 /*
638  * This is the beginning of the NSS cover functions.  These will
639  * provide the interface we want to expose as NSS-ish.  For example,
640  * they will operate on our Items, do any special handling or checking
641  * we want to do, etc.
642  */
643
644
645 PR_BEGIN_EXTERN_C
646
647 /*
648  * A boring cover structure for now.  Perhaps someday it will include
649  * some more interesting fields.
650  */
651 struct NSSBase64DecoderStr {
652     PLBase64Decoder *pl_data;
653 };
654
655 PR_END_EXTERN_C
656
657
658 /*
659  * Function to start a base64 decoding context.
660  */
661 NSSBase64Decoder *
662 NSSBase64Decoder_Create (PRInt32 (*output_fn) (void *, const unsigned char *,
663                                                PRInt32),
664                          void *output_arg)
665 {
666     PLBase64Decoder *pl_data;
667     NSSBase64Decoder *nss_data;
668
669     nss_data = PORT_ZNew(NSSBase64Decoder);
670     if (nss_data == NULL)
671         return NULL;
672
673     pl_data = PL_CreateBase64Decoder (output_fn, output_arg);
674     if (pl_data == NULL) {
675         PORT_Free(nss_data);
676         return NULL;
677     }
678
679     nss_data->pl_data = pl_data;
680     return nss_data;
681 }
682
683
684 /*
685  * Push data through the decoder, causing the output_fn (provided to Create)
686  * to be called with the decoded data.
687  */
688 SECStatus
689 NSSBase64Decoder_Update (NSSBase64Decoder *data, const char *buffer,
690                          PRUint32 size)
691 {
692     PRStatus pr_status;
693
694     /* XXX Should we do argument checking only in debug build? */
695     if (data == NULL) {
696         PORT_SetError (SEC_ERROR_INVALID_ARGS);
697         return SECFailure;
698     }
699
700     pr_status = PL_UpdateBase64Decoder (data->pl_data, buffer, size);
701     if (pr_status == PR_FAILURE)
702         return SECFailure;
703
704     return SECSuccess;
705 }
706
707
708 /*
709  * When you're done decoding, call this to free the data.  If "abort_p"
710  * is false, then calling this may cause the output_fn to be called
711  * one last time (as the last buffered data is flushed out).
712  */
713 SECStatus
714 NSSBase64Decoder_Destroy (NSSBase64Decoder *data, PRBool abort_p)
715 {
716     PRStatus pr_status;
717
718     /* XXX Should we do argument checking only in debug build? */
719     if (data == NULL) {
720         PORT_SetError (SEC_ERROR_INVALID_ARGS);
721         return SECFailure;
722     }
723
724     pr_status = PL_DestroyBase64Decoder (data->pl_data, abort_p);
725
726     PORT_Free(data);
727
728     if (pr_status == PR_FAILURE)
729         return SECFailure;
730
731     return SECSuccess;
732 }
733
734
735 /*
736  * Perform base64 decoding from an ascii string "inStr" to an Item.
737  * The length of the input must be provided as "inLen".  The Item
738  * may be provided (as "outItemOpt"); you can also pass in a NULL
739  * and the Item will be allocated for you.
740  *
741  * In any case, the data within the Item will be allocated for you.
742  * All allocation will happen out of the passed-in "arenaOpt", if non-NULL.
743  * If "arenaOpt" is NULL, standard allocation (heap) will be used and
744  * you will want to free the result via SECITEM_FreeItem.
745  *
746  * Return value is NULL on error, the Item (allocated or provided) otherwise.
747  */
748 SECItem *
749 NSSBase64_DecodeBuffer (PRArenaPool *arenaOpt, SECItem *outItemOpt,
750                         const char *inStr, unsigned int inLen)
751 {
752     SECItem *out_item = NULL;
753     PRUint32 max_out_len = 0;
754     PRUint32 out_len;
755     void *mark = NULL;
756     unsigned char *dummy;
757
758     if ((outItemOpt != NULL && outItemOpt->data != NULL) || inLen == 0) {
759         PORT_SetError (SEC_ERROR_INVALID_ARGS);
760         return NULL;
761     }
762
763     if (arenaOpt != NULL)
764         mark = PORT_ArenaMark (arenaOpt);
765
766     max_out_len = PL_Base64MaxDecodedLength (inLen);
767     out_item = SECITEM_AllocItem (arenaOpt, outItemOpt, max_out_len);
768     if (out_item == NULL) {
769         if (arenaOpt != NULL)
770             PORT_ArenaRelease (arenaOpt, mark);
771         return NULL;
772     }
773
774     dummy = PL_Base64DecodeBuffer (inStr, inLen, out_item->data,
775                                    max_out_len, &out_len);
776     if (dummy == NULL) {
777         if (arenaOpt != NULL) {
778             PORT_ArenaRelease (arenaOpt, mark);
779             if (outItemOpt != NULL) {
780                 outItemOpt->data = NULL;
781                 outItemOpt->len = 0;
782             }
783         } else {
784             SECITEM_FreeItem (out_item,
785                               (outItemOpt == NULL) ? PR_TRUE : PR_FALSE);
786         }
787         return NULL;
788     }
789
790     if (arenaOpt != NULL)
791         PORT_ArenaUnmark (arenaOpt, mark);
792     out_item->len = out_len;
793     return out_item;
794 }
795
796
797 /*
798  * XXX Everything below is deprecated.  If you add new stuff, put it
799  * *above*, not below.
800  */
801
802 /*
803  * XXX The following "ATOB" functions are provided for backward compatibility
804  * with current code.  They should be considered strongly deprecated.
805  * When we can convert all our code over to using the new NSSBase64Decoder_
806  * functions defined above, we should get rid of these altogether.  (Remove
807  * protoypes from base64.h as well -- actually, remove that file completely).
808  * If someone thinks either of these functions provides such a very useful
809  * interface (though, as shown, the same functionality can already be
810  * obtained by calling NSSBase64_DecodeBuffer directly), fine -- but then
811  * that API should be provided with a nice new NSSFoo name and using
812  * appropriate types, etc.
813  */
814
815 #include "base64.h"
816
817 /*
818 ** Return an PORT_Alloc'd string which is the base64 decoded version
819 ** of the input string; set *lenp to the length of the returned data.
820 */
821 unsigned char *
822 ATOB_AsciiToData(const char *string, unsigned int *lenp)
823 {
824     SECItem binary_item, *dummy;
825
826     binary_item.data = NULL;
827     binary_item.len = 0;
828
829     dummy = NSSBase64_DecodeBuffer (NULL, &binary_item, string,
830                                     (PRUint32) PORT_Strlen(string));
831     if (dummy == NULL)
832         return NULL;
833
834     PORT_Assert(dummy == &binary_item);
835
836     *lenp = dummy->len;
837     return dummy->data;
838 }
839  
840 /*
841 ** Convert from ascii to binary encoding of an item.
842 */
843 SECStatus
844 ATOB_ConvertAsciiToItem(SECItem *binary_item, char *ascii)
845 {
846     SECItem *dummy;
847
848     if (binary_item == NULL) {
849         PORT_SetError (SEC_ERROR_INVALID_ARGS);
850         return SECFailure;
851     }
852
853     /*
854      * XXX Would prefer to assert here if data is non-null (actually,
855      * don't need to, just let NSSBase64_DecodeBuffer do it), so as to
856      * to catch unintended memory leaks, but callers are not clean in
857      * this respect so we need to explicitly clear here to avoid the
858      * assert in NSSBase64_DecodeBuffer.
859      */
860     binary_item->data = NULL;
861     binary_item->len = 0;
862
863     dummy = NSSBase64_DecodeBuffer (NULL, binary_item, ascii,
864                                     (PRUint32) PORT_Strlen(ascii));
865
866     if (dummy == NULL)
867         return SECFailure;
868
869     return SECSuccess;
870 }