mirror of
https://github.com/golang/go
synced 2024-11-14 06:10:24 -07:00
crypto/x509: support NumericString in DN components
Fixes #48171 Change-Id: Ia2e1920c0938a1f8659935a4f725a7e5090ef2c0 Reviewed-on: https://go-review.googlesource.com/c/go/+/347034 Trust: Roland Shoemaker <roland@golang.org> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
1ab8273718
commit
896df422a7
@ -51,9 +51,9 @@ func isPrintable(b byte) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parseASN1String parses the ASN.1 string types T61String, PrintableString,
|
// parseASN1String parses the ASN.1 string types T61String, PrintableString,
|
||||||
// UTF8String, BMPString, and IA5String. This is mostly copied from the
|
// UTF8String, BMPString, IA5String, and NumericString. This is mostly copied
|
||||||
// respective encoding/asn1.parse... methods, rather than just increasing
|
// from the respective encoding/asn1.parse... methods, rather than just
|
||||||
// the API surface of that package.
|
// increasing the API surface of that package.
|
||||||
func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
|
func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
|
||||||
switch tag {
|
switch tag {
|
||||||
case cryptobyte_asn1.T61String:
|
case cryptobyte_asn1.T61String:
|
||||||
@ -93,6 +93,13 @@ func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
|
|||||||
return "", errors.New("invalid IA5String")
|
return "", errors.New("invalid IA5String")
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
|
case cryptobyte_asn1.Tag(asn1.TagNumericString):
|
||||||
|
for _, b := range value {
|
||||||
|
if !('0' <= b && b <= '9' || b == ' ') {
|
||||||
|
return "", errors.New("invalid NumericString")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(value), nil
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("unsupported string type: %v", tag)
|
return "", fmt.Errorf("unsupported string type: %v", tag)
|
||||||
}
|
}
|
||||||
|
102
src/crypto/x509/parser_test.go
Normal file
102
src/crypto/x509/parser_test.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
package x509
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/asn1"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseASN1String(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
tag cryptobyte_asn1.Tag
|
||||||
|
value []byte
|
||||||
|
expected string
|
||||||
|
expectedErr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "T61String",
|
||||||
|
tag: cryptobyte_asn1.T61String,
|
||||||
|
value: []byte{80, 81, 82},
|
||||||
|
expected: string("PQR"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PrintableString",
|
||||||
|
tag: cryptobyte_asn1.PrintableString,
|
||||||
|
value: []byte{80, 81, 82},
|
||||||
|
expected: string("PQR"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PrintableString (invalid)",
|
||||||
|
tag: cryptobyte_asn1.PrintableString,
|
||||||
|
value: []byte{1, 2, 3},
|
||||||
|
expectedErr: "invalid PrintableString",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "UTF8String",
|
||||||
|
tag: cryptobyte_asn1.UTF8String,
|
||||||
|
value: []byte{80, 81, 82},
|
||||||
|
expected: string("PQR"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "UTF8String (invalid)",
|
||||||
|
tag: cryptobyte_asn1.UTF8String,
|
||||||
|
value: []byte{255},
|
||||||
|
expectedErr: "invalid UTF-8 string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "BMPString",
|
||||||
|
tag: cryptobyte_asn1.Tag(asn1.TagBMPString),
|
||||||
|
value: []byte{80, 81},
|
||||||
|
expected: string("偑"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "BMPString (invalid length)",
|
||||||
|
tag: cryptobyte_asn1.Tag(asn1.TagBMPString),
|
||||||
|
value: []byte{255},
|
||||||
|
expectedErr: "invalid BMPString",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IA5String",
|
||||||
|
tag: cryptobyte_asn1.IA5String,
|
||||||
|
value: []byte{80, 81},
|
||||||
|
expected: string("PQ"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IA5String (invalid)",
|
||||||
|
tag: cryptobyte_asn1.IA5String,
|
||||||
|
value: []byte{255},
|
||||||
|
expectedErr: "invalid IA5String",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "NumericString",
|
||||||
|
tag: cryptobyte_asn1.Tag(asn1.TagNumericString),
|
||||||
|
value: []byte{49, 50},
|
||||||
|
expected: string("12"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "NumericString (invalid)",
|
||||||
|
tag: cryptobyte_asn1.Tag(asn1.TagNumericString),
|
||||||
|
value: []byte{80},
|
||||||
|
expectedErr: "invalid NumericString",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
out, err := parseASN1String(tc.tag, tc.value)
|
||||||
|
if err != nil && err.Error() != tc.expectedErr {
|
||||||
|
t.Fatalf("parseASN1String returned unexpected error: got %q, want %q", err, tc.expectedErr)
|
||||||
|
} else if err == nil && tc.expectedErr != "" {
|
||||||
|
t.Fatalf("parseASN1String didn't fail, expected: %s", tc.expectedErr)
|
||||||
|
}
|
||||||
|
if out != tc.expected {
|
||||||
|
t.Fatalf("parseASN1String returned unexpected value: got %q, want %q", out, tc.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user