// 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 crl exposes low-level details of PKIX Certificate Revocation Lists // as specified in RFC 5280, section 5. package crl import ( "asn1" "bytes" "encoding/pem" "os" "time" ) // CertificateList represents the ASN.1 structure of the same name. See RFC // 5280, section 5.1. Use crypto/x509/Certificate.CheckCRLSignature to verify // the signature. type CertificateList struct { TBSCertList TBSCertificateList SignatureAlgorithm AlgorithmIdentifier SignatureValue asn1.BitString } // HasExpired returns true iff currentTimeSeconds is past the expiry time of // certList. func (certList *CertificateList) HasExpired(currentTimeSeconds int64) bool { return certList.TBSCertList.NextUpdate.Seconds() <= currentTimeSeconds } // TBSCertificateList represents the ASN.1 structure of the same name. See RFC // 5280, section 5.1. type TBSCertificateList struct { Raw asn1.RawContent Version int "optional,default:2" Signature AlgorithmIdentifier Issuer asn1.RawValue ThisUpdate *time.Time NextUpdate *time.Time RevokedCertificates []RevokedCertificate "optional" Extensions []Extension "tag:0,optional,explicit" } // AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC // 5280, section 4.1.1.2. type AlgorithmIdentifier struct { Algo asn1.ObjectIdentifier Params asn1.RawValue "optional" } // AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC // 5280, section 5.1. type RevokedCertificate struct { SerialNumber asn1.RawValue RevocationTime *time.Time Extensions []Extension "optional" } // AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC // 5280, section 4.2. type Extension struct { Id asn1.ObjectIdentifier IsCritial bool "optional" Value []byte } // pemCRLPrefix is the magic string that indicates that we have a PEM encoded // CRL. var pemCRLPrefix = []byte("-----BEGIN X509 CRL") // pemType is the type of a PEM encoded CRL. var pemType = "X509 CRL" // Parse parses a CRL from the given bytes. It's often the case that PEM // encoded CRLs will appear where they should be DER encoded, so this function // will transparently handle PEM encoding as long as there isn't any leading // garbage. func Parse(crlBytes []byte) (certList *CertificateList, err os.Error) { if bytes.HasPrefix(crlBytes, pemCRLPrefix) { block, _ := pem.Decode(crlBytes) if block != nil && block.Type == pemType { crlBytes = block.Bytes } } return ParseDER(crlBytes) } // ParseDER parses a DER encoded CRL from the given bytes. func ParseDER(derBytes []byte) (certList *CertificateList, err os.Error) { certList = new(CertificateList) _, err = asn1.Unmarshal(derBytes, certList) if err != nil { certList = nil } return }