1
2
3
4
5 package x509
6
7 import (
8 "fmt"
9 "net"
10
11 "github.com/google/certificate-transparency-go/asn1"
12 "github.com/google/certificate-transparency-go/x509/pkix"
13 )
14
15 const (
16
17 tagOtherName = 0
18 tagRFC822Name = 1
19 tagDNSName = 2
20 tagX400Address = 3
21 tagDirectoryName = 4
22 tagEDIPartyName = 5
23 tagURI = 6
24 tagIPAddress = 7
25 tagRegisteredID = 8
26 )
27
28
29
30
31
32
33
34 type OtherName struct {
35 TypeID asn1.ObjectIdentifier
36 Value asn1.RawValue
37 }
38
39
40 type GeneralNames struct {
41 DNSNames []string
42 EmailAddresses []string
43 DirectoryNames []pkix.Name
44 URIs []string
45 IPNets []net.IPNet
46 RegisteredIDs []asn1.ObjectIdentifier
47 OtherNames []OtherName
48 }
49
50
51 func (gn GeneralNames) Len() int {
52 return (len(gn.DNSNames) + len(gn.EmailAddresses) + len(gn.DirectoryNames) +
53 len(gn.URIs) + len(gn.IPNets) + len(gn.RegisteredIDs) + len(gn.OtherNames))
54 }
55
56
57 func (gn GeneralNames) Empty() bool {
58 return gn.Len() == 0
59 }
60
61 func parseGeneralNames(value []byte, gname *GeneralNames) error {
62
63
64
65
66
67
68
69
70
71
72
73
74
75 var seq asn1.RawValue
76 var rest []byte
77 if rest, err := asn1.Unmarshal(value, &seq); err != nil {
78 return fmt.Errorf("x509: failed to parse GeneralNames: %v", err)
79 } else if len(rest) != 0 {
80 return fmt.Errorf("x509: trailing data after GeneralNames")
81 }
82 if !seq.IsCompound || seq.Tag != asn1.TagSequence || seq.Class != asn1.ClassUniversal {
83 return fmt.Errorf("x509: failed to parse GeneralNames sequence, tag %+v", seq)
84 }
85
86 rest = seq.Bytes
87 for len(rest) > 0 {
88 var err error
89 rest, err = parseGeneralName(rest, gname, false)
90 if err != nil {
91 return fmt.Errorf("x509: failed to parse GeneralName: %v", err)
92 }
93 }
94 return nil
95 }
96
97 func parseGeneralName(data []byte, gname *GeneralNames, withMask bool) ([]byte, error) {
98 var v asn1.RawValue
99 var rest []byte
100 var err error
101 rest, err = asn1.Unmarshal(data, &v)
102 if err != nil {
103 return nil, fmt.Errorf("x509: failed to unmarshal GeneralNames: %v", err)
104 }
105 switch v.Tag {
106 case tagOtherName:
107 if !v.IsCompound {
108 return nil, fmt.Errorf("x509: failed to unmarshal GeneralNames.otherName: not compound")
109 }
110 var other OtherName
111 v.FullBytes = append([]byte{}, v.FullBytes...)
112 v.FullBytes[0] = asn1.TagSequence | 0x20
113 _, err = asn1.Unmarshal(v.FullBytes, &other)
114 if err != nil {
115 return nil, fmt.Errorf("x509: failed to unmarshal GeneralNames.otherName: %v", err)
116 }
117 gname.OtherNames = append(gname.OtherNames, other)
118 case tagRFC822Name:
119 gname.EmailAddresses = append(gname.EmailAddresses, string(v.Bytes))
120 case tagDNSName:
121 dns := string(v.Bytes)
122 gname.DNSNames = append(gname.DNSNames, dns)
123 case tagDirectoryName:
124 var rdnSeq pkix.RDNSequence
125 if _, err := asn1.Unmarshal(v.Bytes, &rdnSeq); err != nil {
126 return nil, fmt.Errorf("x509: failed to unmarshal GeneralNames.directoryName: %v", err)
127 }
128 var dirName pkix.Name
129 dirName.FillFromRDNSequence(&rdnSeq)
130 gname.DirectoryNames = append(gname.DirectoryNames, dirName)
131 case tagURI:
132 gname.URIs = append(gname.URIs, string(v.Bytes))
133 case tagIPAddress:
134 vlen := len(v.Bytes)
135 if withMask {
136 switch vlen {
137 case (2 * net.IPv4len), (2 * net.IPv6len):
138 ipNet := net.IPNet{IP: v.Bytes[0 : vlen/2], Mask: v.Bytes[vlen/2:]}
139 gname.IPNets = append(gname.IPNets, ipNet)
140 default:
141 return nil, fmt.Errorf("x509: invalid IP/mask length %d in GeneralNames.iPAddress", vlen)
142 }
143 } else {
144 switch vlen {
145 case net.IPv4len, net.IPv6len:
146 ipNet := net.IPNet{IP: v.Bytes}
147 gname.IPNets = append(gname.IPNets, ipNet)
148 default:
149 return nil, fmt.Errorf("x509: invalid IP length %d in GeneralNames.iPAddress", vlen)
150 }
151 }
152 case tagRegisteredID:
153 var oid asn1.ObjectIdentifier
154 v.FullBytes = append([]byte{}, v.FullBytes...)
155 v.FullBytes[0] = asn1.TagOID
156 _, err = asn1.Unmarshal(v.FullBytes, &oid)
157 if err != nil {
158 return nil, fmt.Errorf("x509: failed to unmarshal GeneralNames.registeredID: %v", err)
159 }
160 gname.RegisteredIDs = append(gname.RegisteredIDs, oid)
161 default:
162 return nil, fmt.Errorf("x509: failed to unmarshal GeneralName: unknown tag %d", v.Tag)
163 }
164 return rest, nil
165 }
166
View as plain text