summaryrefslogtreecommitdiff
path: root/src/pkg/encoding/asn1/marshal.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/encoding/asn1/marshal.go')
-rw-r--r--src/pkg/encoding/asn1/marshal.go43
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 {