Changeset 988 for vendor/current/lib/util/asn1.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/util/asn1.c
r740 r988 18 18 */ 19 19 20 #include "includes.h" 21 #include "../lib/util/asn1.h" 20 #include "replace.h" 21 #include "system/locale.h" 22 #include "lib/util/asn1.h" 23 #include "lib/util/debug.h" 24 #include "lib/util/samba_util.h" 25 26 struct nesting { 27 off_t start; 28 size_t taglen; /* for parsing */ 29 struct nesting *next; 30 }; 31 32 33 struct asn1_data { 34 uint8_t *data; 35 size_t length; 36 off_t ofs; 37 struct nesting *nesting; 38 bool has_error; 39 }; 22 40 23 41 /* allocate an asn1 structure */ … … 37 55 } 38 56 57 bool asn1_has_error(const struct asn1_data *data) 58 { 59 return data->has_error; 60 } 61 62 void asn1_set_error(struct asn1_data *data) 63 { 64 data->has_error = true; 65 } 66 67 bool asn1_has_nesting(const struct asn1_data *data) 68 { 69 return data->nesting != NULL; 70 } 71 72 off_t asn1_current_ofs(const struct asn1_data *data) 73 { 74 return data->ofs; 75 } 76 39 77 /* write to the ASN1 buffer, advancing the buffer pointer */ 40 78 bool asn1_write(struct asn1_data *data, const void *p, int len) 41 79 { 42 80 if (data->has_error) return false; 81 82 if ((len < 0) || (data->ofs + (size_t)len < data->ofs)) { 83 data->has_error = true; 84 return false; 85 } 86 43 87 if (data->length < data->ofs+len) { 44 88 uint8_t *newp; 45 89 newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len); 46 90 if (!newp) { 47 asn1_free(data);48 91 data->has_error = true; 49 92 return false; … … 68 111 struct nesting *nesting; 69 112 70 asn1_write_uint8(data, tag); 113 if (!asn1_write_uint8(data, tag)) { 114 return false; 115 } 71 116 nesting = talloc(data, struct nesting); 72 117 if (!nesting) { … … 86 131 struct nesting *nesting; 87 132 size_t len; 133 134 if (data->has_error) { 135 return false; 136 } 88 137 89 138 nesting = data->nesting; … … 186 235 bool asn1_write_implicit_Integer(struct asn1_data *data, int i) 187 236 { 237 if (data->has_error) { 238 return false; 239 } 240 188 241 if (i == -1) { 189 242 /* -1 is special as it consists of all-0xff bytes. In … … 232 285 p = newp + 1; 233 286 234 /*the ber representation can't use more space th en the string one */287 /*the ber representation can't use more space than the string one */ 235 288 *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID)); 236 289 if (!blob->data) return false; … … 327 380 bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length) 328 381 { 329 asn1_push_tag(data, ASN1_OCTET_STRING); 330 asn1_write(data, p, length); 331 asn1_pop_tag(data); 332 return !data->has_error; 382 if (!asn1_push_tag(data, ASN1_OCTET_STRING)) return false; 383 if (!asn1_write(data, p, length)) return false; 384 return asn1_pop_tag(data); 333 385 } 334 386 … … 336 388 bool asn1_write_LDAPString(struct asn1_data *data, const char *s) 337 389 { 338 asn1_write(data, s, strlen(s)); 339 return !data->has_error; 390 return asn1_write(data, s, strlen(s)); 340 391 } 341 392 … … 343 394 bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s) 344 395 { 345 asn1_write(data, s->data, s->length); 346 return !data->has_error; 396 return asn1_write(data, s->data, s->length); 347 397 } 348 398 … … 350 400 bool asn1_write_GeneralString(struct asn1_data *data, const char *s) 351 401 { 352 asn1_push_tag(data, ASN1_GENERAL_STRING); 353 asn1_write_LDAPString(data, s); 354 asn1_pop_tag(data); 355 return !data->has_error; 402 if (!asn1_push_tag(data, ASN1_GENERAL_STRING)) return false; 403 if (!asn1_write_LDAPString(data, s)) return false; 404 return asn1_pop_tag(data); 356 405 } 357 406 358 407 bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob) 359 408 { 360 asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num)); 361 asn1_write(data, blob->data, blob->length); 362 asn1_pop_tag(data); 363 return !data->has_error; 409 if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false; 410 if (!asn1_write(data, blob->data, blob->length)) return false; 411 return asn1_pop_tag(data); 364 412 } 365 413 … … 367 415 bool asn1_write_BOOLEAN(struct asn1_data *data, bool v) 368 416 { 369 asn1_push_tag(data, ASN1_BOOLEAN); 370 asn1_write_uint8(data, v ? 0xFF : 0); 371 asn1_pop_tag(data); 372 return !data->has_error; 417 if (!asn1_push_tag(data, ASN1_BOOLEAN)) return false; 418 if (!asn1_write_uint8(data, v ? 0xFF : 0)) return false; 419 return asn1_pop_tag(data); 373 420 } 374 421 … … 376 423 { 377 424 uint8_t tmp = 0; 378 asn1_start_tag(data, ASN1_BOOLEAN); 379 asn1_read_uint8(data, &tmp); 425 if (!asn1_start_tag(data, ASN1_BOOLEAN)) return false; 426 *v = false; 427 if (!asn1_read_uint8(data, &tmp)) return false; 380 428 if (tmp == 0xFF) { 381 429 *v = true; 382 } else { 383 *v = false; 384 } 385 asn1_end_tag(data); 386 return !data->has_error; 430 } 431 return asn1_end_tag(data); 387 432 } 388 433 … … 390 435 bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context) 391 436 { 392 asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context)); 393 asn1_write_uint8(data, v ? 0xFF : 0); 394 asn1_pop_tag(data); 395 return !data->has_error; 437 if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context))) return false; 438 if (!asn1_write_uint8(data, v ? 0xFF : 0)) return false; 439 return asn1_pop_tag(data); 396 440 } 397 441 … … 399 443 { 400 444 uint8_t tmp = 0; 401 asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context)); 402 asn1_read_uint8(data, &tmp); 445 if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context))) return false; 446 *v = false; 447 if (!asn1_read_uint8(data, &tmp)) return false; 403 448 if (tmp == 0xFF) { 404 449 *v = true; 405 } else { 406 *v = false; 407 } 408 asn1_end_tag(data); 409 return !data->has_error; 450 } 451 return asn1_end_tag(data); 410 452 } 411 453 … … 415 457 uint8_t b = 0; 416 458 417 asn1_read_uint8(data, &b);459 if (!asn1_read_uint8(data, &b)) return false; 418 460 if (b != ASN1_BOOLEAN) { 419 461 data->has_error = true; 420 462 return false; 421 463 } 422 asn1_read_uint8(data, &b);464 if (!asn1_read_uint8(data, &b)) return false; 423 465 if (b != v) { 424 466 data->has_error = true; … … 502 544 * just get the needed size the tag would consume 503 545 */ 504 bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag, size_t *size) 546 static bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag, 547 size_t *size) 505 548 { 506 549 off_t start_ofs = data->ofs; … … 771 814 } 772 815 773 asn1_read(data, blob.data, len); 774 asn1_end_tag(data); 775 if (data->has_error) { 816 if (!asn1_read(data, blob.data, len)) return false; 817 if (!asn1_end_tag(data)) { 776 818 data_blob_free(&blob); 777 819 return false; … … 818 860 return false; 819 861 } 820 asn1_read(data, *s, len);821 862 (*s)[len] = 0; 822 return !data->has_error;863 return asn1_read(data, *s, len); 823 864 } 824 865 … … 845 886 } 846 887 *blob = data_blob_talloc(mem_ctx, NULL, len+1); 847 if (!blob->data ) {848 data->has_error = true; 849 return false; 850 } 851 asn1_read(data, blob->data, len);852 asn1_end_tag(data);888 if (!blob->data || blob->length < len) { 889 data->has_error = true; 890 return false; 891 } 892 if (!asn1_read(data, blob->data, len)) goto err; 893 if (!asn1_end_tag(data)) goto err; 853 894 blob->length--; 854 895 blob->data[len] = 0; 855 856 if (data->has_error) { 857 data_blob_free(blob); 858 *blob = data_blob_null; 859 return false;860 }861 return true;896 return true; 897 898 err: 899 900 data_blob_free(blob); 901 *blob = data_blob_null; 902 return false; 862 903 } 863 904 … … 877 918 return false; 878 919 } 879 asn1_read(data, blob->data, len); 880 asn1_end_tag(data); 881 return !data->has_error; 920 if (!asn1_read(data, blob->data, len)) return false; 921 return asn1_end_tag(data); 882 922 } 883 923 … … 928 968 if (!asn1_read_uint8(data, padding)) return false; 929 969 930 *blob = data_blob_talloc(mem_ctx, NULL, len );931 if (!blob->data ) {970 *blob = data_blob_talloc(mem_ctx, NULL, len+1); 971 if (!blob->data || blob->length < len) { 932 972 data->has_error = true; 933 973 return false; … … 956 996 while (!data->has_error && asn1_tag_remaining(data)>0) { 957 997 uint8_t b; 958 asn1_read_uint8(data, &b); 998 if (!asn1_read_uint8(data, &b)) { 999 return false; 1000 } 959 1001 *v = (*v << 8) + b; 960 1002 } … … 967 1009 uint8_t b; 968 1010 if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; 969 asn1_read_uint8(data, &b);970 asn1_end_tag(data);1011 if (!asn1_read_uint8(data, &b)) return false; 1012 if (!asn1_end_tag(data)) return false; 971 1013 972 1014 if (v != b) … … 980 1022 { 981 1023 if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false; 982 asn1_write_uint8(data, v); 983 asn1_pop_tag(data); 984 return !data->has_error; 1024 if (!asn1_write_uint8(data, v)) return false; 1025 return asn1_pop_tag(data); 985 1026 } 986 1027 … … 1001 1042 } 1002 1043 1044 bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, 1045 DATA_BLOB *pblob) 1046 { 1047 DATA_BLOB blob; 1048 1049 if (!asn1_blob(asn1, &blob)) { 1050 return false; 1051 } 1052 1053 *pblob = (DATA_BLOB) { .length = blob.length }; 1054 pblob->data = talloc_move(mem_ctx, &blob.data); 1055 1056 /* 1057 * Stop access from here on 1058 */ 1059 asn1->has_error = true; 1060 1061 return true; 1062 } 1063 1003 1064 /* 1004 1065 Fill in an asn1 struct without making a copy … … 1011 1072 } 1012 1073 1013 /* 1014 check if a ASN.1 blob is a full tag 1015 */ 1016 NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) 1017 { 1018 struct asn1_data *asn1 = asn1_init(NULL); 1019 int size; 1020 1021 NT_STATUS_HAVE_NO_MEMORY(asn1); 1022 1023 asn1->data = blob.data; 1024 asn1->length = blob.length; 1025 asn1_start_tag(asn1, tag); 1026 if (asn1->has_error) { 1027 talloc_free(asn1); 1028 return STATUS_MORE_ENTRIES; 1029 } 1030 size = asn1_tag_remaining(asn1) + asn1->ofs; 1031 1032 talloc_free(asn1); 1033 1034 if (size > blob.length) { 1035 return STATUS_MORE_ENTRIES; 1036 } 1037 1038 *packet_size = size; 1039 return NT_STATUS_OK; 1040 } 1041 1042 NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) 1074 int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) 1043 1075 { 1044 1076 struct asn1_data asn1; … … 1052 1084 ok = asn1_peek_tag_needed_size(&asn1, tag, &size); 1053 1085 if (!ok) { 1054 return NT_STATUS_INVALID_BUFFER_SIZE;1086 return EMSGSIZE; 1055 1087 } 1056 1088 1057 1089 if (size > blob.length) { 1058 1090 *packet_size = size; 1059 return STATUS_MORE_ENTRIES;1091 return EAGAIN; 1060 1092 } 1061 1093 1062 1094 *packet_size = size; 1063 return NT_STATUS_OK;1064 } 1095 return 0; 1096 }
Note:
See TracChangeset
for help on using the changeset viewer.