📄 unber.c
字号:
if(BER_TAG_CLASS(tlv_tag) == ASN_TAG_CLASS_UNIVERSAL) { const char *str; ber_tlv_tag_t tvalue = BER_TAG_VALUE(tlv_tag); str = ASN_UNIVERSAL_TAG2STR(tvalue); if(str) printf(" A=\"%s\"", str); } if(fin) printf(">\n");}/* * Print the value in binary form, or reformat for pretty-printing. */static intprint_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag, ber_tlv_len_t tlv_len) { asn1c_integer_t *arcs = 0; /* Object identifier arcs */ unsigned char *vbuf = 0; asn1p_expr_type_e etype = 0; asn1c_integer_t collector = 0; int special_format = 0; ssize_t i; /* Figure out what type is it */ if(BER_TAG_CLASS(tlv_tag) == ASN_TAG_CLASS_UNIVERSAL && pretty_printing) { ber_tlv_tag_t tvalue = BER_TAG_VALUE(tlv_tag); etype = ASN_UNIVERSAL_TAG2TYPE(tvalue); } /* * Determine how to print the value, either in its native binary form, * encoded with &xNN characters, or using pretty-printing. * The basic string types (including "useful types", like UTCTime) * are excempt from this determination logic, because their alphabets * are subsets of the XML's native UTF-8 encoding. */ switch(etype) { case ASN_BASIC_BOOLEAN: if(tlv_len == 1) special_format = 1; else etype = 0; break; case ASN_BASIC_INTEGER: case ASN_BASIC_ENUMERATED: if((size_t)tlv_len <= sizeof(collector)) special_format = 1; else etype = 0; break; case ASN_BASIC_OBJECT_IDENTIFIER: case ASN_BASIC_RELATIVE_OID: if(tlv_len > 0 && tlv_len < 128*1024 /* VERY long OID! */) { arcs = malloc(sizeof(*arcs) * (tlv_len + 1)); if(arcs) { vbuf = malloc(tlv_len + 1); /* Not checking is intentional */ } } case ASN_BASIC_UTCTime: case ASN_BASIC_GeneralizedTime: case ASN_STRING_NumericString: case ASN_STRING_PrintableString: case ASN_STRING_VisibleString: case ASN_STRING_IA5String: case ASN_STRING_UTF8String: break; /* Directly compatible with UTF-8 */ case ASN_STRING_BMPString: case ASN_STRING_UniversalString: break; /* Not directly compatible with UTF-8 */ default: /* Conditionally compatible with UTF-8 */ if(( (etype & ASN_STRING_MASK) || (etype == ASN_BASIC_OCTET_STRING) || /* * AUTOMATIC TAGS or IMPLICIT TAGS in effect, * Treat this primitive type as OCTET_STRING. */ (BER_TAG_CLASS(tlv_tag) != ASN_TAG_CLASS_UNIVERSAL && pretty_printing) ) && (tlv_len > 0 && tlv_len < 128 * 1024)) { vbuf = malloc(tlv_len + 1); /* Not checking is intentional */ } break; } /* If collection vbuf is present, defer printing the F flag. */ if(!vbuf) printf(special_format ? " F>" : ">"); /* * Print the value in binary or text form, * or collect the bytes into vbuf. */ for(i = 0; i < tlv_len; i++) { int ch = fgetc(fp); if(ch == -1) { fprintf(stderr, "%s: Unexpected end of file (V)\n", fname); if(vbuf) free(vbuf); if(arcs) free(arcs); return -1; } switch(etype) { case ASN_BASIC_UTCTime: case ASN_BASIC_GeneralizedTime: case ASN_STRING_NumericString: case ASN_STRING_PrintableString: case ASN_STRING_VisibleString: case ASN_STRING_IA5String: case ASN_STRING_UTF8String: switch(ch) { default: if(((etype == ASN_STRING_UTF8String) || !(ch & 0x80)) && (ch >= 0x20) ) { printf("%c", ch); break; } /* Fall through */ case 0x3c: case 0x3e: case 0x26: printf("&#x%02x;", ch); } break; case ASN_BASIC_BOOLEAN: switch(ch) { case 0: printf("<false/>"); break; case 0xff: printf("<true/>"); break; default: printf("<true value=\"&#x%02x\"/>", ch); } break; case ASN_BASIC_INTEGER: case ASN_BASIC_ENUMERATED: if(i) collector = collector * 256 + ch; else collector = (int)(signed char)ch; break; default: if(vbuf) { vbuf[i] = ch; } else { printf("&#x%02x;", ch); } } } /* Do post-processing */ switch(etype) { case ASN_BASIC_INTEGER: case ASN_BASIC_ENUMERATED: printf("%" PRIdASN, collector); break; case ASN_BASIC_OBJECT_IDENTIFIER: if(vbuf) { OBJECT_IDENTIFIER_t oid; int arcno; oid.buf = vbuf; oid.size = tlv_len; arcno = OBJECT_IDENTIFIER_get_arcs(&oid, arcs, sizeof(*arcs), tlv_len + 1); if(arcno >= 0) { assert(arcno <= (tlv_len + 1)); printf(" F>"); for(i = 0; i < arcno; i++) { if(i) printf("."); printf("%" PRIuASN, arcs[i]); } free(vbuf); vbuf = 0; } } break; case ASN_BASIC_RELATIVE_OID: if(vbuf) { RELATIVE_OID_t oid; int arcno; oid.buf = vbuf; oid.size = tlv_len; arcno = RELATIVE_OID_get_arcs(&oid, arcs, sizeof(*arcs), tlv_len); if(arcno >= 0) { assert(arcno <= (tlv_len + 1)); printf(" F>"); for(i = 0; i < arcno; i++) { if(i) printf("."); printf("%" PRIuASN, arcs[i]); } free(vbuf); vbuf = 0; } } break; default: break; } /* * If the buffer was not consumed, print it out. * It might be an OCTET STRING or other primitive type, * which might actually be printable, but we need to figure it out. */ if(vbuf) { int binary; /* * Check whether the data could be represented as text */ binary = -1 * (tlv_len >> 3); /* Threshold is 12.5% binary */ for(i = 0; i < tlv_len; i++) { switch(vbuf[i]) { case 0x1b: binary = 1; break; case 0x09: case 0x0a: case 0x0d: continue; default: if(vbuf[i] < 0x20 || vbuf[i] >= 0x7f) if(++binary > 0) /* Way too many */ break; continue; } break; } printf(">"); for(i = 0; i < tlv_len; i++) { if(binary > 0 || vbuf[i] < 0x20 || vbuf[i] >= 0x7f || vbuf[i] == 0x26 /* '&' */ || vbuf[i] == 0x3c /* '<' */ || vbuf[i] == 0x3e /* '>' */ ) printf("&#x%02x;", vbuf[i]); else printf("%c", vbuf[i]); } free(vbuf); } if(arcs) free(arcs); return 0;}static intdecode_tlv_from_string(const char *datastring) { unsigned char *data, *dp; size_t dsize; /* Data size */ ssize_t len; ber_tlv_tag_t tlv_tag; ber_tlv_len_t tlv_len; const char *p; int half; dsize = strlen(datastring) + 1; dp = data = calloc(1, dsize); assert(data); for(half = 0, p = datastring; *p; p++) { switch(*p) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *dp |= *p - '0'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': *dp |= *p - 'A' + 10; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': *dp |= *p - 'a' + 10; break; case ' ': case '\t': case '\r': case '\n': continue; default: fprintf(stderr, "Unexpected symbols in data string:\n"); fprintf(stderr, "%s\n", datastring); for(dp = data; datastring < p; datastring++, dp++) *dp = ' '; *dp = '\0'; fprintf(stderr, "%s^ <- here\n", (char *)data); return -1; } if(half) dp++; else (*dp) <<= 4; half = !half; } assert((size_t)(dp - data) <= dsize); dsize = dp - data; printf("BER: "); for(dp = data; dp < data + dsize; dp++) printf("%02X", *dp); printf("\n"); len = ber_fetch_tag(data, dsize, &tlv_tag); switch(len) { case -1: fprintf(stderr, "TAG: Fatal error deciphering tag\n"); return -1; case 0: fprintf(stderr, "TAG: More data expected\n"); return -1; default: printf("TAG: "); ber_tlv_tag_fwrite(tlv_tag, stdout); if(BER_TLV_CONSTRUCTED(data)) { printf(" (constructed)"); } else if(dsize >= 2 && data[0] == 0 && data[1] == 0) { printf(" (end-of-content)"); } else { printf(" (primitive)"); } if(BER_TAG_CLASS(tlv_tag) == ASN_TAG_CLASS_UNIVERSAL) { const char *str; ber_tlv_tag_t tvalue = BER_TAG_VALUE(tlv_tag); str = ASN_UNIVERSAL_TAG2STR(tvalue); if(str) printf(" \"%s\"", str); } printf("\n"); } if(dsize > (size_t)len) { len = ber_fetch_length(BER_TLV_CONSTRUCTED(data), data + len, dsize - len, &tlv_len); switch(len) { case -1: fprintf(stderr, "LEN: Fatal error deciphering length\n"); return -1; case 0: fprintf(stderr, "LEN: More data expected\n"); return -1; default: if(tlv_len == (ber_tlv_len_t)-1) printf("LEN: Indefinite length encoding\n"); else printf("LEN: %ld bytes\n", (long)tlv_len); } } return 0;}/* * Dummy functions. */asn_dec_rval_t ber_check_tags(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_struct_ctx_t *opt_ctx, void *ptr, size_t size, int tag_mode, int last_tag_form, ber_tlv_len_t *last_length, int *opt_tlv_form) { asn_dec_rval_t rv; (void)opt_codec_ctx; (void)td; (void)opt_ctx; (void)ptr; (void)size; (void)tag_mode; (void)last_tag_form; (void)last_length; (void)opt_tlv_form; return rv; }ssize_t der_write_tags(asn_TYPE_descriptor_t *td, size_t slen, int tag_mode, int last_tag_form, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { (void)td; (void)slen; (void)tag_mode; (void)last_tag_form; (void)tag; (void)cb; (void)app_key; return -1; }asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, asn_struct_ctx_t *ctx, void *struct_key, const char *xml_tag, const void *buf_ptr, size_t size, int (*otd)(void *struct_key, const void *chunk_buf, size_t chunk_size), ssize_t (*br)(void *struct_key, const void *chunk_buf, size_t chunk_size, int have_more)) { asn_dec_rval_t rv; (void)opt_codec_ctx; (void)ctx; (void)struct_key; (void)xml_tag; (void)buf_ptr; (void)size; (void)otd; (void)br; return rv; }int xer_is_whitespace(const void *b, size_t s) { (void)b; (void)s; return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -