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 + -
显示快捷键?