Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(36)

Delta Between Two Patch Sets: src/pkg/asn1/asn1.go

Issue 157056: asn1: add support for RawContents (Closed)
Left Patch Set: code review 157056: asn1: add support for Raw_ Created 15 years, 4 months ago
Right Patch Set: code review 157056: asn1: add support for RawContent Created 15 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/asn1/asn1_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // The asn1 package implements parsing of DER-encoded ASN.1 data structures, 5 // The asn1 package implements parsing of DER-encoded ASN.1 data structures,
6 // as defined in ITU-T Rec X.690. 6 // as defined in ITU-T Rec X.690.
7 // 7 //
8 // See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,'' 8 // See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,''
9 // http://luca.ntop.org/Teaching/Appunti/asn1.html. 9 // http://luca.ntop.org/Teaching/Appunti/asn1.html.
10 package asn1 10 package asn1
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 return; 342 return;
343 } 343 }
344 344
345 // A RawValue represents an undecoded ASN.1 object. 345 // A RawValue represents an undecoded ASN.1 object.
346 type RawValue struct { 346 type RawValue struct {
347 Class, Tag int; 347 Class, Tag int;
348 IsCompound bool; 348 IsCompound bool;
349 Bytes []byte; 349 Bytes []byte;
350 } 350 }
351 351
352 // RawContent is used to signal that the undecoded, DER data needs to be
353 // preserved for a struct. To use it, the first field of the struct must have
354 // this type. It's an error for any of the other fields to have this type.
355 type RawContent []byte
356
352 // Tagging 357 // Tagging
353 358
354 // parseTagAndLength parses an ASN.1 tag and length pair from the given offset 359 // parseTagAndLength parses an ASN.1 tag and length pair from the given offset
355 // into a byte array. It returns the parsed data and the new offset. SET and 360 // into a byte array. It returns the parsed data and the new offset. SET and
356 // SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we 361 // SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
357 // don't distinguish between ordered and unordered objects in this code. 362 // don't distinguish between ordered and unordered objects in this code.
358 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i nt, err os.Error) { 363 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i nt, err os.Error) {
359 offset = initOffset; 364 offset = initOffset;
360 b := bytes[offset]; 365 b := bytes[offset];
361 offset++; 366 offset++;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 } 458 }
454 } 459 }
455 return; 460 return;
456 } 461 }
457 462
458 var ( 463 var (
459 bitStringType = reflect.Typeof(BitString{}); 464 bitStringType = reflect.Typeof(BitString{});
460 objectIdentifierType = reflect.Typeof(ObjectIdentifier{}); 465 objectIdentifierType = reflect.Typeof(ObjectIdentifier{});
461 timeType = reflect.Typeof(&time.Time{}); 466 timeType = reflect.Typeof(&time.Time{});
462 rawValueType = reflect.Typeof(RawValue{}); 467 rawValueType = reflect.Typeof(RawValue{});
468 rawContentsType = reflect.Typeof(RawContent(nil));
463 ) 469 )
464 470
465 // invalidLength returns true iff offset + length > sliceLength, or if the 471 // invalidLength returns true iff offset + length > sliceLength, or if the
466 // addition would overflow. 472 // addition would overflow.
467 func invalidLength(offset, length, sliceLength int) bool { 473 func invalidLength(offset, length, sliceLength int) bool {
468 return offset+length < offset || offset+length > sliceLength 474 return offset+length < offset || offset+length > sliceLength
469 } 475 }
470 476
471 // parseField is the main parsing function. Given a byte array and an offset 477 // parseField is the main parsing function. Given a byte array and an offset
472 // into the array, it will try to parse a suitable ASN.1 value out and store it 478 // into the array, it will try to parse a suitable ASN.1 value out and store it
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 expectedTag = *params.tag; 593 expectedTag = *params.tag;
588 } 594 }
589 595
590 // We have unwrapped any explicit tagging at this point. 596 // We have unwrapped any explicit tagging at this point.
591 if t.class != expectedClass || t.tag != expectedTag || t.isCompound != c ompoundType { 597 if t.class != expectedClass || t.tag != expectedTag || t.isCompound != c ompoundType {
592 // Tags don't match. Again, it could be an optional element. 598 // Tags don't match. Again, it could be an optional element.
593 ok := setDefaultValue(v, params); 599 ok := setDefaultValue(v, params);
594 if ok { 600 if ok {
595 offset = initOffset 601 offset = initOffset
596 } else { 602 } else {
597 » » » err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s %#v", expectedTag, t, params, fieldType.Name(), bytes[offset:len( bytes)])} 603 » » » err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
598 } 604 }
599 return; 605 return;
600 } 606 }
601 if invalidLength(offset, t.length, len(bytes)) { 607 if invalidLength(offset, t.length, len(bytes)) {
602 err = SyntaxError{"data truncated"}; 608 err = SyntaxError{"data truncated"};
603 return; 609 return;
604 } 610 }
605 innerBytes := bytes[offset : offset+t.length]; 611 innerBytes := bytes[offset : offset+t.length];
606 612
607 // We deal with the structures defined in this package first. 613 // We deal with the structures defined in this package first.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 offset += t.length; 663 offset += t.length;
658 if err1 == nil { 664 if err1 == nil {
659 val.Set(parsedInt) 665 val.Set(parsedInt)
660 } 666 }
661 err = err1; 667 err = err1;
662 return; 668 return;
663 case *reflect.StructValue: 669 case *reflect.StructValue:
664 structType := fieldType.(*reflect.StructType); 670 structType := fieldType.(*reflect.StructType);
665 671
666 if structType.NumField() > 0 && 672 if structType.NumField() > 0 &&
667 » » » structType.Field(0).Name == "Raw_" { 673 » » » structType.Field(0).Type == rawContentsType {
668 bytes := bytes[initOffset : offset+t.length]; 674 bytes := bytes[initOffset : offset+t.length];
669 » » » val.Field(0).SetValue(reflect.NewValue(bytes)); 675 » » » val.Field(0).SetValue(reflect.NewValue(RawContent(bytes) ));
670 } 676 }
671 677
672 innerOffset := 0; 678 innerOffset := 0;
673 for i := 0; i < structType.NumField(); i++ { 679 for i := 0; i < structType.NumField(); i++ {
674 field := structType.Field(i); 680 field := structType.Field(i);
675 » » » if i == 0 && field.Name == "Raw_" { 681 » » » if i == 0 && field.Type == rawContentsType {
676 continue 682 continue
677 } 683 }
678 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag)); 684 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag));
679 if err != nil { 685 if err != nil {
680 return 686 return
681 } 687 }
682 } 688 }
683 offset += t.length; 689 offset += t.length;
684 // We allow extra bytes at the end of the SEQUENCE because 690 // We allow extra bytes at the end of the SEQUENCE because
685 // adding elements to the end has been used in X.509 as the 691 // adding elements to the end has been used in X.509 as the
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 // An ASN.1 SEQUENCE or SET can be written to a struct 772 // An ASN.1 SEQUENCE or SET can be written to a struct
767 // if each of the elements in the sequence can be 773 // if each of the elements in the sequence can be
768 // written to the corresponding element in the struct. 774 // written to the corresponding element in the struct.
769 // 775 //
770 // The following tags on struct fields have special meaning to Unmarshal: 776 // The following tags on struct fields have special meaning to Unmarshal:
771 // 777 //
772 // optional marks the field as ASN.1 OPTIONAL 778 // optional marks the field as ASN.1 OPTIONAL
773 // [explicit] tag:x specifies the ASN.1 tag number; implies ASN.1 CO NTEXT SPECIFIC 779 // [explicit] tag:x specifies the ASN.1 tag number; implies ASN.1 CO NTEXT SPECIFIC
774 // default:x sets the default value for optional integer fiel ds 780 // default:x sets the default value for optional integer fiel ds
775 // 781 //
776 // If the first field of a structure is named Raw_, then it must a byte slice 782 // If the type of the first field of a structure is RawContent then the raw
777 // and the raw ASN1 contents of the struct will be stored in it. 783 // ASN1 contents of the struct will be stored in it.
778 // 784 //
779 // Other ASN.1 types are not supported; if it encounters them, 785 // Other ASN.1 types are not supported; if it encounters them,
780 // Unmarshal returns a parse error. 786 // Unmarshal returns a parse error.
781 func Unmarshal(val interface{}, b []byte) (rest []byte, err os.Error) { 787 func Unmarshal(val interface{}, b []byte) (rest []byte, err os.Error) {
782 v := reflect.NewValue(val).(*reflect.PtrValue).Elem(); 788 v := reflect.NewValue(val).(*reflect.PtrValue).Elem();
783 offset, err := parseField(v, b, 0, fieldParameters{}); 789 offset, err := parseField(v, b, 0, fieldParameters{});
784 if err != nil { 790 if err != nil {
785 return nil, err 791 return nil, err
786 } 792 }
787 return b[offset:len(b)], nil; 793 return b[offset:len(b)], nil;
788 } 794 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b