Changeset 740 for vendor/current/lib/util/asn1.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/util/asn1.c
r597 r740 215 215 } 216 216 217 bool ber_write_OID_String( DATA_BLOB *blob, const char *OID)218 { 219 u int_t v, v2;217 bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID) 218 { 219 unsigned int v, v2; 220 220 const char *p = (const char *)OID; 221 221 char *newp; 222 222 int i; 223 223 224 if (!isdigit(*p)) return false; 224 225 v = strtoul(p, &newp, 10); 225 226 if (newp[0] != '.') return false; 226 227 p = newp + 1; 227 228 229 if (!isdigit(*p)) return false; 228 230 v2 = strtoul(p, &newp, 10); 229 231 if (newp[0] != '.') return false; … … 231 233 232 234 /*the ber representation can't use more space then the string one */ 233 *blob = data_blob (NULL, strlen(OID));235 *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID)); 234 236 if (!blob->data) return false; 235 237 … … 238 240 i = 1; 239 241 while (*p) { 242 if (!isdigit(*p)) return false; 240 243 v = strtoul(p, &newp, 10); 241 244 if (newp[0] == '.') { 242 245 p = newp + 1; 246 /* check for empty last component */ 247 if (!*p) return false; 243 248 } else if (newp[0] == '\0') { 244 249 p = newp; … … 259 264 } 260 265 266 /** 267 * Serialize partial OID string. 268 * Partial OIDs are in the form: 269 * 1:2.5.6:0x81 270 * 1:2.5.6:0x8182 271 */ 272 bool ber_write_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *partial_oid) 273 { 274 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 275 char *oid = talloc_strdup(tmp_ctx, partial_oid); 276 char *p; 277 278 /* truncate partial part so ber_write_OID_String() works */ 279 p = strchr(oid, ':'); 280 if (p) { 281 *p = '\0'; 282 p++; 283 } 284 285 if (!ber_write_OID_String(mem_ctx, blob, oid)) { 286 talloc_free(tmp_ctx); 287 return false; 288 } 289 290 /* Add partially encoded sub-identifier */ 291 if (p) { 292 DATA_BLOB tmp_blob = strhex_to_data_blob(tmp_ctx, p); 293 if (!data_blob_append(mem_ctx, blob, tmp_blob.data, 294 tmp_blob.length)) { 295 talloc_free(tmp_ctx); 296 return false; 297 } 298 } 299 300 talloc_free(tmp_ctx); 301 302 return true; 303 } 304 261 305 /* write an object ID to a ASN1 buffer */ 262 306 bool asn1_write_OID(struct asn1_data *data, const char *OID) … … 266 310 if (!asn1_push_tag(data, ASN1_OID)) return false; 267 311 268 if (!ber_write_OID_String( &blob, OID)) {312 if (!ber_write_OID_String(NULL, &blob, OID)) { 269 313 data->has_error = true; 270 314 return false; … … 453 497 454 498 return (b == tag); 499 } 500 501 /* 502 * just get the needed size the tag would consume 503 */ 504 bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag, size_t *size) 505 { 506 off_t start_ofs = data->ofs; 507 uint8_t b; 508 size_t taglen = 0; 509 510 if (data->has_error) { 511 return false; 512 } 513 514 if (!asn1_read_uint8(data, &b)) { 515 data->ofs = start_ofs; 516 data->has_error = false; 517 return false; 518 } 519 520 if (b != tag) { 521 data->ofs = start_ofs; 522 data->has_error = false; 523 return false; 524 } 525 526 if (!asn1_read_uint8(data, &b)) { 527 data->ofs = start_ofs; 528 data->has_error = false; 529 return false; 530 } 531 532 if (b & 0x80) { 533 int n = b & 0x7f; 534 if (!asn1_read_uint8(data, &b)) { 535 data->ofs = start_ofs; 536 data->has_error = false; 537 return false; 538 } 539 if (n > 4) { 540 /* 541 * We should not allow more than 4 bytes 542 * for the encoding of the tag length. 543 * 544 * Otherwise we'd overflow the taglen 545 * variable on 32 bit systems. 546 */ 547 data->ofs = start_ofs; 548 data->has_error = false; 549 return false; 550 } 551 taglen = b; 552 while (n > 1) { 553 if (!asn1_read_uint8(data, &b)) { 554 data->ofs = start_ofs; 555 data->has_error = false; 556 return false; 557 } 558 taglen = (taglen << 8) | b; 559 n--; 560 } 561 } else { 562 taglen = b; 563 } 564 565 *size = (data->ofs - start_ofs) + taglen; 566 567 data->ofs = start_ofs; 568 data->has_error = false; 569 return true; 455 570 } 456 571 … … 544 659 } 545 660 546 /* read an object ID from a data blob */ 547 bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) 661 /** 662 * Internal implementation for reading binary OIDs 663 * Reading is done as far in the buffer as valid OID 664 * till buffer ends or not valid sub-identifier is found. 665 */ 666 static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob, 667 char **OID, size_t *bytes_eaten) 548 668 { 549 669 int i; 550 670 uint8_t *b; 551 u int_t v;671 unsigned int v; 552 672 char *tmp_oid = NULL; 553 673 … … 560 680 tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", b[0]%40); 561 681 if (!tmp_oid) goto nomem; 682 683 if (bytes_eaten != NULL) { 684 *bytes_eaten = 0; 685 } 562 686 563 687 for(i = 1, v = 0; i < blob.length; i++) { … … 566 690 tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v); 567 691 v = 0; 692 if (bytes_eaten) 693 *bytes_eaten = i+1; 568 694 } 569 695 if (!tmp_oid) goto nomem; 570 696 } 571 697 572 if (v != 0) {573 talloc_free(tmp_oid);574 return false;575 }576 577 698 *OID = tmp_oid; 578 699 return true; 579 700 580 nomem: 701 nomem: 581 702 return false; 582 703 } 583 704 705 /* read an object ID from a data blob */ 706 bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **OID) 707 { 708 size_t bytes_eaten; 709 710 if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten)) 711 return false; 712 713 return (bytes_eaten == blob.length); 714 } 715 716 /** 717 * Deserialize partial OID string. 718 * Partial OIDs are in the form: 719 * 1:2.5.6:0x81 720 * 1:2.5.6:0x8182 721 */ 722 bool ber_read_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, 723 char **partial_oid) 724 { 725 size_t bytes_left; 726 size_t bytes_eaten; 727 char *identifier = NULL; 728 char *tmp_oid = NULL; 729 730 if (!_ber_read_OID_String_impl(mem_ctx, blob, &tmp_oid, &bytes_eaten)) 731 return false; 732 733 if (bytes_eaten < blob.length) { 734 bytes_left = blob.length - bytes_eaten; 735 identifier = hex_encode_talloc(mem_ctx, &blob.data[bytes_eaten], bytes_left); 736 if (!identifier) goto nomem; 737 738 *partial_oid = talloc_asprintf_append_buffer(tmp_oid, ":0x%s", identifier); 739 if (!*partial_oid) goto nomem; 740 TALLOC_FREE(identifier); 741 } else { 742 *partial_oid = tmp_oid; 743 } 744 745 return true; 746 747 nomem: 748 TALLOC_FREE(identifier); 749 TALLOC_FREE(tmp_oid); 750 return false; 751 } 752 584 753 /* read an object ID from a ASN1 buffer */ 585 bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, c onst char **OID)754 bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **OID) 586 755 { 587 756 DATA_BLOB blob; … … 622 791 bool asn1_check_OID(struct asn1_data *data, const char *OID) 623 792 { 624 c onst char *id;793 char *id; 625 794 626 795 if (!asn1_read_OID(data, data, &id)) return false; 627 796 628 797 if (strcmp(id, OID) != 0) { 629 talloc_free( discard_const(id));630 data->has_error = true; 631 return false; 632 } 633 talloc_free( discard_const(id));798 talloc_free(id); 799 data->has_error = true; 800 return false; 801 } 802 talloc_free(id); 634 803 return true; 635 804 } … … 865 1034 if (size > blob.length) { 866 1035 return STATUS_MORE_ENTRIES; 867 } 1036 } 868 1037 869 1038 *packet_size = size; 870 1039 return NT_STATUS_OK; 871 1040 } 1041 1042 NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size) 1043 { 1044 struct asn1_data asn1; 1045 size_t size; 1046 bool ok; 1047 1048 ZERO_STRUCT(asn1); 1049 asn1.data = blob.data; 1050 asn1.length = blob.length; 1051 1052 ok = asn1_peek_tag_needed_size(&asn1, tag, &size); 1053 if (!ok) { 1054 return NT_STATUS_INVALID_BUFFER_SIZE; 1055 } 1056 1057 if (size > blob.length) { 1058 *packet_size = size; 1059 return STATUS_MORE_ENTRIES; 1060 } 1061 1062 *packet_size = size; 1063 return NT_STATUS_OK; 1064 }
Note:
See TracChangeset
for help on using the changeset viewer.