...
Run Format

Source file src/crypto/x509/pkix/pkix.go

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package pkix contains shared, low level structures used for ASN.1 parsing
     6	// and serialization of X.509 certificates, CRL and OCSP.
     7	package pkix
     8	
     9	import (
    10		"encoding/asn1"
    11		"math/big"
    12		"time"
    13	)
    14	
    15	// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
    16	// 5280, section 4.1.1.2.
    17	type AlgorithmIdentifier struct {
    18		Algorithm  asn1.ObjectIdentifier
    19		Parameters asn1.RawValue `asn1:"optional"`
    20	}
    21	
    22	type RDNSequence []RelativeDistinguishedNameSET
    23	
    24	type RelativeDistinguishedNameSET []AttributeTypeAndValue
    25	
    26	// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
    27	// http://tools.ietf.org/html/rfc5280#section-4.1.2.4
    28	type AttributeTypeAndValue struct {
    29		Type  asn1.ObjectIdentifier
    30		Value interface{}
    31	}
    32	
    33	// AttributeTypeAndValueSET represents a set of ASN.1 sequences of
    34	// AttributeTypeAndValue sequences from RFC 2986 (PKCS #10).
    35	type AttributeTypeAndValueSET struct {
    36		Type  asn1.ObjectIdentifier
    37		Value [][]AttributeTypeAndValue `asn1:"set"`
    38	}
    39	
    40	// Extension represents the ASN.1 structure of the same name. See RFC
    41	// 5280, section 4.2.
    42	type Extension struct {
    43		Id       asn1.ObjectIdentifier
    44		Critical bool `asn1:"optional"`
    45		Value    []byte
    46	}
    47	
    48	// Name represents an X.509 distinguished name. This only includes the common
    49	// elements of a DN. When parsing, all elements are stored in Names and
    50	// non-standard elements can be extracted from there. When marshaling, elements
    51	// in ExtraNames are appended and override other values with the same OID.
    52	type Name struct {
    53		Country, Organization, OrganizationalUnit []string
    54		Locality, Province                        []string
    55		StreetAddress, PostalCode                 []string
    56		SerialNumber, CommonName                  string
    57	
    58		Names      []AttributeTypeAndValue
    59		ExtraNames []AttributeTypeAndValue
    60	}
    61	
    62	func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
    63		for _, rdn := range *rdns {
    64			if len(rdn) == 0 {
    65				continue
    66			}
    67	
    68			for _, atv := range rdn {
    69				n.Names = append(n.Names, atv)
    70				value, ok := atv.Value.(string)
    71				if !ok {
    72					continue
    73				}
    74	
    75				t := atv.Type
    76				if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
    77					switch t[3] {
    78					case 3:
    79						n.CommonName = value
    80					case 5:
    81						n.SerialNumber = value
    82					case 6:
    83						n.Country = append(n.Country, value)
    84					case 7:
    85						n.Locality = append(n.Locality, value)
    86					case 8:
    87						n.Province = append(n.Province, value)
    88					case 9:
    89						n.StreetAddress = append(n.StreetAddress, value)
    90					case 10:
    91						n.Organization = append(n.Organization, value)
    92					case 11:
    93						n.OrganizationalUnit = append(n.OrganizationalUnit, value)
    94					case 17:
    95						n.PostalCode = append(n.PostalCode, value)
    96					}
    97				}
    98			}
    99		}
   100	}
   101	
   102	var (
   103		oidCountry            = []int{2, 5, 4, 6}
   104		oidOrganization       = []int{2, 5, 4, 10}
   105		oidOrganizationalUnit = []int{2, 5, 4, 11}
   106		oidCommonName         = []int{2, 5, 4, 3}
   107		oidSerialNumber       = []int{2, 5, 4, 5}
   108		oidLocality           = []int{2, 5, 4, 7}
   109		oidProvince           = []int{2, 5, 4, 8}
   110		oidStreetAddress      = []int{2, 5, 4, 9}
   111		oidPostalCode         = []int{2, 5, 4, 17}
   112	)
   113	
   114	// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence
   115	// and returns the new value. The relativeDistinguishedNameSET contains an
   116	// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
   117	// search for AttributeTypeAndValue.
   118	func (n Name) appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
   119		if len(values) == 0 || oidInAttributeTypeAndValue(oid, n.ExtraNames) {
   120			return in
   121		}
   122	
   123		s := make([]AttributeTypeAndValue, len(values))
   124		for i, value := range values {
   125			s[i].Type = oid
   126			s[i].Value = value
   127		}
   128	
   129		return append(in, s)
   130	}
   131	
   132	func (n Name) ToRDNSequence() (ret RDNSequence) {
   133		ret = n.appendRDNs(ret, n.Country, oidCountry)
   134		ret = n.appendRDNs(ret, n.Province, oidProvince)
   135		ret = n.appendRDNs(ret, n.Locality, oidLocality)
   136		ret = n.appendRDNs(ret, n.StreetAddress, oidStreetAddress)
   137		ret = n.appendRDNs(ret, n.PostalCode, oidPostalCode)
   138		ret = n.appendRDNs(ret, n.Organization, oidOrganization)
   139		ret = n.appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
   140		if len(n.CommonName) > 0 {
   141			ret = n.appendRDNs(ret, []string{n.CommonName}, oidCommonName)
   142		}
   143		if len(n.SerialNumber) > 0 {
   144			ret = n.appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
   145		}
   146		for _, atv := range n.ExtraNames {
   147			ret = append(ret, []AttributeTypeAndValue{atv})
   148		}
   149	
   150		return ret
   151	}
   152	
   153	// oidInAttributeTypeAndValue returns whether a type with the given OID exists
   154	// in atv.
   155	func oidInAttributeTypeAndValue(oid asn1.ObjectIdentifier, atv []AttributeTypeAndValue) bool {
   156		for _, a := range atv {
   157			if a.Type.Equal(oid) {
   158				return true
   159			}
   160		}
   161		return false
   162	}
   163	
   164	// CertificateList represents the ASN.1 structure of the same name. See RFC
   165	// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
   166	// signature.
   167	type CertificateList struct {
   168		TBSCertList        TBSCertificateList
   169		SignatureAlgorithm AlgorithmIdentifier
   170		SignatureValue     asn1.BitString
   171	}
   172	
   173	// HasExpired reports whether now is past the expiry time of certList.
   174	func (certList *CertificateList) HasExpired(now time.Time) bool {
   175		return now.After(certList.TBSCertList.NextUpdate)
   176	}
   177	
   178	// TBSCertificateList represents the ASN.1 structure of the same name. See RFC
   179	// 5280, section 5.1.
   180	type TBSCertificateList struct {
   181		Raw                 asn1.RawContent
   182		Version             int `asn1:"optional,default:0"`
   183		Signature           AlgorithmIdentifier
   184		Issuer              RDNSequence
   185		ThisUpdate          time.Time
   186		NextUpdate          time.Time            `asn1:"optional"`
   187		RevokedCertificates []RevokedCertificate `asn1:"optional"`
   188		Extensions          []Extension          `asn1:"tag:0,optional,explicit"`
   189	}
   190	
   191	// RevokedCertificate represents the ASN.1 structure of the same name. See RFC
   192	// 5280, section 5.1.
   193	type RevokedCertificate struct {
   194		SerialNumber   *big.Int
   195		RevocationTime time.Time
   196		Extensions     []Extension `asn1:"optional"`
   197	}
   198	

View as plain text