...
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			atv := rdn[0]
    68			n.Names = append(n.Names, atv)
    69			value, ok := atv.Value.(string)
    70			if !ok {
    71				continue
    72			}
    73	
    74			t := atv.Type
    75			if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
    76				switch t[3] {
    77				case 3:
    78					n.CommonName = value
    79				case 5:
    80					n.SerialNumber = value
    81				case 6:
    82					n.Country = append(n.Country, value)
    83				case 7:
    84					n.Locality = append(n.Locality, value)
    85				case 8:
    86					n.Province = append(n.Province, value)
    87				case 9:
    88					n.StreetAddress = append(n.StreetAddress, value)
    89				case 10:
    90					n.Organization = append(n.Organization, value)
    91				case 11:
    92					n.OrganizationalUnit = append(n.OrganizationalUnit, value)
    93				case 17:
    94					n.PostalCode = append(n.PostalCode, value)
    95				}
    96			}
    97		}
    98	}
    99	
   100	var (
   101		oidCountry            = []int{2, 5, 4, 6}
   102		oidOrganization       = []int{2, 5, 4, 10}
   103		oidOrganizationalUnit = []int{2, 5, 4, 11}
   104		oidCommonName         = []int{2, 5, 4, 3}
   105		oidSerialNumber       = []int{2, 5, 4, 5}
   106		oidLocality           = []int{2, 5, 4, 7}
   107		oidProvince           = []int{2, 5, 4, 8}
   108		oidStreetAddress      = []int{2, 5, 4, 9}
   109		oidPostalCode         = []int{2, 5, 4, 17}
   110	)
   111	
   112	// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence
   113	// and returns the new value. The relativeDistinguishedNameSET contains an
   114	// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
   115	// search for AttributeTypeAndValue.
   116	func (n Name) appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
   117		if len(values) == 0 || oidInAttributeTypeAndValue(oid, n.ExtraNames) {
   118			return in
   119		}
   120	
   121		s := make([]AttributeTypeAndValue, len(values))
   122		for i, value := range values {
   123			s[i].Type = oid
   124			s[i].Value = value
   125		}
   126	
   127		return append(in, s)
   128	}
   129	
   130	func (n Name) ToRDNSequence() (ret RDNSequence) {
   131		ret = n.appendRDNs(ret, n.Country, oidCountry)
   132		ret = n.appendRDNs(ret, n.Organization, oidOrganization)
   133		ret = n.appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
   134		ret = n.appendRDNs(ret, n.Locality, oidLocality)
   135		ret = n.appendRDNs(ret, n.Province, oidProvince)
   136		ret = n.appendRDNs(ret, n.StreetAddress, oidStreetAddress)
   137		ret = n.appendRDNs(ret, n.PostalCode, oidPostalCode)
   138		if len(n.CommonName) > 0 {
   139			ret = n.appendRDNs(ret, []string{n.CommonName}, oidCommonName)
   140		}
   141		if len(n.SerialNumber) > 0 {
   142			ret = n.appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
   143		}
   144		for _, atv := range n.ExtraNames {
   145			ret = append(ret, []AttributeTypeAndValue{atv})
   146		}
   147	
   148		return ret
   149	}
   150	
   151	// oidInAttributeTypeAndValue returns whether a type with the given OID exists
   152	// in atv.
   153	func oidInAttributeTypeAndValue(oid asn1.ObjectIdentifier, atv []AttributeTypeAndValue) bool {
   154		for _, a := range atv {
   155			if a.Type.Equal(oid) {
   156				return true
   157			}
   158		}
   159		return false
   160	}
   161	
   162	// CertificateList represents the ASN.1 structure of the same name. See RFC
   163	// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
   164	// signature.
   165	type CertificateList struct {
   166		TBSCertList        TBSCertificateList
   167		SignatureAlgorithm AlgorithmIdentifier
   168		SignatureValue     asn1.BitString
   169	}
   170	
   171	// HasExpired reports whether now is past the expiry time of certList.
   172	func (certList *CertificateList) HasExpired(now time.Time) bool {
   173		return now.After(certList.TBSCertList.NextUpdate)
   174	}
   175	
   176	// TBSCertificateList represents the ASN.1 structure of the same name. See RFC
   177	// 5280, section 5.1.
   178	type TBSCertificateList struct {
   179		Raw                 asn1.RawContent
   180		Version             int `asn1:"optional,default:1"`
   181		Signature           AlgorithmIdentifier
   182		Issuer              RDNSequence
   183		ThisUpdate          time.Time
   184		NextUpdate          time.Time            `asn1:"optional"`
   185		RevokedCertificates []RevokedCertificate `asn1:"optional"`
   186		Extensions          []Extension          `asn1:"tag:0,optional,explicit"`
   187	}
   188	
   189	// RevokedCertificate represents the ASN.1 structure of the same name. See RFC
   190	// 5280, section 5.1.
   191	type RevokedCertificate struct {
   192		SerialNumber   *big.Int
   193		RevocationTime time.Time
   194		Extensions     []Extension `asn1:"optional"`
   195	}
   196	

View as plain text