asn1.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,727 行 · 第 1/3 页

C
1,727
字号
/*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#ifdef DEBUGstatic const char CVS_ID[] = "@(#) $RCSfile: asn1.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:54:49 $ $Name: NSS_3_1_1_RTM $";#endif /* DEBUG *//* * asn1.c * * At this point in time, this file contains the NSS wrappers for * the old "SEC" ASN.1 encoder/decoder stuff. */#ifndef ASN1M_H#include "asn1m.h"#endif /* ASN1M_H */#include "plarena.h"#include "secasn1.h"/* * The pointer-tracking stuff */#ifdef DEBUGextern const NSSError NSS_ERROR_INTERNAL_ERROR;static nssPointerTracker decoder_pointer_tracker;static PRStatusdecoder_add_pointer(  const nssASN1Decoder *decoder){  PRStatus rv;  rv = nssPointerTracker_initialize(&decoder_pointer_tracker);  if( PR_SUCCESS != rv ) {    return rv;  }  rv = nssPointerTracker_add(&decoder_pointer_tracker, decoder);  if( PR_SUCCESS != rv ) {    NSSError e = NSS_GetError();    if( NSS_ERROR_NO_MEMORY != e ) {      nss_SetError(NSS_ERROR_INTERNAL_ERROR);    }    return rv;  }  return PR_SUCCESS;}static PRStatusdecoder_remove_pointer(  const nssASN1Decoder *decoder){  PRStatus rv;  rv = nssPointerTracker_remove(&decoder_pointer_tracker, decoder);  if( PR_SUCCESS != rv ) {    nss_SetError(NSS_ERROR_INTERNAL_ERROR);  }  return rv;}/* * nssASN1Decoder_verify * * This routine is only available in debug builds. * * If the specified pointer is a valid pointer to an nssASN1Decoder * object, this routine will return PR_SUCCESS.  Otherwise, it will  * put an error on the error stack and return PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_INVALID_ASN1DECODER * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success */NSS_IMPLEMENT PRStatusnssASN1Decoder_verify(  nssASN1Decoder *decoder){  PRStatus rv;  rv = nssPointerTracker_initialize(&decoder_pointer_tracker);  if( PR_SUCCESS != rv ) {    return PR_FAILURE;  }  rv = nssPointerTracker_verify(&decoder_pointer_tracker, decoder);  if( PR_SUCCESS != rv ) {    nss_SetError(NSS_ERROR_INVALID_ASN1DECODER);    return PR_FAILURE;  }  return PR_SUCCESS;}static nssPointerTracker encoder_pointer_tracker;static PRStatusencoder_add_pointer(  const nssASN1Encoder *encoder){  PRStatus rv;  rv = nssPointerTracker_initialize(&encoder_pointer_tracker);  if( PR_SUCCESS != rv ) {    return rv;  }  rv = nssPointerTracker_add(&encoder_pointer_tracker, encoder);  if( PR_SUCCESS != rv ) {    NSSError e = NSS_GetError();    if( NSS_ERROR_NO_MEMORY != e ) {      nss_SetError(NSS_ERROR_INTERNAL_ERROR);    }    return rv;  }  return PR_SUCCESS;}static PRStatusencoder_remove_pointer(  const nssASN1Encoder *encoder){  PRStatus rv;  rv = nssPointerTracker_remove(&encoder_pointer_tracker, encoder);  if( PR_SUCCESS != rv ) {    nss_SetError(NSS_ERROR_INTERNAL_ERROR);  }  return rv;}/* * nssASN1Encoder_verify * * This routine is only available in debug builds. * * If the specified pointer is a valid pointer to an nssASN1Encoder * object, this routine will return PR_SUCCESS.  Otherwise, it will  * put an error on the error stack and return PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_INVALID_ASN1ENCODER * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success */NSS_IMPLEMENT PRStatusnssASN1Encoder_verify(  nssASN1Encoder *encoder){  PRStatus rv;  rv = nssPointerTracker_initialize(&encoder_pointer_tracker);  if( PR_SUCCESS != rv ) {    return PR_FAILURE;  }  rv = nssPointerTracker_verify(&encoder_pointer_tracker, encoder);  if( PR_SUCCESS != rv ) {    nss_SetError(NSS_ERROR_INVALID_ASN1ENCODER);    return PR_FAILURE;  }  return PR_SUCCESS;}#endif /* DEBUG *//* * nssASN1Decoder_Create * * This routine creates an ASN.1 Decoder, which will use the specified * template to decode a datastream into the specified destination * structure.  If the optional arena argument is non-NULL, blah blah  * blah.  XXX fgmr Should we include an nssASN1EncodingType argument,  * as a hint?  Or is each encoding distinctive?  This routine may  * return NULL upon error, in which case an error will have been  * placed upon the error stack. * * The error may be one of the following values: *  NSS_ERROR_NO_MEMORY *  NSS_ERROR_INVALID_ARENA *  NSS_ERROR_INVALID_POINTER *  ... * * Return value: *  NULL upon error *  A pointer to an ASN.1 Decoder upon success. */NSS_IMPLEMENT nssASN1Decoder *nssASN1Decoder_Create(  NSSArena *arenaOpt,  void *destination,  const nssASN1Template template[]){  SEC_ASN1DecoderContext *rv;  PLArenaPool *hack = (PLArenaPool *)arenaOpt;#ifdef DEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (nssASN1Decoder *)NULL;    }  }  /*    * May destination be NULL?  I'd think so, since one might   * have only a filter proc.  But if not, check the pointer here.   */  if( (nssASN1Template *)NULL == template ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (nssASN1Decoder *)NULL;  }#endif /* DEBUG */  rv = SEC_ASN1DecoderStart(hack, destination, template);  if( (SEC_ASN1DecoderContext *)NULL == rv ) {    nss_SetError(PORT_GetError()); /* also evil */    return (nssASN1Decoder *)NULL;  }#ifdef DEBUG  if( PR_SUCCESS != decoder_add_pointer(rv) ) {    (void)SEC_ASN1DecoderFinish(rv);    return (nssASN1Decoder *)NULL;  }#endif /* DEBUG */  return (nssASN1Decoder *)rv;}/* * nssASN1Decoder_Update * * This routine feeds data to the decoder.  In the event of an error,  * it will place an error on the error stack and return PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_NO_MEMORY *  NSS_ERROR_INVALID_POINTER *  NSS_ERROR_INVALID_ASN1DECODER *  NSS_ERROR_INVALID_BER *  ... * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success. */NSS_IMPLEMENT PRStatusnssASN1Decoder_Update(  nssASN1Decoder *decoder,  const void *data,  PRUint32 amount){  PRStatus rv;#ifdef DEBUG  if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {    return PR_FAILURE;  }  if( (void *)NULL == data ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return PR_FAILURE;  }#endif /* DEBUG */  rv = SEC_ASN1DecoderUpdate((SEC_ASN1DecoderContext *)decoder,                              (const char *)data,                             (unsigned long)amount);  if( PR_SUCCESS != rv ) {    nss_SetError(PORT_GetError()); /* ugly */    return PR_FAILURE;  }  return PR_SUCCESS;}/* * nssASN1Decoder_Finish * * This routine finishes the decoding and destroys the decoder. * In the event of an error, it will place an error on the error * stack and return PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_INVALID_ASN1DECODER * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success */NSS_IMPLEMENT PRStatusnssASN1Decoder_Finish(  nssASN1Decoder *decoder){  PRStatus rv;#ifdef DEBUG  if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {    return PR_FAILURE;  }#endif /* DEBUG */  rv = SEC_ASN1DecoderFinish((SEC_ASN1DecoderContext *)decoder);  if( PR_SUCCESS != rv ) {    nss_SetError(PORT_GetError()); /* ugly */  }#ifdef DEBUG  {    PRStatus rv2 = decoder_remove_pointer(decoder);    if( PR_SUCCESS == rv ) {      rv = rv2;    }  }#endif /* DEBUG */  return rv;}/* * nssASN1Decoder_SetFilter * * This routine registers a callback filter routine with the decoder, * which will be called blah blah blah.  The specified argument will * be passed as-is to the filter routine.  The routine pointer may * be NULL, in which case no filter callback will be called.  If the * noStore boolean is PR_TRUE, then decoded fields will not be stored * in the destination structure specified when the decoder was  * created.  This routine returns a PRStatus value; in the event of * an error, it will place an error on the error stack and return * PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_INVALID_ASN1DECODER * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success */NSS_IMPLEMENT PRStatusnssASN1Decoder_SetFilter(  nssASN1Decoder *decoder,  nssASN1DecoderFilterFunction *callback,  void *argument,  PRBool noStore){#ifdef DEBUG  if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {    return PR_FAILURE;  }#endif /* DEBUG */  if( (nssASN1DecoderFilterFunction *)NULL == callback ) {     SEC_ASN1DecoderClearFilterProc((SEC_ASN1DecoderContext *)decoder);  } else {     SEC_ASN1DecoderSetFilterProc((SEC_ASN1DecoderContext *)decoder,                                  (SEC_ASN1WriteProc)callback,                                  argument, noStore);  }  /* No error returns defined for those routines */  return PR_SUCCESS;}/* * nssASN1Decoder_GetFilter * * If the optional pCallbackOpt argument to this routine is non-null, * then the pointer to any callback function established for this * decoder with nssASN1Decoder_SetFilter will be stored at the  * location indicated by it.  If the optional pArgumentOpt * pointer is non-null, the filter's closure argument will be stored * there.  If the optional pNoStoreOpt pointer is non-null, the * noStore value specified when setting the filter will be stored * there.  This routine returns a PRStatus value; in the event of * an error it will place an error on the error stack and return * PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_INVALID_ASN1DECODER * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success */extern const NSSError NSS_ERROR_INTERNAL_ERROR;NSS_IMPLEMENT PRStatusnssASN1Decoder_GetFilter(  nssASN1Decoder *decoder,  nssASN1DecoderFilterFunction **pCallbackOpt,  void **pArgumentOpt,  PRBool *pNoStoreOpt){#ifdef DEBUG  if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {    return PR_FAILURE;  }#endif /* DEBUG */  if( (nssASN1DecoderFilterFunction **)NULL != pCallbackOpt ) {    *pCallbackOpt = (nssASN1DecoderFilterFunction *)NULL;  }  if( (void **)NULL != pArgumentOpt ) {    *pArgumentOpt = (void *)NULL;  }  if( (PRBool *)NULL != pNoStoreOpt ) {    *pNoStoreOpt = PR_FALSE;  }  /* Error because it's unimplemented */  nss_SetError(NSS_ERROR_INTERNAL_ERROR);  return PR_FAILURE;}/* * nssASN1Decoder_SetNotify * * This routine registers a callback notify routine with the decoder, * which will be called whenever.. The specified argument will be * passed as-is to the notify routine.  The routine pointer may be * NULL, in which case no notify routine will be called.  This routine * returns a PRStatus value; in the event of an error it will place * an error on the error stack and return PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_INVALID_ASN1DECODER * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success */NSS_IMPLEMENT PRStatusnssASN1Decoder_SetNotify(  nssASN1Decoder *decoder,  nssASN1NotifyFunction *callback,  void *argument){#ifdef DEBUG  if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {    return PR_FAILURE;  }#endif /* DEBUG */  if( (nssASN1NotifyFunction *)NULL == callback ) {    SEC_ASN1DecoderClearNotifyProc((SEC_ASN1DecoderContext *)decoder);  } else {    SEC_ASN1DecoderSetNotifyProc((SEC_ASN1DecoderContext *)decoder,                                 (SEC_ASN1NotifyProc)callback,                                 argument);  }  /* No error returns defined for those routines */  return PR_SUCCESS;}/* * nssASN1Decoder_GetNotify * * If the optional pCallbackOpt argument to this routine is non-null, * then the pointer to any callback function established for this * decoder with nssASN1Decoder_SetNotify will be stored at the  * location indicated by it.  If the optional pArgumentOpt pointer is * non-null, the filter's closure argument will be stored there. * This routine returns a PRStatus value; in the event of an error it * will place an error on the error stack and return PR_FAILURE. * * The error may be one of the following values: *  NSS_ERROR_INVALID_ASN1DECODER * * Return value: *  PR_FAILURE upon error *  PR_SUCCESS upon success */NSS_IMPLEMENT PRStatusnssASN1Decoder_GetNotify(  nssASN1Decoder *decoder,  nssASN1NotifyFunction **pCallbackOpt,  void **pArgumentOpt){#ifdef DEBUG  if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {    return PR_FAILURE;  }#endif /* DEBUG */  if( (nssASN1NotifyFunction **)NULL != pCallbackOpt ) {    *pCallbackOpt = (nssASN1NotifyFunction *)NULL;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?