feat(dir2config)

This commit is contained in:
Mikaël Cluseau
2018-12-11 00:44:05 +11:00
parent 26b6efd54c
commit 7435995592
106 changed files with 5352 additions and 4052 deletions

View File

@ -121,7 +121,7 @@ func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
}
cert, err := ParseCertificate(block.Bytes)
if err != nil {
if IsFatal(err) {
continue
}

View File

@ -0,0 +1,37 @@
// 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 (
"crypto/elliptic"
"math/big"
"sync"
)
// This file holds ECC curves that are not supported by the main Go crypto/elliptic
// library, but which have been observed in certificates in the wild.
var initonce sync.Once
var p192r1 *elliptic.CurveParams
func initAllCurves() {
initSECP192R1()
}
func initSECP192R1() {
// See SEC-2, section 2.2.2
p192r1 = &elliptic.CurveParams{Name: "P-192"}
p192r1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16)
p192r1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 16)
p192r1.B, _ = new(big.Int).SetString("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", 16)
p192r1.Gx, _ = new(big.Int).SetString("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", 16)
p192r1.Gy, _ = new(big.Int).SetString("07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", 16)
p192r1.BitSize = 192
}
func secp192r1() elliptic.Curve {
initonce.Do(initAllCurves)
return p192r1
}

View File

