这个工具在
1 | strongswan/src/libstrongswan/asn1 |
以下是使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | #include <asn1/asn1.h> #include <asn1/asn1_parser.h> #define INTEGER_SIZE 32 static chunk_t chunk_to_asn1(chunk_t chunk) { chunk_t x; chunk_t y; chunk_t hash; chunk_t content; chunk_t asn1; x.ptr = chunk.ptr; x.len = INTEGER_SIZE; y.ptr = chunk.ptr + INTEGER_SIZE; y.len = INTEGER_SIZE; content.ptr = y.ptr + INTEGER_SIZE; content.len = chunk.len - INTEGER_SIZE * 3; hash.ptr = content.ptr + content.len; hash.len = INTEGER_SIZE; asn1 = asn1_wrap(ASN1_SEQUENCE, "mmmm", asn1_integer("c", x), asn1_integer("c", y), asn1_simple_object(ASN1_OCTET_STRING, hash), asn1_simple_object(ASN1_OCTET_STRING, content)); chunk_free(&chunk); return asn1; } static const asn1Object_t patterns[] = { { 0, "seq", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ { 1, "x", ASN1_INTEGER, ASN1_BODY }, /* 1 */ { 1, "y", ASN1_INTEGER, ASN1_BODY }, /* 2 */ { 1, "hash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */ { 1, "content", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */ { 0, "exit", ASN1_EOC, ASN1_EXIT } }; #define PATTERN_KEY_X 1 #define PATTERN_KEY_Y 2 #define PATTERN_KEY_HASH 3 #define PATTERN_KEY_CONTENT 4 static chunk_t correct_integer(chunk_t chunk) { if (chunk.len == INTEGER_SIZE + 1) return chunk_skip(chunk, 1); return chunk; } static bool parse_asn1(chunk_t asn1, chunk_t* x, chunk_t* y, chunk_t* hash, chunk_t* content) { chunk_t object; asn1_parser_t *parser; bool success = FALSE; int object_id, oid, i; parser = asn1_parser_create(patterns, asn1); while (parser->iterate(parser, &object_id, &object)) { switch (object_id) { case PATTERN_KEY_X: *x = correct_integer(object); break; case PATTERN_KEY_Y: *y = correct_integer(object); break; case PATTERN_KEY_HASH: *hash = object; break; case PATTERN_KEY_CONTENT: *content = object; break; } } success = parser->success(parser); parser->destroy(parser); return success; } static bool chunk_from_asn1(chunk_t* chunk, chunk_t asn1) { chunk_t x; chunk_t y; chunk_t hash; chunk_t content; if (!parse_asn1(asn1, &x, &y, &hash, &content)) return false; *chunk = chunk_cat("cccc", x, y, content, hash); return true; } static void random_data(chunk_t chunk) { int fd = open("/dev/urandom", O_RDONLY); read(fd, chunk.ptr, chunk.len); close(fd); } int test() { bool is_ok; chunk_t result; chunk_t asn1; chunk_t total = chunk_alloc(INTEGER_SIZE * 3 + 345); random_data(total); asn1 = chunk_to_asn1(total); is_ok = chunk_from_asn1(&result, asn1); chunk_free(&result); chunk_free(&asn1); chunk_free(&total); return is_ok; } |
因为asn1模块里对ASN1_INTEGER类型有个two's complement处理,如果这个数最高位为1,则在此数前加一个0值字节,所以correct_integer函数的目地在于更正输出。