1
2
3
4
5 package x509
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "errors"
11 "fmt"
12
13 "github.com/google/certificate-transparency-go/asn1"
14 )
15
16
17
18 type IPAddressPrefix asn1.BitString
19
20
21 type IPAddressRange struct {
22 Min IPAddressPrefix
23 Max IPAddressPrefix
24 }
25
26
27
28 const (
29 IPv4AddressFamilyIndicator = uint16(1)
30 IPv6AddressFamilyIndicator = uint16(2)
31 )
32
33
34 type IPAddressFamilyBlocks struct {
35
36
37 AFI uint16
38
39
40 SAFI byte
41
42
43 InheritFromIssuer bool
44
45 AddressPrefixes []IPAddressPrefix
46
47 AddressRanges []IPAddressRange
48 }
49
50
51 type ipAddressFamily struct {
52 AddressFamily []byte
53 Choice asn1.RawValue
54 }
55
56
57
58 type ipAddressRange struct {
59 Min asn1.BitString
60 Max asn1.BitString
61 }
62
63 func parseRPKIAddrBlocks(data []byte, nfe *NonFatalErrors) []*IPAddressFamilyBlocks {
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 var addrBlocks []ipAddressFamily
86 if rest, err := asn1.Unmarshal(data, &addrBlocks); err != nil {
87 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks extension: %v", err))
88 return nil
89 } else if len(rest) != 0 {
90 nfe.AddError(errors.New("trailing data after ipAddrBlocks extension"))
91 return nil
92 }
93
94 var results []*IPAddressFamilyBlocks
95 for i, block := range addrBlocks {
96 var fam IPAddressFamilyBlocks
97 if l := len(block.AddressFamily); l < 2 || l > 3 {
98 nfe.AddError(fmt.Errorf("invalid address family length (%d) for ipAddrBlock.addressFamily", l))
99 continue
100 }
101 fam.AFI = binary.BigEndian.Uint16(block.AddressFamily[0:2])
102 if len(block.AddressFamily) > 2 {
103 fam.SAFI = block.AddressFamily[2]
104 }
105
106
107 if bytes.Equal(block.Choice.FullBytes, asn1.NullBytes) {
108 fam.InheritFromIssuer = true
109 results = append(results, &fam)
110 continue
111 }
112
113 var addrRanges []asn1.RawValue
114 if _, err := asn1.Unmarshal(block.Choice.FullBytes, &addrRanges); err != nil {
115 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges: %v", i, err))
116 continue
117 }
118 for j, ar := range addrRanges {
119
120
121 switch ar.Tag {
122 case asn1.TagBitString:
123
124 var val asn1.BitString
125 if _, err := asn1.Unmarshal(ar.FullBytes, &val); err != nil {
126 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d].addressPrefix: %v", i, j, err))
127 continue
128 }
129 fam.AddressPrefixes = append(fam.AddressPrefixes, IPAddressPrefix(val))
130
131 case asn1.TagSequence:
132 var val ipAddressRange
133 if _, err := asn1.Unmarshal(ar.FullBytes, &val); err != nil {
134 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d].addressRange: %v", i, j, err))
135 continue
136 }
137 fam.AddressRanges = append(fam.AddressRanges, IPAddressRange{Min: IPAddressPrefix(val.Min), Max: IPAddressPrefix(val.Max)})
138
139 default:
140 nfe.AddError(fmt.Errorf("unexpected ASN.1 type in ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d]: %+v", i, j, ar))
141 }
142 }
143 results = append(results, &fam)
144 }
145 return results
146 }
147
148
149
150 type ASIDRange struct {
151 Min int
152 Max int
153 }
154
155
156
157 type ASIdentifiers struct {
158
159
160 InheritFromIssuer bool
161
162 ASIDs []int
163
164 ASIDRanges []ASIDRange
165 }
166
167 type asIdentifiers struct {
168 ASNum asn1.RawValue `asn1:"optional,tag:0"`
169 RDI asn1.RawValue `asn1:"optional,tag:1"`
170 }
171
172 func parseASIDChoice(val asn1.RawValue, nfe *NonFatalErrors) *ASIdentifiers {
173
174
175
176
177
178
179
180
181
182
183
184 if len(val.FullBytes) == 0 {
185 return nil
186 }
187
188
189 if bytes.Equal(val.Bytes, asn1.NullBytes) {
190 return &ASIdentifiers{InheritFromIssuer: true}
191 }
192 var ids []asn1.RawValue
193 if rest, err := asn1.Unmarshal(val.Bytes, &ids); err != nil {
194 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges: %v", err))
195 return nil
196 } else if len(rest) != 0 {
197 nfe.AddError(errors.New("trailing data after ASIdentifiers.asIdsOrRanges"))
198 return nil
199 }
200 var asID ASIdentifiers
201 for i, id := range ids {
202
203
204 switch id.Tag {
205 case asn1.TagInteger:
206 var val int
207 if _, err := asn1.Unmarshal(id.FullBytes, &val); err != nil {
208 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges[%d].id: %v", i, err))
209 continue
210 }
211 asID.ASIDs = append(asID.ASIDs, val)
212
213 case asn1.TagSequence:
214 var val ASIDRange
215 if _, err := asn1.Unmarshal(id.FullBytes, &val); err != nil {
216 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges[%d].range: %v", i, err))
217 continue
218 }
219 asID.ASIDRanges = append(asID.ASIDRanges, val)
220
221 default:
222 nfe.AddError(fmt.Errorf("unexpected value in ASIdentifiers.asIdsOrRanges[%d]: %+v", i, id))
223 }
224 }
225 return &asID
226 }
227
228 func parseRPKIASIdentifiers(data []byte, nfe *NonFatalErrors) (*ASIdentifiers, *ASIdentifiers) {
229
230
231
232
233 var asIDs asIdentifiers
234 if rest, err := asn1.Unmarshal(data, &asIDs); err != nil {
235 nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers extension: %v", err))
236 return nil, nil
237 } else if len(rest) != 0 {
238 nfe.AddError(errors.New("trailing data after ASIdentifiers extension"))
239 return nil, nil
240 }
241 return parseASIDChoice(asIDs.ASNum, nfe), parseASIDChoice(asIDs.RDI, nfe)
242 }
243
View as plain text