github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/fix/testdata/reflect.asn1.go.out (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // The asn1 package implements parsing of DER-encoded ASN.1 data structures, 6 // as defined in ITU-T Rec X.690. 7 // 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. 10 package asn1 11 12 // ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc 13 // are different encoding formats for those objects. Here, we'll be dealing 14 // with DER, the Distinguished Encoding Rules. DER is used in X.509 because 15 // it's fast to parse and, unlike BER, has a unique encoding for every object. 16 // When calculating hashes over objects, it's important that the resulting 17 // bytes be the same at both ends and DER removes this margin of error. 18 // 19 // ASN.1 is very complex and this package doesn't attempt to implement 20 // everything by any means. 21 22 import ( 23 "fmt" 24 "os" 25 "reflect" 26 "time" 27 ) 28 29 // A StructuralError suggests that the ASN.1 data is valid, but the Go type 30 // which is receiving it doesn't match. 31 type StructuralError struct { 32 Msg string 33 } 34 35 func (e StructuralError) String() string { return "ASN.1 structure error: " + e.Msg } 36 37 // A SyntaxError suggests that the ASN.1 data is invalid. 38 type SyntaxError struct { 39 Msg string 40 } 41 42 func (e SyntaxError) String() string { return "ASN.1 syntax error: " + e.Msg } 43 44 // We start by dealing with each of the primitive types in turn. 45 46 // BOOLEAN 47 48 func parseBool(bytes []byte) (ret bool, err os.Error) { 49 if len(bytes) != 1 { 50 err = SyntaxError{"invalid boolean"} 51 return 52 } 53 54 return bytes[0] != 0, nil 55 } 56 57 // INTEGER 58 59 // parseInt64 treats the given bytes as a big-endian, signed integer and 60 // returns the result. 61 func parseInt64(bytes []byte) (ret int64, err os.Error) { 62 if len(bytes) > 8 { 63 // We'll overflow an int64 in this case. 64 err = StructuralError{"integer too large"} 65 return 66 } 67 for bytesRead := 0; bytesRead < len(bytes); bytesRead++ { 68 ret <<= 8 69 ret |= int64(bytes[bytesRead]) 70 } 71 72 // Shift up and down in order to sign extend the result. 73 ret <<= 64 - uint8(len(bytes))*8 74 ret >>= 64 - uint8(len(bytes))*8 75 return 76 } 77 78 // parseInt treats the given bytes as a big-endian, signed integer and returns 79 // the result. 80 func parseInt(bytes []byte) (int, os.Error) { 81 ret64, err := parseInt64(bytes) 82 if err != nil { 83 return 0, err 84 } 85 if ret64 != int64(int(ret64)) { 86 return 0, StructuralError{"integer too large"} 87 } 88 return int(ret64), nil 89 } 90 91 // BIT STRING 92 93 // BitString is the structure to use when you want an ASN.1 BIT STRING type. A 94 // bit string is padded up to the nearest byte in memory and the number of 95 // valid bits is recorded. Padding bits will be zero. 96 type BitString struct { 97 Bytes []byte // bits packed into bytes. 98 BitLength int // length in bits. 99 } 100 101 // At returns the bit at the given index. If the index is out of range it 102 // returns false. 103 func (b BitString) At(i int) int { 104 if i < 0 || i >= b.BitLength { 105 return 0 106 } 107 x := i / 8 108 y := 7 - uint(i%8) 109 return int(b.Bytes[x]>>y) & 1 110 } 111 112 // RightAlign returns a slice where the padding bits are at the beginning. The 113 // slice may share memory with the BitString. 114 func (b BitString) RightAlign() []byte { 115 shift := uint(8 - (b.BitLength % 8)) 116 if shift == 8 || len(b.Bytes) == 0 { 117 return b.Bytes 118 } 119 120 a := make([]byte, len(b.Bytes)) 121 a[0] = b.Bytes[0] >> shift 122 for i := 1; i < len(b.Bytes); i++ { 123 a[i] = b.Bytes[i-1] << (8 - shift) 124 a[i] |= b.Bytes[i] >> shift 125 } 126 127 return a 128 } 129 130 // parseBitString parses an ASN.1 bit string from the given byte array and returns it. 131 func parseBitString(bytes []byte) (ret BitString, err os.Error) { 132 if len(bytes) == 0 { 133 err = SyntaxError{"zero length BIT STRING"} 134 return 135 } 136 paddingBits := int(bytes[0]) 137 if paddingBits > 7 || 138 len(bytes) == 1 && paddingBits > 0 || 139 bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 { 140 err = SyntaxError{"invalid padding bits in BIT STRING"} 141 return 142 } 143 ret.BitLength = (len(bytes)-1)*8 - paddingBits 144 ret.Bytes = bytes[1:] 145 return 146 } 147 148 // OBJECT IDENTIFIER 149 150 // An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER. 151 type ObjectIdentifier []int 152 153 // Equal returns true iff oi and other represent the same identifier. 154 func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool { 155 if len(oi) != len(other) { 156 return false 157 } 158 for i := 0; i < len(oi); i++ { 159 if oi[i] != other[i] { 160 return false 161 } 162 } 163 164 return true 165 } 166 167 // parseObjectIdentifier parses an OBJECT IDENTIFER from the given bytes and 168 // returns it. An object identifer is a sequence of variable length integers 169 // that are assigned in a hierarachy. 170 func parseObjectIdentifier(bytes []byte) (s []int, err os.Error) { 171 if len(bytes) == 0 { 172 err = SyntaxError{"zero length OBJECT IDENTIFIER"} 173 return 174 } 175 176 // In the worst case, we get two elements from the first byte (which is 177 // encoded differently) and then every varint is a single byte long. 178 s = make([]int, len(bytes)+1) 179 180 // The first byte is 40*value1 + value2: 181 s[0] = int(bytes[0]) / 40 182 s[1] = int(bytes[0]) % 40 183 i := 2 184 for offset := 1; offset < len(bytes); i++ { 185 var v int 186 v, offset, err = parseBase128Int(bytes, offset) 187 if err != nil { 188 return 189 } 190 s[i] = v 191 } 192 s = s[0:i] 193 return 194 } 195 196 // ENUMERATED 197 198 // An Enumerated is represented as a plain int. 199 type Enumerated int 200 201 // FLAG 202 203 // A Flag accepts any data and is set to true if present. 204 type Flag bool 205 206 // parseBase128Int parses a base-128 encoded int from the given offset in the 207 // given byte array. It returns the value and the new offset. 208 func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err os.Error) { 209 offset = initOffset 210 for shifted := 0; offset < len(bytes); shifted++ { 211 if shifted > 4 { 212 err = StructuralError{"base 128 integer too large"} 213 return 214 } 215 ret <<= 7 216 b := bytes[offset] 217 ret |= int(b & 0x7f) 218 offset++ 219 if b&0x80 == 0 { 220 return 221 } 222 } 223 err = SyntaxError{"truncated base 128 integer"} 224 return 225 } 226 227 // UTCTime 228 229 func parseUTCTime(bytes []byte) (ret *time.Time, err os.Error) { 230 s := string(bytes) 231 ret, err = time.Parse("0601021504Z0700", s) 232 if err == nil { 233 return 234 } 235 ret, err = time.Parse("060102150405Z0700", s) 236 return 237 } 238 239 // parseGeneralizedTime parses the GeneralizedTime from the given byte array 240 // and returns the resulting time. 241 func parseGeneralizedTime(bytes []byte) (ret *time.Time, err os.Error) { 242 return time.Parse("20060102150405Z0700", string(bytes)) 243 } 244 245 // PrintableString 246 247 // parsePrintableString parses a ASN.1 PrintableString from the given byte 248 // array and returns it. 249 func parsePrintableString(bytes []byte) (ret string, err os.Error) { 250 for _, b := range bytes { 251 if !isPrintable(b) { 252 err = SyntaxError{"PrintableString contains invalid character"} 253 return 254 } 255 } 256 ret = string(bytes) 257 return 258 } 259 260 // isPrintable returns true iff the given b is in the ASN.1 PrintableString set. 261 func isPrintable(b byte) bool { 262 return 'a' <= b && b <= 'z' || 263 'A' <= b && b <= 'Z' || 264 '0' <= b && b <= '9' || 265 '\'' <= b && b <= ')' || 266 '+' <= b && b <= '/' || 267 b == ' ' || 268 b == ':' || 269 b == '=' || 270 b == '?' || 271 // This is techincally not allowed in a PrintableString. 272 // However, x509 certificates with wildcard strings don't 273 // always use the correct string type so we permit it. 274 b == '*' 275 } 276 277 // IA5String 278 279 // parseIA5String parses a ASN.1 IA5String (ASCII string) from the given 280 // byte array and returns it. 281 func parseIA5String(bytes []byte) (ret string, err os.Error) { 282 for _, b := range bytes { 283 if b >= 0x80 { 284 err = SyntaxError{"IA5String contains invalid character"} 285 return 286 } 287 } 288 ret = string(bytes) 289 return 290 } 291 292 // T61String 293 294 // parseT61String parses a ASN.1 T61String (8-bit clean string) from the given 295 // byte array and returns it. 296 func parseT61String(bytes []byte) (ret string, err os.Error) { 297 return string(bytes), nil 298 } 299 300 // A RawValue represents an undecoded ASN.1 object. 301 type RawValue struct { 302 Class, Tag int 303 IsCompound bool 304 Bytes []byte 305 FullBytes []byte // includes the tag and length 306 } 307 308 // RawContent is used to signal that the undecoded, DER data needs to be 309 // preserved for a struct. To use it, the first field of the struct must have 310 // this type. It's an error for any of the other fields to have this type. 311 type RawContent []byte 312 313 // Tagging 314 315 // parseTagAndLength parses an ASN.1 tag and length pair from the given offset 316 // into a byte array. It returns the parsed data and the new offset. SET and 317 // SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we 318 // don't distinguish between ordered and unordered objects in this code. 319 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err os.Error) { 320 offset = initOffset 321 b := bytes[offset] 322 offset++ 323 ret.class = int(b >> 6) 324 ret.isCompound = b&0x20 == 0x20 325 ret.tag = int(b & 0x1f) 326 327 // If the bottom five bits are set, then the tag number is actually base 128 328 // encoded afterwards 329 if ret.tag == 0x1f { 330 ret.tag, offset, err = parseBase128Int(bytes, offset) 331 if err != nil { 332 return 333 } 334 } 335 if offset >= len(bytes) { 336 err = SyntaxError{"truncated tag or length"} 337 return 338 } 339 b = bytes[offset] 340 offset++ 341 if b&0x80 == 0 { 342 // The length is encoded in the bottom 7 bits. 343 ret.length = int(b & 0x7f) 344 } else { 345 // Bottom 7 bits give the number of length bytes to follow. 346 numBytes := int(b & 0x7f) 347 // We risk overflowing a signed 32-bit number if we accept more than 3 bytes. 348 if numBytes > 3 { 349 err = StructuralError{"length too large"} 350 return 351 } 352 if numBytes == 0 { 353 err = SyntaxError{"indefinite length found (not DER)"} 354 return 355 } 356 ret.length = 0 357 for i := 0; i < numBytes; i++ { 358 if offset >= len(bytes) { 359 err = SyntaxError{"truncated tag or length"} 360 return 361 } 362 b = bytes[offset] 363 offset++ 364 ret.length <<= 8 365 ret.length |= int(b) 366 } 367 } 368 369 return 370 } 371 372 // parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse 373 // a number of ASN.1 values from the given byte array and returns them as a 374 // slice of Go values of the given type. 375 func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err os.Error) { 376 expectedTag, compoundType, ok := getUniversalType(elemType) 377 if !ok { 378 err = StructuralError{"unknown Go type for slice"} 379 return 380 } 381 382 // First we iterate over the input and count the number of elements, 383 // checking that the types are correct in each case. 384 numElements := 0 385 for offset := 0; offset < len(bytes); { 386 var t tagAndLength 387 t, offset, err = parseTagAndLength(bytes, offset) 388 if err != nil { 389 return 390 } 391 // We pretend that GENERAL STRINGs are PRINTABLE STRINGs so 392 // that a sequence of them can be parsed into a []string. 393 if t.tag == tagGeneralString { 394 t.tag = tagPrintableString 395 } 396 if t.class != classUniversal || t.isCompound != compoundType || t.tag != expectedTag { 397 err = StructuralError{"sequence tag mismatch"} 398 return 399 } 400 if invalidLength(offset, t.length, len(bytes)) { 401 err = SyntaxError{"truncated sequence"} 402 return 403 } 404 offset += t.length 405 numElements++ 406 } 407 ret = reflect.MakeSlice(sliceType, numElements, numElements) 408 params := fieldParameters{} 409 offset := 0 410 for i := 0; i < numElements; i++ { 411 offset, err = parseField(ret.Index(i), bytes, offset, params) 412 if err != nil { 413 return 414 } 415 } 416 return 417 } 418 419 var ( 420 bitStringType = reflect.TypeOf(BitString{}) 421 objectIdentifierType = reflect.TypeOf(ObjectIdentifier{}) 422 enumeratedType = reflect.TypeOf(Enumerated(0)) 423 flagType = reflect.TypeOf(Flag(false)) 424 timeType = reflect.TypeOf(&time.Time{}) 425 rawValueType = reflect.TypeOf(RawValue{}) 426 rawContentsType = reflect.TypeOf(RawContent(nil)) 427 ) 428 429 // invalidLength returns true iff offset + length > sliceLength, or if the 430 // addition would overflow. 431 func invalidLength(offset, length, sliceLength int) bool { 432 return offset+length < offset || offset+length > sliceLength 433 } 434 435 // parseField is the main parsing function. Given a byte array and an offset 436 // into the array, it will try to parse a suitable ASN.1 value out and store it 437 // in the given Value. 438 func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err os.Error) { 439 offset = initOffset 440 fieldType := v.Type() 441 442 // If we have run out of data, it may be that there are optional elements at the end. 443 if offset == len(bytes) { 444 if !setDefaultValue(v, params) { 445 err = SyntaxError{"sequence truncated"} 446 } 447 return 448 } 449 450 // Deal with raw values. 451 if fieldType == rawValueType { 452 var t tagAndLength 453 t, offset, err = parseTagAndLength(bytes, offset) 454 if err != nil { 455 return 456 } 457 if invalidLength(offset, t.length, len(bytes)) { 458 err = SyntaxError{"data truncated"} 459 return 460 } 461 result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]} 462 offset += t.length 463 v.Set(reflect.ValueOf(result)) 464 return 465 } 466 467 // Deal with the ANY type. 468 if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 { 469 ifaceValue := v 470 var t tagAndLength 471 t, offset, err = parseTagAndLength(bytes, offset) 472 if err != nil { 473 return 474 } 475 if invalidLength(offset, t.length, len(bytes)) { 476 err = SyntaxError{"data truncated"} 477 return 478 } 479 var result interface{} 480 if !t.isCompound && t.class == classUniversal { 481 innerBytes := bytes[offset : offset+t.length] 482 switch t.tag { 483 case tagPrintableString: 484 result, err = parsePrintableString(innerBytes) 485 case tagIA5String: 486 result, err = parseIA5String(innerBytes) 487 case tagT61String: 488 result, err = parseT61String(innerBytes) 489 case tagInteger: 490 result, err = parseInt64(innerBytes) 491 case tagBitString: 492 result, err = parseBitString(innerBytes) 493 case tagOID: 494 result, err = parseObjectIdentifier(innerBytes) 495 case tagUTCTime: 496 result, err = parseUTCTime(innerBytes) 497 case tagOctetString: 498 result = innerBytes 499 default: 500 // If we don't know how to handle the type, we just leave Value as nil. 501 } 502 } 503 offset += t.length 504 if err != nil { 505 return 506 } 507 if result != nil { 508 ifaceValue.Set(reflect.ValueOf(result)) 509 } 510 return 511 } 512 universalTag, compoundType, ok1 := getUniversalType(fieldType) 513 if !ok1 { 514 err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)} 515 return 516 } 517 518 t, offset, err := parseTagAndLength(bytes, offset) 519 if err != nil { 520 return 521 } 522 if params.explicit { 523 expectedClass := classContextSpecific 524 if params.application { 525 expectedClass = classApplication 526 } 527 if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) { 528 if t.length > 0 { 529 t, offset, err = parseTagAndLength(bytes, offset) 530 if err != nil { 531 return 532 } 533 } else { 534 if fieldType != flagType { 535 err = StructuralError{"Zero length explicit tag was not an asn1.Flag"} 536 return 537 } 538 539 flagValue := v 540 flagValue.SetBool(true) 541 return 542 } 543 } else { 544 // The tags didn't match, it might be an optional element. 545 ok := setDefaultValue(v, params) 546 if ok { 547 offset = initOffset 548 } else { 549 err = StructuralError{"explicitly tagged member didn't match"} 550 } 551 return 552 } 553 } 554 555 // Special case for strings: PrintableString and IA5String both map to 556 // the Go type string. getUniversalType returns the tag for 557 // PrintableString when it sees a string so, if we see an IA5String on 558 // the wire, we change the universal type to match. 559 if universalTag == tagPrintableString && t.tag == tagIA5String { 560 universalTag = tagIA5String 561 } 562 // Likewise for GeneralString 563 if universalTag == tagPrintableString && t.tag == tagGeneralString { 564 universalTag = tagGeneralString 565 } 566 567 // Special case for time: UTCTime and GeneralizedTime both map to the 568 // Go type time.Time. 569 if universalTag == tagUTCTime && t.tag == tagGeneralizedTime { 570 universalTag = tagGeneralizedTime 571 } 572 573 expectedClass := classUniversal 574 expectedTag := universalTag 575 576 if !params.explicit && params.tag != nil { 577 expectedClass = classContextSpecific 578 expectedTag = *params.tag 579 } 580 581 if !params.explicit && params.application && params.tag != nil { 582 expectedClass = classApplication 583 expectedTag = *params.tag 584 } 585 586 // We have unwrapped any explicit tagging at this point. 587 if t.class != expectedClass || t.tag != expectedTag || t.isCompound != compoundType { 588 // Tags don't match. Again, it could be an optional element. 589 ok := setDefaultValue(v, params) 590 if ok { 591 offset = initOffset 592 } else { 593 err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)} 594 } 595 return 596 } 597 if invalidLength(offset, t.length, len(bytes)) { 598 err = SyntaxError{"data truncated"} 599 return 600 } 601 innerBytes := bytes[offset : offset+t.length] 602 offset += t.length 603 604 // We deal with the structures defined in this package first. 605 switch fieldType { 606 case objectIdentifierType: 607 newSlice, err1 := parseObjectIdentifier(innerBytes) 608 sliceValue := v 609 sliceValue.Set(reflect.MakeSlice(sliceValue.Type(), len(newSlice), len(newSlice))) 610 if err1 == nil { 611 reflect.Copy(sliceValue, reflect.ValueOf(newSlice)) 612 } 613 err = err1 614 return 615 case bitStringType: 616 structValue := v 617 bs, err1 := parseBitString(innerBytes) 618 if err1 == nil { 619 structValue.Set(reflect.ValueOf(bs)) 620 } 621 err = err1 622 return 623 case timeType: 624 ptrValue := v 625 var time *time.Time 626 var err1 os.Error 627 if universalTag == tagUTCTime { 628 time, err1 = parseUTCTime(innerBytes) 629 } else { 630 time, err1 = parseGeneralizedTime(innerBytes) 631 } 632 if err1 == nil { 633 ptrValue.Set(reflect.ValueOf(time)) 634 } 635 err = err1 636 return 637 case enumeratedType: 638 parsedInt, err1 := parseInt(innerBytes) 639 enumValue := v 640 if err1 == nil { 641 enumValue.SetInt(int64(parsedInt)) 642 } 643 err = err1 644 return 645 case flagType: 646 flagValue := v 647 flagValue.SetBool(true) 648 return 649 } 650 switch val := v; val.Kind() { 651 case reflect.Bool: 652 parsedBool, err1 := parseBool(innerBytes) 653 if err1 == nil { 654 val.SetBool(parsedBool) 655 } 656 err = err1 657 return 658 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 659 switch val.Type().Kind() { 660 case reflect.Int: 661 parsedInt, err1 := parseInt(innerBytes) 662 if err1 == nil { 663 val.SetInt(int64(parsedInt)) 664 } 665 err = err1 666 return 667 case reflect.Int64: 668 parsedInt, err1 := parseInt64(innerBytes) 669 if err1 == nil { 670 val.SetInt(parsedInt) 671 } 672 err = err1 673 return 674 } 675 case reflect.Struct: 676 structType := fieldType 677 678 if structType.NumField() > 0 && 679 structType.Field(0).Type == rawContentsType { 680 bytes := bytes[initOffset:offset] 681 val.Field(0).Set(reflect.ValueOf(RawContent(bytes))) 682 } 683 684 innerOffset := 0 685 for i := 0; i < structType.NumField(); i++ { 686 field := structType.Field(i) 687 if i == 0 && field.Type == rawContentsType { 688 continue 689 } 690 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag)) 691 if err != nil { 692 return 693 } 694 } 695 // We allow extra bytes at the end of the SEQUENCE because 696 // adding elements to the end has been used in X.509 as the 697 // version numbers have increased. 698 return 699 case reflect.Slice: 700 sliceType := fieldType 701 if sliceType.Elem().Kind() == reflect.Uint8 { 702 val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes))) 703 reflect.Copy(val, reflect.ValueOf(innerBytes)) 704 return 705 } 706 newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem()) 707 if err1 == nil { 708 val.Set(newSlice) 709 } 710 err = err1 711 return 712 case reflect.String: 713 var v string 714 switch universalTag { 715 case tagPrintableString: 716 v, err = parsePrintableString(innerBytes) 717 case tagIA5String: 718 v, err = parseIA5String(innerBytes) 719 case tagT61String: 720 v, err = parseT61String(innerBytes) 721 case tagGeneralString: 722 // GeneralString is specified in ISO-2022/ECMA-35, 723 // A brief review suggests that it includes structures 724 // that allow the encoding to change midstring and 725 // such. We give up and pass it as an 8-bit string. 726 v, err = parseT61String(innerBytes) 727 default: 728 err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)} 729 } 730 if err == nil { 731 val.SetString(v) 732 } 733 return 734 } 735 err = StructuralError{"unknown Go type"} 736 return 737 } 738 739 // setDefaultValue is used to install a default value, from a tag string, into 740 // a Value. It is successful is the field was optional, even if a default value 741 // wasn't provided or it failed to install it into the Value. 742 func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) { 743 if !params.optional { 744 return 745 } 746 ok = true 747 if params.defaultValue == nil { 748 return 749 } 750 switch val := v; val.Kind() { 751 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 752 val.SetInt(*params.defaultValue) 753 } 754 return 755 } 756 757 // Unmarshal parses the DER-encoded ASN.1 data structure b 758 // and uses the reflect package to fill in an arbitrary value pointed at by val. 759 // Because Unmarshal uses the reflect package, the structs 760 // being written to must use upper case field names. 761 // 762 // An ASN.1 INTEGER can be written to an int or int64. 763 // If the encoded value does not fit in the Go type, 764 // Unmarshal returns a parse error. 765 // 766 // An ASN.1 BIT STRING can be written to a BitString. 767 // 768 // An ASN.1 OCTET STRING can be written to a []byte. 769 // 770 // An ASN.1 OBJECT IDENTIFIER can be written to an 771 // ObjectIdentifier. 772 // 773 // An ASN.1 ENUMERATED can be written to an Enumerated. 774 // 775 // An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a *time.Time. 776 // 777 // An ASN.1 PrintableString or IA5String can be written to a string. 778 // 779 // Any of the above ASN.1 values can be written to an interface{}. 780 // The value stored in the interface has the corresponding Go type. 781 // For integers, that type is int64. 782 // 783 // An ASN.1 SEQUENCE OF x or SET OF x can be written 784 // to a slice if an x can be written to the slice's element type. 785 // 786 // An ASN.1 SEQUENCE or SET can be written to a struct 787 // if each of the elements in the sequence can be 788 // written to the corresponding element in the struct. 789 // 790 // The following tags on struct fields have special meaning to Unmarshal: 791 // 792 // optional marks the field as ASN.1 OPTIONAL 793 // [explicit] tag:x specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC 794 // default:x sets the default value for optional integer fields 795 // 796 // If the type of the first field of a structure is RawContent then the raw 797 // ASN1 contents of the struct will be stored in it. 798 // 799 // Other ASN.1 types are not supported; if it encounters them, 800 // Unmarshal returns a parse error. 801 func Unmarshal(b []byte, val interface{}) (rest []byte, err os.Error) { 802 return UnmarshalWithParams(b, val, "") 803 } 804 805 // UnmarshalWithParams allows field parameters to be specified for the 806 // top-level element. The form of the params is the same as the field tags. 807 func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err os.Error) { 808 v := reflect.ValueOf(val).Elem() 809 offset, err := parseField(v, b, 0, parseFieldParameters(params)) 810 if err != nil { 811 return nil, err 812 } 813 return b[offset:], nil 814 }