nssb64e.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 763 行 · 第 1/2 页
C
763 行
}/* * Function to start a base64 encoding context. * An "output_fn" is required; the "output_arg" parameter to that is optional. * If linebreaks in the encoded output are desired, "line_length" specifies * where to place them -- it will be rounded down to the nearest multiple of 4 * (if it is not already an even multiple of 4). If it is zero, no linebreaks * will be added. (FYI, a linebreak is CRLF -- two characters.) */static PLBase64Encoder *PL_CreateBase64Encoder (PRInt32 (*output_fn) (void *, const char *, PRInt32), void *output_arg, PRUint32 line_length){ PLBase64Encoder *data; if (output_fn == NULL) { PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0); return NULL; } data = pl_base64_create_encoder (line_length, NULL, 0); if (data == NULL) return NULL; data->output_fn = output_fn; data->output_arg = output_arg; return data;}/* * Push data through the encoder, causing the output_fn (provided to Create) * to be called with the encoded data. */static PRStatusPL_UpdateBase64Encoder (PLBase64Encoder *data, const unsigned char *buffer, PRUint32 size){ /* XXX Should we do argument checking only in debug build? */ if (data == NULL || buffer == NULL || size == 0) { PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; } return pl_base64_encode_buffer (data, buffer, size);}/* * When you're done encoding, call this to free the data. If "abort_p" * is false, then calling this may cause the output_fn to be called * one last time (as the last buffered data is flushed out). */static PRStatusPL_DestroyBase64Encoder (PLBase64Encoder *data, PRBool abort_p){ PRStatus status = PR_SUCCESS; /* XXX Should we do argument checking only in debug build? */ if (data == NULL) { PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; } /* Flush out the last few buffered characters. */ if (!abort_p) status = pl_base64_encode_flush (data); if (data->output_buffer != NULL) PR_Free(data->output_buffer); PR_Free(data); return status;}/* * Perform base64 encoding from an input buffer to an output buffer. * The output buffer can be provided (as "dest"); you can also pass in * a NULL and this function will allocate a buffer large enough for you, * and return it. If you do provide the output buffer, you must also * provide the maximum length of that buffer (as "maxdestlen"). * The actual encoded length of output will be returned to you in * "output_destlen". * * If linebreaks in the encoded output are desired, "line_length" specifies * where to place them -- it will be rounded down to the nearest multiple of 4 * (if it is not already an even multiple of 4). If it is zero, no linebreaks * will be added. (FYI, a linebreak is CRLF -- two characters.) * * Return value is NULL on error, the output buffer (allocated or provided) * otherwise. */static char *PL_Base64EncodeBuffer (const unsigned char *src, PRUint32 srclen, PRUint32 line_length, char *dest, PRUint32 maxdestlen, PRUint32 *output_destlen){ PRUint32 need_length; PLBase64Encoder *data = NULL; PRStatus status; PR_ASSERT(srclen > 0); if (srclen == 0) return dest; /* * How much space could we possibly need for encoding this input? */ need_length = PL_Base64MaxEncodedLength (srclen, line_length); /* * Make sure we have at least that much, if output buffer provided. */ if (dest != NULL) { PR_ASSERT(maxdestlen >= need_length); if (maxdestlen < need_length) { PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); return NULL; } } else { maxdestlen = need_length; } data = pl_base64_create_encoder(line_length, dest, maxdestlen); if (data == NULL) return NULL; status = pl_base64_encode_buffer (data, src, srclen); /* * We do not wait for Destroy to flush, because Destroy will also * get rid of our encoder context, which we need to look at first! */ if (status == PR_SUCCESS) status = pl_base64_encode_flush (data); if (status != PR_SUCCESS) { (void) PL_DestroyBase64Encoder (data, PR_TRUE); return NULL; } dest = data->output_buffer; /* Must clear this or Destroy will free it. */ data->output_buffer = NULL; *output_destlen = data->output_length; status = PL_DestroyBase64Encoder (data, PR_FALSE); if (status == PR_FAILURE) { PR_Free(dest); return NULL; } return dest;}/* * XXX End of base64 encoding code to be moved into NSPR. ******************************************************** *//* * This is the beginning of the NSS cover functions. These will * provide the interface we want to expose as NSS-ish. For example, * they will operate on our Items, do any special handling or checking * we want to do, etc. */PR_BEGIN_EXTERN_C/* * A boring cover structure for now. Perhaps someday it will include * some more interesting fields. */struct NSSBase64EncoderStr { PLBase64Encoder *pl_data;};PR_END_EXTERN_C/* * Function to start a base64 encoding context. */NSSBase64Encoder *NSSBase64Encoder_Create (PRInt32 (*output_fn) (void *, const char *, PRInt32), void *output_arg){ PLBase64Encoder *pl_data; NSSBase64Encoder *nss_data; nss_data = PORT_ZNew(NSSBase64Encoder); if (nss_data == NULL) return NULL; pl_data = PL_CreateBase64Encoder (output_fn, output_arg, 64); if (pl_data == NULL) { PORT_Free(nss_data); return NULL; } nss_data->pl_data = pl_data; return nss_data;}/* * Push data through the encoder, causing the output_fn (provided to Create) * to be called with the encoded data. */SECStatusNSSBase64Encoder_Update (NSSBase64Encoder *data, const unsigned char *buffer, PRUint32 size){ PRStatus pr_status; /* XXX Should we do argument checking only in debug build? */ if (data == NULL) { PORT_SetError (SEC_ERROR_INVALID_ARGS); return SECFailure; } pr_status = PL_UpdateBase64Encoder (data->pl_data, buffer, size); if (pr_status == PR_FAILURE) return SECFailure; return SECSuccess;}/* * When you're done encoding, call this to free the data. If "abort_p" * is false, then calling this may cause the output_fn to be called * one last time (as the last buffered data is flushed out). */SECStatusNSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p){ PRStatus pr_status; /* XXX Should we do argument checking only in debug build? */ if (data == NULL) { PORT_SetError (SEC_ERROR_INVALID_ARGS); return SECFailure; } pr_status = PL_DestroyBase64Encoder (data->pl_data, abort_p); PORT_Free(data); if (pr_status == PR_FAILURE) return SECFailure; return SECSuccess;}/* * Perform base64 encoding of binary data "inItem" to an ascii string. * The output buffer may be provided (as "outStrOpt"); you can also pass * in a NULL and the buffer will be allocated for you. The result will * be null-terminated, and if the buffer is provided, "maxOutLen" must * specify the maximum length of the buffer and will be checked to * supply sufficient space space for the encoded result. (If "outStrOpt" * is NULL, "maxOutLen" is ignored.) * * If "outStrOpt" is NULL, allocation will happen out of the passed-in * "arenaOpt", if *it* is non-NULL, otherwise standard allocation (heap) * will be used. * * Return value is NULL on error, the output buffer (allocated or provided) * otherwise. */char *NSSBase64_EncodeItem (PRArenaPool *arenaOpt, char *outStrOpt, unsigned int maxOutLen, SECItem *inItem){ char *out_string = outStrOpt; PRUint32 max_out_len; PRUint32 out_len; void *mark = NULL; char *dummy; PORT_Assert(inItem != NULL && inItem->data != NULL && inItem->len != 0); if (inItem == NULL || inItem->data == NULL || inItem->len == 0) { PORT_SetError (SEC_ERROR_INVALID_ARGS); return NULL; } max_out_len = PL_Base64MaxEncodedLength (inItem->len, 64); if (arenaOpt != NULL) mark = PORT_ArenaMark (arenaOpt); if (out_string == NULL) { if (arenaOpt != NULL) out_string = PORT_ArenaAlloc (arenaOpt, max_out_len + 1); else out_string = PORT_Alloc (max_out_len + 1); if (out_string == NULL) { if (arenaOpt != NULL) PORT_ArenaRelease (arenaOpt, mark); return NULL; } } else { if ((max_out_len + 1) > maxOutLen) { PORT_SetError (SEC_ERROR_OUTPUT_LEN); return NULL; } max_out_len = maxOutLen; } dummy = PL_Base64EncodeBuffer (inItem->data, inItem->len, 64, out_string, max_out_len, &out_len); if (dummy == NULL) { if (arenaOpt != NULL) { PORT_ArenaRelease (arenaOpt, mark); } else { PORT_Free (out_string); } return NULL; } if (arenaOpt != NULL) PORT_ArenaUnmark (arenaOpt, mark); out_string[out_len] = '\0'; return out_string;}/* * XXX Everything below is deprecated. If you add new stuff, put it * *above*, not below. *//* * XXX The following "BTOA" functions are provided for backward compatibility * with current code. They should be considered strongly deprecated. * When we can convert all our code over to using the new NSSBase64Encoder_ * functions defined above, we should get rid of these altogether. (Remove * protoypes from base64.h as well -- actually, remove that file completely). * If someone thinks either of these functions provides such a very useful * interface (though, as shown, the same functionality can already be * obtained by calling NSSBase64_EncodeItem directly), fine -- but then * that API should be provided with a nice new NSSFoo name and using * appropriate types, etc. */#include "base64.h"/*** Return an PORT_Alloc'd ascii string which is the base64 encoded** version of the input string.*/char *BTOA_DataToAscii(const unsigned char *data, unsigned int len){ SECItem binary_item; binary_item.data = (unsigned char *)data; binary_item.len = len; return NSSBase64_EncodeItem (NULL, NULL, 0, &binary_item);}/*** Convert from binary encoding of an item to ascii.*/char *BTOA_ConvertItemToAscii (SECItem *binary_item){ return NSSBase64_EncodeItem (NULL, NULL, 0, binary_item);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?