268 lines
6.7 KiB
Go
268 lines
6.7 KiB
Go
// Copyright 2017 Google Inc. 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 (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"net"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/google/certificate-transparency-go/asn1"
|
|
"github.com/google/certificate-transparency-go/x509/pkix"
|
|
)
|
|
|
|
func TestParseGeneralNames(t *testing.T) {
|
|
var tests = []struct {
|
|
data string // as hex
|
|
want GeneralNames
|
|
wantErr string
|
|
}{
|
|
{
|
|
data: ("3012" +
|
|
("8210" + "7777772e676f6f676c652e636f2e756b")),
|
|
want: GeneralNames{
|
|
DNSNames: []string{"www.google.co.uk"},
|
|
},
|
|
},
|
|
{
|
|
data: ("3024" +
|
|
("8210" + "7777772e676f6f676c652e636f2e756b") +
|
|
("8610" + "7777772e676f6f676c652e636f2e756b")),
|
|
want: GeneralNames{
|
|
DNSNames: []string{"www.google.co.uk"},
|
|
URIs: []string{"www.google.co.uk"},
|
|
},
|
|
},
|
|
{
|
|
data: "0a0101",
|
|
wantErr: "failed to parse GeneralNames sequence",
|
|
},
|
|
{
|
|
data: "0a",
|
|
wantErr: "failed to parse GeneralNames:",
|
|
},
|
|
{
|
|
data: "03000a0101",
|
|
wantErr: "trailing data",
|
|
},
|
|
{
|
|
data: ("3005" + ("8703" + "010203")),
|
|
wantErr: "invalid IP length",
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
inData := fromHex(test.data)
|
|
var got GeneralNames
|
|
err := parseGeneralNames(inData, &got)
|
|
if err != nil {
|
|
if test.wantErr == "" {
|
|
t.Errorf("parseGeneralNames(%s)=%v; want nil", test.data, err)
|
|
} else if !strings.Contains(err.Error(), test.wantErr) {
|
|
t.Errorf("parseGeneralNames(%s)=%v; want %q", test.data, err, test.wantErr)
|
|
}
|
|
continue
|
|
}
|
|
if test.wantErr != "" {
|
|
t.Errorf("parseGeneralNames(%s)=%+v,nil; want %q", test.data, got, test.wantErr)
|
|
continue
|
|
}
|
|
if !reflect.DeepEqual(got, test.want) {
|
|
t.Errorf("parseGeneralNames(%s)=%+v; want %+v", test.data, got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseGeneralName(t *testing.T) {
|
|
var tests = []struct {
|
|
data string // as hex
|
|
withMask bool
|
|
want GeneralNames
|
|
wantErr string
|
|
}{
|
|
{
|
|
data: ("a008" +
|
|
("0603" + "551d0e") + // OID: subject-key-id
|
|
("0a01" + "01")), // enum=1
|
|
want: GeneralNames{
|
|
OtherNames: []OtherName{
|
|
{
|
|
TypeID: OIDExtensionSubjectKeyId,
|
|
Value: asn1.RawValue{
|
|
Class: asn1.ClassUniversal,
|
|
Tag: asn1.TagEnum,
|
|
IsCompound: false,
|
|
Bytes: fromHex("01"),
|
|
FullBytes: fromHex("0a0101"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
data: ("8008" +
|
|
("0603" + "551d0e") + // OID: subject-key-id
|
|
("0a01" + "01")), // enum=1
|
|
wantErr: "not compound",
|
|
},
|
|
{
|
|
data: ("a005" +
|
|
("0603" + "551d0e")), // OID: subject-key-id
|
|
wantErr: "sequence truncated",
|
|
},
|
|
{
|
|
data: ("8110" + "77777740676f6f676c652e636f2e756b"),
|
|
want: GeneralNames{
|
|
EmailAddresses: []string{"www@google.co.uk"},
|
|
},
|
|
},
|
|
{
|
|
data: ("8210" + "7777772e676f6f676c652e636f2e756b"),
|
|
want: GeneralNames{
|
|
DNSNames: []string{"www.google.co.uk"},
|
|
},
|
|
},
|
|
{
|
|
data: ("844b" +
|
|
("3049" +
|
|
("310b" +
|
|
("3009" +
|
|
("0603" + "550406") +
|
|
("1302" + "5553"))) + // "US"
|
|
("3113" +
|
|
("3011" +
|
|
("0603" + "55040a") +
|
|
("130a" + "476f6f676c6520496e63"))) + // "Google Inc"
|
|
("3125" +
|
|
("3023" +
|
|
("0603" + "550403") +
|
|
("131c" + "476f6f676c6520496e7465726e657420417574686f72697479204732"))))), // "GoogleInternet Authority G2"
|
|
want: GeneralNames{
|
|
DirectoryNames: []pkix.Name{
|
|
{
|
|
Country: []string{"US"},
|
|
Organization: []string{"Google Inc"},
|
|
CommonName: "Google Internet Authority G2",
|
|
Names: []pkix.AttributeTypeAndValue{
|
|
{Type: pkix.OIDCountry, Value: "US"},
|
|
{Type: pkix.OIDOrganization, Value: "Google Inc"},
|
|
{Type: pkix.OIDCommonName, Value: "Google Internet Authority G2"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
data: ("8410" + "7777772e676f6f676c652e636f2e756b"),
|
|
wantErr: "failed to unmarshal GeneralNames.directoryName",
|
|
},
|
|
{
|
|
data: ("8610" + "7777772e676f6f676c652e636f2e756b"),
|
|
want: GeneralNames{
|
|
URIs: []string{"www.google.co.uk"},
|
|
},
|
|
},
|
|
{
|
|
data: ("8704" + "01020304"),
|
|
want: GeneralNames{
|
|
IPNets: []net.IPNet{{IP: net.IP{1, 2, 3, 4}}},
|
|
},
|
|
},
|
|
{
|
|
data: ("8708" + "01020304ffffff00"),
|
|
withMask: true,
|
|
want: GeneralNames{
|
|
IPNets: []net.IPNet{{IP: net.IP{1, 2, 3, 4}, Mask: net.IPMask{0xff, 0xff, 0xff, 0x00}}},
|
|
},
|
|
},
|
|
{
|
|
data: ("8710" + "01020304111213142122232431323334"),
|
|
want: GeneralNames{
|
|
IPNets: []net.IPNet{{IP: net.IP{1, 2, 3, 4, 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34}}},
|
|
},
|
|
},
|
|
{
|
|
data: ("8703" + "010203"),
|
|
wantErr: "invalid IP length",
|
|
},
|
|
{
|
|
data: ("8707" + "01020304ffffff"),
|
|
withMask: true,
|
|
wantErr: "invalid IP/mask length",
|
|
},
|
|
{
|
|
data: ("8803" + "551d0e"), // OID: subject-key-id
|
|
want: GeneralNames{
|
|
RegisteredIDs: []asn1.ObjectIdentifier{OIDExtensionSubjectKeyId},
|
|
},
|
|
},
|
|
{
|
|
data: ("8803" + "551d8e"),
|
|
wantErr: "syntax error",
|
|
},
|
|
{
|
|
data: ("9003" + "551d8e"),
|
|
wantErr: "unknown tag",
|
|
},
|
|
{
|
|
data: ("8803"),
|
|
wantErr: "data truncated",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
inData := fromHex(test.data)
|
|
var got GeneralNames
|
|
_, err := parseGeneralName(inData, &got, test.withMask)
|
|
if err != nil {
|
|
if test.wantErr == "" {
|
|
t.Errorf("parseGeneralName(%s)=%v; want nil", test.data, err)
|
|
} else if !strings.Contains(err.Error(), test.wantErr) {
|
|
t.Errorf("parseGeneralName(%s)=%v; want %q", test.data, err, test.wantErr)
|
|
}
|
|
continue
|
|
}
|
|
if test.wantErr != "" {
|
|
t.Errorf("parseGeneralName(%s)=%+v,nil; want %q", test.data, got, test.wantErr)
|
|
continue
|
|
}
|
|
if !reflect.DeepEqual(got, test.want) {
|
|
t.Errorf("parseGeneralName(%s)=%+v; want %+v", test.data, got, test.want)
|
|
}
|
|
if got.Empty() {
|
|
t.Errorf("parseGeneralName(%s).Empty(%+v)=true; want false", test.data, got)
|
|
}
|
|
if gotLen, wantLen := got.Len(), 1; gotLen != wantLen {
|
|
t.Errorf("parseGeneralName(%s).Len(%+v)=%d; want %d", test.data, got, gotLen, wantLen)
|
|
}
|
|
if !bytes.Equal(inData, fromHex(test.data)) {
|
|
t.Errorf("parseGeneralName(%s) modified data to %x", test.data, inData)
|
|
}
|
|
|
|
// Wrap the GeneralName up in a SEQUENCE and check that we get the same result using parseGeneralNames.
|
|
if test.withMask {
|
|
continue
|
|
}
|
|
seqData := append([]byte{0x30, byte(len(inData))}, inData...)
|
|
var gotSeq GeneralNames
|
|
err = parseGeneralNames(seqData, &gotSeq)
|
|
if err != nil {
|
|
t.Errorf("parseGeneralNames(%x)=%v; want nil", seqData, err)
|
|
continue
|
|
}
|
|
if !reflect.DeepEqual(gotSeq, test.want) {
|
|
t.Errorf("parseGeneralNames(%x)=%+v; want %+v", seqData, gotSeq, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func fromHex(s string) []byte {
|
|
d, _ := hex.DecodeString(s)
|
|
return d
|
|
}
|