// Copyright 2011 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 pkix contains shared, low level structures used for ASN.1 parsing// and serialization of X.509 certificates, CRL and OCSP.
package pkiximport ()// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC// 5280, section 4.1.1.2.typeAlgorithmIdentifierstruct { Algorithm asn1.ObjectIdentifier Parameters asn1.RawValue`asn1:"optional"`}typeRDNSequence []RelativeDistinguishedNameSETvar attributeTypeNames = map[string]string{"2.5.4.6": "C","2.5.4.10": "O","2.5.4.11": "OU","2.5.4.3": "CN","2.5.4.5": "SERIALNUMBER","2.5.4.7": "L","2.5.4.8": "ST","2.5.4.9": "STREET","2.5.4.17": "POSTALCODE",}// String returns a string representation of the sequence r,// roughly following the RFC 2253 Distinguished Names syntax.func ( RDNSequence) () string { := ""for := 0; < len(); ++ { := [len()-1-]if > 0 { += "," }for , := range {if > 0 { += "+" } := .Type.String() , := attributeTypeNames[]if ! { , := asn1.Marshal(.Value)if == nil { += + "=#" + hex.EncodeToString()continue// No value escaping necessary. } = } := fmt.Sprint(.Value) := make([]rune, 0, len())for , := range { := falseswitch {case',', '+', '"', '\\', '<', '>', ';': = truecase' ': = == 0 || == len()-1case'#': = == 0 }if { = append(, '\\', ) } else { = append(, ) } } += + "=" + string() } }return}typeRelativeDistinguishedNameSET []AttributeTypeAndValue// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in// RFC 5280, Section 4.1.2.4.typeAttributeTypeAndValuestruct { Type asn1.ObjectIdentifier Value any}// AttributeTypeAndValueSET represents a set of ASN.1 sequences of// [AttributeTypeAndValue] sequences from RFC 2986 (PKCS #10).typeAttributeTypeAndValueSETstruct { Type asn1.ObjectIdentifier Value [][]AttributeTypeAndValue`asn1:"set"`}// Extension represents the ASN.1 structure of the same name. See RFC// 5280, section 4.2.typeExtensionstruct { Id asn1.ObjectIdentifier Critical bool`asn1:"optional"` Value []byte}// Name represents an X.509 distinguished name. This only includes the common// elements of a DN. Note that Name is only an approximation of the X.509// structure. If an accurate representation is needed, asn1.Unmarshal the raw// subject or issuer as an [RDNSequence].typeNamestruct { Country, Organization, OrganizationalUnit []string Locality, Province []string StreetAddress, PostalCode []string SerialNumber, CommonName string// Names contains all parsed attributes. When parsing distinguished names, // this can be used to extract non-standard attributes that are not parsed // by this package. When marshaling to RDNSequences, the Names field is // ignored, see ExtraNames. Names []AttributeTypeAndValue// ExtraNames contains attributes to be copied, raw, into any marshaled // distinguished names. Values override any attributes with the same OID. // The ExtraNames field is not populated when parsing, see Names. ExtraNames []AttributeTypeAndValue}// FillFromRDNSequence populates n from the provided [RDNSequence].// Multi-entry RDNs are flattened, all entries are added to the// relevant n fields, and the grouping is not preserved.func ( *Name) ( *RDNSequence) {for , := range * {iflen() == 0 {continue }for , := range { .Names = append(.Names, ) , := .Value.(string)if ! {continue } := .Typeiflen() == 4 && [0] == 2 && [1] == 5 && [2] == 4 {switch [3] {case3: .CommonName = case5: .SerialNumber = case6: .Country = append(.Country, )case7: .Locality = append(.Locality, )case8: .Province = append(.Province, )case9: .StreetAddress = append(.StreetAddress, )case10: .Organization = append(.Organization, )case11: .OrganizationalUnit = append(.OrganizationalUnit, )case17: .PostalCode = append(.PostalCode, ) } } } }}var ( oidCountry = []int{2, 5, 4, 6} oidOrganization = []int{2, 5, 4, 10} oidOrganizationalUnit = []int{2, 5, 4, 11} oidCommonName = []int{2, 5, 4, 3} oidSerialNumber = []int{2, 5, 4, 5} oidLocality = []int{2, 5, 4, 7} oidProvince = []int{2, 5, 4, 8} oidStreetAddress = []int{2, 5, 4, 9} oidPostalCode = []int{2, 5, 4, 17})// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence// and returns the new value. The relativeDistinguishedNameSET contains an// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and// search for AttributeTypeAndValue.func ( Name) ( RDNSequence, []string, asn1.ObjectIdentifier) RDNSequence {iflen() == 0 || oidInAttributeTypeAndValue(, .ExtraNames) {return } := make([]AttributeTypeAndValue, len())for , := range { [].Type = [].Value = }returnappend(, )}// ToRDNSequence converts n into a single [RDNSequence]. The following// attributes are encoded as multi-value RDNs://// - Country// - Organization// - OrganizationalUnit// - Locality// - Province// - StreetAddress// - PostalCode//// Each ExtraNames entry is encoded as an individual RDN.func ( Name) () ( RDNSequence) { = .appendRDNs(, .Country, oidCountry) = .appendRDNs(, .Province, oidProvince) = .appendRDNs(, .Locality, oidLocality) = .appendRDNs(, .StreetAddress, oidStreetAddress) = .appendRDNs(, .PostalCode, oidPostalCode) = .appendRDNs(, .Organization, oidOrganization) = .appendRDNs(, .OrganizationalUnit, oidOrganizationalUnit)iflen(.CommonName) > 0 { = .appendRDNs(, []string{.CommonName}, oidCommonName) }iflen(.SerialNumber) > 0 { = .appendRDNs(, []string{.SerialNumber}, oidSerialNumber) }for , := range .ExtraNames { = append(, []AttributeTypeAndValue{}) }return}// String returns the string form of n, roughly following// the RFC 2253 Distinguished Names syntax.func ( Name) () string {varRDNSequence// If there are no ExtraNames, surface the parsed value (all entries in // Names) instead.if .ExtraNames == nil {for , := range .Names { := .Typeiflen() == 4 && [0] == 2 && [1] == 5 && [2] == 4 {switch [3] {case3, 5, 6, 7, 8, 9, 10, 11, 17:// These attributes were already parsed into named fields.continue } }// Place non-standard parsed values at the beginning of the sequence // so they will be at the end of the string. See Issue 39924. = append(, []AttributeTypeAndValue{}) } } = append(, .ToRDNSequence()...)return .String()}// oidInAttributeTypeAndValue reports whether a type with the given OID exists// in atv.func oidInAttributeTypeAndValue( asn1.ObjectIdentifier, []AttributeTypeAndValue) bool {for , := range {if .Type.Equal() {returntrue } }returnfalse}// CertificateList represents the ASN.1 structure of the same name. See RFC// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the// signature.//// Deprecated: x509.RevocationList should be used instead.typeCertificateListstruct { TBSCertList TBSCertificateList SignatureAlgorithm AlgorithmIdentifier SignatureValue asn1.BitString}// HasExpired reports whether certList should have been updated by now.func ( *CertificateList) ( time.Time) bool {return !.Before(.TBSCertList.NextUpdate)}// TBSCertificateList represents the ASN.1 structure of the same name. See RFC// 5280, section 5.1.//// Deprecated: x509.RevocationList should be used instead.typeTBSCertificateListstruct { Raw asn1.RawContent Version int`asn1:"optional,default:0"` Signature AlgorithmIdentifier Issuer RDNSequence ThisUpdate time.Time NextUpdate time.Time`asn1:"optional"` RevokedCertificates []RevokedCertificate`asn1:"optional"` Extensions []Extension`asn1:"tag:0,optional,explicit"`}// RevokedCertificate represents the ASN.1 structure of the same name. See RFC// 5280, section 5.1.typeRevokedCertificatestruct { SerialNumber *big.Int RevocationTime time.Time Extensions []Extension`asn1:"optional"`}
The pages are generated with Goldsv0.6.9-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.