SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: commonName,
- Organization: []string{"Acme Co"},
+ Organization: []string{"Σ Acme Co"},
},
NotBefore: time.Unix(1000, 0),
NotAfter: time.Unix(100000, 0),
ret.stringType = tagIA5String
case part == "printable":
ret.stringType = tagPrintableString
+ case part == "utf8":
+ ret.stringType = tagUTF8String
case strings.HasPrefix(part, "default:"):
i, err := strconv.ParseInt(part[8:], 10, 64)
if err == nil {
import (
"bytes"
+ "errors"
"fmt"
"io"
"math/big"
"reflect"
"time"
+ "unicode/utf8"
)
// A forkableWriter is an in-memory buffer that can be
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 {
}
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
}
}
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 {
{testSET([]int{10}), "310302010a"},
{omitEmptyTest{[]string{}}, "3000"},
{omitEmptyTest{[]string{"1"}}, "30053003130131"},
+ {"Σ", "0c02cea3"},
}
func TestMarshal(t *testing.T) {
}
}
}
+
+func TestInvalidUTF8(t *testing.T) {
+ _, err := Marshal(string([]byte{0xff, 0xff}))
+ if err == nil {
+ t.Errorf("invalid UTF8 string was accepted")
+ }
+}