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

Side by Side Diff: src/pkg/asn1/asn1.go

Issue 157056: asn1: add support for RawContents (Closed)
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:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/pkg/asn1/asn1_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 case *reflect.Int64Value: 661 case *reflect.Int64Value:
656 parsedInt, err1 := parseInt64(innerBytes); 662 parsedInt, err1 := parseInt64(innerBytes);
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);
671
672 if structType.NumField() > 0 &&
673 structType.Field(0).Type == rawContentsType {
674 bytes := bytes[initOffset : offset+t.length];
675 val.Field(0).SetValue(reflect.NewValue(RawContent(bytes) ));
676 }
677
665 innerOffset := 0; 678 innerOffset := 0;
666 for i := 0; i < structType.NumField(); i++ { 679 for i := 0; i < structType.NumField(); i++ {
667 field := structType.Field(i); 680 field := structType.Field(i);
681 if i == 0 && field.Type == rawContentsType {
682 continue
683 }
668 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag)); 684 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag));
669 if err != nil { 685 if err != nil {
670 return 686 return
671 } 687 }
672 } 688 }
673 offset += t.length; 689 offset += t.length;
674 // We allow extra bytes at the end of the SEQUENCE because 690 // We allow extra bytes at the end of the SEQUENCE because
675 // 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
676 // version numbers have increased. 692 // version numbers have increased.
677 return; 693 return;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 // 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
757 // if each of the elements in the sequence can be 773 // if each of the elements in the sequence can be
758 // written to the corresponding element in the struct. 774 // written to the corresponding element in the struct.
759 // 775 //
760 // The following tags on struct fields have special meaning to Unmarshal: 776 // The following tags on struct fields have special meaning to Unmarshal:
761 // 777 //
762 // optional marks the field as ASN.1 OPTIONAL 778 // optional marks the field as ASN.1 OPTIONAL
763 // [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
764 // default:x sets the default value for optional integer fiel ds 780 // default:x sets the default value for optional integer fiel ds
765 // 781 //
782 // If the type of the first field of a structure is RawContent then the raw
783 // ASN1 contents of the struct will be stored in it.
784 //
766 // Other ASN.1 types are not supported; if it encounters them, 785 // Other ASN.1 types are not supported; if it encounters them,
767 // Unmarshal returns a parse error. 786 // Unmarshal returns a parse error.
768 func Unmarshal(val interface{}, b []byte) (rest []byte, err os.Error) { 787 func Unmarshal(val interface{}, b []byte) (rest []byte, err os.Error) {
769 v := reflect.NewValue(val).(*reflect.PtrValue).Elem(); 788 v := reflect.NewValue(val).(*reflect.PtrValue).Elem();
770 offset, err := parseField(v, b, 0, fieldParameters{}); 789 offset, err := parseField(v, b, 0, fieldParameters{});
771 if err != nil { 790 if err != nil {
772 return nil, err 791 return nil, err
773 } 792 }
774 return b[offset:len(b)], nil; 793 return b[offset:len(b)], nil;
775 } 794 }
OLDNEW
« no previous file with comments | « no previous file | src/pkg/asn1/asn1_test.go » ('j') | no next file with comments »

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