1
2
3
4
5
6
7
8
9
10 package asn1
11
12
13
14
15
16
17
18
19
20
21
22 import (
23 "big"
24 "fmt"
25 "os"
26 "reflect"
27 "time"
28 )
29
30
31
32 type StructuralError struct {
33 Msg string
34 }
35
36 func (e StructuralError) String() string { return "ASN.1 structure error: " + e.Msg }
37
38
39 type SyntaxError struct {
40 Msg string
41 }
42
43 func (e SyntaxError) String() string { return "ASN.1 syntax error: " + e.Msg }
44
45
46
47
48
49 func parseBool(bytes []byte) (ret bool, err os.Error) {
50 if len(bytes) != 1 {
51 err = SyntaxError{"invalid boolean"}
52 return
53 }
54
55 return bytes[0] != 0, nil
56 }
57
58
59
60
61
62 func parseInt64(bytes []byte) (ret int64, err os.Error) {
63 if len(bytes) > 8 {
64
65 err = StructuralError{"integer too large"}
66 return
67 }
68 for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
69 ret <<= 8
70 ret |= int64(bytes[bytesRead])
71 }
72
73
74 ret <<= 64 - uint8(len(bytes))*8
75 ret >>= 64 - uint8(len(bytes))*8
76 return
77 }
78
79
80
81 func parseInt(bytes []byte) (int, os.Error) {
82 ret64, err := parseInt64(bytes)
83 if err != nil {
84 return 0, err
85 }
86 if ret64 != int64(int(ret64)) {
87 return 0, StructuralError{"integer too large"}
88 }
89 return int(ret64), nil
90 }
91
92 var bigOne = big.NewInt(1)
93
94
95
96 func parseBigInt(bytes []byte) *big.Int {
97 ret := new(big.Int)
98 if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
99
100 notBytes := make([]byte, len(bytes))
101 for i := range notBytes {
102 notBytes[i] = ^bytes[i]
103 }
104 ret.SetBytes(notBytes)
105 ret.Add(ret, bigOne)
106 ret.Neg(ret)
107 return ret
108 }
109 ret.SetBytes(bytes)
110 return ret
111 }
112
113
114
115
116
117
118 type BitString struct {
119 Bytes []byte
120 BitLength int
121 }
122
123
124
125 func (b BitString) At(i int) int {
126 if i < 0 || i >= b.BitLength {
127 return 0
128 }
129 x := i / 8
130 y := 7 - uint(i%8)
131 return int(b.Bytes[x]>>y) & 1
132 }
133
134
135
136 func (b BitString) RightAlign() []byte {
137 shift := uint(8 - (b.BitLength % 8))
138 if shift == 8 || len(b.Bytes) == 0 {
139 return b.Bytes
140 }
141
142 a := make([]byte, len(b.Bytes))
143 a[0] = b.Bytes[0] >> shift
144 for i := 1; i < len(b.Bytes); i++ {
145 a[i] = b.Bytes[i-1] << (8 - shift)
146 a[i] |= b.Bytes[i] >> shift
147 }
148
149 return a
150 }
151
152
153 func parseBitString(bytes []byte) (ret BitString, err os.Error) {
154 if len(bytes) == 0 {
155 err = SyntaxError{"zero length BIT STRING"}
156 return
157 }
158 paddingBits := int(bytes[0])
159 if paddingBits > 7 ||
160 len(bytes) == 1 && paddingBits > 0 ||
161 bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
162 err = SyntaxError{"invalid padding bits in BIT STRING"}
163 return
164 }
165 ret.BitLength = (len(bytes)-1)*8 - paddingBits
166 ret.Bytes = bytes[1:]
167 return
168 }
169
170
171
172
173 type ObjectIdentifier []int
174
175
176 func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
177 if len(oi) != len(other) {
178 return false
179 }
180 for i := 0; i < len(oi); i++ {
181 if oi[i] != other[i] {
182 return false
183 }
184 }
185
186 return true
187 }
188
189
190
191
192 func parseObjectIdentifier(bytes []byte) (s []int, err os.Error) {
193 if len(bytes) == 0 {
194 err = SyntaxError{"zero length OBJECT IDENTIFIER"}
195 return
196 }
197
198
199
200 s = make([]int, len(bytes)+1)
201
202
203 s[0] = int(bytes[0]) / 40
204 s[1] = int(bytes[0]) % 40
205 i := 2
206 for offset := 1; offset < len(bytes); i++ {
207 var v int
208 v, offset, err = parseBase128Int(bytes, offset)
209 if err != nil {
210 return
211 }
212 s[i] = v
213 }
214 s = s[0:i]
215 return
216 }
217
218
219
220
221 type Enumerated int
222
223
224
225
226 type Flag bool
227
228
229
230 func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err os.Error) {
231 offset = initOffset
232 for shifted := 0; offset < len(bytes); shifted++ {
233 if shifted > 4 {
234 err = StructuralError{"base 128 integer too large"}
235 return
236 }
237 ret <<= 7
238 b := bytes[offset]
239 ret |= int(b & 0x7f)
240 offset++
241 if b&0x80 == 0 {
242 return
243 }
244 }
245 err = SyntaxError{"truncated base 128 integer"}
246 return
247 }
248
249
250
251 func parseUTCTime(bytes []byte) (ret *time.Time, err os.Error) {
252 s := string(bytes)
253 ret, err = time.Parse("0601021504Z0700", s)
254 if err == nil {
255 return
256 }
257 ret, err = time.Parse("060102150405Z0700", s)
258 return
259 }
260
261
262
263 func parseGeneralizedTime(bytes []byte) (ret *time.Time, err os.Error) {
264 return time.Parse("20060102150405Z0700", string(bytes))
265 }
266
267
268
269
270
271 func parsePrintableString(bytes []byte) (ret string, err os.Error) {
272 for _, b := range bytes {
273 if !isPrintable(b) {
274 err = SyntaxError{"PrintableString contains invalid character"}
275 return
276 }
277 }
278 ret = string(bytes)
279 return
280 }
281
282
283 func isPrintable(b byte) bool {
284 return 'a' <= b && b <= 'z' ||
285 'A' <= b && b <= 'Z' ||
286 '0' <= b && b <= '9' ||
287 '\'' <= b && b <= ')' ||
288 '+' <= b && b <= '/' ||
289 b == ' ' ||
290 b == ':' ||
291 b == '=' ||
292 b == '?' ||
293
294
295
296 b == '*'
297 }
298
299
300
301
302
303 func parseIA5String(bytes []byte) (ret string, err os.Error) {
304 for _, b := range bytes {
305 if b >= 0x80 {
306 err = SyntaxError{"IA5String contains invalid character"}
307 return
308 }
309 }
310 ret = string(bytes)
311 return
312 }
313
314
315
316
317
318 func parseT61String(bytes []byte) (ret string, err os.Error) {
319 return string(bytes), nil
320 }
321
322
323
324
325
326 func parseUTF8String(bytes []byte) (ret string, err os.Error) {
327 return string(bytes), nil
328 }
329
330
331 type RawValue struct {
332 Class, Tag int
333 IsCompound bool
334 Bytes []byte
335 FullBytes []byte
336 }
337
338
339
340
341 type RawContent []byte
342
343
344
345
346
347
348
349 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err os.Error) {
350 offset = initOffset
351 b := bytes[offset]
352 offset++
353 ret.class = int(b >> 6)
354 ret.isCompound = b&0x20 == 0x20
355 ret.tag = int(b & 0x1f)
356
357
358
359 if ret.tag == 0x1f {
360 ret.tag, offset, err = parseBase128Int(bytes, offset)
361 if err != nil {
362 return
363 }
364 }
365 if offset >= len(bytes) {
366 err = SyntaxError{"truncated tag or length"}
367 return
368 }
369 b = bytes[offset]
370 offset++
371 if b&0x80 == 0 {
372
373 ret.length = int(b & 0x7f)
374 } else {
375
376 numBytes := int(b & 0x7f)
377
378 if numBytes > 3 {
379 err = StructuralError{"length too large"}
380 return
381 }
382 if numBytes == 0 {
383 err = SyntaxError{"indefinite length found (not DER)"}
384 return
385 }
386 ret.length = 0
387 for i := 0; i < numBytes; i++ {
388 if offset >= len(bytes) {
389 err = SyntaxError{"truncated tag or length"}
390 return
391 }
392 b = bytes[offset]
393 offset++
394 ret.length <<= 8
395 ret.length |= int(b)
396 }
397 }
398
399 return
400 }
401
402
403
404
405 func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err os.Error) {
406 expectedTag, compoundType, ok := getUniversalType(elemType)
407 if !ok {
408 err = StructuralError{"unknown Go type for slice"}
409 return
410 }
411
412
413
414 numElements := 0
415 for offset := 0; offset < len(bytes); {
416 var t tagAndLength
417 t, offset, err = parseTagAndLength(bytes, offset)
418 if err != nil {
419 return
420 }
421
422
423 if t.tag == tagGeneralString {
424 t.tag = tagPrintableString
425 }
426 if t.class != classUniversal || t.isCompound != compoundType || t.tag != expectedTag {
427 err = StructuralError{"sequence tag mismatch"}
428 return
429 }
430 if invalidLength(offset, t.length, len(bytes)) {
431 err = SyntaxError{"truncated sequence"}
432 return
433 }
434 offset += t.length
435 numElements++
436 }
437 ret = reflect.MakeSlice(sliceType, numElements, numElements)
438 params := fieldParameters{}
439 offset := 0
440 for i := 0; i < numElements; i++ {
441 offset, err = parseField(ret.Index(i), bytes, offset, params)
442 if err != nil {
443 return
444 }
445 }
446 return
447 }
448
449 var (
450 bitStringType = reflect.TypeOf(BitString{})
451 objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
452 enumeratedType = reflect.TypeOf(Enumerated(0))
453 flagType = reflect.TypeOf(Flag(false))
454 timeType = reflect.TypeOf(&time.Time{})
455 rawValueType = reflect.TypeOf(RawValue{})
456 rawContentsType = reflect.TypeOf(RawContent(nil))
457 bigIntType = reflect.TypeOf(new(big.Int))
458 )
459
460
461
462 func invalidLength(offset, length, sliceLength int) bool {
463 return offset+length < offset || offset+length > sliceLength
464 }
465
466
467
468
469 func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err os.Error) {
470 offset = initOffset
471 fieldType := v.Type()
472
473
474 if offset == len(bytes) {
475 if !setDefaultValue(v, params) {
476 err = SyntaxError{"sequence truncated"}
477 }
478 return
479 }
480
481
482 if fieldType == rawValueType {
483 var t tagAndLength
484 t, offset, err = parseTagAndLength(bytes, offset)
485 if err != nil {
486 return
487 }
488 if invalidLength(offset, t.length, len(bytes)) {
489 err = SyntaxError{"data truncated"}
490 return
491 }
492 result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]}
493 offset += t.length
494 v.Set(reflect.ValueOf(result))
495 return
496 }
497
498
499 if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
500 var t tagAndLength
501 t, offset, err = parseTagAndLength(bytes, offset)
502 if err != nil {
503 return
504 }
505 if invalidLength(offset, t.length, len(bytes)) {
506 err = SyntaxError{"data truncated"}
507 return
508 }
509 var result interface{}
510 if !t.isCompound && t.class == classUniversal {
511 innerBytes := bytes[offset : offset+t.length]
512 switch t.tag {
513 case tagPrintableString:
514 result, err = parsePrintableString(innerBytes)
515 case tagIA5String:
516 result, err = parseIA5String(innerBytes)
517 case tagT61String:
518 result, err = parseT61String(innerBytes)
519 case tagInteger:
520 result, err = parseInt64(innerBytes)
521 case tagBitString:
522 result, err = parseBitString(innerBytes)
523 case tagOID:
524 result, err = parseObjectIdentifier(innerBytes)
525 case tagUTCTime:
526 result, err = parseUTCTime(innerBytes)
527 case tagOctetString:
528 result = innerBytes
529 default:
530
531 }
532 }
533 offset += t.length
534 if err != nil {
535 return
536 }
537 if result != nil {
538 v.Set(reflect.ValueOf(result))
539 }
540 return
541 }
542 universalTag, compoundType, ok1 := getUniversalType(fieldType)
543 if !ok1 {
544 err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
545 return
546 }
547
548 t, offset, err := parseTagAndLength(bytes, offset)
549 if err != nil {
550 return
551 }
552 if params.explicit {
553 expectedClass := classContextSpecific
554 if params.application {
555 expectedClass = classApplication
556 }
557 if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
558 if t.length > 0 {
559 t, offset, err = parseTagAndLength(bytes, offset)
560 if err != nil {
561 return
562 }
563 } else {
564 if fieldType != flagType {
565 err = StructuralError{"Zero length explicit tag was not an asn1.Flag"}
566 return
567 }
568 v.SetBool(true)
569 return
570 }
571 } else {
572
573 ok := setDefaultValue(v, params)
574 if ok {
575 offset = initOffset
576 } else {
577 err = StructuralError{"explicitly tagged member didn't match"}
578 }
579 return
580 }
581 }
582
583
584
585
586
587 if universalTag == tagPrintableString {
588 switch t.tag {
589 case tagIA5String, tagGeneralString, tagT61String, tagUTF8String:
590 universalTag = t.tag
591 }
592 }
593
594
595
596 if universalTag == tagUTCTime && t.tag == tagGeneralizedTime {
597 universalTag = tagGeneralizedTime
598 }
599
600 expectedClass := classUniversal
601 expectedTag := universalTag
602
603 if !params.explicit && params.tag != nil {
604 expectedClass = classContextSpecific
605 expectedTag = *params.tag
606 }
607
608 if !params.explicit && params.application && params.tag != nil {
609 expectedClass = classApplication
610 expectedTag = *params.tag
611 }
612
613
614 if t.class != expectedClass || t.tag != expectedTag || t.isCompound != compoundType {
615
616 ok := setDefaultValue(v, params)
617 if ok {
618 offset = initOffset
619 } else {
620 err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
621 }
622 return
623 }
624 if invalidLength(offset, t.length, len(bytes)) {
625 err = SyntaxError{"data truncated"}
626 return
627 }
628 innerBytes := bytes[offset : offset+t.length]
629 offset += t.length
630
631
632 switch fieldType {
633 case objectIdentifierType:
634 newSlice, err1 := parseObjectIdentifier(innerBytes)
635 v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
636 if err1 == nil {
637 reflect.Copy(v, reflect.ValueOf(newSlice))
638 }
639 err = err1
640 return
641 case bitStringType:
642 bs, err1 := parseBitString(innerBytes)
643 if err1 == nil {
644 v.Set(reflect.ValueOf(bs))
645 }
646 err = err1
647 return
648 case timeType:
649 var time *time.Time
650 var err1 os.Error
651 if universalTag == tagUTCTime {
652 time, err1 = parseUTCTime(innerBytes)
653 } else {
654 time, err1 = parseGeneralizedTime(innerBytes)
655 }
656 if err1 == nil {
657 v.Set(reflect.ValueOf(time))
658 }
659 err = err1
660 return
661 case enumeratedType:
662 parsedInt, err1 := parseInt(innerBytes)
663 if err1 == nil {
664 v.SetInt(int64(parsedInt))
665 }
666 err = err1
667 return
668 case flagType:
669 v.SetBool(true)
670 return
671 case bigIntType:
672 parsedInt := parseBigInt(innerBytes)
673 v.Set(reflect.ValueOf(parsedInt))
674 return
675 }
676 switch val := v; val.Kind() {
677 case reflect.Bool:
678 parsedBool, err1 := parseBool(innerBytes)
679 if err1 == nil {
680 val.SetBool(parsedBool)
681 }
682 err = err1
683 return
684 case reflect.Int, reflect.Int32:
685 parsedInt, err1 := parseInt(innerBytes)
686 if err1 == nil {
687 val.SetInt(int64(parsedInt))
688 }
689 err = err1
690 return
691 case reflect.Int64:
692 parsedInt, err1 := parseInt64(innerBytes)
693 if err1 == nil {
694 val.SetInt(parsedInt)
695 }
696 err = err1
697 return
698
699 case reflect.Struct:
700 structType := fieldType
701
702 if structType.NumField() > 0 &&
703 structType.Field(0).Type == rawContentsType {
704 bytes := bytes[initOffset:offset]
705 val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
706 }
707
708 innerOffset := 0
709 for i := 0; i < structType.NumField(); i++ {
710 field := structType.Field(i)
711 if i == 0 && field.Type == rawContentsType {
712 continue
713 }
714 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
715 if err != nil {
716 return
717 }
718 }
719
720
721
722 return
723 case reflect.Slice:
724 sliceType := fieldType
725 if sliceType.Elem().Kind() == reflect.Uint8 {
726 val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
727 reflect.Copy(val, reflect.ValueOf(innerBytes))
728 return
729 }
730 newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
731 if err1 == nil {
732 val.Set(newSlice)
733 }
734 err = err1
735 return
736 case reflect.String:
737 var v string
738 switch universalTag {
739 case tagPrintableString:
740 v, err = parsePrintableString(innerBytes)
741 case tagIA5String:
742 v, err = parseIA5String(innerBytes)
743 case tagT61String:
744 v, err = parseT61String(innerBytes)
745 case tagUTF8String:
746 v, err = parseUTF8String(innerBytes)
747 case tagGeneralString:
748
749
750
751
752 v, err = parseT61String(innerBytes)
753 default:
754 err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
755 }
756 if err == nil {
757 val.SetString(v)
758 }
759 return
760 }
761 err = StructuralError{"unsupported: " + v.Type().String()}
762 return
763 }
764
765
766
767
768 func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
769 if !params.optional {
770 return
771 }
772 ok = true
773 if params.defaultValue == nil {
774 return
775 }
776 switch val := v; val.Kind() {
777 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
778 val.SetInt(*params.defaultValue)
779 }
780 return
781 }
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827 func Unmarshal(b []byte, val interface{}) (rest []byte, err os.Error) {
828 return UnmarshalWithParams(b, val, "")
829 }
830
831
832
833 func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err os.Error) {
834 v := reflect.ValueOf(val).Elem()
835 offset, err := parseField(v, b, 0, parseFieldParameters(params))
836 if err != nil {
837 return nil, err
838 }
839 return b[offset:], nil
840 }