diff --git a/x509util/extensions.go b/x509util/extensions.go index 6e649902..61fd0a97 100644 --- a/x509util/extensions.go +++ b/x509util/extensions.go @@ -495,8 +495,8 @@ func parseFieldParameters(str string) (p asn1Params) { p.Type = part params = append(params, part) // types that are parsed from the string. - // int and oid are not a type that can be set in a tag. - case "int", "oid": + // int, oid, and bool are not a type that can be set in a tag. + case "int", "oid", "bool", "boolean": p.Type = part // types parsed from the string as a time case "utc", "generalized": @@ -574,6 +574,12 @@ func marshalValue(value, params string) ([]byte, error) { } } return asn1.MarshalWithParams(t, p.Params) + case "bool", "boolean": + b, err := strconv.ParseBool(value) + if err != nil { + return nil, errors.Wrap(err, "invalid bool value") + } + return asn1.MarshalWithParams(b, p.Params) default: // if it's an unknown type, default to printable if !isPrintableString(value, true, true) { return nil, fmt.Errorf("invalid printable value") diff --git a/x509util/extensions_test.go b/x509util/extensions_test.go index b2b8d0be..0e364bca 100644 --- a/x509util/extensions_test.go +++ b/x509util/extensions_test.go @@ -370,6 +370,12 @@ func TestSubjectAlternativeName_RawValue(t *testing.T) { {"otherName whitespaces", fields{"1.2.3.4", ",,printable:abc1234", nil}, asn1.RawValue{ FullBytes: append([]byte{160, 16, 6, 3, 42, 3, 4, 160, 9, 19, 7}, []byte("abc1234")...), }, false}, + {"otherName bool:true", fields{"1.2.3.4", "bool:true", nil}, asn1.RawValue{ + FullBytes: []byte{160, 10, 6, 3, 42, 3, 4, 160, 3, 1, 1, 255}, + }, false}, + {"otherName boolean:false", fields{"1.2.3.4", "boolean:false", nil}, asn1.RawValue{ + FullBytes: []byte{160, 10, 6, 3, 42, 3, 4, 160, 3, 1, 1, 0}, + }, false}, {"fail dn", fields{"dn", "1234", nil}, asn1.RawValue{}, true}, {"fail x400Address", fields{"x400Address", "1234", nil}, asn1.RawValue{}, true}, {"fail ediPartyName", fields{"ediPartyName", "1234", nil}, asn1.RawValue{}, true}, diff --git a/x509util/options_test.go b/x509util/options_test.go index c7b6dc06..067d1322 100644 --- a/x509util/options_test.go +++ b/x509util/options_test.go @@ -79,7 +79,7 @@ func TestWithTemplate(t *testing.T) { {"id": "1.2.3.4", "value": {{ asn1Enc (first .Insecure.CR.DNSNames) | toJson }}}, {"id": "1.2.3.5", "value": {{ asn1Marshal (first .Insecure.CR.DNSNames) | toJson }}}, {"id": "1.2.3.6", "value": {{ asn1Seq (asn1Enc (first .Insecure.CR.DNSNames)) (asn1Enc "int:123456") | toJson }}}, - {"id": "1.2.3.7", "value": {{ asn1Set (asn1Marshal (first .Insecure.CR.DNSNames) "utf8") (asn1Enc "int:123456") | toJson }}} + {"id": "1.2.3.7", "value": {{ asn1Set (asn1Marshal (first .Insecure.CR.DNSNames) "utf8") (asn1Enc "bool:true") | toJson }}} ] }` @@ -181,7 +181,7 @@ func TestWithTemplate(t *testing.T) { {"id": "1.2.3.4", "value": "Ewdmb28uY29t"}, {"id": "1.2.3.5", "value": "Ewdmb28uY29t"}, {"id": "1.2.3.6", "value": "MA4TB2Zvby5jb20CAwHiQA=="}, - {"id": "1.2.3.7", "value": "MQ4MB2Zvby5jb20CAwHiQA=="} + {"id": "1.2.3.7", "value": "MQwMB2Zvby5jb20BAf8="} ] }`), }, false}, @@ -340,9 +340,11 @@ func Test_asn1Encode(t *testing.T) { {"ok generalized", args{"generalized:" + now.Format(time.RFC3339)}, mustMarshal(t, now, "generalized"), false}, {"ok int", args{"int:1234"}, mustMarshal(t, 1234, ""), false}, {"ok numeric", args{"numeric:1234"}, mustMarshal(t, "1234", "numeric"), false}, + {"ok bool", args{"bool:true"}, mustMarshal(t, true, ""), false}, {"ok raw", args{"raw:" + mustMarshal(t, 1234, "")}, mustMarshal(t, 1234, ""), false}, {"fail numeric", args{"numeric:not-a-number"}, "", true}, {"fail time", args{"utc:not-a-time"}, "", true}, + {"fail bool", args{"bool:untrue"}, "", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -375,6 +377,7 @@ func Test_asn1Marshal(t *testing.T) { {"ok time", args{now, nil}, mustMarshal(t, now, "utc"), false}, {"ok seq", args{[]any{"string", 1234}, nil}, mustMarshal(t, []any{"string", 1234}, ""), false}, {"ok set", args{[]any{"string", 1234}, []string{"set"}}, mustMarshal(t, []any{"string", 1234}, "set"), false}, + {"ok bool", args{false, nil}, mustMarshal(t, false, ""), false}, {"fail numeric", args{"string", []string{"numeric"}}, "", true}, } for _, tt := range tests {