diff options
Diffstat (limited to 'src/pkg/encoding/asn1/marshal.go')
| -rw-r--r-- | src/pkg/encoding/asn1/marshal.go | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/src/pkg/encoding/asn1/marshal.go b/src/pkg/encoding/asn1/marshal.go index 163bca575..0c216fdb3 100644 --- a/src/pkg/encoding/asn1/marshal.go +++ b/src/pkg/encoding/asn1/marshal.go @@ -6,11 +6,13 @@ package asn1 import ( "bytes" + "errors" "fmt" "io" "math/big" "reflect" "time" + "unicode/utf8" ) // A forkableWriter is an in-memory buffer that can be @@ -280,6 +282,11 @@ func marshalIA5String(out *forkableWriter, s string) (err error) { return } +func marshalUTF8String(out *forkableWriter, s string) (err error) { + _, err = out.Write([]byte(s)) + return +} + func marshalTwoDigits(out *forkableWriter, v int) (err error) { err = out.WriteByte(byte('0' + (v/10)%10)) if err != nil { @@ -289,8 +296,7 @@ func marshalTwoDigits(out *forkableWriter, v int) (err error) { } func marshalUTCTime(out *forkableWriter, t time.Time) (err error) { - utc := t.UTC() - year, month, day := utc.Date() + year, month, day := t.Date() switch { case 1950 <= year && year < 2000: @@ -314,7 +320,7 @@ func marshalUTCTime(out *forkableWriter, t time.Time) (err error) { return } - hour, min, sec := utc.Clock() + hour, min, sec := t.Clock() err = marshalTwoDigits(out, hour) if err != nil { @@ -446,10 +452,13 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter } return case reflect.String: - if params.stringType == tagIA5String { + switch params.stringType { + case tagIA5String: return marshalIA5String(out, v.String()) - } else { + case tagPrintableString: return marshalPrintableString(out, v.String()) + default: + return marshalUTF8String(out, v.String()) } return } @@ -492,11 +501,27 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) } class := classUniversal - if params.stringType != 0 { - if tag != tagPrintableString { - return StructuralError{"Explicit string type given to non-string member"} + if params.stringType != 0 && tag != tagPrintableString { + return StructuralError{"Explicit string type given to non-string member"} + } + + if tag == tagPrintableString { + if params.stringType == 0 { + // This is a string without an explicit string type. We'll use + // a PrintableString if the character set in the string is + // sufficiently limited, otherwise we'll use a UTF8String. + for _, r := range v.String() { + if r >= utf8.RuneSelf || !isPrintable(byte(r)) { + if !utf8.ValidString(v.String()) { + return errors.New("asn1: string not valid UTF-8") + } + tag = tagUTF8String + break + } + } + } else { + tag = params.stringType } - tag = params.stringType } if params.set { |
