asn1.c

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

C
1,727
字号
  dest = (NSSItem*)arg;  PR_ASSERT (dest != NULL);  memcpy((unsigned char *)dest->data + dest->size, buf, len);  dest->size += len;}/* * nssASN1_EncodeItem * * There must be a better name.  If the optional arena argument is * non-null, it'll be used for the space.  If the optional rvOpt is * non-null, it'll be the return value-- if it is null, a new one * will be allocated. * * The error may be one of the following values: *  NSS_ERROR_NO_MEMORY *  NSS_ERROR_INVALID_ARENA *  NSS_ERROR_INVALID_POINTER *  NSS_ERROR_ENCODING_NOT_SUPPORTED * * Return value: *  NULL upon error *  A valid pointer to an NSSDER upon success */NSS_IMPLEMENT NSSDER *nssASN1_EncodeItem(  NSSArena *arenaOpt,  NSSDER *rvOpt,  const void *source,  const nssASN1Template template[],  NSSASN1EncodingType encoding){  PLArenaPool *hack = (PLArenaPool *)arenaOpt;  NSSDER *rv;  PRUint32 len = 0;  PRStatus status;#ifdef DEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSDER *)NULL;    }  }  if( (void *)NULL == source ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSDER *)NULL;  }  if( (nssASN1Template *)NULL == template ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSDER *)NULL;  }#endif /* DEBUG */  status = nssASN1_Encode(source, template, encoding,                           (nssASN1EncoderWriteFunction *)nssasn1_encode_item_count,                           &len);  if( PR_SUCCESS != status ) {    return (NSSDER *)NULL;  }  if( (NSSDER *)NULL == rvOpt ) {    rv = nss_ZNEW(arenaOpt, NSSDER);    if( (NSSDER *)NULL == rv ) {      return (NSSDER *)NULL;    }  } else {    rv = rvOpt;  }  rv->size = len;  rv->data = nss_ZAlloc(arenaOpt, len);  if( (void *)NULL == rv->data ) {    if( (NSSDER *)NULL == rvOpt ) {      nss_ZFreeIf(rv);    }    return (NSSDER *)NULL;  }  rv->size = 0; /* for nssasn1_encode_item_store */  status = nssASN1_Encode(source, template, encoding,                          (nssASN1EncoderWriteFunction *)nssasn1_encode_item_store,                           rv);  if( PR_SUCCESS != status ) {    nss_ZFreeIf(rv->data);    if( (NSSDER *)NULL == rvOpt ) {      nss_ZFreeIf(rv);    }    return (NSSDER *)NULL;  }  PR_ASSERT(rv->size == len);  return rv;}/* * nssASN1_CreatePRUint32FromBER * */NSS_IMPLEMENT PRStatusnssASN1_CreatePRUint32FromBER(  NSSBER *encoded,  PRUint32 *pResult){  nss_SetError(NSS_ERROR_INTERNAL_ERROR);  return PR_FALSE;}/* * nssASN1_GetDERFromPRUint32 * */NSS_EXTERN NSSDER *nssASN1_GetDERFromPRUint32(  NSSArena *arenaOpt,  NSSDER *rvOpt,  PRUint32 value){  NSSDER *rv;  PLArenaPool *hack = (PLArenaPool *)arenaOpt;  SECItem *item;#ifdef DEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSDER *)NULL;    }  }#endif /* DEBUG */  if( (NSSDER *)NULL == rvOpt ) {    rv = nss_ZNEW(arenaOpt, NSSDER);    if( (NSSDER *)NULL == rv ) {      return (NSSDER *)NULL;    }  } else {    rv = rvOpt;  }  item = SEC_ASN1EncodeUnsignedInteger(hack, (SECItem *)rv, value);  if( (SECItem *)NULL == item ) {    if( (NSSDER *)NULL == rvOpt ) {      (void)nss_ZFreeIf(rv);    }    nss_SetError(PORT_GetError()); /* ugly */    return (NSSDER *)NULL;  }  /*    * I happen to know that these things look alike.. but I'm only   * doing it for these "temporary" wrappers.  This is an evil thing.   */  return (NSSDER *)item;}/*himom*/NSS_IMPLEMENT PRStatusnssASN1_CreatePRInt32FromBER(  NSSBER *encoded,  PRInt32 *pResult){  nss_SetError(NSS_ERROR_INTERNAL_ERROR);  return PR_FALSE;}/* * nssASN1_GetDERFromPRInt32 * */NSS_IMPLEMENT NSSDER *nssASN1_GetDERFromPRInt32(  NSSArena *arenaOpt,  NSSDER *rvOpt,  PRInt32 value){  NSSDER *rv;  PLArenaPool *hack = (PLArenaPool *)arenaOpt;  SECItem *item;#ifdef DEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSDER *)NULL;    }  }#endif /* DEBUG */  if( (NSSDER *)NULL == rvOpt ) {    rv = nss_ZNEW(arenaOpt, NSSDER);    if( (NSSDER *)NULL == rv ) {      return (NSSDER *)NULL;    }  } else {    rv = rvOpt;  }  item = SEC_ASN1EncodeInteger(hack, (SECItem *)rv, value);  if( (SECItem *)NULL == item ) {    if( (NSSDER *)NULL == rvOpt ) {      (void)nss_ZFreeIf(rv);    }    nss_SetError(PORT_GetError()); /* ugly */    return (NSSDER *)NULL;  }  /*    * I happen to know that these things look alike.. but I'm only   * doing it for these "temporary" wrappers.  This is an evil thing.   */  return (NSSDER *)item;}/* * Generic Templates * One for each of the simple types, plus a special one for ANY, plus: *	- a pointer to each one of those *	- a set of each one of those * * Note that these are alphabetical (case insensitive); please add new * ones in the appropriate place. */const nssASN1Template *nssASN1Template_Any =                             (nssASN1Template *)SEC_AnyTemplate;const nssASN1Template *nssASN1Template_BitString =                       (nssASN1Template *)SEC_BitStringTemplate;const nssASN1Template *nssASN1Template_BMPString =                       (nssASN1Template *)SEC_BMPStringTemplate;const nssASN1Template *nssASN1Template_Boolean =                         (nssASN1Template *)SEC_BooleanTemplate;const nssASN1Template *nssASN1Template_Enumerated =                      (nssASN1Template *)SEC_EnumeratedTemplate;const nssASN1Template *nssASN1Template_GeneralizedTime =                 (nssASN1Template *)SEC_GeneralizedTimeTemplate;const nssASN1Template *nssASN1Template_IA5String =                       (nssASN1Template *)SEC_IA5StringTemplate;const nssASN1Template *nssASN1Template_Integer =                         (nssASN1Template *)SEC_IntegerTemplate;const nssASN1Template *nssASN1Template_Null =                            (nssASN1Template *)SEC_NullTemplate;const nssASN1Template *nssASN1Template_ObjectID =                        (nssASN1Template *)SEC_ObjectIDTemplate;const nssASN1Template *nssASN1Template_OctetString =                     (nssASN1Template *)SEC_OctetStringTemplate;const nssASN1Template *nssASN1Template_PrintableString =                 (nssASN1Template *)SEC_PrintableStringTemplate;const nssASN1Template *nssASN1Template_T61String =                       (nssASN1Template *)SEC_T61StringTemplate;const nssASN1Template *nssASN1Template_UniversalString =                 (nssASN1Template *)SEC_UniversalStringTemplate;const nssASN1Template *nssASN1Template_UTCTime =                         (nssASN1Template *)SEC_UTCTimeTemplate;const nssASN1Template *nssASN1Template_UTF8String =                      (nssASN1Template *)SEC_UTF8StringTemplate;const nssASN1Template *nssASN1Template_VisibleString =                   (nssASN1Template *)SEC_VisibleStringTemplate;const nssASN1Template *nssASN1Template_PointerToAny =                    (nssASN1Template *)SEC_PointerToAnyTemplate;const nssASN1Template *nssASN1Template_PointerToBitString =              (nssASN1Template *)SEC_PointerToBitStringTemplate;const nssASN1Template *nssASN1Template_PointerToBMPString =              (nssASN1Template *)SEC_PointerToBMPStringTemplate;const nssASN1Template *nssASN1Template_PointerToBoolean =                (nssASN1Template *)SEC_PointerToBooleanTemplate;const nssASN1Template *nssASN1Template_PointerToEnumerated =             (nssASN1Template *)SEC_PointerToEnumeratedTemplate;const nssASN1Template *nssASN1Template_PointerToGeneralizedTime =        (nssASN1Template *)SEC_PointerToGeneralizedTimeTemplate;const nssASN1Template *nssASN1Template_PointerToIA5String =              (nssASN1Template *)SEC_PointerToIA5StringTemplate;const nssASN1Template *nssASN1Template_PointerToInteger =                (nssASN1Template *)SEC_PointerToIntegerTemplate;const nssASN1Template *nssASN1Template_PointerToNull =                   (nssASN1Template *)SEC_PointerToNullTemplate;const nssASN1Template *nssASN1Template_PointerToObjectID =               (nssASN1Template *)SEC_PointerToObjectIDTemplate;const nssASN1Template *nssASN1Template_PointerToOctetString =            (nssASN1Template *)SEC_PointerToOctetStringTemplate;const nssASN1Template *nssASN1Template_PointerToPrintableString =        (nssASN1Template *)SEC_PointerToPrintableStringTemplate;const nssASN1Template *nssASN1Template_PointerToT61String =              (nssASN1Template *)SEC_PointerToT61StringTemplate;const nssASN1Template *nssASN1Template_PointerToUniversalString =        (nssASN1Template *)SEC_PointerToUniversalStringTemplate;const nssASN1Template *nssASN1Template_PointerToUTCTime =                (nssASN1Template *)SEC_PointerToUTCTimeTemplate;const nssASN1Template *nssASN1Template_PointerToUTF8String =             (nssASN1Template *)SEC_PointerToUTF8StringTemplate;const nssASN1Template *nssASN1Template_PointerToVisibleString =          (nssASN1Template *)SEC_PointerToVisibleStringTemplate;const nssASN1Template *nssASN1Template_SetOfAny =                        (nssASN1Template *)SEC_SetOfAnyTemplate;const nssASN1Template *nssASN1Template_SetOfBitString =                  (nssASN1Template *)SEC_SetOfBitStringTemplate;const nssASN1Template *nssASN1Template_SetOfBMPString =                  (nssASN1Template *)SEC_SetOfBMPStringTemplate;const nssASN1Template *nssASN1Template_SetOfBoolean =                    (nssASN1Template *)SEC_SetOfBooleanTemplate;const nssASN1Template *nssASN1Template_SetOfEnumerated =                 (nssASN1Template *)SEC_SetOfEnumeratedTemplate;const nssASN1Template *nssASN1Template_SetOfGeneralizedTime =            (nssASN1Template *)SEC_SetOfGeneralizedTimeTemplate;const nssASN1Template *nssASN1Template_SetOfIA5String =                  (nssASN1Template *)SEC_SetOfIA5StringTemplate;const nssASN1Template *nssASN1Template_SetOfInteger =                    (nssASN1Template *)SEC_SetOfIntegerTemplate;const nssASN1Template *nssASN1Template_SetOfNull =                       (nssASN1Template *)SEC_SetOfNullTemplate;const nssASN1Template *nssASN1Template_SetOfObjectID =                   (nssASN1Template *)SEC_SetOfObjectIDTemplate;const nssASN1Template *nssASN1Template_SetOfOctetString =                (nssASN1Template *)SEC_SetOfOctetStringTemplate;const nssASN1Template *nssASN1Template_SetOfPrintableString =            (nssASN1Template *)SEC_SetOfPrintableStringTemplate;const nssASN1Template *nssASN1Template_SetOfT61String =                  (nssASN1Template *)SEC_SetOfT61StringTemplate;const nssASN1Template *nssASN1Template_SetOfUniversalString =            (nssASN1Template *)SEC_SetOfUniversalStringTemplate;const nssASN1Template *nssASN1Template_SetOfUTCTime =                    (nssASN1Template *)SEC_SetOfUTCTimeTemplate;const nssASN1Template *nssASN1Template_SetOfUTF8String =                 (nssASN1Template *)SEC_SetOfUTF8StringTemplate;const nssASN1Template *nssASN1Template_SetOfVisibleString =              (nssASN1Template *)SEC_SetOfVisibleStringTemplate;/* * */NSS_IMPLEMENT NSSUTF8 *nssUTF8_CreateFromBER(  NSSArena *arenaOpt,  nssStringType type,  NSSBER *berData){  NSSUTF8 *rv = NULL;  PRUint8 tag;  NSSArena *a;  NSSItem in;  NSSItem out;  PRStatus st;  const nssASN1Template *templ;#ifdef NSSDEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSUTF8 *)NULL;    }  }  if( (NSSBER *)NULL == berData ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSUTF8 *)NULL;  }  if( (void *)NULL == berData->data ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSUTF8 *)NULL;  }#endif /* NSSDEBUG */  a = NSSArena_Create();  if( (NSSArena *)NULL == a ) {    return (NSSUTF8 *)NULL;  }  in = *berData;  /*   * By the way, at first I succumbed to the temptation to make   * this an incestuous nested switch statement.  Count yourself   * lucky I cleaned it up.   */  switch( type ) {  case nssStringType_DirectoryString:    /*     * draft-ietf-pkix-ipki-part1-11 says in part:     *     * DirectoryString { INTEGER:maxSize } ::= CHOICE {     *   teletexString           TeletexString (SIZE (1..maxSize)),     *   printableString         PrintableString (SIZE (1..maxSize)),     *   universalString         UniversalString (SIZE (1..maxSize)),     *   bmpString               BMPString (SIZE(1..maxSize)),     *   utf8String              UTF8String (SIZE(1..maxSize))     *                       }     *     * The tags are:     *  TeletexString       UNIVERSAL 20     *  PrintableString     UNIVERSAL 19     *  UniversalString     UNIVERSAL 28     *  BMPString           UNIVERSAL 30     *  UTF8String          UNIVERSAL 12     *     * "UNIVERSAL" tags have bits 8 and 7 zero, bit 6 is zero for     * primitive encodings, and if the tag value is less than 30,     * the tag value is directly encoded in bits 5 through 1.     */    in.data = (void *)&(((PRUint8 *)berData->data)[1]);    in.size = berData->size-1;        tag = *(PRUint8 *)berData->data;    switch( tag & nssASN1_TAGNUM_MASK ) {    case 20:      /*       * XXX fgmr-- we have to accept Latin-1 for Teletex; (see       * below) but is T61 a suitable value for "Latin-1"?       */      templ = nssASN1Template_T61String;      type = nssStringType_TeletexString;      break;    case 19:      templ = nssASN1Template_PrintableString;      type = nssStringType_PrintableString;      break;    case 28:      templ = nssASN1Template_UniversalString;      type = nssStringType_UniversalString;      break;    case 30:      templ = nssASN1Template_BMPString;      type = nssStringType_BMPString;      break;    case 12:      templ = nssASN1Template_UTF8String;      type = nssStringType_UTF8String;      break;    default:      nss_SetError(NSS_ERROR_INVALID_POINTER); /* "pointer"? */      (void)NSSArena_Destroy(a);      return (NSSUTF8 *)NULL;    }    break;  case nssStringType_TeletexString:    /*     * XXX fgmr-- we have to accept Latin-1 for Teletex; (see     * below) but is T61 a suitable value for "Latin-1"?     */    templ = nssASN1Template_T61String;    break;     case nssStringType_PrintableString:    templ = nssASN1Template_PrintableString;    break;  case nssStringType_UniversalString:    templ = nssASN1Template_UniversalString;    break;  case nssStringType_BMPString:    templ = nssASN1Template_BMPString;    break;  case nssStringType_UTF8String:    templ = nssASN1Template_UTF8String;    break;  case nssStringType_PHGString:    templ = nssASN1Template_IA5String;    break;  default:    nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);    (void)NSSArena_Destroy(a);    return (NSSUTF8 *)NULL;  }      st = nssASN1_DecodeBER(a, &out, templ, &in);    if( PR_SUCCESS == st ) {    rv = nssUTF8_Create(arenaOpt, type, out.data, out.size);  }  (void)NSSArena_Destroy(a);    return rv;}NSS_EXTERN NSSDER *nssUTF8_GetDEREncoding(  NSSArena *arenaOpt,  nssStringType type,  const NSSUTF8 *string){  NSSDER *rv = (NSSDER *)NULL;  NSSItem str;  NSSDER *der;  const nssASN1Template *templ;  NSSArena *a;#ifdef NSSDEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSDER *)NULL;    }  }  if( (const NSSUTF8 *)NULL == string ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSDER *)NULL;  }#endif /* NSSDEBUG */  str.data = (void *)string;  str.size = nssUTF8_Size(string, (PRStatus *)NULL);  if( 0 == str.size ) {    return (NSSDER *)NULL;  }  a = NSSArena_Create();  if( (NSSArena *)NULL == a ) {    return (NSSDER *)NULL;  }  switch( type ) {  case nssStringType_DirectoryString:    {      NSSDER *utf;      PRUint8 *c;      utf = nssASN1_EncodeItem(a, (NSSDER *)NULL, &str,                                nssASN1Template_UTF8String,                               NSSASN1DER);      if( (NSSDER *)NULL == utf ) {        (void)NSSArena_Destroy(a);        return (NSSDER *)NULL;      }      rv = nss_ZNEW(arenaOpt, NSSDER);      if( (NSSDER *)NULL == rv ) {        (void)NSSArena_Destroy(a);        return (NSSDER *)NULL;      }      rv->size = utf->size + 1;      rv->data = nss_ZAlloc(arenaOpt, rv->size);      if( (void *)NULL == rv->data ) {        (void)nss_ZFreeIf(rv);        (void)NSSArena_Destroy(a);        return (NSSDER *)NULL;      }            c = (PRUint8 *)rv->data;      (void)nsslibc_memcpy(&c[1], utf->data, utf->size);      *c = 12; /* UNIVERSAL primitive encoding tag for UTF8String */      (void)NSSArena_Destroy(a);      return rv;    }  case nssStringType_TeletexString:    /*     * XXX fgmr-- we have to accept Latin-1 for Teletex; (see     * below) but is T61 a suitable value for "Latin-1"?     */    templ = nssASN1Template_T61String;    break;  case nssStringType_PrintableString:    templ = nssASN1Template_PrintableString;    break;  case nssStringType_UniversalString:    templ = nssASN1Template_UniversalString;    break;  case nssStringType_BMPString:    templ = nssASN1Template_BMPString;    break;  case nssStringType_UTF8String:    templ = nssASN1Template_UTF8String;    break;  case nssStringType_PHGString:    templ = nssASN1Template_IA5String;    break;  default:    nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);    (void)NSSArena_Destroy(a);    return (NSSDER *)NULL;  }  der = nssUTF8_GetDEREncoding(a, type, string);  if( (NSSItem *)NULL == der ) {    (void)NSSArena_Destroy(a);    return (NSSDER *)NULL;  }  rv = nssASN1_EncodeItem(arenaOpt, (NSSDER *)NULL, der, templ, NSSASN1DER);  if( (NSSDER *)NULL == rv ) {    (void)NSSArena_Destroy(a);    return (NSSDER *)NULL;  }  (void)NSSArena_Destroy(a);  return rv;}

⌨️ 快捷键说明

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