@ -14,12 +14,15 @@ import (
"github.com/google/certificate-transparency-go/x509/pkix"
)
// OID values for CRL extensions (TBSCertList.Extensions), RFC 5280 s5.2.
var (
// OID values for CRL extensions (TBSCertList.Extensions), RFC 5280 s5.2.
OIDExtensionCRLNumber = asn1.ObjectIdentifier{2, 5, 29, 20}
OIDExtensionDeltaCRLIndicator = asn1.ObjectIdentifier{2, 5, 29, 27}
OIDExtensionIssuingDistributionPoint = asn1.ObjectIdentifier{2, 5, 29, 28}
// OID values for CRL entry extensions (RevokedCertificate.Extensions), RFC 5280 s5.3
)
// OID values for CRL entry extensions (RevokedCertificate.Extensions), RFC 5280 s5.3
var (
OIDExtensionCRLReasons = asn1.ObjectIdentifier{2, 5, 29, 21}
OIDExtensionInvalidityDate = asn1.ObjectIdentifier{2, 5, 29, 24}
OIDExtensionCertificateIssuer = asn1.ObjectIdentifier{2, 5, 29, 29}
@ -238,7 +241,7 @@ func ParseCertificateListDER(derBytes []byte) (*CertificateList, error) {
}
case e.Id.Equal(OIDExtensionAuthorityInfoAccess):
// RFC 5280 s5.2.7
var aia []authorityInfoAccess
var aia []accessDescription
if rest, err := asn1.Unmarshal(e.Value, &aia); err != nil {
errs.AddID(ErrInvalidCertListAuthInfoAccess, err)
} else if len(rest) != 0 {

View File

@ -0,0 +1,242 @@
// 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)
}

View File

@ -72,11 +72,12 @@ func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *e
return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
}
var nfe NonFatalErrors
var curve elliptic.Curve
if namedCurveOID != nil {
curve = namedCurveFromOID(*namedCurveOID)
curve = namedCurveFromOID(*namedCurveOID, &nfe)
} else {
curve = namedCurveFromOID(privKey.NamedCurveOID)
curve = namedCurveFromOID(privKey.NamedCurveOID, &nfe)
}
if curve == nil {
return nil, errors.New("x509: unknown elliptic curve")

View File

@ -8,9 +8,39 @@
// can be used to override the system default locations for the SSL certificate
// file and SSL certificate files directory, respectively.
//
// This is a fork of the go library crypto/x509 package, it's more relaxed
// about certificates that it'll accept, and exports the TBSCertificate
// structure.
// This is a fork of the Go library crypto/x509 package, primarily adapted for
// use with Certificate Transparency. Main areas of difference are:
//
// - Life as a fork:
// - Rename OS-specific cgo code so it doesn't clash with main Go library.
// - Use local library imports (asn1, pkix) throughout.
// - Add version-specific wrappers for Go version-incompatible code (in
// nilref_*_darwin.go, ptr_*_windows.go).
// - Laxer certificate parsing:
// - Add options to disable various validation checks (times, EKUs etc).
// - Use NonFatalErrors type for some errors and continue parsing; this
// can be checked with IsFatal(err).
// - Support for short bitlength ECDSA curves (in curves.go).
// - Certificate Transparency specific function:
// - Parsing and marshaling of SCTList extension.
// - RemoveSCTList() function for rebuilding CT leaf entry.
// - Pre-certificate processing (RemoveCTPoison(), BuildPrecertTBS(),
// ParseTBSCertificate(), IsPrecertificate()).
// - Revocation list processing:
// - Detailed CRL parsing (in revoked.go)
// - Detailed error recording mechanism (in error.go, errors.go)
// - Factor out parseDistributionPoints() for reuse.
// - Factor out and generalize GeneralNames parsing (in names.go)
// - Fix CRL commenting.
// - RPKI support:
// - Support for SubjectInfoAccess extension
// - Support for RFC3779 extensions (in rpki.go)
// - General improvements:
// - Export and use OID values throughout.
// - Export OIDFromNamedCurve().
// - Export SignatureAlgorithmFromAI().
// - Add OID value to UnhandledCriticalExtension error.
// - Minor typo/lint fixes.
package x509
import (
@ -69,7 +99,16 @@ func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
if algo == UnknownPublicKeyAlgorithm {
return nil, errors.New("x509: unknown public key algorithm")
}
return parsePublicKey(algo, &pki)
var nfe NonFatalErrors
pub, err = parsePublicKey(algo, &pki, &nfe)
if err != nil {
return pub, err
}
// Treat non-fatal errors as fatal for this entrypoint.
if len(nfe.Errors) > 0 {
return nil, nfe.Errors[0]
}
return pub, nil
}
func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
@ -500,15 +539,21 @@ func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm
// secp521r1 OBJECT IDENTIFIER ::= {
// iso(1) identified-organization(3) certicom(132) curve(0) 35 }
//
// NB: secp256r1 is equivalent to prime256v1
// secp192r1 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
// prime(1) 1 }
//
// NB: secp256r1 is equivalent to prime256v1,
// secp192r1 is equivalent to ansix9p192r and prime192v1
var (
OIDNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
OIDNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
OIDNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
OIDNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
OIDNamedCurveP192 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 1}
)
func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
func namedCurveFromOID(oid asn1.ObjectIdentifier, nfe *NonFatalErrors) elliptic.Curve {
switch {
case oid.Equal(OIDNamedCurveP224):
return elliptic.P224()
@ -518,6 +563,9 @@ func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
return elliptic.P384()
case oid.Equal(OIDNamedCurveP521):
return elliptic.P521()
case oid.Equal(OIDNamedCurveP192):
nfe.AddError(errors.New("insecure curve (secp192r1) specified"))
return secp192r1()
}
return nil
}
@ -534,6 +582,8 @@ func OIDFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
return OIDNamedCurveP384, true
case elliptic.P521():
return OIDNamedCurveP521, true
case secp192r1():
return OIDNamedCurveP192, true
}
return nil, false
@ -737,6 +787,10 @@ type Certificate struct {
OCSPServer []string
IssuingCertificateURL []string
// Subject Information Access
SubjectTimestamps []string
SubjectCARepositories []string
// Subject Alternate Name values. (Note that these values may not be valid
// if invalid values were contained within a parsed certificate. For
// example, an element of DNSNames may not be a valid DNS domain name.)
@ -761,6 +815,9 @@ type Certificate struct {
PolicyIdentifiers []asn1.ObjectIdentifier
RPKIAddressRanges []*IPAddressFamilyBlocks
RPKIASNumbers, RPKIRoutingDomainIDs *ASIdentifiers
// Certificate Transparency SCT extension contents; this is a TLS-encoded
// SignedCertificateTimestampList (RFC 6962 s3.3).
RawSCT []byte
@ -1175,7 +1232,7 @@ const (
)
// RFC 5280, 4.2.2.1
type authorityInfoAccess struct {
type accessDescription struct {
Method asn1.ObjectIdentifier
Location asn1.RawValue
}
@ -1192,14 +1249,14 @@ type distributionPointName struct {
RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
}
func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo, nfe *NonFatalErrors) (interface{}, error) {
asn1Data := keyData.PublicKey.RightAlign()
switch algo {
case RSA:
// RSA public keys must have a NULL in the parameters
// (https://tools.ietf.org/html/rfc3279#section-2.3.1).
if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
return nil, errors.New("x509: RSA key missing NULL parameters")
nfe.AddError(errors.New("x509: RSA key missing NULL parameters"))
}
p := new(pkcs1PublicKey)
@ -1263,9 +1320,9 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
if len(rest) != 0 {
return nil, errors.New("x509: trailing data after ECDSA parameters")
}
namedCurve := namedCurveFromOID(*namedCurveOID)
namedCurve := namedCurveFromOID(*namedCurveOID, nfe)
if namedCurve == nil {
return nil, errors.New("x509: unsupported elliptic curve")
return nil, fmt.Errorf("x509: unsupported elliptic curve %v", namedCurveOID)
}
x, y := elliptic.Unmarshal(namedCurve, asn1Data)
if x == nil {
@ -1310,6 +1367,20 @@ func (e *NonFatalErrors) HasError() bool {
return len(e.Errors) > 0
}
// IsFatal indicates whether an error is fatal.
func IsFatal(err error) bool {
if err == nil {
return false
}
if _, ok := err.(NonFatalErrors); ok {
return false
}
if errs, ok := err.(*Errors); ok {
return errs.Fatal()
}
return true
}
func parseDistributionPoints(data []byte, crldp *[]string) error {
// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
//
@ -1622,7 +1693,7 @@ func parseCertificate(in *certificate) (*Certificate, error) {
out.PublicKeyAlgorithm =
getPublicKeyAlgorithmFromOID(in.TBSCertificate.PublicKey.Algorithm.Algorithm)
var err error
out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey)
out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey, &nfe)
if err != nil {
return nil, err
}
@ -1729,10 +1800,14 @@ func parseCertificate(in *certificate) (*Certificate, error) {
// KeyPurposeId ::= OBJECT IDENTIFIER
var keyUsage []asn1.ObjectIdentifier
if rest, err := asn1.Unmarshal(e.Value, &keyUsage); err != nil {
return nil, err
} else if len(rest) != 0 {
return nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage")
if len(e.Value) == 0 {
nfe.AddError(errors.New("x509: empty ExtendedKeyUsage"))
} else {
if rest, err := asn1.Unmarshal(e.Value, &keyUsage); err != nil {
return nil, err
} else if len(rest) != 0 {
return nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage")
}
}
for _, u := range keyUsage {
@ -1772,12 +1847,15 @@ func parseCertificate(in *certificate) (*Certificate, error) {
}
} else if e.Id.Equal(OIDExtensionAuthorityInfoAccess) {
// RFC 5280 4.2.2.1: Authority Information Access
var aia []authorityInfoAccess
var aia []accessDescription
if rest, err := asn1.Unmarshal(e.Value, &aia); err != nil {
return nil, err
} else if len(rest) != 0 {
return nil, errors.New("x509: trailing data after X.509 authority information")
}
if len(aia) == 0 {
nfe.AddError(errors.New("x509: empty AuthorityInfoAccess extension"))
}
for _, v := range aia {
// GeneralName: uniformResourceIdentifier [6] IA5String
@ -1790,6 +1868,34 @@ func parseCertificate(in *certificate) (*Certificate, error) {
out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes))
}
}
} else if e.Id.Equal(OIDExtensionSubjectInfoAccess) {
// RFC 5280 4.2.2.2: Subject Information Access
var sia []accessDescription
if rest, err := asn1.Unmarshal(e.Value, &sia); err != nil {
return nil, err
} else if len(rest) != 0 {
return nil, errors.New("x509: trailing data after X.509 subject information")
}
if len(sia) == 0 {
nfe.AddError(errors.New("x509: empty SubjectInfoAccess extension"))
}
for _, v := range sia {
// TODO(drysdale): cope with non-URI types of GeneralName
// GeneralName: uniformResourceIdentifier [6] IA5String
if v.Location.Tag != 6 {
continue
}
if v.Method.Equal(OIDSubjectInfoAccessTimestamp) {
out.SubjectTimestamps = append(out.SubjectTimestamps, string(v.Location.Bytes))
} else if v.Method.Equal(OIDSubjectInfoAccessCARepo) {
out.SubjectCARepositories = append(out.SubjectCARepositories, string(v.Location.Bytes))
}
}
} else if e.Id.Equal(OIDExtensionIPPrefixList) {
out.RPKIAddressRanges = parseRPKIAddrBlocks(e.Value, &nfe)
} else if e.Id.Equal(OIDExtensionASList) {
out.RPKIASNumbers, out.RPKIRoutingDomainIDs = parseRPKIASIdentifiers(e.Value, &nfe)
} else if e.Id.Equal(OIDExtensionCTSCT) {
if rest, err := asn1.Unmarshal(e.Value, &out.RawSCT); err != nil {
nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal SCT list extension: %v", err))
@ -1934,15 +2040,23 @@ var (
OIDExtensionAuthorityInfoAccess = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1}
OIDExtensionSubjectInfoAccess = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11}
// OIDExtensionCTPoison is defined in RFC 6962 s3.1.
OIDExtensionCTPoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3}
// OIDExtensionCTSCT is defined in RFC 6962 s3.3.
OIDExtensionCTSCT = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2}
// OIDExtensionIPPrefixList is defined in RFC 3779 s2.
OIDExtensionIPPrefixList = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 7}
// OIDExtensionASList is defined in RFC 3779 s3.
OIDExtensionASList = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 8}
)
var (
OIDAuthorityInfoAccessOCSP = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
OIDAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
OIDSubjectInfoAccessTimestamp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 3}
OIDSubjectInfoAccessCARepo = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 5}
OIDAnyPolicy = asn1.ObjectIdentifier{2, 5, 29, 32, 0}
)
// oidInExtensions returns whether an extension with the given oid exists in
@ -1991,7 +2105,7 @@ func isIA5String(s string) error {
}
func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte) (ret []pkix.Extension, err error) {
ret = make([]pkix.Extension, 11 /* maximum number of elements. */)
ret = make([]pkix.Extension, 12 /* maximum number of elements. */)
n := 0
if template.KeyUsage != 0 &&
@ -2076,15 +2190,15 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId
if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) &&
!oidInExtensions(OIDExtensionAuthorityInfoAccess, template.ExtraExtensions) {
ret[n].Id = OIDExtensionAuthorityInfoAccess
var aiaValues []authorityInfoAccess
var aiaValues []accessDescription
for _, name := range template.OCSPServer {
aiaValues = append(aiaValues, authorityInfoAccess{
aiaValues = append(aiaValues, accessDescription{
Method: OIDAuthorityInfoAccessOCSP,
Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(name)},
})
}
for _, name := range template.IssuingCertificateURL {
aiaValues = append(aiaValues, authorityInfoAccess{
aiaValues = append(aiaValues, accessDescription{
Method: OIDAuthorityInfoAccessIssuers,
Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(name)},
})
@ -2096,6 +2210,29 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId
n++
}
if len(template.SubjectTimestamps) > 0 || len(template.SubjectCARepositories) > 0 &&
!oidInExtensions(OIDExtensionSubjectInfoAccess, template.ExtraExtensions) {
ret[n].Id = OIDExtensionSubjectInfoAccess
var siaValues []accessDescription
for _, ts := range template.SubjectTimestamps {
siaValues = append(siaValues, accessDescription{
Method: OIDSubjectInfoAccessTimestamp,
Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(ts)},
})
}
for _, repo := range template.SubjectCARepositories {
siaValues = append(siaValues, accessDescription{
Method: OIDSubjectInfoAccessCARepo,
Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(repo)},
})
}
ret[n].Value, err = asn1.Marshal(siaValues)
if err != nil {
return
}
n++
}
if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
!oidInExtensions(OIDExtensionSubjectAltName, template.ExtraExtensions) {
ret[n].Id = OIDExtensionSubjectAltName
@ -2349,12 +2486,25 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori
var emptyASN1Subject = []byte{0x30, 0}
// CreateCertificate creates a new X.509v3 certificate based on a template.
// The following members of template are used: AuthorityKeyId,
// BasicConstraintsValid, DNSNames, ExcludedDNSDomains, ExtKeyUsage,
// IsCA, KeyUsage, MaxPathLen, MaxPathLenZero, NotAfter, NotBefore,
// PermittedDNSDomains, PermittedDNSDomainsCritical, SerialNumber,
// SignatureAlgorithm, Subject, SubjectKeyId, UnknownExtKeyUsage,
// and RawSCT.
// The following members of template are used:
// - SerialNumber
// - Subject
// - NotBefore, NotAfter
// - SignatureAlgorithm
// - For extensions:
// - KeyUsage
// - ExtKeyUsage
// - BasicConstraintsValid, IsCA, MaxPathLen, MaxPathLenZero
// - SubjectKeyId
// - AuthorityKeyId
// - OCSPServer, IssuingCertificateURL
// - SubjectTimestamps, SubjectCARepositories
// - DNSNames, EmailAddresses, IPAddresses, URIs
// - PolicyIdentifiers
// - ExcludedDNSDomains, ExcludedIPRanges, ExcludedEmailAddresses, ExcludedURIDomains, PermittedDNSDomainsCritical,
// PermittedDNSDomains, PermittedIPRanges, PermittedEmailAddresses, PermittedURIDomains
// - CRLDistributionPoints
// - RawSCT, SCTList
//
// The certificate is signed by parent. If parent is equal to template then the
// certificate is self-signed. The parameter pub is the public key of the
@ -2863,10 +3013,15 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
}
var err error
out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey)
var nfe NonFatalErrors
out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey, &nfe)
if err != nil {
return nil, err
}
// Treat non-fatal errors as fatal here.
if len(nfe.Errors) > 0 {
return nil, nfe.Errors[0]
}
var subject pkix.RDNSequence
if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
@ -2881,7 +3036,6 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
return nil, err
}
var nfe NonFatalErrors
for _, extension := range out.Extensions {
if extension.Id.Equal(OIDExtensionSubjectAltName) {
out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(extension.Value, &nfe)