123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- // Copyright 2018 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 (
- "bytes"
- "encoding/binary"
- "errors"
- "fmt"
- "github.com/google/certificate-transparency-go/asn1"
- )
- // IPAddressPrefix describes an IP address prefix as an ASN.1 bit string,
- // where the BitLength field holds the prefix length.
- type IPAddressPrefix asn1.BitString
- // IPAddressRange describes an (inclusive) IP address range.
- type IPAddressRange struct {
- Min IPAddressPrefix
- Max IPAddressPrefix
- }
- // Most relevant values for AFI from:
- // http://www.iana.org/assignments/address-family-numbers.
- const (
- IPv4AddressFamilyIndicator = uint16(1)
- IPv6AddressFamilyIndicator = uint16(2)
- )
- // IPAddressFamilyBlocks describes a set of ranges of IP addresses.
- type IPAddressFamilyBlocks struct {
- // AFI holds an address family indicator from
- // http://www.iana.org/assignments/address-family-numbers.
- AFI uint16
- // SAFI holds a subsequent address family indicator from
- // http://www.iana.org/assignments/safi-namespace.
- SAFI byte
- // InheritFromIssuer indicates that the set of addresses should
- // be taken from the issuer's certificate.
- InheritFromIssuer bool
- // AddressPrefixes holds prefixes if InheritFromIssuer is false.
- AddressPrefixes []IPAddressPrefix
- // AddressRanges holds ranges if InheritFromIssuer is false.
- AddressRanges []IPAddressRange
- }
- // Internal types for asn1 unmarshalling.
- type ipAddressFamily struct {
- AddressFamily []byte // 2-byte AFI plus optional 1 byte SAFI
- Choice asn1.RawValue
- }
- // Internally, use raw asn1.BitString rather than the IPAddressPrefix
- // type alias (so that asn1.Unmarshal() decodes properly).
- type ipAddressRange struct {
- Min asn1.BitString
- Max asn1.BitString
- }
- func parseRPKIAddrBlocks(data []byte, nfe *NonFatalErrors) []*IPAddressFamilyBlocks {
- // RFC 3779 2.2.3
- // IPAddrBlocks ::= SEQUENCE OF IPAddressFamily
- //
- // IPAddressFamily ::= SEQUENCE { -- AFI & optional SAFI --
- // addressFamily OCTET STRING (SIZE (2..3)),
- // ipAddressChoice IPAddressChoice }
- //
- // IPAddressChoice ::= CHOICE {
- // inherit NULL, -- inherit from issuer --
- // addressesOrRanges SEQUENCE OF IPAddressOrRange }
- //
- // IPAddressOrRange ::= CHOICE {
- // addressPrefix IPAddress,
- // addressRange IPAddressRange }
- //
- // IPAddressRange ::= SEQUENCE {
- // min IPAddress,
- // max IPAddress }
- //
- // IPAddress ::= BIT STRING
- var addrBlocks []ipAddressFamily
- if rest, err := asn1.Unmarshal(data, &addrBlocks); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks extension: %v", err))
- return nil
- } else if len(rest) != 0 {
- nfe.AddError(errors.New("trailing data after ipAddrBlocks extension"))
- return nil
- }
- var results []*IPAddressFamilyBlocks
- for i, block := range addrBlocks {
- var fam IPAddressFamilyBlocks
- if l := len(block.AddressFamily); l < 2 || l > 3 {
- nfe.AddError(fmt.Errorf("invalid address family length (%d) for ipAddrBlock.addressFamily", l))
- continue
- }
- fam.AFI = binary.BigEndian.Uint16(block.AddressFamily[0:2])
- if len(block.AddressFamily) > 2 {
- fam.SAFI = block.AddressFamily[2]
- }
- // IPAddressChoice is an ASN.1 CHOICE where the chosen alternative is indicated by (implicit)
- // tagging of the alternatives -- here, either NULL or SEQUENCE OF.
- if bytes.Equal(block.Choice.FullBytes, asn1.NullBytes) {
- fam.InheritFromIssuer = true
- results = append(results, &fam)
- continue
- }
- var addrRanges []asn1.RawValue
- if _, err := asn1.Unmarshal(block.Choice.FullBytes, &addrRanges); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges: %v", i, err))
- continue
- }
- for j, ar := range addrRanges {
- // Each IPAddressOrRange is a CHOICE where the alternatives have distinct (implicit)
- // tags -- here, either BIT STRING or SEQUENCE.
- switch ar.Tag {
- case asn1.TagBitString:
- // BIT STRING for single prefix IPAddress
- var val asn1.BitString
- if _, err := asn1.Unmarshal(ar.FullBytes, &val); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d].addressPrefix: %v", i, j, err))
- continue
- }
- fam.AddressPrefixes = append(fam.AddressPrefixes, IPAddressPrefix(val))
- case asn1.TagSequence:
- var val ipAddressRange
- if _, err := asn1.Unmarshal(ar.FullBytes, &val); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d].addressRange: %v", i, j, err))
- continue
- }
- fam.AddressRanges = append(fam.AddressRanges, IPAddressRange{Min: IPAddressPrefix(val.Min), Max: IPAddressPrefix(val.Max)})
- default:
- nfe.AddError(fmt.Errorf("unexpected ASN.1 type in ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d]: %+v", i, j, ar))
- }
- }
- results = append(results, &fam)
- }
- return results
- }
- // ASIDRange describes an inclusive range of AS Identifiers (AS numbers or routing
- // domain identifiers).
- type ASIDRange struct {
- Min int
- Max int
- }
- // ASIdentifiers describes a collection of AS Identifiers (AS numbers or routing
- // domain identifiers).
- type ASIdentifiers struct {
- // InheritFromIssuer indicates that the set of AS identifiers should
- // be taken from the issuer's certificate.
- InheritFromIssuer bool
- // ASIDs holds AS identifiers if InheritFromIssuer is false.
- ASIDs []int
- // ASIDs holds AS identifier ranges (inclusive) if InheritFromIssuer is false.
- ASIDRanges []ASIDRange
- }
- type asIdentifiers struct {
- ASNum asn1.RawValue `asn1:"optional,tag:0"`
- RDI asn1.RawValue `asn1:"optional,tag:1"`
- }
- func parseASIDChoice(val asn1.RawValue, nfe *NonFatalErrors) *ASIdentifiers {
- // RFC 3779 2.3.2
- // ASIdentifierChoice ::= CHOICE {
- // inherit NULL, -- inherit from issuer --
- // asIdsOrRanges SEQUENCE OF ASIdOrRange }
- // ASIdOrRange ::= CHOICE {
- // id ASId,
- // range ASRange }
- // ASRange ::= SEQUENCE {
- // min ASId,
- // max ASId }
- // ASId ::= INTEGER
- if len(val.FullBytes) == 0 { // OPTIONAL
- return nil
- }
- // ASIdentifierChoice is an ASN.1 CHOICE where the chosen alternative is indicated by (implicit)
- // tagging of the alternatives -- here, either NULL or SEQUENCE OF.
- if bytes.Equal(val.Bytes, asn1.NullBytes) {
- return &ASIdentifiers{InheritFromIssuer: true}
- }
- var ids []asn1.RawValue
- if rest, err := asn1.Unmarshal(val.Bytes, &ids); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges: %v", err))
- return nil
- } else if len(rest) != 0 {
- nfe.AddError(errors.New("trailing data after ASIdentifiers.asIdsOrRanges"))
- return nil
- }
- var asID ASIdentifiers
- for i, id := range ids {
- // Each ASIdOrRange is a CHOICE where the alternatives have distinct (implicit)
- // tags -- here, either INTEGER or SEQUENCE.
- switch id.Tag {
- case asn1.TagInteger:
- var val int
- if _, err := asn1.Unmarshal(id.FullBytes, &val); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges[%d].id: %v", i, err))
- continue
- }
- asID.ASIDs = append(asID.ASIDs, val)
- case asn1.TagSequence:
- var val ASIDRange
- if _, err := asn1.Unmarshal(id.FullBytes, &val); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges[%d].range: %v", i, err))
- continue
- }
- asID.ASIDRanges = append(asID.ASIDRanges, val)
- default:
- nfe.AddError(fmt.Errorf("unexpected value in ASIdentifiers.asIdsOrRanges[%d]: %+v", i, id))
- }
- }
- return &asID
- }
- func parseRPKIASIdentifiers(data []byte, nfe *NonFatalErrors) (*ASIdentifiers, *ASIdentifiers) {
- // RFC 3779 2.3.2
- // ASIdentifiers ::= SEQUENCE {
- // asnum [0] EXPLICIT ASIdentifierChoice OPTIONAL,
- // rdi [1] EXPLICIT ASIdentifierChoice OPTIONAL}
- var asIDs asIdentifiers
- if rest, err := asn1.Unmarshal(data, &asIDs); err != nil {
- nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers extension: %v", err))
- return nil, nil
- } else if len(rest) != 0 {
- nfe.AddError(errors.New("trailing data after ASIdentifiers extension"))
- return nil, nil
- }
- return parseASIDChoice(asIDs.ASNum, nfe), parseASIDChoice(asIDs.RDI, nfe)
- }
|