github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/crypto/x509/pkix/pkix.go (about) 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 }